tagging
This commit is contained in:
parent
85643184ea
commit
2112f730a8
|
@ -0,0 +1 @@
|
|||
topButtons: none
|
|
@ -0,0 +1,18 @@
|
|||
admin:
|
||||
text: ADMIN
|
||||
color: "#ff5555"
|
||||
trialmod:
|
||||
text: TRIAL MOD
|
||||
color: "#ffbb00"
|
||||
mod:
|
||||
text: MOD
|
||||
color: "#00aa00"
|
||||
media:
|
||||
text: MEDIA
|
||||
color: "#ff55ff"
|
||||
bot:
|
||||
text: BOT
|
||||
color: "#5555ff"
|
||||
owner:
|
||||
text: OWNER
|
||||
color: "#aa0000"
|
|
@ -11,7 +11,7 @@ defaultFlags:
|
|||
|
||||
# Whether or not to allow users to change their color.
|
||||
# Based on some reports, the MPP.com server stopped allowing this around 2016.
|
||||
enableColorChanging: true
|
||||
enableColorChanging: false
|
||||
|
||||
# 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.
|
||||
|
|
|
@ -12,13 +12,13 @@ datasource db {
|
|||
}
|
||||
|
||||
model User {
|
||||
id String @id @unique @map("_id")
|
||||
name String @default("Anonymous")
|
||||
color String @default("#ffffff")
|
||||
flags String @default("{}") // JSON flags object
|
||||
tag String // JSON tag
|
||||
tokens String @default("[]") // JSON tokens
|
||||
group String @default("default") // Permission group
|
||||
id String @id @unique @map("_id")
|
||||
name String @default("Anonymous")
|
||||
color String @default("#ffffff")
|
||||
flags String @default("{}") // JSON flags object
|
||||
tag String? // JSON tag
|
||||
tokens String @default("[]") // JSON tokens
|
||||
group String @default("default") // Permission group
|
||||
}
|
||||
|
||||
model ChatHistory {
|
||||
|
@ -34,7 +34,8 @@ model Channel {
|
|||
}
|
||||
|
||||
model Role {
|
||||
userId String @unique
|
||||
id Int @id @unique @default(autoincrement())
|
||||
userId String
|
||||
roleId String
|
||||
}
|
||||
|
||||
|
|
|
@ -321,6 +321,7 @@ export class Channel extends EventEmitter {
|
|||
|
||||
this.on("user data update", (user: User) => {
|
||||
try {
|
||||
if (!this.ppl.map(p => p._id).includes(user.id)) return;
|
||||
if (typeof user.name !== "string") return;
|
||||
if (typeof user.color !== "string") return;
|
||||
if (typeof user.id !== "string") return;
|
||||
|
|
|
@ -15,7 +15,8 @@ export const config = ConfigManager.loadConfig<Record<string, string[]>>(
|
|||
"usersetOthers",
|
||||
"siteBan",
|
||||
"siteBanAnyReason",
|
||||
"siteBanAnyDuration"
|
||||
"siteBanAnyDuration",
|
||||
"event.admin.*"
|
||||
]
|
||||
}
|
||||
);
|
|
@ -29,7 +29,7 @@ export async function giveRole(userId: string, roleId: string) {
|
|||
}
|
||||
|
||||
export async function removeRole(userId: string, roleId: string) {
|
||||
return await prisma.role.delete({
|
||||
return await prisma.role.deleteMany({
|
||||
where: {
|
||||
userId,
|
||||
roleId
|
||||
|
|
|
@ -19,7 +19,7 @@ import { loadForcedStartupChannels } from "./channel/forceLoad";
|
|||
import { Logger } from "./util/Logger";
|
||||
// docker hates this next one
|
||||
import { startReadline } from "./util/readline";
|
||||
import { loadDefaultPermissions } from "./data/permission";
|
||||
import { loadDefaultPermissions } from "./data/permissions";
|
||||
|
||||
// wrapper for some reason
|
||||
export function startServer() {
|
||||
|
|
|
@ -8,7 +8,8 @@ import {
|
|||
loadDefaultPermissions,
|
||||
removeAllRolePermissions,
|
||||
removeRolePermission
|
||||
} from "~/data/permission";
|
||||
} from "~/data/permissions";
|
||||
import { builtinTags, removeTag, setBuiltinTag } from "../tags";
|
||||
|
||||
Command.addCommand(
|
||||
new Command(["help", "h", "commands", "cmds"], "help", msg => {
|
||||
|
@ -94,11 +95,19 @@ Command.addCommand(
|
|||
|
||||
if (msg.args[1] === "add") {
|
||||
if (!msg.args[3]) return "No role id provided";
|
||||
|
||||
await giveRole(msg.args[2], msg.args[3]);
|
||||
await setBuiltinTag(msg.args[2], msg.args[3]);
|
||||
|
||||
return `Gave user ${msg.args[2]} role ${msg.args[3]}`;
|
||||
} else if (msg.args[1] === "remove") {
|
||||
if (!msg.args[3]) return "No role id provided";
|
||||
await removeRole(msg.args[2], msg.args[3]);
|
||||
|
||||
if (Object.keys(builtinTags).includes(msg.args[3])) {
|
||||
await removeTag(msg.args[2]);
|
||||
}
|
||||
|
||||
return `Removed role ${msg.args[3]} from ${msg.args[2]}`;
|
||||
} else if (msg.args[1] === "list") {
|
||||
const roles = await getRoles(msg.args[2]);
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
import { Socket } from "~/ws/Socket";
|
||||
import { ConfigManager } from "./config";
|
||||
import { Tag } from "./types";
|
||||
import { readUser, updateUser } from "~/data/user";
|
||||
import { prisma } from "~/data/prisma";
|
||||
import { User } from "@prisma/client";
|
||||
import { ChannelList } from "~/channel/ChannelList";
|
||||
|
||||
export const builtinTags = ConfigManager.loadConfig<Record<string, Tag>>(
|
||||
"config/tags.yml",
|
||||
{
|
||||
admin: {
|
||||
text: "ADMIN",
|
||||
color: "#ff5555"
|
||||
},
|
||||
trialmod: {
|
||||
text: "TRIAL MOD",
|
||||
color: "#ffbb00"
|
||||
},
|
||||
mod: {
|
||||
text: "MOD",
|
||||
color: "#00aa00"
|
||||
},
|
||||
media: {
|
||||
text: "MEDIA",
|
||||
color: "#ff55ff"
|
||||
},
|
||||
bot: {
|
||||
text: "BOT",
|
||||
color: "#5555ff"
|
||||
},
|
||||
owner: {
|
||||
text: "OWNER",
|
||||
color: "#aa0000"
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
function propogateUser(user: User) {
|
||||
const channelList = ChannelList.getList();
|
||||
|
||||
for (const ch of channelList) {
|
||||
ch.emit("user data update", user);
|
||||
}
|
||||
}
|
||||
|
||||
export async function setBuiltinTag(userId: string, tagId: string) {
|
||||
const user = await readUser(userId);
|
||||
if (!user) return;
|
||||
|
||||
const tag = builtinTags[tagId];
|
||||
if (!tag) return;
|
||||
|
||||
user.tag = JSON.stringify(tag);
|
||||
await updateUser(user.id, user);
|
||||
|
||||
propogateUser(user);
|
||||
}
|
||||
|
||||
export async function setTag(userId: string, tag: Tag) {
|
||||
const user = await readUser(userId);
|
||||
if (!user) return;
|
||||
|
||||
user.tag = JSON.stringify(tag);
|
||||
await updateUser(user.id, user);
|
||||
|
||||
propogateUser(user);
|
||||
}
|
||||
|
||||
export async function removeTag(userId: string) {
|
||||
const user = await readUser(userId);
|
||||
if (!user) return;
|
||||
|
||||
user.tag = "";
|
||||
await updateUser(user.id, user);
|
||||
|
||||
propogateUser(user);
|
||||
}
|
|
@ -231,6 +231,18 @@ declare interface ServerEvents {
|
|||
name: string;
|
||||
};
|
||||
|
||||
setcolor: {
|
||||
m: "setcolor";
|
||||
_id: string;
|
||||
color: string;
|
||||
};
|
||||
|
||||
setname: {
|
||||
m: "setname";
|
||||
_id: string;
|
||||
color: string;
|
||||
};
|
||||
|
||||
user_flag: {
|
||||
m: "user_flag";
|
||||
_id: string;
|
||||
|
|
|
@ -41,8 +41,9 @@ import {
|
|||
getUserPermissions,
|
||||
hasPermission,
|
||||
validatePermission
|
||||
} from "~/data/permission";
|
||||
} from "~/data/permissions";
|
||||
import { getRoles } from "~/data/role";
|
||||
import { setTag } from "~/util/tags";
|
||||
|
||||
const logger = new Logger("Sockets");
|
||||
|
||||
|
@ -792,10 +793,8 @@ export class Socket extends EventEmitter {
|
|||
**/
|
||||
public setTag(text: string, color: string) {
|
||||
//logger.debug("Setting tag:", text, color);
|
||||
const user = this.getUser();
|
||||
if (!user) return;
|
||||
user.tag = JSON.stringify({ text, color });
|
||||
updateUser(this.getUserID(), user);
|
||||
if (!this.user) return;
|
||||
setTag(this.user.id, { text, color });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -836,6 +835,11 @@ export class Socket extends EventEmitter {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this socket has a given permission
|
||||
* @param perm Permission string
|
||||
* @returns Whether this socket has the given permission
|
||||
*/
|
||||
public async hasPermission(perm: string) {
|
||||
if (!this.user) return false;
|
||||
|
||||
|
@ -844,6 +848,8 @@ export class Socket extends EventEmitter {
|
|||
for (const permission of permissions) {
|
||||
if (validatePermission(perm, permission)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
import type { ServerEventListener, ServerEvents } from "../util/types";
|
||||
import type { EventID, ServerEventListener, ServerEvents } from "../util/types";
|
||||
|
||||
export class EventGroup {
|
||||
public eventList = new Array<ServerEventListener<keyof ServerEvents>>();
|
||||
public eventList = new Array<ServerEventListener<any>>();
|
||||
constructor(public id: string) {}
|
||||
|
||||
public add(listener: ServerEventListener<keyof ServerEvents>) {
|
||||
public add(listener: ServerEventListener<any>) {
|
||||
this.eventList.push(listener);
|
||||
}
|
||||
|
||||
public addMany(...listeners: ServerEventListener<keyof ServerEvents>[]) {
|
||||
public addMany(...listeners: ServerEventListener<any>[]) {
|
||||
for (const l of listeners) this.add(l);
|
||||
}
|
||||
|
||||
public remove(listener: ServerEventListener<keyof ServerEvents>) {
|
||||
public remove(listener: ServerEventListener<any>) {
|
||||
this.eventList.splice(this.eventList.indexOf(listener), 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { getUserPermissions } from "~/data/permission";
|
||||
import { getUserPermissions } from "~/data/permissions";
|
||||
import { Logger } from "~/util/Logger";
|
||||
import { getMOTD } from "~/util/motd";
|
||||
import { createToken, getToken, validateToken } from "~/util/token";
|
||||
|
|
|
@ -14,7 +14,7 @@ export function handleMessage(socket: Socket, text: string) {
|
|||
logger.warn(
|
||||
"Received message that isn't an array! --",
|
||||
transmission,
|
||||
" -- from",
|
||||
"-- from",
|
||||
socket.getUserID()
|
||||
);
|
||||
} else {
|
||||
|
|
|
@ -8,6 +8,8 @@ import env from "../util/env";
|
|||
import { getMOTD } from "../util/motd";
|
||||
import nunjucks from "nunjucks";
|
||||
import type { ServerWebSocket } from "bun";
|
||||
import { ConfigManager } from "~/util/config";
|
||||
import { config as usersConfig } from "./usersConfig";
|
||||
|
||||
const logger = new Logger("WebSocket Server");
|
||||
|
||||
|
@ -15,6 +17,17 @@ const logger = new Logger("WebSocket Server");
|
|||
// for checking if they visited the site and are also connected to the websocket
|
||||
const httpIpCache = new Map<string, number>();
|
||||
|
||||
interface IFrontendConfig {
|
||||
topButtons: "original" | "none";
|
||||
}
|
||||
|
||||
const config = ConfigManager.loadConfig<IFrontendConfig>(
|
||||
"config/frontend.yml",
|
||||
{
|
||||
topButtons: "original"
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Get a rendered version of the index file
|
||||
* @returns Response with html in it
|
||||
|
@ -29,7 +42,9 @@ async function getIndex() {
|
|||
const index = Bun.file("./public/index.html");
|
||||
|
||||
const rendered = nunjucks.renderString(await index.text(), {
|
||||
motd: getMOTD()
|
||||
motd: getMOTD(),
|
||||
config,
|
||||
usersConfig
|
||||
});
|
||||
|
||||
const response = new Response(rendered);
|
||||
|
@ -38,7 +53,7 @@ async function getIndex() {
|
|||
return response;
|
||||
}
|
||||
|
||||
type ServerWebSocketMPP = ServerWebSocket<{ ip: string, socket: Socket }>
|
||||
type ServerWebSocketMPP = ServerWebSocket<{ ip: string; socket: Socket }>;
|
||||
|
||||
export const app = Bun.serve<{ ip: string }>({
|
||||
port: env.PORT,
|
||||
|
@ -81,7 +96,7 @@ export const app = Bun.serve<{ ip: string }>({
|
|||
if (data) {
|
||||
return new Response(data);
|
||||
}
|
||||
|
||||
|
||||
return getIndex();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue