diff options
author | Flam3rboy <34555296+Flam3rboy@users.noreply.github.com> | 2021-08-29 00:03:40 +0200 |
---|---|---|
committer | Flam3rboy <34555296+Flam3rboy@users.noreply.github.com> | 2021-08-29 00:03:40 +0200 |
commit | c9ff1774b435b5af72faa97386890b3cb659744c (patch) | |
tree | b6f19efe257faa3e41b21862bda6cf1737d8b15a /api/src/routes/guilds | |
parent | :construction: typeorm (diff) | |
download | server-c9ff1774b435b5af72faa97386890b3cb659744c.tar.xz |
:sparkles: typeorm api rewrite done
Diffstat (limited to 'api/src/routes/guilds')
-rw-r--r-- | api/src/routes/guilds/#guild_id/bans.ts | 71 | ||||
-rw-r--r-- | api/src/routes/guilds/#guild_id/delete.ts | 19 | ||||
-rw-r--r-- | api/src/routes/guilds/#guild_id/index.ts | 39 | ||||
-rw-r--r-- | api/src/routes/guilds/#guild_id/invites.ts | 2 | ||||
-rw-r--r-- | api/src/routes/guilds/#guild_id/members/#member_id/index.ts | 27 | ||||
-rw-r--r-- | api/src/routes/guilds/#guild_id/members/#member_id/nick.ts | 5 | ||||
-rw-r--r-- | api/src/routes/guilds/#guild_id/members/#member_id/roles/#role_id/index.ts | 7 | ||||
-rw-r--r-- | api/src/routes/guilds/#guild_id/members/index.ts | 21 | ||||
-rw-r--r-- | api/src/routes/guilds/#guild_id/roles.ts | 68 | ||||
-rw-r--r-- | api/src/routes/guilds/#guild_id/vanity-url.ts | 38 | ||||
-rw-r--r-- | api/src/routes/guilds/#guild_id/welcome_screen.ts | 28 | ||||
-rw-r--r-- | api/src/routes/guilds/#guild_id/widget.json.ts | 95 | ||||
-rw-r--r-- | api/src/routes/guilds/index.ts | 17 | ||||
-rw-r--r-- | api/src/routes/guilds/templates/index.ts | 25 |
14 files changed, 178 insertions, 284 deletions
diff --git a/api/src/routes/guilds/#guild_id/bans.ts b/api/src/routes/guilds/#guild_id/bans.ts index cbc0b0fa..b84a68a7 100644 --- a/api/src/routes/guilds/#guild_id/bans.ts +++ b/api/src/routes/guilds/#guild_id/bans.ts @@ -1,22 +1,17 @@ import { Request, Response, Router } from "express"; -import { BanModel, emitEvent, getPermission, GuildBanAddEvent, GuildBanRemoveEvent, Guild, toObject } from "@fosscord/util"; +import { emitEvent, getPermission, GuildBanAddEvent, GuildBanRemoveEvent, Guild, Ban, User, Member } from "@fosscord/util"; import { HTTPError } from "lambert-server"; import { getIpAdress } from "../../../util/ipAddress"; import { BanCreateSchema } from "../../../schema/Ban"; import { check } from "../../../util/instanceOf"; -import { removeMember } from "../../../util/Member"; -import { getPublicUser } from "../../../util/User"; const router: Router = Router(); router.get("/", async (req: Request, res: Response) => { const { guild_id } = req.params; - const guild = await Guild.exists({ id: guild_id }); - if (!guild) throw new HTTPError("Guild not found", 404); - - var bans = await Ban.find({ guild_id: guild_id }, { user_id: true, reason: true }); + var bans = await Ban.find({ guild_id: guild_id }); return res.json(bans); }); @@ -32,29 +27,32 @@ router.put("/:user_id", check(BanCreateSchema), async (req: Request, res: Respon const { guild_id } = req.params; const banned_user_id = req.params.user_id; - const banned_user = await getPublicUser(banned_user_id); + const banned_user = await User.getPublicUser(banned_user_id); const perms = await getPermission(req.user_id, guild_id); perms.hasThrow("BAN_MEMBERS"); if (req.user_id === banned_user_id) throw new HTTPError("You can't ban yourself", 400); + if (perms.cache.guild?.owner_id === banned_user_id) throw new HTTPError("You can't ban the owner", 400); - await removeMember(banned_user_id, guild_id); - - const ban = await new BanModel({ + const ban = new Ban({ user_id: banned_user_id, guild_id: guild_id, ip: getIpAdress(req), executor_id: req.user_id, reason: req.body.reason // || otherwise empty - }).save(); + }); - await emitEvent({ - event: "GUILD_BAN_ADD", - data: { - guild_id: guild_id, - user: banned_user - }, - guild_id: guild_id - } as GuildBanAddEvent); + await Promise.all([ + Member.removeFromGuild(banned_user_id, guild_id), + ban.save(), + emitEvent({ + event: "GUILD_BAN_ADD", + data: { + guild_id: guild_id, + user: banned_user + }, + guild_id: guild_id + } as GuildBanAddEvent) + ]); return res.json(ban); }); @@ -63,26 +61,25 @@ router.delete("/:user_id", async (req: Request, res: Response) => { var { guild_id } = req.params; var banned_user_id = req.params.user_id; - const banned_user = await getPublicUser(banned_user_id); - const guild = await Guild.exists({ id: guild_id }); - if (!guild) throw new HTTPError("Guild not found", 404); - + const banned_user = await User.getPublicUser(banned_user_id); const perms = await getPermission(req.user_id, guild_id); perms.hasThrow("BAN_MEMBERS"); - await Ban.deleteOne({ - user_id: banned_user_id, - guild_id - }); - - await emitEvent({ - event: "GUILD_BAN_REMOVE", - data: { - guild_id, - user: banned_user - }, - guild_id - } as GuildBanRemoveEvent); + await Promise.all([ + Ban.delete({ + user_id: banned_user_id, + guild_id + }), + + emitEvent({ + event: "GUILD_BAN_REMOVE", + data: { + guild_id, + user: banned_user + }, + guild_id + } as GuildBanRemoveEvent) + ]); return res.status(204).send(); }); diff --git a/api/src/routes/guilds/#guild_id/delete.ts b/api/src/routes/guilds/#guild_id/delete.ts index a53271ce..043260e9 100644 --- a/api/src/routes/guilds/#guild_id/delete.ts +++ b/api/src/routes/guilds/#guild_id/delete.ts @@ -1,4 +1,4 @@ -import { Channel, emitEvent, EmojiModel, GuildDeleteEvent, Guild, InviteModel, Member, Message, Role, User } from "@fosscord/util"; +import { Channel, emitEvent, GuildDeleteEvent, Guild, Member, Message, Role, Invite, Emoji } from "@fosscord/util"; import { Router, Request, Response } from "express"; import { HTTPError } from "lambert-server"; @@ -9,7 +9,7 @@ const router = Router(); router.post("/", async (req: Request, res: Response) => { var { guild_id } = req.params; - const guild = await Guild.findOneOrFail({ id: guild_id }, "owner_id"); + const guild = await Guild.findOneOrFail({ where: { id: guild_id }, select: ["owner_id"] }); if (guild.owner_id !== req.user_id) throw new HTTPError("You are not the owner of this guild", 401); await emitEvent({ @@ -21,14 +21,13 @@ router.post("/", async (req: Request, res: Response) => { } as GuildDeleteEvent); await Promise.all([ - Guild.deleteOne({ id: guild_id }), - User.updateMany({ guilds: guild_id }, { $pull: { guilds: guild_id } }), - Role.deleteMany({ guild_id }), - Channel.deleteMany({ guild_id }), - Emoji.deleteMany({ guild_id }), - Invite.deleteMany({ guild_id }), - Message.deleteMany({ guild_id }), - Member.deleteMany({ guild_id }) + Guild.delete({ id: guild_id }), + Role.delete({ guild_id }), + Channel.delete({ guild_id }), + Emoji.delete({ guild_id }), + Invite.delete({ guild_id }), + Message.delete({ guild_id }), + Member.delete({ guild_id }) ]); return res.sendStatus(204); diff --git a/api/src/routes/guilds/#guild_id/index.ts b/api/src/routes/guilds/#guild_id/index.ts index af9ea9d6..d205b164 100644 --- a/api/src/routes/guilds/#guild_id/index.ts +++ b/api/src/routes/guilds/#guild_id/index.ts @@ -1,19 +1,5 @@ import { Request, Response, Router } from "express"; -import { - Channel, - emitEvent, - EmojiModel, - getPermission, - GuildDeleteEvent, - Guild, - GuildUpdateEvent, - InviteModel, - Member, - Message, - Role, - toObject, - User -} from "@fosscord/util"; +import { emitEvent, getPermission, Guild, GuildUpdateEvent, Member } from "@fosscord/util"; import { HTTPError } from "lambert-server"; import { GuildUpdateSchema } from "../../../schema/Guild"; @@ -26,9 +12,15 @@ const router = Router(); router.get("/", async (req: Request, res: Response) => { const { guild_id } = req.params; - const guild = await Guild.findOneOrFail({ id: guild_id }).populate({ path: "joined_at", match: { id: req.user_id } }); - const member = await Member.exists({ guild_id: guild_id, id: req.user_id }); - if (!member) throw new HTTPError("You are not a member of the guild you are trying to access", 401); + const [guild, member_count, member] = await Promise.all([ + Guild.findOneOrFail({ id: guild_id }), + Member.count({ guild_id: guild_id, id: req.user_id }), + Member.findOneOrFail(req.user_id) + ]); + if (!member_count) throw new HTTPError("You are not a member of the guild you are trying to access", 401); + + // @ts-ignore + guild.joined_at = member?.joined_at; return res.json(guild); }); @@ -45,15 +37,12 @@ router.patch("/", check(GuildUpdateSchema), async (req: Request, res: Response) if (body.banner) body.banner = await handleFile(`/banners/${guild_id}`, body.banner); if (body.splash) body.splash = await handleFile(`/splashes/${guild_id}`, body.splash); - const guild = await Guild.findOneOrFailAndUpdate({ id: guild_id }, body, { new: true }).populate({ - path: "joined_at", - match: { id: req.user_id } - }); - const data = guild; + const guild = await Guild.findOneOrFail({ id: guild_id }); + guild.assign(body); - emitEvent({ event: "GUILD_UPDATE", data: data, guild_id } as GuildUpdateEvent); + await Promise.all([guild.save(), emitEvent({ event: "GUILD_UPDATE", data: guild, guild_id } as GuildUpdateEvent)]); - return res.json(data); + return res.json(guild); }); export default router; diff --git a/api/src/routes/guilds/#guild_id/invites.ts b/api/src/routes/guilds/#guild_id/invites.ts index ca72cce8..1843b689 100644 --- a/api/src/routes/guilds/#guild_id/invites.ts +++ b/api/src/routes/guilds/#guild_id/invites.ts @@ -1,4 +1,4 @@ -import { getPermission, InviteModel, toObject } from "@fosscord/util"; +import { getPermission, Invite } from "@fosscord/util"; import { Request, Response, Router } from "express"; const router = Router(); diff --git a/api/src/routes/guilds/#guild_id/members/#member_id/index.ts b/api/src/routes/guilds/#guild_id/members/#member_id/index.ts index 1dacbdad..db29cd08 100644 --- a/api/src/routes/guilds/#guild_id/members/#member_id/index.ts +++ b/api/src/routes/guilds/#guild_id/members/#member_id/index.ts @@ -3,7 +3,6 @@ import { Guild, Member, User, - toObject, GuildMemberAddEvent, getPermission, PermissionResolvable, @@ -12,15 +11,15 @@ import { emitEvent } from "@fosscord/util"; import { HTTPError } from "lambert-server"; -import { addMember, isMember, removeMember } from "../../../../../util/Member"; import { check } from "../../../../../util/instanceOf"; import { MemberChangeSchema } from "../../../../../schema/Member"; +import { In } from "typeorm"; const router = Router(); router.get("/", async (req: Request, res: Response) => { const { guild_id, member_id } = req.params; - await isMember(req.user_id, guild_id); + await Member.IsInGuildOrFail(req.user_id, guild_id); const member = await Member.findOneOrFail({ id: member_id, guild_id }); @@ -31,18 +30,22 @@ router.patch("/", check(MemberChangeSchema), async (req: Request, res: Response) const { guild_id, member_id } = req.params; const body = req.body as MemberChangeSchema; if (body.roles) { - const roles = await Role.find({ id: { $in: body.roles } }); + const roles = await Role.find({ id: In(body.roles) }); if (body.roles.length !== roles.length) throw new HTTPError("Roles not found", 404); // TODO: check if user has permission to add role } - const member = await Member.findOneOrFailAndUpdate({ id: member_id, guild_id }, body, { new: true }); + const member = await Member.findOneOrFail({ id: member_id, guild_id }); + member.assign(req.body); - await emitEvent({ - event: "GUILD_MEMBER_UPDATE", - guild_id, - data: member - } as GuildMemberUpdateEvent); + Promise.all([ + member.save(), + emitEvent({ + event: "GUILD_MEMBER_UPDATE", + guild_id, + data: { ...member, roles: member.role_ids } + } as GuildMemberUpdateEvent) + ]); res.json(member); }); @@ -52,7 +55,7 @@ router.put("/", async (req: Request, res: Response) => { throw new HTTPError("Maintenance: Currently you can't add a member", 403); // TODO: only for oauth2 applications - await addMember(member_id, guild_id); + await Member.addToGuild(member_id, guild_id); res.sendStatus(204); }); @@ -62,7 +65,7 @@ router.delete("/", async (req: Request, res: Response) => { const perms = await getPermission(req.user_id, guild_id); perms.hasThrow("KICK_MEMBERS"); - await removeMember(member_id, guild_id); + await Member.removeFromGuild(member_id, guild_id); res.sendStatus(204); }); diff --git a/api/src/routes/guilds/#guild_id/members/#member_id/nick.ts b/api/src/routes/guilds/#guild_id/members/#member_id/nick.ts index e4308364..3f2975e6 100644 --- a/api/src/routes/guilds/#guild_id/members/#member_id/nick.ts +++ b/api/src/routes/guilds/#guild_id/members/#member_id/nick.ts @@ -1,8 +1,7 @@ -import { getPermission, PermissionResolvable } from "@fosscord/util"; +import { getPermission, Member, PermissionResolvable } from "@fosscord/util"; import { Request, Response, Router } from "express"; import { check } from "lambert-server"; import { MemberNickChangeSchema } from "../../../../../schema/Member"; -import { changeNickname } from "../../../../../util/Member"; const router = Router(); @@ -17,7 +16,7 @@ router.patch("/", check(MemberNickChangeSchema), async (req: Request, res: Respo const perms = await getPermission(req.user_id, guild_id); perms.hasThrow(permissionString); - await changeNickname(member_id, guild_id, req.body.nick); + await Member.changeNickname(member_id, guild_id, req.body.nick); res.status(200).send(); }); diff --git a/api/src/routes/guilds/#guild_id/members/#member_id/roles/#role_id/index.ts b/api/src/routes/guilds/#guild_id/members/#member_id/roles/#role_id/index.ts index fad0695e..cb9bad9a 100644 --- a/api/src/routes/guilds/#guild_id/members/#member_id/roles/#role_id/index.ts +++ b/api/src/routes/guilds/#guild_id/members/#member_id/roles/#role_id/index.ts @@ -1,6 +1,5 @@ -import { getPermission } from "@fosscord/util"; +import { getPermission, Member } from "@fosscord/util"; import { Request, Response, Router } from "express"; -import { addRole, removeRole } from "../../../../../../../util/Member"; const router = Router(); @@ -10,7 +9,7 @@ router.delete("/:member_id/roles/:role_id", async (req: Request, res: Response) const perms = await getPermission(req.user_id, guild_id); perms.hasThrow("MANAGE_ROLES"); - await removeRole(member_id, guild_id, role_id); + await Member.removeRole(member_id, guild_id, role_id); res.sendStatus(204); }); @@ -20,7 +19,7 @@ router.put("/:member_id/roles/:role_id", async (req: Request, res: Response) => const perms = await getPermission(req.user_id, guild_id); perms.hasThrow("MANAGE_ROLES"); - await addRole(member_id, guild_id, role_id); + await Member.addRole(member_id, guild_id, role_id); res.sendStatus(204); }); diff --git a/api/src/routes/guilds/#guild_id/members/index.ts b/api/src/routes/guilds/#guild_id/members/index.ts index 656d3acd..0bfd71cb 100644 --- a/api/src/routes/guilds/#guild_id/members/index.ts +++ b/api/src/routes/guilds/#guild_id/members/index.ts @@ -1,8 +1,7 @@ import { Request, Response, Router } from "express"; -import { Guild, Member, toObject } from "@fosscord/util"; -import { HTTPError } from "lambert-server"; +import { Guild, Member, PublicMemberProjection } from "@fosscord/util"; import { instanceOf, Length } from "../../../../util/instanceOf"; -import { PublicMemberProjection, isMember } from "../../../../util/Member"; +import { MoreThan } from "typeorm"; const router = Router(); @@ -11,7 +10,7 @@ const router = Router(); router.get("/", async (req: Request, res: Response) => { const { guild_id } = req.params; const guild = await Guild.findOneOrFail({ id: guild_id }); - await isMember(req.user_id, guild_id); + await Member.IsInGuildOrFail(req.user_id, guild_id); try { instanceOf({ $limit: new Length(Number, 1, 1000), $after: String }, req.query, { @@ -23,12 +22,16 @@ router.get("/", async (req: Request, res: Response) => { return res.status(400).json({ code: 50035, message: "Invalid Query", success: false, errors: error }); } - // @ts-ignore - if (!req.query.limit) req.query.limit = 1; - const { limit, after } = (<unknown>req.query) as { limit: number; after: string }; - const query = after ? { id: { $gt: after } } : {}; + const { limit, after } = (<unknown>req.query) as { limit?: number; after?: string }; + const query = after ? { id: MoreThan(after) } : {}; + + const members = await Member.find({ + where: { guild_id, ...query }, + select: PublicMemberProjection, + take: limit || 1, + order: { id: "ASC" } + }); - var members = await Member.find({ guild_id, ...query }, PublicMemberProjection).limit(limit); return res.json(members); }); diff --git a/api/src/routes/guilds/#guild_id/roles.ts b/api/src/routes/guilds/#guild_id/roles.ts index 5ebc0580..e9e777b9 100644 --- a/api/src/routes/guilds/#guild_id/roles.ts +++ b/api/src/routes/guilds/#guild_id/roles.ts @@ -1,10 +1,7 @@ import { Request, Response, Router } from "express"; import { Role, - Guild, getPermission, - toObject, - User, Snowflake, Member, GuildRoleCreateEvent, @@ -16,15 +13,13 @@ import { HTTPError } from "lambert-server"; import { check } from "../../../util/instanceOf"; import { RoleModifySchema } from "../../../schema/Roles"; -import { getPublicUser } from "../../../util/User"; -import { isMember } from "../../../util/Member"; const router: Router = Router(); router.get("/", async (req: Request, res: Response) => { const guild_id = req.params.guild_id; - await isMember(req.user_id, guild_id); + await Member.IsInGuildOrFail(req.user_id, guild_id); const roles = await Role.find({ guild_id: guild_id }); @@ -35,12 +30,8 @@ router.post("/", check(RoleModifySchema), async (req: Request, res: Response) => const guild_id = req.params.guild_id; const body = req.body as RoleModifySchema; - const guild = await Guild.findOneOrFail({ id: guild_id }, { id: true }); - const user = await User.findOneOrFail({ id: req.user_id }); - const perms = await getPermission(req.user_id, guild_id); perms.hasThrow("MANAGE_ROLES"); - if (!body.name) throw new HTTPError("You need to specify a name"); const role = await new Role({ ...body, @@ -49,7 +40,7 @@ router.post("/", check(RoleModifySchema), async (req: Request, res: Response) => managed: false, position: 0, tags: null, - permissions: body.permissions || 0n + permissions: perms.bitfield & (body.permissions || 0n) }).save(); await emitEvent({ @@ -72,19 +63,20 @@ router.delete("/:role_id", async (req: Request, res: Response) => { const permissions = await getPermission(req.user_id, guild_id); permissions.hasThrow("MANAGE_ROLES"); - await Role.deleteOne({ - id: role_id, - guild_id: guild_id - }); - - await emitEvent({ - event: "GUILD_ROLE_DELETE", - guild_id, - data: { + await Promise.all([ + Role.delete({ + id: role_id, + guild_id: guild_id + }), + emitEvent({ + event: "GUILD_ROLE_DELETE", guild_id, - role_id - } - } as GuildRoleDeleteEvent); + data: { + guild_id, + role_id + } + } as GuildRoleDeleteEvent) + ]); res.sendStatus(204); }); @@ -96,30 +88,22 @@ router.patch("/:role_id", check(RoleModifySchema), async (req: Request, res: Res const { role_id } = req.params; const body = req.body as RoleModifySchema; - const guild = await Guild.findOneOrFail({ id: guild_id }, { id: true }); - const user = await User.findOneOrFail({ id: req.user_id }); - const perms = await getPermission(req.user_id, guild_id); perms.hasThrow("MANAGE_ROLES"); - const role = await Role.findOneOrFailAndUpdate( - { - id: role_id, - guild_id: guild_id - }, - // @ts-ignore - body, - { new: true } - ); + const role = new Role({ ...body, role_id, guild_id, permissions: perms.bitfield & (body.permissions || 0n) }); - await emitEvent({ - event: "GUILD_ROLE_UPDATE", - guild_id, - data: { + await Promise.all([ + role.save(), + emitEvent({ + event: "GUILD_ROLE_UPDATE", guild_id, - role - } - } as GuildRoleUpdateEvent); + data: { + guild_id, + role + } + } as GuildRoleUpdateEvent) + ]); res.json(role); }); diff --git a/api/src/routes/guilds/#guild_id/vanity-url.ts b/api/src/routes/guilds/#guild_id/vanity-url.ts index 335cea27..58940b42 100644 --- a/api/src/routes/guilds/#guild_id/vanity-url.ts +++ b/api/src/routes/guilds/#guild_id/vanity-url.ts @@ -1,8 +1,7 @@ -import { Channel, ChannelType, getPermission, Guild, InviteModel, trimSpecial } from "@fosscord/util"; +import { Channel, ChannelType, getPermission, Guild, Invite, trimSpecial } from "@fosscord/util"; import { Router, Request, Response } from "express"; import { HTTPError } from "lambert-server"; import { check, Length } from "../../../util/instanceOf"; -import { isMember } from "../../../util/Member"; const router = Router(); @@ -14,42 +13,37 @@ router.get("/", async (req: Request, res: Response) => { const permission = await getPermission(req.user_id, guild_id); permission.hasThrow("MANAGE_GUILD"); - const guild = await Guild.findOneOrFail({ id: guild_id }); - if (!guild.vanity_url_code) return res.json({ code: null }); - const { uses } = await Invite.findOneOrFail({ code: guild.vanity_url_code }); + const guild = await Guild.findOneOrFail({ where: { id: guild_id }, relations: ["vanity_url"] }); + if (!guild.vanity_url) return res.json({ code: null }); - return res.json({ code: guild.vanity_url_code, uses }); + return res.json({ code: guild.vanity_url_code, uses: guild.vanity_url.uses }); }); // TODO: check if guild is elgible for vanity url router.patch("/", check({ code: new Length(String, 0, 20) }), async (req: Request, res: Response) => { const { guild_id } = req.params; - var code = req.body.code.replace(InviteRegex); - if (!code) code = null; + const code = req.body.code.replace(InviteRegex); + + await Invite.findOneOrFail({ code }); const guild = await Guild.findOneOrFail({ id: guild_id }); - const permission = await getPermission(req.user_id, guild_id, undefined, { guild }); + const permission = await getPermission(req.user_id, guild_id); permission.hasThrow("MANAGE_GUILD"); - const alreadyExists = await Promise.all([ - Guild.findOneOrFail({ vanity_url_code: code }).catch(() => null), - Invite.findOneOrFail({ code: code }).catch(() => null) - ]); - if (alreadyExists.some((x) => x)) throw new HTTPError("Vanity url already exists", 400); - - await Guild.update({ id: guild_id }, { vanity_url_code: code }); const { id } = await Channel.findOneOrFail({ guild_id, type: ChannelType.GUILD_TEXT }); - await Invite.update( - { code: guild.vanity_url_code }, - { + guild.vanity_url_code = code; + + Promise.all([ + guild.save(), + Invite.delete({ code: guild.vanity_url_code }), + new Invite({ code: code, uses: 0, created_at: new Date(), guild_id, channel_id: id - }, - { upsert: true } - ); + }).save() + ]); return res.json({ code: code }); }); diff --git a/api/src/routes/guilds/#guild_id/welcome_screen.ts b/api/src/routes/guilds/#guild_id/welcome_screen.ts index b457efb6..defbcd40 100644 --- a/api/src/routes/guilds/#guild_id/welcome_screen.ts +++ b/api/src/routes/guilds/#guild_id/welcome_screen.ts @@ -1,11 +1,9 @@ import { Request, Response, Router } from "express"; -import { Guild, getPermission, toObject, Snowflake } from "@fosscord/util"; +import { Guild, getPermission, Snowflake, Member } from "@fosscord/util"; import { HTTPError } from "lambert-server"; import { check } from "../../../util/instanceOf"; -import { isMember } from "../../../util/Member"; -import { GuildAddChannelToWelcomeScreenSchema } from "../../../schema/Guild"; -import { getPublicUser } from "../../../util/User"; +import { GuildUpdateWelcomeScreenSchema } from "../../../schema/Guild"; const router: Router = Router(); @@ -14,34 +12,24 @@ router.get("/", async (req: Request, res: Response) => { const guild = await Guild.findOneOrFail({ id: guild_id }); - await isMember(req.user_id, guild_id); + await Member.IsInGuildOrFail(req.user_id, guild_id); res.json(guild.welcome_screen); }); -router.post("/", check(GuildAddChannelToWelcomeScreenSchema), async (req: Request, res: Response) => { +router.patch("/", check(GuildUpdateWelcomeScreenSchema), async (req: Request, res: Response) => { const guild_id = req.params.guild_id; - const body = req.body as GuildAddChannelToWelcomeScreenSchema; + const body = req.body as GuildUpdateWelcomeScreenSchema; const guild = await Guild.findOneOrFail({ id: guild_id }); - var channelObject = { - ...body - }; - const perms = await getPermission(req.user_id, guild_id); perms.hasThrow("MANAGE_GUILD"); if (!guild.welcome_screen.enabled) throw new HTTPError("Welcome screen disabled", 400); - if (guild.welcome_screen.welcome_channels.some((channel) => channel.channel_id === body.channel_id)) - throw new Error("Welcome Channel exists"); - - await Guild.findOneOrFailAndUpdate( - { - id: guild_id - }, - { $push: { "welcome_screen.welcome_channels": channelObject } } - ); + if (body.welcome_channels) guild.welcome_screen.welcome_channels = body.welcome_channels; // TODO: check if they exist and are valid + if (body.description) guild.welcome_screen.description = body.description; + if (body.enabled != null) guild.welcome_screen.enabled = body.enabled; res.sendStatus(204); }); diff --git a/api/src/routes/guilds/#guild_id/widget.json.ts b/api/src/routes/guilds/#guild_id/widget.json.ts index 10bc3ac0..ae1f0599 100644 --- a/api/src/routes/guilds/#guild_id/widget.json.ts +++ b/api/src/routes/guilds/#guild_id/widget.json.ts @@ -1,5 +1,5 @@ import { Request, Response, Router } from "express"; -import { Config, Permissions, Guild, InviteModel, Channel, Member } from "@fosscord/util"; +import { Config, Permissions, Guild, Invite, Channel, Member } from "@fosscord/util"; import { HTTPError } from "lambert-server"; import { random } from "../../../util/RandomInviteID"; @@ -21,7 +21,8 @@ router.get("/", async (req: Request, res: Response) => { if (!guild.widget_enabled) throw new HTTPError("Widget Disabled", 404); // Fetch existing widget invite for widget channel - var invite = await Invite.findOneOrFail({ channel_id: guild.widget_channel_id, inviter_id: { $type: 10 } }); + var invite = await Invite.findOne({ channel_id: guild.widget_channel_id }); + if (guild.widget_channel_id && !invite) { // Create invite for channel if none exists // TODO: Refactor invite create code to a shared function @@ -40,85 +41,29 @@ router.get("/", async (req: Request, res: Response) => { inviter_id: null }; - invite = await new InviteModel(body).save(); + invite = await new Invite(body).save(); } // Fetch voice channels, and the @everyone permissions object - let channels: any[] = []; - await Channel.find({ guild_id: guild_id, type: 2 }, { permission_overwrites: { $elemMatch: { id: guild_id } } }) - .select("id name position permission_overwrites") - .sort({ position: 1 }) - .cursor() - .eachAsync((doc) => { - // Only return channels where @everyone has the CONNECT permission - if ( - doc.permission_overwrites === undefined || - Permissions.channelPermission(doc.permission_overwrites, Permissions.FLAGS.CONNECT) === Permissions.FLAGS.CONNECT - ) { - channels.push({ - id: doc.id, - name: doc.name, - position: doc.position - }); - } - }); + const channels = [] as any[]; + + (await Channel.find({ where: { guild_id: guild_id, type: 2 }, order: { position: "ASC" } })).filter((doc) => { + // Only return channels where @everyone has the CONNECT permission + if ( + doc.permission_overwrites === undefined || + Permissions.channelPermission(doc.permission_overwrites, Permissions.FLAGS.CONNECT) === Permissions.FLAGS.CONNECT + ) { + channels.push({ + id: doc.id, + name: doc.name, + position: doc.position + }); + } + }); // Fetch members // TODO: Understand how Discord's max 100 random member sample works, and apply to here (see top of this file) - let members: any[] = []; - await Member.find({ guild_id: guild_id }) - .populate({ path: "user", select: { _id: 0, username: 1, avatar: 1, presence: 1 } }) - .select("id user nick deaf mute") - .cursor() - .eachAsync((doc) => { - const status = doc.user?.presence?.status || "offline"; - if (status == "offline") return; - - let item = {}; - - item = { - ...item, - id: null, // this is updated during the sort outside of the query - username: doc.nick || doc.user?.username, - discriminator: "0000", // intended (https://github.com/discord/discord-api-docs/issues/1287) - avatar: null, // intended, avatar_url below will return a unique guild + user url to the avatar - status: status - }; - - const activity = doc.user?.presence?.activities?.[0]; - if (activity) { - item = { - ...item, - game: { name: activity.name } - }; - } - - // TODO: If the member is in a voice channel, return extra widget details - // Extra fields returned include deaf, mute, self_deaf, self_mute, supress, and channel_id (voice channel connected to) - // Get this from VoiceState - - // TODO: Implement a widget-avatar endpoint on the CDN, and implement logic here to request it - // Get unique avatar url for guild user, cdn to serve the actual avatar image on this url - /* - const avatar = doc.user?.avatar; - if (avatar) { - const CDN_HOST = Config.get().cdn.endpoint || "http://localhost:3003"; - const avatar_url = "/widget-avatars/" + ; - item = { - ...item, - avatar_url: avatar_url - } - } - */ - - members.push(item); - }); - - // Sort members, and update ids (Unable to do under the mongoose query due to https://mongoosejs.com/docs/faq.html#populate_sort_order) - members = members.sort((first, second) => 0 - (first.username > second.username ? -1 : 1)); - members.forEach((x, i) => { - x.id = i; - }); + let members = await Member.find({ where: { guild_id: guild_id } }); // Construct object to respond with const data = { diff --git a/api/src/routes/guilds/index.ts b/api/src/routes/guilds/index.ts index 05be07d9..c158c7d4 100644 --- a/api/src/routes/guilds/index.ts +++ b/api/src/routes/guilds/index.ts @@ -1,10 +1,8 @@ import { Router, Request, Response } from "express"; -import { Role, Guild, Snowflake, Guild, RoleDocument, Config } from "@fosscord/util"; +import { Role, Guild, Snowflake, Config, User, Member } from "@fosscord/util"; import { HTTPError } from "lambert-server"; import { check } from "./../../util/instanceOf"; import { GuildCreateSchema } from "../../schema/Guild"; -import { getPublicUser } from "../../util/User"; -import { addMember } from "../../util/Member"; import { createChannel } from "../../util/Channel"; const router: Router = Router(); @@ -15,14 +13,13 @@ router.post("/", check(GuildCreateSchema), async (req: Request, res: Response) = const body = req.body as GuildCreateSchema; const { maxGuilds } = Config.get().limits.user; - const user = await getPublicUser(req.user_id, { guilds: true }); - - if (user.guilds.length >= maxGuilds) { + const guild_count = await Member.count({ where: { id: req.user_id } }); + if (guild_count >= maxGuilds) { throw new HTTPError(`Maximum number of guilds reached ${maxGuilds}`, 403); } const guild_id = Snowflake.generate(); - const guild: Guild = { + const guild = new Guild({ name: body.name, region: Config.get().regions.default, owner_id: req.user_id, @@ -62,7 +59,7 @@ router.post("/", check(GuildCreateSchema), async (req: Request, res: Response) = }, widget_channel_id: undefined, widget_enabled: false - }; + }); const [guild_doc, role] = await Promise.all([ new Guild(guild).save(), @@ -94,14 +91,14 @@ router.post("/", check(GuildCreateSchema), async (req: Request, res: Response) = body.channels?.map((x) => { var id = ids.get(x.id) || Snowflake.generate(); - // TODO: should we abort if parent_id is a category? (or not to allow sub category channels) + // TODO: should we abort if parent_id is a category? (to disallow sub category channels) var parent_id = ids.get(x.parent_id); return createChannel({ ...x, guild_id, id, parent_id }, req.user_id, { keepId: true, skipExistsCheck: true }); }) ); - await addMember(req.user_id, guild_id); + await Member.addToGuild(req.user_id, guild_id); res.status(201).json({ id: guild.id }); }); diff --git a/api/src/routes/guilds/templates/index.ts b/api/src/routes/guilds/templates/index.ts index b8c1012d..7a8ac886 100644 --- a/api/src/routes/guilds/templates/index.ts +++ b/api/src/routes/guilds/templates/index.ts @@ -1,10 +1,9 @@ import { Request, Response, Router } from "express"; const router: Router = Router(); -import { Template, Guild, Role, Snowflake, Config, User } from "@fosscord/util"; +import { Template, Guild, Role, Snowflake, Config, User, Member } from "@fosscord/util"; import { HTTPError } from "lambert-server"; import { GuildTemplateCreateSchema } from "../../../schema/Guild"; import { check } from "../../../util/instanceOf"; -import { addMember } from "../../../util/Member"; router.get("/:code", async (req: Request, res: Response) => { const { code } = req.params; @@ -19,9 +18,9 @@ router.post("/:code", check(GuildTemplateCreateSchema), async (req: Request, res const body = req.body as GuildTemplateCreateSchema; const { maxGuilds } = Config.get().limits.user; - const user = await User.getPublicUser(req.user_id, { guilds: true }); - if (user.guilds.length >= maxGuilds) { + const guild_count = await Member.count({ id: req.user_id }); + if (guild_count >= maxGuilds) { throw new HTTPError(`Maximum number of guilds reached ${maxGuilds}`, 403); } @@ -29,15 +28,13 @@ router.post("/:code", check(GuildTemplateCreateSchema), async (req: Request, res const guild_id = Snowflake.generate(); - const guild: Guild = { - ...body, - ...template.serialized_source_guild, - id: guild_id, - owner_id: req.user_id - }; - - const [guild_doc, role] = await Promise.all([ - new Guild(guild).save(), + const [guild, role] = await Promise.all([ + new Guild({ + ...body, + ...template.serialized_source_guild, + id: guild_id, + owner_id: req.user_id + }).save(), new Role({ id: guild_id, guild_id: guild_id, @@ -52,7 +49,7 @@ router.post("/:code", check(GuildTemplateCreateSchema), async (req: Request, res }).save() ]); - await addMember(req.user_id, guild_id, { guild: guild_doc }); + await Member.addToGuild(req.user_id, guild_id); res.status(201).json({ id: guild.id }); }); |