diff options
author | Erkin Alp Güney <erkinalp9035@gmail.com> | 2022-03-05 17:49:23 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-05 17:49:23 +0300 |
commit | f972bfc5287b492556eb05582bc6741e0d59b820 (patch) | |
tree | 63f855ae36294319352c5e826c400046a6c6318c /api | |
parent | Added email sanitisation to /users/@me PATCH. Could previously have email as ... (diff) | |
parent | document which field is which (diff) | |
download | server-f972bfc5287b492556eb05582bc6741e0d59b820.tar.xz |
Merge branch 'master' into fix/claim_accounts
Diffstat (limited to 'api')
-rw-r--r-- | api/assets/openapi.json | 7 | ||||
-rw-r--r-- | api/package-lock.json | 20 | ||||
-rw-r--r-- | api/src/routes/guilds/#guild_id/bans.ts | 67 | ||||
-rw-r--r-- | api/src/routes/users/#id/profile.ts | 16 | ||||
-rw-r--r-- | api/src/routes/users/@me/index.ts | 4 |
5 files changed, 93 insertions, 21 deletions
diff --git a/api/assets/openapi.json b/api/assets/openapi.json index 15e55bf9..1af0600d 100644 --- a/api/assets/openapi.json +++ b/api/assets/openapi.json @@ -2821,6 +2821,10 @@ "type": "string", "format": "date-time" }, + "premium_since": { + "type": "string", + "format": "date-time" + }, "verified": { "type": "boolean" }, @@ -3800,7 +3804,8 @@ "format": "date-time" }, "premium_since": { - "type": "integer" + "type": "string", + "format": "date-time" }, "deaf": { "type": "boolean" diff --git a/api/package-lock.json b/api/package-lock.json index a7c29a79..e3e29800 100644 --- a/api/package-lock.json +++ b/api/package-lock.json @@ -6711,8 +6711,9 @@ } }, "../util/node_modules/url-parse": { - "version": "1.5.3", - "integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==", + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -15124,8 +15125,9 @@ } }, "node_modules/url-parse": { - "version": "1.5.3", - "integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==", + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -21697,8 +21699,9 @@ } }, "url-parse": { - "version": "1.5.3", - "integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==", + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", "requires": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -26849,8 +26852,9 @@ } }, "url-parse": { - "version": "1.5.3", - "integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==", + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", "requires": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" diff --git a/api/src/routes/guilds/#guild_id/bans.ts b/api/src/routes/guilds/#guild_id/bans.ts index 1e09a38d..7ccf34d7 100644 --- a/api/src/routes/guilds/#guild_id/bans.ts +++ b/api/src/routes/guilds/#guild_id/bans.ts @@ -1,5 +1,5 @@ import { Request, Response, Router } from "express"; -import { emitEvent, getPermission, GuildBanAddEvent, GuildBanRemoveEvent, Guild, Ban, User, Member } from "@fosscord/util"; +import { DiscordApiErrors, emitEvent, getPermission, GuildBanAddEvent, GuildBanRemoveEvent, Guild, Ban, User, Member } from "@fosscord/util"; import { HTTPError } from "lambert-server"; import { getIpAdress, route } from "@fosscord/api"; @@ -17,6 +17,14 @@ export interface BanRegistrySchema { reason?: string | undefined; }; +export interface BanModeratorSchema { + id: string; + user_id: string; + guild_id: string; + executor_id: string; + reason?: string | undefined; +}; + const router: Router = Router(); /* TODO: Deleting the secrets is just a temporary go-around. Views should be implemented for both safety and better handling. */ @@ -27,11 +35,14 @@ router.get("/", route({ permission: "BAN_MEMBERS" }), async (req: Request, res: let bans = await Ban.find({ guild_id: guild_id }); /* Filter secret from database registry.*/ + + bans.filter(ban => ban.user_id !== ban.executor_id); + // pretend self-bans don't exist to prevent victim chasing bans.forEach((registry: BanRegistrySchema) => { delete registry.ip; }); - + return res.json(bans); }); @@ -41,7 +52,12 @@ router.get("/:user", route({ permission: "BAN_MEMBERS" }), async (req: Request, let ban = await Ban.findOneOrFail({ guild_id: guild_id, user_id: user_id }) as BanRegistrySchema; + if (ban.user_id === ban.executor_id) throw DiscordApiErrors.UNKNOWN_BAN; + // pretend self-bans don't exist to prevent victim chasing + /* Filter secret from registry. */ + + ban = ban as BanModeratorSchema; delete ban.ip @@ -52,10 +68,12 @@ router.put("/:user_id", route({ body: "BanCreateSchema", permission: "BAN_MEMBER const { guild_id } = req.params; const banned_user_id = req.params.user_id; - const banned_user = await User.getPublicUser(banned_user_id); - - if (req.user_id === banned_user_id) throw new HTTPError("You can't ban yourself", 400); + if ( (req.user_id === banned_user_id) && (banned_user_id === req.permission!.cache.guild?.owner_id)) + throw new HTTPError("You are the guild owner, hence can't ban yourself", 403); + if (req.permission!.cache.guild?.owner_id === banned_user_id) throw new HTTPError("You can't ban the owner", 400); + + const banned_user = await User.getPublicUser(banned_user_id); const ban = new Ban({ user_id: banned_user_id, @@ -81,11 +99,48 @@ router.put("/:user_id", route({ body: "BanCreateSchema", permission: "BAN_MEMBER return res.json(ban); }); +router.put("/@me", route({ body: "BanCreateSchema"}), async (req: Request, res: Response) => { + const { guild_id } = req.params; + + const banned_user = await User.getPublicUser(req.params.user_id); + + if (req.permission!.cache.guild?.owner_id === req.params.user_id) + throw new HTTPError("You are the guild owner, hence can't ban yourself", 403); + + const ban = new Ban({ + user_id: req.params.user_id, + guild_id: guild_id, + ip: getIpAdress(req), + executor_id: req.params.user_id, + reason: req.body.reason // || otherwise empty + }); + + await Promise.all([ + Member.removeFromGuild(req.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); +}); + router.delete("/:user_id", route({ permission: "BAN_MEMBERS" }), async (req: Request, res: Response) => { const { guild_id, user_id } = req.params; + let ban = await Ban.findOneOrFail({ guild_id: guild_id, user_id: user_id }); + + if (ban.user_id === ban.executor_id) throw DiscordApiErrors.UNKNOWN_BAN; + // make self-bans irreversible and hide them from view to avoid victim chasing + const banned_user = await User.getPublicUser(user_id); - + await Promise.all([ Ban.delete({ user_id: user_id, diff --git a/api/src/routes/users/#id/profile.ts b/api/src/routes/users/#id/profile.ts index 9481451d..4dbb84cf 100644 --- a/api/src/routes/users/#id/profile.ts +++ b/api/src/routes/users/#id/profile.ts @@ -16,22 +16,30 @@ router.get("/", route({ test: { response: { body: "UserProfileResponse" } } }), const user = await User.getPublicUser(req.params.id, { relations: ["connected_accounts"] }); var mutual_guilds: object[] = []; - + var premium_guild_since; const requested_member = await Member.find( { id: req.params.id, }) const self_member = await Member.find( { id: req.user_id, }) for(const rmem of requested_member) { + if(rmem.premium_since) { + if(premium_guild_since){ + if(premium_guild_since > rmem.premium_since) { + premium_guild_since = rmem.premium_since; + } + } else { + premium_guild_since = rmem.premium_since; + } + } for(const smem of self_member) { if (smem.guild_id === rmem.guild_id) { mutual_guilds.push({id: rmem.guild_id, nick: rmem.nick}) } } } - res.json({ connected_accounts: user.connected_accounts, - premium_guild_since: null, // TODO - premium_since: null, // TODO + premium_guild_since: premium_guild_since, // TODO + premium_since: user.premium_since, // TODO mutual_guilds: mutual_guilds, // TODO {id: "", nick: null} when ?with_mutual_guilds=true user: { username: user.username, diff --git a/api/src/routes/users/@me/index.ts b/api/src/routes/users/@me/index.ts index 93d2cb01..bf62e7fc 100644 --- a/api/src/routes/users/@me/index.ts +++ b/api/src/routes/users/@me/index.ts @@ -65,8 +65,8 @@ router.patch("/", route({ body: "UserModifySchema" }), async (req: Request, res: } var check_username = body?.username?.replace(/\s/g, ''); - //claiming an account does not provide username so check if username in body before throw - if (!check_username && body.username) { + + if(!check_username && !body?.avatar && !body?.banner) { throw FieldErrors({ username: { code: "BASE_TYPE_REQUIRED", message: req.t("common:field.BASE_TYPE_REQUIRED") } }); |