Add ID generation methods, add tags to userset updates
This commit is contained in:
parent
05299383a4
commit
ee2d6c4dde
|
@ -2,3 +2,4 @@ DATABASE_URL="file:./db.sqlite"
|
|||
PORT=8443
|
||||
ADMIN_PASS=
|
||||
SALT=
|
||||
COLOR_SALT=
|
||||
|
|
|
@ -26,6 +26,7 @@ Brandon's server originally used MongoDB for storing user data, but there are to
|
|||
- Usernames/colors
|
||||
- Allowing color changing can be toggled in the config, similar to MPP.com
|
||||
- Default user parameters can be set
|
||||
- Configurable ID and color generation methods
|
||||
- Channels
|
||||
- Channel list
|
||||
- Channel settings
|
||||
|
@ -46,6 +47,8 @@ Brandon's server originally used MongoDB for storing user data, but there are to
|
|||
- Server must be setup as a pm2/docker/systemd process for automatic restarting
|
||||
- Ability to change tags
|
||||
- Similar to the MPP.net server, but uses a Brandon-style admin message
|
||||
- Ability to rename channels
|
||||
- Chat clearing similar to MPP.net
|
||||
|
||||
## TODO
|
||||
|
||||
|
@ -67,6 +70,7 @@ Brandon's server originally used MongoDB for storing user data, but there are to
|
|||
- Test every frontend
|
||||
- Test fishing bot
|
||||
- Remote console
|
||||
- Modify frontend to use templating
|
||||
|
||||
## Backlog/Notes
|
||||
|
||||
|
@ -75,7 +79,6 @@ Brandon's server originally used MongoDB for storing user data, but there are to
|
|||
- Split script.js into multiple files
|
||||
- Implement tags as a server option, toggles code on frontend
|
||||
- Same with color changing
|
||||
- Bun memory usage can skyrocket
|
||||
- Reload config files on save
|
||||
- Expose API?
|
||||
|
||||
|
@ -115,7 +118,7 @@ such as enabling the color changing option in the userset modal menu, or sending
|
|||
$ cp .env.template .env
|
||||
```
|
||||
|
||||
Edit `.env` to your needs.
|
||||
Edit `.env` to your needs. Some variables are required for certain features to work.
|
||||
|
||||
- Edit the files in the `config` folder to match your needs
|
||||
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
# Which channels to load on startup.
|
||||
# Channel config file
|
||||
|
||||
forceLoad:
|
||||
- lobby
|
||||
- test/awkward
|
||||
|
||||
# Default channel settings for lobby channels.
|
||||
lobbySettings:
|
||||
lobby: true
|
||||
chat: true
|
||||
|
@ -11,36 +10,20 @@ lobbySettings:
|
|||
visible: true
|
||||
color: "#73b3cc"
|
||||
color2: "#273546"
|
||||
|
||||
# Default channel settings for normal user-created channels.
|
||||
# Note that this allows for channel settings users can't set, like visible and lobby.
|
||||
defaultSettings:
|
||||
chat: true
|
||||
crownsolo: false
|
||||
color: "#3b5054"
|
||||
color2: "#001014"
|
||||
visible: true
|
||||
|
||||
# Regex patterns for lobby channel names.
|
||||
# Any channel name that matches any of these patterns will be considered a lobby channel on instantiation.
|
||||
lobbyRegexes:
|
||||
- ^lobby[0-9][0-9]$
|
||||
- ^lobby[0-9]$
|
||||
- ^lobby$
|
||||
- ^lobbyNaN$
|
||||
- ^test/.+$
|
||||
|
||||
# The channel to use for the lobby backdoor.
|
||||
lobbyBackdoor: lolwutsecretlobbybackdoor
|
||||
|
||||
# The channel that users get sent to when they are banned from a channel/join a channel they are already banned in/join a channel that is full and not a regular lobby.
|
||||
# This will not be used for real lobby channels. (channels that start with "lobby" and may have numbers on the end)
|
||||
fullChannel: test/awkward
|
||||
|
||||
# Whether or not to publish channel user limits in the channel list.
|
||||
sendLimit: false
|
||||
|
||||
# Whether to give a user the crown when they join a channel they were already the owner of when they left.
|
||||
# Reportedly, this is a feature on the original server, but it's not working there.
|
||||
# This is corrected in MPP.net's server.
|
||||
chownOnRejoin: true
|
||||
sendTags: false
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# Notification config file
|
||||
|
||||
# Whether to allow HTML in notifications.
|
||||
# This is a security risk, so only enable this if you trust your admins.
|
||||
allowXSS: true
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# Rate limit config file
|
||||
|
||||
# Difference between rate limits and rate limit chains:
|
||||
# Rate limits will not allow anything to be sent until the rate limit interval has passed.
|
||||
# Rate limit chains, on the other hand, will allow messages to be sent until the rate limit chain's limit has been reached.
|
||||
|
|
|
@ -1,24 +1,29 @@
|
|||
# User data config file
|
||||
|
||||
# The default username for new users.
|
||||
defaultName: Anonymous
|
||||
|
||||
# The default user flags for new users.
|
||||
# These flags control arbitrary data that could be checked by any part of the code.
|
||||
# This is an internal feature available on MPP.com, but not MPP.net.
|
||||
defaultFlags:
|
||||
volume: 100
|
||||
|
||||
# Whether or not to allow users to change their color.
|
||||
# Brandon's server has this set to false, but multiple users have reported it to be on before 2016.
|
||||
# Based on some reports, the MPP.com server stopped allowing this around 2016.
|
||||
enableColorChanging: true
|
||||
|
||||
# Allows custom data inside note messages.
|
||||
# This was in the original server, but not in MPP.net's server.
|
||||
# This only exists for backwards compatibility with scripts like nagalun's drarwing script.
|
||||
# Whether to allow custom data inside note messages.
|
||||
# This was in the original server, but not in MPP.net's server do to stricter sanitization.
|
||||
# This only exists for backwards compatibility with scripts like nagalun's drawing script.
|
||||
enableCustomNoteData: true
|
||||
|
||||
# Whether or not to enable tags that are sent publicly.
|
||||
# This won't prevent admins from changing tags internally, but it will not be sent to clients.
|
||||
# This won't prevent admins from changing tags internally, but they will not be sent to clients if set to false.
|
||||
enableTags: true
|
||||
|
||||
# This is the user data that the server will use to send admin chat messages with.
|
||||
# This is a feature available on MPP.com, but was unknown to the MPP.net developers, therefore not implemented on MPP.net.
|
||||
adminParticipant:
|
||||
_id: "0"
|
||||
name: mpp
|
||||
|
@ -30,12 +35,28 @@ adminParticipant:
|
|||
enableAdminEval: true
|
||||
|
||||
# The token validation scheme. Valid values are "none", "jwt" and "uuid".
|
||||
# This server will still validate existing tokens generated with other schemes if not set to "none".
|
||||
tokenAuth: none
|
||||
# This server will still validate existing tokens generated with other schemes if not set to "none", mimicking MPP.net's server.
|
||||
# This is set to "none" by default because MPP.com does not have a token system.
|
||||
tokenAuth: jwt
|
||||
|
||||
# The browser challenge scheme. Valid values are "none", "obf" and "basic".
|
||||
# The browser challenge scheme. Valid options are "none", "obf" and "basic".
|
||||
# This is to change what is sent in the "b" message.
|
||||
# "none" will disable the browser challenge,
|
||||
# "obf" will sent an obfuscated function to the client,
|
||||
# and "basic" will just send a simple function that expects a boolean.
|
||||
browserChallenge: none
|
||||
browserChallenge: basic
|
||||
|
||||
# Scheme for generating user IDs.
|
||||
# Valid options are "random", "sha256", "mpp" and "uuid".
|
||||
# "random" will generate a random ID. As of writing, this is in use by MPP.com's server, but likely a mistake or poor workaround.
|
||||
# "sha256" will generate a hash of the user's IP address and the server's SALT with the SHA256 algorithm.
|
||||
# "mpp" will generate a hash of the user's IP address in the same way that MPP.com and MPP.net do. This is the default.
|
||||
# "uuid" will generate a UUID for the user ID.
|
||||
idGeneration: mpp
|
||||
|
||||
# Scheme for generating user colors.
|
||||
# Valid options are "random", "sha256", "mpp" and "white".
|
||||
# "random" will generate a random color for the user. This is not a known feature of any other server.
|
||||
# "sha256" will generate a color based on a hash of the user's ID.
|
||||
# "mpp" will generate a color based on the user's ID with a separate salt variable. This salt must be provided in the "COLOR_SALT" environment variable in the .env file.
|
||||
colorGeneration: mpp
|
||||
|
|
|
@ -18,6 +18,7 @@ model User {
|
|||
flags String @default("{}") // JSON flags object
|
||||
tag String // JSON tag
|
||||
tokens String @default("[]") // JSON tokens
|
||||
group String @default("default") // Permission group
|
||||
}
|
||||
|
||||
model ChatHistory {
|
||||
|
|
|
@ -53,7 +53,9 @@ export class Channel extends EventEmitter {
|
|||
}
|
||||
|
||||
private async deleteChatHistory() {
|
||||
try {
|
||||
await deleteChatHistory(this.getID());
|
||||
} catch (err) { }
|
||||
}
|
||||
|
||||
public logger: Logger;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { createEnv } from "@t3-oss/env-core";
|
||||
import { z } from "zod";
|
||||
import { config } from "../ws/usersConfig";
|
||||
|
||||
// Best way to do env ever
|
||||
export const env = createEnv({
|
||||
|
@ -7,7 +8,8 @@ export const env = createEnv({
|
|||
PORT: z.coerce.number(),
|
||||
HOST: z.union([z.string().url(), z.string().ip()]).optional(),
|
||||
SALT: z.string().min(10),
|
||||
ADMIN_PASS: z.string()
|
||||
ADMIN_PASS: z.string(),
|
||||
COLOR_SALT: config.colorGeneration == "mpp" ? z.string().min(10) : z.string().optional(),
|
||||
},
|
||||
isServer: true,
|
||||
// Bun loads process.env automatically so we don't have to use modules
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { createHash, randomBytes } from "crypto"; import env from "./env";
|
||||
import { spoop_text } from "./helpers";
|
||||
import { config } from "../ws/usersConfig";
|
||||
|
||||
export function createID() {
|
||||
// Maybe I could make this funnier than it needs to be...
|
||||
|
@ -21,24 +22,46 @@ export function createID() {
|
|||
}
|
||||
|
||||
export function createUserID(ip: string) {
|
||||
if (config.idGeneration == "random") {
|
||||
return createID();
|
||||
} else if (config.idGeneration == "sha256") {
|
||||
return createHash("sha256")
|
||||
.update(ip)
|
||||
.update(env.SALT)
|
||||
.digest("hex")
|
||||
.substring(0, 24);
|
||||
} else if (config.idGeneration == "mpp") {
|
||||
return createHash("md5")
|
||||
.update("::ffff:" + ip + env.SALT)
|
||||
.digest("hex")
|
||||
.substring(0, 24);
|
||||
}
|
||||
}
|
||||
|
||||
export function createSocketID() {
|
||||
return crypto.randomUUID();
|
||||
}
|
||||
|
||||
export function createColor(ip: string) {
|
||||
return (
|
||||
"#" +
|
||||
createHash("sha256")
|
||||
.update(ip)
|
||||
export function createColor(_id: string) {
|
||||
if (config.colorGeneration == "random") {
|
||||
return "#" + Math.floor(Math.random() * 16777215).toString(16);
|
||||
} else if (config.colorGeneration == "sha256") {
|
||||
return "#" + createHash("sha256")
|
||||
.update(_id)
|
||||
.update(env.SALT)
|
||||
.digest("hex")
|
||||
.substring(24, 24 + 6)
|
||||
);
|
||||
.substring(24, 24 + 6);
|
||||
} else if (config.colorGeneration == "mpp") {
|
||||
const hash = createHash("md5");
|
||||
hash.update(_id + env.COLOR_SALT);
|
||||
const output = hash.digest();
|
||||
|
||||
const r = output.readUInt8(0) - 0x40;
|
||||
const g = output.readUInt8(1) + 0x20;
|
||||
const b = output.readUInt8(2);
|
||||
|
||||
return "#" + r.toString(16) + g.toString(16) + b.toString(16);
|
||||
} else if (config.colorGeneration == "white") {
|
||||
return "#ffffff";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,12 +143,14 @@ export class Socket extends EventEmitter {
|
|||
|
||||
// Send a challenge to the browser for MPP.net frontends
|
||||
if (config.browserChallenge == "basic") {
|
||||
// Basic function
|
||||
this.sendArray([{
|
||||
m: "b",
|
||||
code: `~return true;`
|
||||
}]);
|
||||
} else if (config.browserChallenge == "obf") {
|
||||
|
||||
// Obfuscated challenge building
|
||||
// TODO
|
||||
}
|
||||
})();
|
||||
|
||||
|
@ -524,7 +526,8 @@ export class Socket extends EventEmitter {
|
|||
id: part.id,
|
||||
name: part.name,
|
||||
x: cursorPos.x,
|
||||
y: cursorPos.y
|
||||
y: cursorPos.y,
|
||||
tag: config.enableTags ? part.tag : undefined
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -50,13 +50,13 @@ export const hi: ServerEventListener<"hi"> = {
|
|||
// Validate the token
|
||||
const valid = await validateToken(socket.getUserID(), msg.token);
|
||||
if (!valid) {
|
||||
socket.ban(60000, "Invalid token");
|
||||
return;
|
||||
}
|
||||
|
||||
//socket.ban(60000, "Invalid token");
|
||||
//return;
|
||||
} else {
|
||||
token = msg.token;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let part = socket.getParticipant();
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@ export interface UsersConfig {
|
|||
enableAdminEval: boolean;
|
||||
tokenAuth: "jwt" | "uuid" | "none";
|
||||
browserChallenge: "none" | "obf" | "basic";
|
||||
idGeneration: "random" | "sha256" | "mpp" | "uuid";
|
||||
colorGeneration: "random" | "sha256" | "mpp" | "white";
|
||||
}
|
||||
|
||||
export const usersConfigPath = "config/users.yml";
|
||||
|
@ -31,7 +33,9 @@ export const defaultUsersConfig: UsersConfig = {
|
|||
},
|
||||
enableAdminEval: false,
|
||||
tokenAuth: "none",
|
||||
browserChallenge: "none"
|
||||
browserChallenge: "none",
|
||||
idGeneration: "mpp",
|
||||
colorGeneration: "mpp"
|
||||
};
|
||||
|
||||
// Importing this elsewhere causes bun to segfault
|
||||
|
|
Loading…
Reference in New Issue