From f44f5d7ac2d24ff836c2e1d4b2fa58da04b13052 Mon Sep 17 00:00:00 2001 From: Madeline <46743919+MaddyUnderStars@users.noreply.github.com> Date: Sun, 25 Sep 2022 18:24:21 +1000 Subject: Refactor to mono-repo + upgrade packages --- .../guilds/#guild_id/roles/#role_id/index.ts | 69 +++++++++++++ src/api/routes/guilds/#guild_id/roles/index.ts | 111 +++++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 src/api/routes/guilds/#guild_id/roles/#role_id/index.ts create mode 100644 src/api/routes/guilds/#guild_id/roles/index.ts (limited to 'src/api/routes/guilds/#guild_id/roles') diff --git a/src/api/routes/guilds/#guild_id/roles/#role_id/index.ts b/src/api/routes/guilds/#guild_id/roles/#role_id/index.ts new file mode 100644 index 00000000..a01068c0 --- /dev/null +++ b/src/api/routes/guilds/#guild_id/roles/#role_id/index.ts @@ -0,0 +1,69 @@ +import { Router, Request, Response } from "express"; +import { Role, Member, GuildRoleUpdateEvent, GuildRoleDeleteEvent, emitEvent, handleFile } from "@fosscord/util"; +import { route } from "@fosscord/api"; +import { HTTPError } from "lambert-server"; +import { RoleModifySchema } from "../"; + +const router = Router(); + +router.get("/", route({}), async (req: Request, res: Response) => { + const { guild_id, role_id } = req.params; + await Member.IsInGuildOrFail(req.user_id, guild_id); + const role = await Role.findOneOrFail({ where: { guild_id, id: role_id } }); + return res.json(role); +}); + +router.delete("/", route({ permission: "MANAGE_ROLES" }), async (req: Request, res: Response) => { + const { guild_id, role_id } = req.params; + if (role_id === guild_id) throw new HTTPError("You can't delete the @everyone role"); + + await Promise.all([ + Role.delete({ + id: role_id, + guild_id: guild_id + }), + emitEvent({ + event: "GUILD_ROLE_DELETE", + guild_id, + data: { + guild_id, + role_id + } + } as GuildRoleDeleteEvent) + ]); + + res.sendStatus(204); +}); + +// TODO: check role hierarchy + +router.patch("/", route({ body: "RoleModifySchema", permission: "MANAGE_ROLES" }), async (req: Request, res: Response) => { + const { role_id, guild_id } = req.params; + const body = req.body as RoleModifySchema; + + if (body.icon && body.icon.length) body.icon = await handleFile(`/role-icons/${role_id}`, body.icon as string); + else body.icon = undefined; + + const role = Role.create({ + ...body, + id: role_id, + guild_id, + permissions: String(req.permission!.bitfield & BigInt(body.permissions || "0")) + }); + + await Promise.all([ + role.save(), + emitEvent({ + event: "GUILD_ROLE_UPDATE", + guild_id, + data: { + guild_id, + role + } + } as GuildRoleUpdateEvent) + ]); + + res.json(role); +}); + +export default router; diff --git a/src/api/routes/guilds/#guild_id/roles/index.ts b/src/api/routes/guilds/#guild_id/roles/index.ts new file mode 100644 index 00000000..7e839f08 --- /dev/null +++ b/src/api/routes/guilds/#guild_id/roles/index.ts @@ -0,0 +1,111 @@ +import { Request, Response, Router } from "express"; +import { + Role, + getPermission, + Member, + GuildRoleCreateEvent, + GuildRoleUpdateEvent, + GuildRoleDeleteEvent, + emitEvent, + Config, + DiscordApiErrors, + handleFile +} from "@fosscord/util"; +import { HTTPError } from "lambert-server"; +import { route } from "@fosscord/api"; + +const router: Router = Router(); + +export interface RoleModifySchema { + name?: string; + permissions?: string; + color?: number; + hoist?: boolean; // whether the role should be displayed separately in the sidebar + mentionable?: boolean; // whether the role should be mentionable + position?: number; + icon?: string; + unicode_emoji?: string; +} + +export type RolePositionUpdateSchema = { + id: string; + position: number; +}[]; + +router.get("/", route({}), async (req: Request, res: Response) => { + const guild_id = req.params.guild_id; + + await Member.IsInGuildOrFail(req.user_id, guild_id); + + const roles = await Role.find({ where: { guild_id: guild_id } }); + + return res.json(roles); +}); + +router.post("/", route({ body: "RoleModifySchema", permission: "MANAGE_ROLES" }), async (req: Request, res: Response) => { + const guild_id = req.params.guild_id; + const body = req.body as RoleModifySchema; + + const role_count = await Role.count({ where: { guild_id } }); + const { maxRoles } = Config.get().limits.guild; + + if (role_count > maxRoles) throw DiscordApiErrors.MAXIMUM_ROLES.withParams(maxRoles); + + const role = Role.create({ + // values before ...body are default and can be overriden + position: 0, + hoist: false, + color: 0, + mentionable: false, + ...body, + guild_id: guild_id, + managed: false, + permissions: String(req.permission!.bitfield & BigInt(body.permissions || "0")), + tags: undefined, + icon: undefined, + unicode_emoji: undefined + }); + + await Promise.all([ + role.save(), + emitEvent({ + event: "GUILD_ROLE_CREATE", + guild_id, + data: { + guild_id, + role: role + } + } as GuildRoleCreateEvent) + ]); + + res.json(role); +}); + +router.patch("/", route({ body: "RolePositionUpdateSchema" }), async (req: Request, res: Response) => { + const { guild_id } = req.params; + const body = req.body as RolePositionUpdateSchema; + + const perms = await getPermission(req.user_id, guild_id); + perms.hasThrow("MANAGE_ROLES"); + + await Promise.all(body.map(async (x) => Role.update({ guild_id, id: x.id }, { position: x.position }))); + + const roles = await Role.find({ where: body.map((x) => ({ id: x.id, guild_id })) }); + + await Promise.all( + roles.map((x) => + emitEvent({ + event: "GUILD_ROLE_UPDATE", + guild_id, + data: { + guild_id, + role: x + } + } as GuildRoleUpdateEvent) + ) + ); + + res.json(roles); +}); + +export default router; -- cgit 1.4.1