1
0
mirror of https://github.com/spacebarchat/server.git synced 2024-11-14 06:32:36 +01:00

🎨 [Route] templates refactor

This commit is contained in:
Flam3rboy 2021-05-07 20:03:24 +02:00
parent 4e765c424e
commit 78fa2835ab
7 changed files with 12407 additions and 184 deletions

5
.vscode/launch.json vendored
View File

@ -9,9 +9,10 @@
"type": "node", "type": "node",
"request": "launch", "request": "launch",
"name": "Launch Server", "name": "Launch Server",
"program": "${workspaceFolder}/dist/index.js", "program": "${workspaceFolder}/dist/start.js",
"preLaunchTask": "tsc: build - tsconfig.json", "preLaunchTask": "tsc: build - tsconfig.json",
"outFiles": ["${workspaceFolder}/dist/**/*.js"] "outFiles": ["${workspaceFolder}/dist/**/*.js"],
"envFile": "${workspaceFolder}/.env"
}, },
{ {
"name": "Debug current file", "name": "Debug current file",

12314
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -2,135 +2,96 @@ import { Request, Response, Router } from "express";
import { TemplateModel, GuildModel, getPermission, toObject, UserModel, Snowflake } from "@fosscord/server-util"; import { TemplateModel, GuildModel, getPermission, toObject, UserModel, Snowflake } from "@fosscord/server-util";
import { HTTPError } from "lambert-server"; import { HTTPError } from "lambert-server";
import { TemplateCreateSchema, TemplateModifySchema } from "../../../schema/Template"; import { TemplateCreateSchema, TemplateModifySchema } from "../../../schema/Template";
import { emitEvent } from "../../../util/Event";
import { check } from "../../../util/instanceOf"; import { check } from "../../../util/instanceOf";
import { getPublicUser } from "../../../util/User"; import { generateCode } from "../../../util/String";
const router: Router = Router(); const router: Router = Router();
router.get("/", async (req: Request, res: Response) => { const TemplateGuildProjection = {
const guild_id = req.params.id; name: true,
description: true,
region: true,
verification_level: true,
default_message_notifications: true,
explicit_content_filter: true,
preferred_locale: true,
afk_timeout: true,
roles: true,
channels: true,
afk_channel_id: true,
system_channel_id: true,
system_channel_flags: true,
icon_hash: true,
};
const guild = await GuildModel.exists({ id: guild_id }); router.get("/", async (req: Request, res: Response) => {
if (!guild) throw new HTTPError("Guild not found", 404); const { guild_id } = req.params;
var templates = await TemplateModel.find({ source_guild_id: guild_id }).exec(); var templates = await TemplateModel.find({ source_guild_id: guild_id }).exec();
return res.json(toObject(templates)); return res.json(toObject(templates));
}); });
router.post("/", check(TemplateCreateSchema), async (req: Request, res: Response) => { router.post("/", check(TemplateCreateSchema), async (req: Request, res: Response) => {
const guild_id = req.params.guild_id; const guild_id = req.params.guild_id;
const { name } = req.body;
const guild = await GuildModel.findOne({ id: guild_id }, { id: true }).exec(); const guild = await GuildModel.findOne({ id: guild_id }, TemplateGuildProjection).exec();
if (!guild) throw new HTTPError("Guild not found", 404); if (!guild) throw new HTTPError("Guild not found", 404);
if (!name) throw new HTTPError("Unknown name", 404);
const user = await UserModel.findOne({ id: req.user_id }).exec();
if (!user) throw new HTTPError("User not found", 404);
const perms = await getPermission(req.user_id, guild_id); const perms = await getPermission(req.user_id, guild_id);
perms.hasThrow("MANAGE_GUILD");
if (!perms.has("MANAGE_GUILD")) const template = await new TemplateModel({
throw new HTTPError("You missing the MANAGE_GUILD permission", 401);
const template_id = Snowflake.generate();
var template = {
...req.body, ...req.body,
id: template_id, code: generateCode(),
creator_id: req.user_id, creator_id: req.user_id,
creator: user,
created_at: new Date(), created_at: new Date(),
updated_at: new Date(), updated_at: new Date(),
source_guild_id: guild_id, source_guild_id: guild_id,
serialized_source_guild: guild serialized_source_guild: guild,
} }).save();
const templatenew = await new TemplateModel(template).save(); res.json(toObject(template)).send();
res.json(toObject(templatenew)).send();
}); });
router.delete("/:template_id", async (req: Request, res: Response) => { router.delete("/:code", async (req: Request, res: Response) => {
const guild_id = req.params.guild_id; const guild_id = req.params.guild_id;
const { template_id } = req.params; const { code } = req.params;
const guild = await GuildModel.findOne({ id: guild_id }, { id: true }).exec();
if (!guild) throw new HTTPError("Guild not found", 404);
if (!template_id) throw new HTTPError("Unknown template_id", 404);
const user = await UserModel.findOne({ id: req.user_id }).exec();
if (!user) throw new HTTPError("User not found", 404);
const perms = await getPermission(req.user_id, guild_id); const perms = await getPermission(req.user_id, guild_id);
perms.hasThrow("MANAGE_GUILD");
if (!perms.has("MANAGE_GUILD")) const template = await TemplateModel.findOneAndDelete({
throw new HTTPError("You missing the MANAGE_GUILD permission", 401); code,
await TemplateModel.findOneAndDelete({
id: template_id,
source_guild_id: guild_id
}).exec(); }).exec();
res.send("Deleted"); res.send(toObject(template));
}); });
router.put("/:template_id", async (req: Request, res: Response) => { router.put("/:code", async (req: Request, res: Response) => {
const guild_id = req.params.guild_id; const guild_id = req.params.guild_id;
const { template_id } = req.params; const { code } = req.params;
const guild = await GuildModel.findOne({ id: guild_id }, { id: true }).exec(); const guild = await GuildModel.findOne({ id: guild_id }, TemplateGuildProjection).exec();
if (!guild) throw new HTTPError("Guild not found", 404); if (!guild) throw new HTTPError("Guild not found", 404);
if (!template_id) throw new HTTPError("Unknown template_id", 404);
const user = await UserModel.findOne({ id: req.user_id }).exec();
if (!user) throw new HTTPError("User not found", 404);
const template = await TemplateModel.findOneAndDelete({ id: template_id }).exec();
if (!template) throw new HTTPError("template not found", 404);
const perms = await getPermission(req.user_id, guild_id); const perms = await getPermission(req.user_id, guild_id);
perms.hasThrow("MANAGE_GUILD");
if (!perms.has("MANAGE_GUILD")) const template = await TemplateModel.findOneAndUpdate({ code }, { serialized_source_guild: guild }).exec();
throw new HTTPError("You missing the MANAGE_GUILD permission", 401);
var templateobj = await TemplateModel.findOneAndUpdate({ res.json(toObject(template)).send();
id: template_id,
serialized_source_guild: guild
}).exec();
res.json(toObject(templateobj)).send();
}); });
router.patch("/:template_id", check(TemplateModifySchema), async (req: Request, res: Response) => { router.patch("/:code", check(TemplateModifySchema), async (req: Request, res: Response) => {
const guild_id = req.params.guild_id; const { guild_id } = req.params;
const { template_id } = req.params; const { code } = req.params;
const guild = await GuildModel.findOne({ id: guild_id }, { id: true }).exec();
if (!guild) throw new HTTPError("Guild not found", 404);
if (!template_id) throw new HTTPError("Unknown template_id", 404);
const user = await UserModel.findOne({ id: req.user_id }).exec();
if (!user) throw new HTTPError("User not found", 404);
const template = await TemplateModel.findOne({ id: template_id }).exec();
if (!template) throw new HTTPError("template not found", 404);
const perms = await getPermission(req.user_id, guild_id); const perms = await getPermission(req.user_id, guild_id);
perms.hasThrow("MANAGE_GUILD");
if (!perms.has("MANAGE_GUILD")) const template = await TemplateModel.findOneAndUpdate({ code }, { name: req.body.name, description: req.body.description }).exec();
throw new HTTPError("You missing the MANAGE_GUILD permission", 401);
var templateobj = await TemplateModel.findOneAndUpdate({ res.json(toObject(template)).send();
id: template_id
}, {name: req.body.name,
description: req.body.description || "No description"}).exec();
res.json(toObject(templateobj)).send();
}); });
export default router; export default router;

View File

@ -8,23 +8,17 @@ import { check } from "../../../util/instanceOf";
import Config from "../../../util/Config"; import Config from "../../../util/Config";
import { addMember } from "../../../util/Member"; import { addMember } from "../../../util/Member";
router.get("/:template_id", async (req: Request, res: Response) => { router.get("/:code", async (req: Request, res: Response) => {
const { code } = req.params;
const guild_id = req.params.guild_id; const template = await TemplateModel.findOne({ id: code }).exec();
const { template_id } = req.params;
const guild = await GuildModel.findOne({ id: guild_id }, { id: true }).exec();
if (!guild) throw new HTTPError("Guild not found", 404);
if (!template_id) throw new HTTPError("Unknown template_id", 404);
const template = await TemplateModel.findOne({ id: template_id }).exec();
if (!template) throw new HTTPError("template not found", 404); if (!template) throw new HTTPError("template not found", 404);
res.json(toObject(template)).send(); res.json(toObject(template)).send();
}); });
router.post("/:template_id", check(GuildTemplateCreateSchema), async (req: Request, res: Response) => { router.post("/:code", check(GuildTemplateCreateSchema), async (req: Request, res: Response) => {
const { template_id } = req.params; const { code } = req.params;
const body = req.body as GuildTemplateCreateSchema; const body = req.body as GuildTemplateCreateSchema;
const { maxGuilds } = Config.get().limits.user; const { maxGuilds } = Config.get().limits.user;
@ -34,9 +28,7 @@ router.post("/:template_id", check(GuildTemplateCreateSchema), async (req: Reque
throw new HTTPError(`Maximum number of guilds reached ${maxGuilds}`, 403); throw new HTTPError(`Maximum number of guilds reached ${maxGuilds}`, 403);
} }
if (!template_id) throw new HTTPError("Unknown template_id", 404); const template = await TemplateModel.findOne({ code: code }).exec();
const template = await TemplateModel.findOne({ id: template_id }).exec();
if (!template) throw new HTTPError("template not found", 404); if (!template) throw new HTTPError("template not found", 404);
const guild_id = Snowflake.generate(); const guild_id = Snowflake.generate();
@ -45,7 +37,7 @@ router.post("/:template_id", check(GuildTemplateCreateSchema), async (req: Reque
...body, ...body,
...template.serialized_source_guild, ...template.serialized_source_guild,
id: guild_id, id: guild_id,
owner_id: req.user_id owner_id: req.user_id,
}; };
await Promise.all([ await Promise.all([
@ -68,5 +60,4 @@ router.post("/:template_id", check(GuildTemplateCreateSchema), async (req: Reque
res.status(201).json({ id: guild.id }); res.status(201).json({ id: guild.id });
}); });
export default router; export default router;

View File

@ -1,21 +1,19 @@
export const TemplateCreateSchema = { export const TemplateCreateSchema = {
name: String, name: String,
$description: String, $description: String,
}; };
export interface TemplateCreateSchema { export interface TemplateCreateSchema {
name: string, name: string;
description?: string, description?: string;
} }
export const TemplateModifySchema = { export const TemplateModifySchema = {
name: String, name: String,
$description: String, $description: String,
}; };
export interface TemplateModifySchema { export interface TemplateModifySchema {
name: string, name: string;
description?: string, description?: string;
} }

47
src/util/Base64.ts Normal file
View File

@ -0,0 +1,47 @@
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+";
// binary to string lookup table
const b2s = alphabet.split("");
// string to binary lookup table
// 123 == 'z'.charCodeAt(0) + 1
const s2b = new Array(123);
for (let i = 0; i < alphabet.length; i++) {
s2b[alphabet.charCodeAt(i)] = i;
}
// number to base64
export const ntob = (n: number): string => {
if (n < 0) return `-${ntob(-n)}`;
let lo = n >>> 0;
let hi = (n / 4294967296) >>> 0;
let right = "";
while (hi > 0) {
right = b2s[0x3f & lo] + right;
lo >>>= 6;
lo |= (0x3f & hi) << 26;
hi >>>= 6;
}
let left = "";
do {
left = b2s[0x3f & lo] + left;
lo >>>= 6;
} while (lo > 0);
return left + right;
};
// base64 to number
export const bton = (base64: string) => {
let number = 0;
const sign = base64.charAt(0) === "-" ? 1 : 0;
for (let i = sign; i < base64.length; i++) {
number = number * 64 + s2b[base64.charCodeAt(i)];
}
return sign ? -number : number;
};

View File

@ -1,4 +1,5 @@
import { Request } from "express"; import { Request } from "express";
import { ntob } from "./Base64";
import { FieldErrors } from "./instanceOf"; import { FieldErrors } from "./instanceOf";
export function checkLength(str: string, min: number, max: number, key: string, req: Request) { export function checkLength(str: string, min: number, max: number, key: string, req: Request) {
@ -11,3 +12,7 @@ export function checkLength(str: string, min: number, max: number, key: string,
}); });
} }
} }
export function generateCode() {
return ntob(Date.now() + Math.randomIntBetween(0, 10000));
}