Handle ban command arguments as array
This provides a much more reliable way to handle arguments with spaces, such as usernames. The ban process's stdout and stderr are now redirected to the server, in case they have output that would be good in the server's logs.
This commit is contained in:
@@ -20,7 +20,7 @@ export default interface IConfig {
|
|||||||
node : string;
|
node : string;
|
||||||
displayname : string;
|
displayname : string;
|
||||||
motd : string;
|
motd : string;
|
||||||
bancmd : string;
|
bancmd : string | string[];
|
||||||
moderatorEnabled : boolean;
|
moderatorEnabled : boolean;
|
||||||
usernameblacklist : string[];
|
usernameblacklist : string[];
|
||||||
maxChatLength : number;
|
maxChatLength : number;
|
||||||
|
|||||||
34
src/User.ts
34
src/User.ts
@@ -4,7 +4,9 @@ import {WebSocket} from 'ws';
|
|||||||
import {IPData} from './IPData.js';
|
import {IPData} from './IPData.js';
|
||||||
import IConfig from './IConfig.js';
|
import IConfig from './IConfig.js';
|
||||||
import RateLimiter from './RateLimiter.js';
|
import RateLimiter from './RateLimiter.js';
|
||||||
import { execaCommand } from 'execa';
|
import { execa, execaCommand, ExecaSyncError } from 'execa';
|
||||||
|
import log from './log.js';
|
||||||
|
|
||||||
export class User {
|
export class User {
|
||||||
socket : WebSocket;
|
socket : WebSocket;
|
||||||
nopSendInterval : NodeJS.Timeout;
|
nopSendInterval : NodeJS.Timeout;
|
||||||
@@ -100,13 +102,35 @@ export class User {
|
|||||||
this.sendMsg(guacutils.encode("chat", "", "You are no longer muted."));
|
this.sendMsg(guacutils.encode("chat", "", "You are no longer muted."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private banCmdArgs(arg: string) : string {
|
||||||
|
return arg.replace(/\$IP/g, this.IP.address).replace(/\$NAME/g, this.username || "");
|
||||||
|
}
|
||||||
|
|
||||||
async ban() {
|
async ban() {
|
||||||
// Prevent the user from taking turns or chatting, in case the ban command takes a while
|
// Prevent the user from taking turns or chatting, in case the ban command takes a while
|
||||||
this.IP.muted = true;
|
this.IP.muted = true;
|
||||||
//@ts-ignore
|
|
||||||
var cmd = this.Config.collabvm.bancmd.replace(/\$IP/g, this.IP.address).replace(/\$NAME/g, this.username);
|
try {
|
||||||
await execaCommand(cmd);
|
if (Array.isArray(this.Config.collabvm.bancmd)) {
|
||||||
this.kick();
|
let args: string[] = this.Config.collabvm.bancmd.map((a: string) => this.banCmdArgs(a));
|
||||||
|
if (args.length || args[0].length) {
|
||||||
|
await execa(args.shift()!, args, {stdout: process.stdout, stderr: process.stderr});
|
||||||
|
this.kick();
|
||||||
|
} else {
|
||||||
|
log("ERROR", `Failed to ban ${this.IP.address} (${this.username}): Empty command`);
|
||||||
|
}
|
||||||
|
} else if (typeof this.Config.collabvm.bancmd == "string") {
|
||||||
|
let cmd: string = this.banCmdArgs(this.Config.collabvm.bancmd);
|
||||||
|
if (cmd.length) {
|
||||||
|
await execaCommand(cmd, {stdout: process.stdout, stderr: process.stderr});
|
||||||
|
this.kick();
|
||||||
|
} else {
|
||||||
|
log("ERROR", `Failed to ban ${this.IP.address} (${this.username}): Empty command`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
log("ERROR", `Failed to ban ${this.IP.address} (${this.username}): ${(e as ExecaSyncError).shortMessage}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async kick() {
|
async kick() {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
export default function log(loglevel : string, message : string) {
|
export default function log(loglevel : string, ...message : string[]) {
|
||||||
console[
|
console[
|
||||||
(loglevel === "ERROR" || loglevel === "FATAL") ? "error" :
|
(loglevel === "ERROR" || loglevel === "FATAL") ? "error" :
|
||||||
(loglevel === "WARN") ? "warn" :
|
(loglevel === "WARN") ? "warn" :
|
||||||
"log"
|
"log"
|
||||||
](`[${new Date().toLocaleString()}] [${loglevel}] ${message}`);
|
](`[${new Date().toLocaleString()}] [${loglevel}]`, ...message);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user