Sanitize channel settings on channel creation
This commit is contained in:
parent
adf3a2d3fe
commit
621131699d
|
@ -60,20 +60,20 @@ export class Channel extends EventEmitter {
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.settings = {};
|
|
||||||
mixin(this.settings, config.defaultSettings);
|
|
||||||
this.logger = new Logger("Channel - " + _id);
|
this.logger = new Logger("Channel - " + _id);
|
||||||
|
this.settings = {};
|
||||||
|
|
||||||
// Validate settings in set
|
// Copy default settings
|
||||||
// Set the verified settings
|
mixin(this.settings, config.defaultSettings);
|
||||||
|
|
||||||
if (!this.isLobby()) {
|
if (!this.isLobby()) {
|
||||||
if (set) {
|
if (set) {
|
||||||
//this.logger.debug("Passed settings:", set);
|
// Validate settings in set
|
||||||
const validatedSet = validateChannelSettings(set);
|
const validatedSet = validateChannelSettings(set);
|
||||||
//this.logger.debug("Validated settings:", validatedSet);
|
|
||||||
|
|
||||||
for (const key of Object.keys(set)) {
|
// Set the verified settings
|
||||||
|
for (const key of Object.keys(validatedSet)) {
|
||||||
|
this.logger.debug(`${key}: ${(validatedSet as any)[key]}`);
|
||||||
if ((validatedSet as any)[key] === false) continue;
|
if ((validatedSet as any)[key] === false) continue;
|
||||||
(this.settings as any)[key] = (set as any)[key];
|
(this.settings as any)[key] = (set as any)[key];
|
||||||
}
|
}
|
||||||
|
@ -95,6 +95,7 @@ export class Channel extends EventEmitter {
|
||||||
|
|
||||||
ChannelList.add(this);
|
ChannelList.add(this);
|
||||||
// TODO implement owner_id
|
// TODO implement owner_id
|
||||||
|
this.settings.owner_id = owner_id;
|
||||||
|
|
||||||
this.logger.info("Created");
|
this.logger.info("Created");
|
||||||
}
|
}
|
||||||
|
@ -382,10 +383,6 @@ export class Channel extends EventEmitter {
|
||||||
* @returns undefined
|
* @returns undefined
|
||||||
*/
|
*/
|
||||||
public join(socket: Socket, force: boolean = false): void {
|
public join(socket: Socket, force: boolean = false): void {
|
||||||
//! /!\ Players are forced to join the same channel on two different tabs!
|
|
||||||
//? TODO Should this be a bug or a feature?
|
|
||||||
//this.logger.debug("join triggered");
|
|
||||||
|
|
||||||
if (this.isDestroyed()) return;
|
if (this.isDestroyed()) return;
|
||||||
const part = socket.getParticipant() as Participant;
|
const part = socket.getParticipant() as Participant;
|
||||||
|
|
||||||
|
@ -400,6 +397,18 @@ export class Channel extends EventEmitter {
|
||||||
for (const ch of chs) {
|
for (const ch of chs) {
|
||||||
const chid = ch.getID();
|
const chid = ch.getID();
|
||||||
if (chid == config.fullChannel) {
|
if (chid == config.fullChannel) {
|
||||||
|
const banTime = this.getBanTime(socket.getUserID());
|
||||||
|
this.logger.debug("Ban time:", banTime);
|
||||||
|
if (banTime) {
|
||||||
|
const minutes = Math.floor((banTime.endTime - banTime.startTime) / 1000 / 60);
|
||||||
|
|
||||||
|
socket.sendNotification({
|
||||||
|
class: "short",
|
||||||
|
duration: 7000,
|
||||||
|
target: "#room",
|
||||||
|
text: `Currently banned from "${this.getID()}" for ${minutes} minutes.`
|
||||||
|
});
|
||||||
|
}
|
||||||
return socket.setChannel(chid)
|
return socket.setChannel(chid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -859,10 +868,7 @@ export class Channel extends EventEmitter {
|
||||||
|
|
||||||
uuidsToKick = [...uuidsToKick, ...bannedUUIDs];
|
uuidsToKick = [...uuidsToKick, ...bannedUUIDs];
|
||||||
|
|
||||||
this.logger.debug("Banned UUIDs:", uuidsToKick);
|
|
||||||
|
|
||||||
for (const socket of socketsBySocketID.values()) {
|
for (const socket of socketsBySocketID.values()) {
|
||||||
this.logger.debug("Checking UUID:", socket.getUUID(), "| Result:", uuidsToKick.indexOf(socket.getUUID()) !== -1);
|
|
||||||
if (uuidsToKick.indexOf(socket.getUUID()) !== -1) {
|
if (uuidsToKick.indexOf(socket.getUUID()) !== -1) {
|
||||||
socket.sendNotification({
|
socket.sendNotification({
|
||||||
title: "Notice",
|
title: "Notice",
|
||||||
|
@ -875,7 +881,6 @@ export class Channel extends EventEmitter {
|
||||||
// If they are here, move them to the ban channel
|
// If they are here, move them to the ban channel
|
||||||
const ch = socket.getCurrentChannel();
|
const ch = socket.getCurrentChannel();
|
||||||
if (ch) {
|
if (ch) {
|
||||||
this.logger.debug("Current channel:", ch.getID(), "| We are:", this.getID());
|
|
||||||
if (ch.getID() == this.getID())
|
if (ch.getID() == this.getID())
|
||||||
socket.setChannel(banChannel.getID());
|
socket.setChannel(banChannel.getID());
|
||||||
}
|
}
|
||||||
|
@ -1028,6 +1033,19 @@ export class Channel extends EventEmitter {
|
||||||
return config.fullChannel;
|
return config.fullChannel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the amount of time someone is banned in this channel for.
|
||||||
|
* @param userId User ID
|
||||||
|
* @returns Object containing endTime and startTime of the ban
|
||||||
|
**/
|
||||||
|
public getBanTime(userId: string) {
|
||||||
|
for (const ban of this.bans) {
|
||||||
|
if (userId == ban.userId) {
|
||||||
|
return { endTime: ban.endTime, startTime: ban.startTime };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Channel;
|
export default Channel;
|
||||||
|
|
|
@ -36,6 +36,7 @@ export function loadDefaultForcedChannels() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasFullChannel) {
|
if (!hasFullChannel) {
|
||||||
new Channel(config.fullChannel, undefined, undefined, undefined, true);
|
//new Channel(config.fullChannel, undefined, undefined, undefined, true);
|
||||||
|
forceloadChannel(config.fullChannel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
import { Logger } from "../util/Logger";
|
|
||||||
import { IChannelSettings } from "../util/types";
|
import { IChannelSettings } from "../util/types";
|
||||||
|
|
||||||
type Validator = "boolean" | "string" | "number" | ((val: unknown) => boolean);
|
type Validator = "boolean" | "string" | "number" | ((val: unknown) => boolean);
|
||||||
|
|
||||||
// This record contains the exact data Brandon used to check channel settings, down to the regex.
|
// This record contains almost the exact code Brandon used to check channel settings, down to the regex.
|
||||||
// It also contains things that might be useful to other people in the future (things that make me vomit)
|
// It also contains things that might be useful in the future, like MPPNet settings
|
||||||
const validationRecord: Record<keyof IChannelSettings, Validator> = {
|
const validationRecord: Record<keyof IChannelSettings, Validator> = {
|
||||||
// Brandon
|
// Brandon's stuff
|
||||||
lobby: "boolean",
|
lobby: "boolean",
|
||||||
visible: "boolean",
|
visible: "boolean",
|
||||||
chat: "boolean",
|
chat: "boolean",
|
||||||
|
@ -21,17 +20,25 @@ const validationRecord: Record<keyof IChannelSettings, Validator> = {
|
||||||
},
|
},
|
||||||
owner_id: "string",
|
owner_id: "string",
|
||||||
|
|
||||||
// MPPClone (why?)
|
// MPPNet's stuff
|
||||||
limit: "number",
|
limit: val => {
|
||||||
|
return typeof val === "number" && val <= 99 && val >= 0
|
||||||
|
},
|
||||||
noindex: "boolean"
|
noindex: "boolean"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// i made this
|
||||||
|
const adminOnlyKeys = [
|
||||||
|
"lobby",
|
||||||
|
"owner_id"
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check the validity of channel settings
|
* Check the validity of channel settings
|
||||||
* @param set Dirty settings
|
* @param set Dirty settings
|
||||||
* @returns Record of which settings are correct
|
* @returns Record of which settings are correct (true) and which ones aren't (false)
|
||||||
*/
|
*/
|
||||||
export function validateChannelSettings(set: Partial<IChannelSettings>) {
|
export function validateChannelSettings(set: Partial<IChannelSettings>, admin = false) {
|
||||||
// Create record
|
// Create record
|
||||||
let record: Partial<Record<keyof IChannelSettings, boolean>> = {};
|
let record: Partial<Record<keyof IChannelSettings, boolean>> = {};
|
||||||
|
|
||||||
|
@ -47,6 +54,9 @@ export function validateChannelSettings(set: Partial<IChannelSettings>) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Are we allowed?
|
||||||
|
if (adminOnlyKeys.indexOf(key) !== -1 && !admin) continue;
|
||||||
|
|
||||||
// Set valid status
|
// Set valid status
|
||||||
record[key as keyof IChannelSettings] = validate(val, validator);
|
record[key as keyof IChannelSettings] = validate(val, validator);
|
||||||
}
|
}
|
||||||
|
@ -58,8 +68,8 @@ export default validateChannelSettings;
|
||||||
|
|
||||||
export function validate(value: any, validator: Validator) {
|
export function validate(value: any, validator: Validator) {
|
||||||
// What type of validator?
|
// What type of validator?
|
||||||
if (typeof validator == "function") {
|
if (typeof validator === "function") {
|
||||||
// We are copying Zod's functionality
|
// Run the function
|
||||||
return validator(value) === true;
|
return validator(value) === true;
|
||||||
} else if (typeof value === validator) {
|
} else if (typeof value === validator) {
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in New Issue