diff options
author | Emma [it/its]@Rory& <root@rory.gay> | 2023-12-11 01:12:54 +0100 |
---|---|---|
committer | Emma [it/its]@Rory& <root@rory.gay> | 2023-12-11 01:12:54 +0100 |
commit | 0a8ceb9e6349284e75545a01ffad608b020f78e2 (patch) | |
tree | 17a9163f963eddabf9168b0b630096b2f7535b64 /src/api/routes | |
parent | Prettier: use editorconfig (diff) | |
download | server-dev/emma-refactors.tar.xz |
Actually run prettier dev/emma-refactors
Diffstat (limited to 'src/api/routes')
109 files changed, 758 insertions, 1598 deletions
diff --git a/src/api/routes/applications/#id/bot/index.ts b/src/api/routes/applications/#id/bot/index.ts index 3c431e3d..5d58e6ed 100644 --- a/src/api/routes/applications/#id/bot/index.ts +++ b/src/api/routes/applications/#id/bot/index.ts @@ -50,15 +50,14 @@ router.post( relations: ["owner"], }); - if (app.owner.id != req.user_id) - throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION; + if (app.owner.id != req.user_id) throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION; const user = await createAppBotUser(app, req); res.send({ token: await generateToken(user.id), }).status(204); - }, + } ); router.post( @@ -77,13 +76,9 @@ router.post( const bot = await User.findOneOrFail({ where: { id: req.params.id } }); const owner = await User.findOneOrFail({ where: { id: req.user_id } }); - if (owner.id != req.user_id) - throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION; + if (owner.id != req.user_id) throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION; - if ( - owner.totp_secret && - (!req.body.code || verifyToken(owner.totp_secret, req.body.code)) - ) + if (owner.totp_secret && (!req.body.code || verifyToken(owner.totp_secret, req.body.code))) throw new HTTPError(req.t("auth:login.INVALID_TOTP_CODE"), 60008); bot.data = { hash: undefined, valid_tokens_since: new Date() }; @@ -93,7 +88,7 @@ router.post( const token = await generateToken(bot.id); res.json({ token }).status(200); - }, + } ); router.patch( @@ -120,14 +115,9 @@ router.patch( if (!app.bot) throw DiscordApiErrors.BOT_ONLY_ENDPOINT; - if (app.owner.id != req.user_id) - throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION; + if (app.owner.id != req.user_id) throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION; - if (body.avatar) - body.avatar = await handleFile( - `/avatars/${app.id}`, - body.avatar as string, - ); + if (body.avatar) body.avatar = await handleFile(`/avatars/${app.id}`, body.avatar as string); app.bot.assign(body); @@ -135,7 +125,7 @@ router.patch( await app.save(); res.json(app).status(200); - }, + } ); export default router; diff --git a/src/api/routes/applications/#id/entitlements.ts b/src/api/routes/applications/#id/entitlements.ts index 6388e6b3..4ad0b60f 100644 --- a/src/api/routes/applications/#id/entitlements.ts +++ b/src/api/routes/applications/#id/entitlements.ts @@ -34,7 +34,7 @@ router.get( // TODO: //const { exclude_consumed } = req.query; res.status(200).send([]); - }, + } ); export default router; diff --git a/src/api/routes/applications/#id/index.ts b/src/api/routes/applications/#id/index.ts index c372869a..9b8c2d46 100644 --- a/src/api/routes/applications/#id/index.ts +++ b/src/api/routes/applications/#id/index.ts @@ -17,11 +17,7 @@ */ import { route } from "@spacebar/api"; -import { - Application, - ApplicationModifySchema, - DiscordApiErrors, -} from "@spacebar/util"; +import { Application, ApplicationModifySchema, DiscordApiErrors } from "@spacebar/util"; import { Request, Response, Router } from "express"; import { HTTPError } from "lambert-server"; import { verifyToken } from "node-2fa"; @@ -45,11 +41,10 @@ router.get( where: { id: req.params.id }, relations: ["owner", "bot"], }); - if (app.owner.id != req.user_id) - throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION; + if (app.owner.id != req.user_id) throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION; return res.json(app); - }, + } ); router.patch( @@ -73,14 +68,9 @@ router.patch( relations: ["owner", "bot"], }); - if (app.owner.id != req.user_id) - throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION; + if (app.owner.id != req.user_id) throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION; - if ( - app.owner.totp_secret && - (!req.body.code || - verifyToken(app.owner.totp_secret, req.body.code)) - ) + if (app.owner.totp_secret && (!req.body.code || verifyToken(app.owner.totp_secret, req.body.code))) throw new HTTPError(req.t("auth:login.INVALID_TOTP_CODE"), 60008); if (app.bot) { @@ -93,7 +83,7 @@ router.patch( await app.save(); return res.json(app); - }, + } ); router.post( @@ -111,20 +101,15 @@ router.post( where: { id: req.params.id }, relations: ["bot", "owner"], }); - if (app.owner.id != req.user_id) - throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION; - - if ( - app.owner.totp_secret && - (!req.body.code || - verifyToken(app.owner.totp_secret, req.body.code)) - ) + if (app.owner.id != req.user_id) throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION; + + if (app.owner.totp_secret && (!req.body.code || verifyToken(app.owner.totp_secret, req.body.code))) throw new HTTPError(req.t("auth:login.INVALID_TOTP_CODE"), 60008); await Application.delete({ id: app.id }); res.send().status(200); - }, + } ); export default router; diff --git a/src/api/routes/applications/#id/skus.ts b/src/api/routes/applications/#id/skus.ts index dc4fad23..b98bb6c4 100644 --- a/src/api/routes/applications/#id/skus.ts +++ b/src/api/routes/applications/#id/skus.ts @@ -32,7 +32,7 @@ router.get( }), async (req: Request, res: Response) => { res.json([]).status(200); - }, + } ); export default router; diff --git a/src/api/routes/applications/detectable.ts b/src/api/routes/applications/detectable.ts index 5cf9d171..e80d0313 100644 --- a/src/api/routes/applications/detectable.ts +++ b/src/api/routes/applications/detectable.ts @@ -33,7 +33,7 @@ router.get( async (req: Request, res: Response) => { //TODO res.send([]).status(200); - }, + } ); export default router; diff --git a/src/api/routes/applications/index.ts b/src/api/routes/applications/index.ts index 5bba3338..6eeadbc3 100644 --- a/src/api/routes/applications/index.ts +++ b/src/api/routes/applications/index.ts @@ -17,14 +17,7 @@ */ import { route } from "@spacebar/api"; -import { - Application, - ApplicationCreateSchema, - Config, - User, - createAppBotUser, - trimSpecial, -} from "@spacebar/util"; +import { Application, ApplicationCreateSchema, Config, User, createAppBotUser, trimSpecial } from "@spacebar/util"; import { Request, Response, Router } from "express"; const router: Router = Router(); @@ -44,7 +37,7 @@ router.get( relations: ["owner", "bot"], }); res.json(results).status(200); - }, + } ); router.post( @@ -77,7 +70,7 @@ router.post( } else await app.save(); res.json(app); - }, + } ); export default router; diff --git a/src/api/routes/auth/forgot.ts b/src/api/routes/auth/forgot.ts index 6fa86021..a17a2936 100644 --- a/src/api/routes/auth/forgot.ts +++ b/src/api/routes/auth/forgot.ts @@ -17,13 +17,7 @@ */ import { getIpAdress, route, verifyCaptcha } from "@spacebar/api"; -import { - Config, - Email, - FieldErrors, - ForgotPasswordSchema, - User, -} from "@spacebar/util"; +import { Config, Email, FieldErrors, ForgotPasswordSchema, User } from "@spacebar/util"; import { Request, Response, Router } from "express"; import { HTTPError } from "lambert-server"; const router = Router(); @@ -47,10 +41,7 @@ router.post( const config = Config.get(); - if ( - config.passwordReset.requireCaptcha && - config.security.captcha.enabled - ) { + if (config.passwordReset.requireCaptcha && config.security.captcha.enabled) { const { sitekey, service } = config.security.captcha; if (!captcha_key) { return res.status(400).json({ @@ -87,8 +78,7 @@ router.post( if (!user.email) throw FieldErrors({ login: { - message: - "This account does not have an email address associated with it.", + message: "This account does not have an email address associated with it.", code: "NO_EMAIL", }, }); @@ -110,12 +100,10 @@ router.post( return res.sendStatus(204); }) .catch((e) => { - console.error( - `Failed to send password reset email to ${user.username}#${user.discriminator}: ${e}`, - ); + console.error(`Failed to send password reset email to ${user.username}#${user.discriminator}: ${e}`); throw new HTTPError("Failed to send password reset email", 500); }); - }, + } ); export default router; diff --git a/src/api/routes/auth/generate-registration-tokens.ts b/src/api/routes/auth/generate-registration-tokens.ts index 80fdaed1..e13e26f1 100644 --- a/src/api/routes/auth/generate-registration-tokens.ts +++ b/src/api/routes/auth/generate-registration-tokens.ts @@ -29,13 +29,11 @@ router.get( query: { count: { type: "number", - description: - "The number of registration tokens to generate. Defaults to 1.", + description: "The number of registration tokens to generate. Defaults to 1.", }, length: { type: "number", - description: - "The length of each registration token. Defaults to 255.", + description: "The length of each registration token. Defaults to 255.", }, }, right: "OPERATOR", @@ -43,18 +41,14 @@ router.get( }), async (req: Request, res: Response) => { const count = req.query.count ? parseInt(req.query.count as string) : 1; - const length = req.query.length - ? parseInt(req.query.length as string) - : 255; + const length = req.query.length ? parseInt(req.query.length as string) : 255; const tokens: ValidRegistrationToken[] = []; for (let i = 0; i < count; i++) { const token = ValidRegistrationToken.create({ token: random(length), - expires_at: - Date.now() + - Config.get().security.defaultRegistrationTokenExpiration, + expires_at: Date.now() + Config.get().security.defaultRegistrationTokenExpiration, }); tokens.push(token); } @@ -67,16 +61,11 @@ router.get( }); const ret = req.query.include_url - ? tokens.map( - (x) => - `${Config.get().general.frontPage}/register?token=${ - x.token - }`, - ) + ? tokens.map((x) => `${Config.get().general.frontPage}/register?token=${x.token}`) : tokens.map((x) => x.token); if (req.query.plain) return res.send(ret.join("\n")); return res.json({ tokens: ret }); - }, + } ); diff --git a/src/api/routes/auth/location-metadata.ts b/src/api/routes/auth/location-metadata.ts index 28293e59..f1625702 100644 --- a/src/api/routes/auth/location-metadata.ts +++ b/src/api/routes/auth/location-metadata.ts @@ -38,7 +38,7 @@ router.get( country_code: country_code, promotional_email_opt_in: { required: true, pre_checked: false }, }); - }, + } ); export default router; diff --git a/src/api/routes/auth/login.ts b/src/api/routes/auth/login.ts index a2100333..5563597f 100644 --- a/src/api/routes/auth/login.ts +++ b/src/api/routes/auth/login.ts @@ -47,8 +47,7 @@ router.post( }, }), async (req: Request, res: Response) => { - const { login, password, captcha_key, undelete } = - req.body as LoginSchema; + const { login, password, captcha_key, undelete } = req.body as LoginSchema; const config = Config.get(); @@ -101,10 +100,7 @@ router.post( }); // the salt is saved in the password refer to bcrypt docs - const same_password = await bcrypt.compare( - password, - user.data.hash || "", - ); + const same_password = await bcrypt.compare(password, user.data.hash || ""); if (!same_password) { throw FieldErrors({ login: { @@ -123,8 +119,7 @@ router.post( throw FieldErrors({ login: { code: "ACCOUNT_LOGIN_VERIFICATION_EMAIL", - message: - "Email verification is required, please check your email.", + message: "Email verification is required, please check your email.", }, }); } @@ -153,9 +148,7 @@ router.post( const challenge = JSON.stringify({ publicKey: { ...options, - challenge: Buffer.from(options.challenge).toString( - "base64", - ), + challenge: Buffer.from(options.challenge).toString("base64"), allowCredentials: user.security_keys.map((x) => ({ id: x.key_id, type: "public-key", @@ -179,10 +172,8 @@ router.post( if (undelete) { // undelete refers to un'disable' here - if (user.disabled) - await User.update({ id: user.id }, { disabled: false }); - if (user.deleted) - await User.update({ id: user.id }, { deleted: false }); + if (user.disabled) await User.update({ id: user.id }, { disabled: false }); + if (user.deleted) await User.update({ id: user.id }, { deleted: false }); } else { if (user.deleted) return res.status(400).json({ @@ -203,7 +194,7 @@ router.post( // https://user-images.githubusercontent.com/6506416/81051916-dd8c9900-8ec2-11ea-8794-daf12d6f31f0.png res.json({ token, settings: { ...user.settings, index: undefined } }); - }, + } ); /** diff --git a/src/api/routes/auth/logout.ts b/src/api/routes/auth/logout.ts index 94a3e474..9686f5cb 100644 --- a/src/api/routes/auth/logout.ts +++ b/src/api/routes/auth/logout.ts @@ -31,16 +31,12 @@ router.post( }), async (req: Request, res: Response) => { if (req.body.provider != null || req.body.voip_provider != null) { - console.log( - `[LOGOUT]: provider or voip provider not null!`, - req.body, - ); + console.log(`[LOGOUT]: provider or voip provider not null!`, req.body); } else { delete req.body.provider; delete req.body.voip_provider; - if (Object.keys(req.body).length != 0) - console.log(`[LOGOUT]: Extra fields sent in logout!`, req.body); + if (Object.keys(req.body).length != 0) console.log(`[LOGOUT]: Extra fields sent in logout!`, req.body); } res.status(204).send(); - }, + } ); diff --git a/src/api/routes/auth/mfa/totp.ts b/src/api/routes/auth/mfa/totp.ts index 4df408f9..956993b3 100644 --- a/src/api/routes/auth/mfa/totp.ts +++ b/src/api/routes/auth/mfa/totp.ts @@ -59,11 +59,7 @@ router.post( if (!backup) { const ret = verifyToken(user.totp_secret || "", code); - if (!ret || ret.delta != 0) - throw new HTTPError( - req.t("auth:login.INVALID_TOTP_CODE"), - 60008, - ); + if (!ret || ret.delta != 0) throw new HTTPError(req.t("auth:login.INVALID_TOTP_CODE"), 60008); } else { backup.consumed = true; await backup.save(); @@ -75,7 +71,7 @@ router.post( token: await generateToken(user.id), settings: { ...user.settings, index: undefined }, }); - }, + } ); export default router; diff --git a/src/api/routes/auth/mfa/webauthn.ts b/src/api/routes/auth/mfa/webauthn.ts index b58d2944..c1a7ddb9 100644 --- a/src/api/routes/auth/mfa/webauthn.ts +++ b/src/api/routes/auth/mfa/webauthn.ts @@ -17,14 +17,7 @@ */ import { route } from "@spacebar/api"; -import { - generateToken, - SecurityKey, - User, - verifyWebAuthnToken, - WebAuthn, - WebAuthnTotpSchema, -} from "@spacebar/util"; +import { generateToken, SecurityKey, User, verifyWebAuthnToken, WebAuthn, WebAuthnTotpSchema } from "@spacebar/util"; import { Request, Response, Router } from "express"; import { ExpectedAssertionResult } from "fido2-lib"; import { HTTPError } from "lambert-server"; @@ -65,46 +58,33 @@ router.post( }); const ret = await verifyWebAuthnToken(ticket); - if (!ret) - throw new HTTPError(req.t("auth:login.INVALID_TOTP_CODE"), 60008); + if (!ret) throw new HTTPError(req.t("auth:login.INVALID_TOTP_CODE"), 60008); await User.update({ id: user.id }, { totp_last_ticket: "" }); const clientAttestationResponse = JSON.parse(code); - if (!clientAttestationResponse.rawId) - throw new HTTPError("Missing rawId", 400); + if (!clientAttestationResponse.rawId) throw new HTTPError("Missing rawId", 400); - clientAttestationResponse.rawId = toArrayBuffer( - Buffer.from(clientAttestationResponse.rawId, "base64url"), - ); + clientAttestationResponse.rawId = toArrayBuffer(Buffer.from(clientAttestationResponse.rawId, "base64url")); const securityKey = await SecurityKey.findOneOrFail({ where: { - key_id: Buffer.from( - clientAttestationResponse.rawId, - "base64url", - ).toString("base64"), + key_id: Buffer.from(clientAttestationResponse.rawId, "base64url").toString("base64"), }, }); const assertionExpectations: ExpectedAssertionResult = JSON.parse( - Buffer.from( - clientAttestationResponse.response.clientDataJSON, - "base64", - ).toString(), + Buffer.from(clientAttestationResponse.response.clientDataJSON, "base64").toString() ); - const authnResult = await WebAuthn.fido2.assertionResult( - clientAttestationResponse, - { - ...assertionExpectations, - factor: "second", - publicKey: securityKey.public_key, - prevCounter: securityKey.counter, - userHandle: securityKey.key_id, - }, - ); + const authnResult = await WebAuthn.fido2.assertionResult(clientAttestationResponse, { + ...assertionExpectations, + factor: "second", + publicKey: securityKey.public_key, + prevCounter: securityKey.counter, + userHandle: securityKey.key_id, + }); const counter = authnResult.authnrData.get("counter"); @@ -116,7 +96,7 @@ router.post( token: await generateToken(user.id), user_settings: user.settings, }); - }, + } ); export default router; diff --git a/src/api/routes/auth/register.ts b/src/api/routes/auth/register.ts index de1cbd3d..dc72a3ca 100644 --- a/src/api/routes/auth/register.ts +++ b/src/api/routes/auth/register.ts @@ -16,13 +16,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */ -import { - IPAnalysis, - getIpAdress, - isProxy, - route, - verifyCaptcha, -} from "@spacebar/api"; +import { IPAnalysis, getIpAdress, isProxy, route, verifyCaptcha } from "@spacebar/api"; import { Config, FieldErrors, @@ -65,13 +59,9 @@ router.post( }); await regToken.remove(); regTokenUsed = true; - console.log( - `[REGISTER] Registration token ${token} used for registration!`, - ); + console.log(`[REGISTER] Registration token ${token} used for registration!`); } else { - console.log( - `[REGISTER] Invalid registration token ${token} used for registration by ${ip}!`, - ); + console.log(`[REGISTER] Invalid registration token ${token} used for registration by ${ip}!`); } } @@ -104,11 +94,7 @@ router.post( }); } - if ( - !regTokenUsed && - register.requireCaptcha && - security.captcha.enabled - ) { + if (!regTokenUsed && register.requireCaptcha && security.captcha.enabled) { const { sitekey, service } = security.captcha; if (!body.captcha_key) { return res?.status(400).json({ @@ -139,9 +125,7 @@ router.post( throw FieldErrors({ email: { code: "EMAIL_ALREADY_REGISTERED", - message: req.t( - "auth:register.EMAIL_ALREADY_REGISTERED", - ), + message: req.t("auth:register.EMAIL_ALREADY_REGISTERED"), }, }); } @@ -176,9 +160,7 @@ router.post( throw FieldErrors({ email: { code: "EMAIL_ALREADY_REGISTERED", - message: req.t( - "auth:register.EMAIL_ALREADY_REGISTERED", - ), + message: req.t("auth:register.EMAIL_ALREADY_REGISTERED"), }, }); } @@ -198,14 +180,9 @@ router.post( message: req.t("common:field.BASE_TYPE_REQUIRED"), }, }); - } else if ( - register.dateOfBirth.required && - register.dateOfBirth.minimum - ) { + } else if (register.dateOfBirth.required && register.dateOfBirth.minimum) { const minimum = new Date(); - minimum.setFullYear( - minimum.getFullYear() - register.dateOfBirth.minimum, - ); + minimum.setFullYear(minimum.getFullYear() - register.dateOfBirth.minimum); body.date_of_birth = new Date(body.date_of_birth as Date); // higher is younger @@ -228,10 +205,7 @@ router.post( throw FieldErrors({ password: { code: "PASSWORD_REQUIREMENTS_MIN_LENGTH", - message: req.t( - "auth:register.PASSWORD_REQUIREMENTS_MIN_LENGTH", - { min: min }, - ), + message: req.t("auth:register.PASSWORD_REQUIREMENTS_MIN_LENGTH", { min: min }), }, }); } @@ -249,8 +223,7 @@ router.post( if ( !regTokenUsed && !body.invite && - (register.requireInvite || - (register.guestsRequireInvite && !register.email)) + (register.requireInvite || (register.guestsRequireInvite && !register.email)) ) { // require invite to register -> e.g. for organizations to send invites to their employees throw FieldErrors({ @@ -266,18 +239,14 @@ router.post( limits.absoluteRate.register.enabled && (await User.count({ where: { - created_at: MoreThan( - new Date( - Date.now() - limits.absoluteRate.register.window, - ), - ), + created_at: MoreThan(new Date(Date.now() - limits.absoluteRate.register.window)), }, })) >= limits.absoluteRate.register.limit ) { console.log( - `Global register ratelimit exceeded for ${getIpAdress(req)}, ${ - req.body.username - }, ${req.body.invite || "No invite given"}`, + `Global register ratelimit exceeded for ${getIpAdress(req)}, ${req.body.username}, ${ + req.body.invite || "No invite given" + }` ); throw FieldErrors({ email: { @@ -295,7 +264,7 @@ router.post( } return res.json({ token: await generateToken(user.id) }); - }, + } ); export default router; diff --git a/src/api/routes/auth/reset.ts b/src/api/routes/auth/reset.ts index b3ca1e9e..746363cc 100644 --- a/src/api/routes/auth/reset.ts +++ b/src/api/routes/auth/reset.ts @@ -17,14 +17,7 @@ */ import { route } from "@spacebar/api"; -import { - checkToken, - Email, - FieldErrors, - generateToken, - PasswordResetSchema, - User, -} from "@spacebar/util"; +import { checkToken, Email, FieldErrors, generateToken, PasswordResetSchema, User } from "@spacebar/util"; import bcrypt from "bcrypt"; import { Request, Response, Router } from "express"; @@ -76,7 +69,7 @@ router.post( await Email.sendPasswordChanged(user, user.email!); res.json({ token: await generateToken(user.id) }); - }, + } ); export default router; diff --git a/src/api/routes/auth/verify/index.ts b/src/api/routes/auth/verify/index.ts index 49f74277..49f3398e 100644 --- a/src/api/routes/auth/verify/index.ts +++ b/src/api/routes/auth/verify/index.ts @@ -17,13 +17,7 @@ */ import { getIpAdress, route, verifyCaptcha } from "@spacebar/api"; -import { - checkToken, - Config, - FieldErrors, - generateToken, - User, -} from "@spacebar/util"; +import { checkToken, Config, FieldErrors, generateToken, User } from "@spacebar/util"; import { Request, Response, Router } from "express"; const router = Router(); @@ -97,7 +91,7 @@ router.post( await User.update({ id: user.id }, { verified: true }); return res.json(await getToken(user)); - }, + } ); export default router; diff --git a/src/api/routes/auth/verify/resend.ts b/src/api/routes/auth/verify/resend.ts index 701f0ea8..ced7c578 100644 --- a/src/api/routes/auth/verify/resend.ts +++ b/src/api/routes/auth/verify/resend.ts @@ -52,12 +52,10 @@ router.post( return res.sendStatus(204); }) .catch((e) => { - console.error( - `Failed to send verification email to ${user.username}#${user.discriminator}: ${e}`, - ); + console.error(`Failed to send verification email to ${user.username}#${user.discriminator}: ${e}`); throw new HTTPError("Failed to send verification email", 500); }); - }, + } ); export default router; diff --git a/src/api/routes/auth/verify/view-backup-codes-challenge.ts b/src/api/routes/auth/verify/view-backup-codes-challenge.ts index 5407de82..59c98f00 100644 --- a/src/api/routes/auth/verify/view-backup-codes-challenge.ts +++ b/src/api/routes/auth/verify/view-backup-codes-challenge.ts @@ -52,7 +52,7 @@ router.post( nonce: "NoncePlaceholder", regenerate_nonce: "RegenNoncePlaceholder", }); - }, + } ); export default router; diff --git a/src/api/routes/channels/#channel_id/index.ts b/src/api/routes/channels/#channel_id/index.ts index 567c7c92..a5fe1ef9 100644 --- a/src/api/routes/channels/#channel_id/index.ts +++ b/src/api/routes/channels/#channel_id/index.ts @@ -52,7 +52,7 @@ router.get( }); return res.send(channel); - }, + } ); router.delete( @@ -101,7 +101,7 @@ router.delete( } res.send(channel); - }, + } ); router.patch( @@ -122,11 +122,7 @@ router.patch( async (req: Request, res: Response) => { const payload = req.body as ChannelModifySchema; const { channel_id } = req.params; - if (payload.icon) - payload.icon = await handleFile( - `/channel-icons/${channel_id}`, - payload.icon, - ); + if (payload.icon) payload.icon = await handleFile(`/channel-icons/${channel_id}`, payload.icon); const channel = await Channel.findOneOrFail({ where: { id: channel_id }, @@ -143,7 +139,7 @@ router.patch( ]); res.send(channel); - }, + } ); export default router; diff --git a/src/api/routes/channels/#channel_id/invites.ts b/src/api/routes/channels/#channel_id/invites.ts index ae32e80d..af0e5cc9 100644 --- a/src/api/routes/channels/#channel_id/invites.ts +++ b/src/api/routes/channels/#channel_id/invites.ts @@ -65,9 +65,7 @@ router.post( const { guild_id } = channel; const expires_at = - body.max_age == 0 || body.max_age == undefined - ? undefined - : new Date(body.max_age * 1000 + Date.now()); + body.max_age == 0 || body.max_age == undefined ? undefined : new Date(body.max_age * 1000 + Date.now()); const invite = await Invite.create({ code: random(), @@ -95,7 +93,7 @@ router.post( } as InviteCreateEvent); res.status(201).send(data); - }, + } ); router.get( @@ -126,7 +124,7 @@ router.get( }); res.status(200).send(invites); - }, + } ); export default router; diff --git a/src/api/routes/channels/#channel_id/messages/#message_id/ack.ts b/src/api/routes/channels/#channel_id/messages/#message_id/ack.ts index a6dcae6b..58ca9d26 100644 --- a/src/api/routes/channels/#channel_id/messages/#message_id/ack.ts +++ b/src/api/routes/channels/#channel_id/messages/#message_id/ack.ts @@ -17,12 +17,7 @@ */ import { route } from "@spacebar/api"; -import { - emitEvent, - getPermission, - MessageAckEvent, - ReadState, -} from "@spacebar/util"; +import { emitEvent, getPermission, MessageAckEvent, ReadState } from "@spacebar/util"; import { Request, Response, Router } from "express"; const router = Router(); @@ -43,18 +38,13 @@ router.post( async (req: Request, res: Response) => { const { channel_id, message_id } = req.params; - const permission = await getPermission( - req.user_id, - undefined, - channel_id, - ); + const permission = await getPermission(req.user_id, undefined, channel_id); permission.hasThrow("VIEW_CHANNEL"); let read_state = await ReadState.findOne({ where: { user_id: req.user_id, channel_id }, }); - if (!read_state) - read_state = ReadState.create({ user_id: req.user_id, channel_id }); + if (!read_state) read_state = ReadState.create({ user_id: req.user_id, channel_id }); read_state.last_message_id = message_id; await read_state.save(); @@ -70,7 +60,7 @@ router.post( } as MessageAckEvent); res.json({ token: null }); - }, + } ); export default router; diff --git a/src/api/routes/channels/#channel_id/messages/#message_id/crosspost.ts b/src/api/routes/channels/#channel_id/messages/#message_id/crosspost.ts index 5ca645c0..7529f508 100644 --- a/src/api/routes/channels/#channel_id/messages/#message_id/crosspost.ts +++ b/src/api/routes/channels/#channel_id/messages/#message_id/crosspost.ts @@ -57,7 +57,7 @@ router.post( flags: 1, components: [], }).status(200); - }, + } ); export default router; diff --git a/src/api/routes/channels/#channel_id/messages/#message_id/index.ts b/src/api/routes/channels/#channel_id/messages/#message_id/index.ts index c4d2e1e8..82dc5b87 100644 --- a/src/api/routes/channels/#channel_id/messages/#message_id/index.ts +++ b/src/api/routes/channels/#channel_id/messages/#message_id/index.ts @@ -75,11 +75,7 @@ router.patch( relations: ["attachments"], }); - const permissions = await getPermission( - req.user_id, - undefined, - channel_id, - ); + const permissions = await getPermission(req.user_id, undefined, channel_id); const rights = await getRights(req.user_id); @@ -139,7 +135,7 @@ router.patch( // these are not in the Discord.com response mention_channels: new_message.mention_channels, }); - }, + } ); // Backfill message with specific timestamp @@ -196,13 +192,8 @@ router.put( if (req.file) { try { - const file = await uploadFile( - `/attachments/${req.params.channel_id}`, - req.file, - ); - attachments.push( - Attachment.create({ ...file, proxy_url: file.url }), - ); + const file = await uploadFile(`/attachments/${req.params.channel_id}`, req.file); + attachments.push(Attachment.create({ ...file, proxy_url: file.url })); } catch (error) { return res.status(400).json(error); } @@ -241,12 +232,10 @@ router.put( ]); // no await as it shouldnt block the message send function and silently catch error - postHandleMessage(message).catch((e) => - console.error("[Message] post-message handler failed", e), - ); + postHandleMessage(message).catch((e) => console.error("[Message] post-message handler failed", e)); return res.json(message); - }, + } ); router.get( @@ -272,17 +261,12 @@ router.get( relations: ["attachments"], }); - const permissions = await getPermission( - req.user_id, - undefined, - channel_id, - ); + const permissions = await getPermission(req.user_id, undefined, channel_id); - if (message.author_id !== req.user_id) - permissions.hasThrow("READ_MESSAGE_HISTORY"); + if (message.author_id !== req.user_id) permissions.hasThrow("READ_MESSAGE_HISTORY"); return res.json(message); - }, + } ); router.delete( @@ -310,11 +294,7 @@ router.delete( if (message.author_id !== req.user_id) { if (!rights.has("MANAGE_MESSAGES")) { - const permission = await getPermission( - req.user_id, - channel.guild_id, - channel_id, - ); + const permission = await getPermission(req.user_id, channel.guild_id, channel_id); permission.hasThrow("MANAGE_MESSAGES"); } } else rights.hasThrow("SELF_DELETE_MESSAGES"); @@ -332,7 +312,7 @@ router.delete( } as MessageDeleteEvent); res.sendStatus(204); - }, + } ); export default router; diff --git a/src/api/routes/channels/#channel_id/messages/#message_id/reactions.ts b/src/api/routes/channels/#channel_id/messages/#message_id/reactions.ts index c2222b0a..cea8197b 100644 --- a/src/api/routes/channels/#channel_id/messages/#message_id/reactions.ts +++ b/src/api/routes/channels/#channel_id/messages/#message_id/reactions.ts @@ -88,7 +88,7 @@ router.delete( } as MessageReactionRemoveAllEvent); res.sendStatus(204); - }, + } ); router.delete( @@ -113,9 +113,7 @@ router.delete( }); const already_added = message.reactions.find( - (x) => - (x.emoji.id === emoji.id && emoji.id) || - x.emoji.name === emoji.name, + (x) => (x.emoji.id === emoji.id && emoji.id) || x.emoji.name === emoji.name ); if (!already_added) throw new HTTPError("Reaction not found", 404); message.reactions.remove(already_added); @@ -135,7 +133,7 @@ router.delete( ]); res.sendStatus(204); - }, + } ); router.get( @@ -161,9 +159,7 @@ router.get( where: { id: message_id, channel_id }, }); const reaction = message.reactions.find( - (x) => - (x.emoji.id === emoji.id && emoji.id) || - x.emoji.name === emoji.name, + (x) => (x.emoji.id === emoji.id && emoji.id) || x.emoji.name === emoji.name ); if (!reaction) throw new HTTPError("Reaction not found", 404); @@ -175,7 +171,7 @@ router.get( }); res.json(users); - }, + } ); router.put( @@ -204,9 +200,7 @@ router.put( where: { id: message_id, channel_id }, }); const already_added = message.reactions.find( - (x) => - (x.emoji.id === emoji.id && emoji.id) || - x.emoji.name === emoji.name, + (x) => (x.emoji.id === emoji.id && emoji.id) || x.emoji.name === emoji.name ); if (!already_added) req.permission?.hasThrow("ADD_REACTIONS"); @@ -222,8 +216,7 @@ router.put( } if (already_added) { - if (already_added.user_ids.includes(req.user_id)) - return res.sendStatus(204); // Do not throw an error ¯\_(ツ)_/¯ as discord also doesn't throw any error + if (already_added.user_ids.includes(req.user_id)) return res.sendStatus(204); // Do not throw an error ¯\_(ツ)_/¯ as discord also doesn't throw any error already_added.count++; already_added.user_ids.push(req.user_id); } else @@ -258,7 +251,7 @@ router.put( } as MessageReactionAddEvent); res.sendStatus(204); - }, + } ); router.delete( @@ -288,30 +281,19 @@ router.delete( if (user_id === "@me") user_id = req.user_id; else { - const permissions = await getPermission( - req.user_id, - undefined, - channel_id, - ); + const permissions = await getPermission(req.user_id, undefined, channel_id); permissions.hasThrow("MANAGE_MESSAGES"); } const already_added = message.reactions.find( - (x) => - (x.emoji.id === emoji.id && emoji.id) || - x.emoji.name === emoji.name, + (x) => (x.emoji.id === emoji.id && emoji.id) || x.emoji.name === emoji.name ); - if (!already_added || !already_added.user_ids.includes(user_id)) - throw new HTTPError("Reaction not found", 404); + if (!already_added || !already_added.user_ids.includes(user_id)) throw new HTTPError("Reaction not found", 404); already_added.count--; if (already_added.count <= 0) message.reactions.remove(already_added); - else - already_added.user_ids.splice( - already_added.user_ids.indexOf(user_id), - 1, - ); + else already_added.user_ids.splice(already_added.user_ids.indexOf(user_id), 1); await message.save(); @@ -328,7 +310,7 @@ router.delete( } as MessageReactionRemoveEvent); res.sendStatus(204); - }, + } ); export default router; diff --git a/src/api/routes/channels/#channel_id/messages/bulk-delete.ts b/src/api/routes/channels/#channel_id/messages/bulk-delete.ts index 9b607d59..3cd90faf 100644 --- a/src/api/routes/channels/#channel_id/messages/bulk-delete.ts +++ b/src/api/routes/channels/#channel_id/messages/bulk-delete.ts @@ -17,15 +17,7 @@ */ import { route } from "@spacebar/api"; -import { - Channel, - Config, - emitEvent, - getPermission, - getRights, - Message, - MessageDeleteBulkEvent, -} from "@spacebar/util"; +import { Channel, Config, emitEvent, getPermission, getRights, Message, MessageDeleteBulkEvent } from "@spacebar/util"; import { Request, Response, Router } from "express"; import { HTTPError } from "lambert-server"; @@ -54,30 +46,22 @@ router.post( const channel = await Channel.findOneOrFail({ where: { id: channel_id }, }); - if (!channel.guild_id) - throw new HTTPError("Can't bulk delete dm channel messages", 400); + if (!channel.guild_id) throw new HTTPError("Can't bulk delete dm channel messages", 400); const rights = await getRights(req.user_id); rights.hasThrow("SELF_DELETE_MESSAGES"); const superuser = rights.has("MANAGE_MESSAGES"); - const permission = await getPermission( - req.user_id, - channel?.guild_id, - channel_id, - ); + const permission = await getPermission(req.user_id, channel?.guild_id, channel_id); const { maxBulkDelete } = Config.get().limits.message; const { messages } = req.body as { messages: string[] }; - if (messages.length === 0) - throw new HTTPError("You must specify messages to bulk delete"); + if (messages.length === 0) throw new HTTPError("You must specify messages to bulk delete"); if (!superuser) { permission.hasThrow("MANAGE_MESSAGES"); if (messages.length > maxBulkDelete) - throw new HTTPError( - `You cannot delete more than ${maxBulkDelete} messages`, - ); + throw new HTTPError(`You cannot delete more than ${maxBulkDelete} messages`); } await Message.delete(messages); @@ -89,5 +73,5 @@ router.post( } as MessageDeleteBulkEvent); res.sendStatus(204); - }, + } ); diff --git a/src/api/routes/channels/#channel_id/messages/index.ts b/src/api/routes/channels/#channel_id/messages/index.ts index a5bfcfd7..c80b5f48 100644 --- a/src/api/routes/channels/#channel_id/messages/index.ts +++ b/src/api/routes/channels/#channel_id/messages/index.ts @@ -40,13 +40,7 @@ import { import { Request, Response, Router } from "express"; import { HTTPError } from "lambert-server"; import multer from "multer"; -import { - FindManyOptions, - FindOperator, - LessThan, - MoreThan, - MoreThanOrEqual, -} from "typeorm"; +import { FindManyOptions, FindOperator, LessThan, MoreThan, MoreThanOrEqual } from "typeorm"; import { URL } from "url"; const router: Router = Router(); @@ -68,8 +62,7 @@ router.get( }, limit: { type: "number", - description: - "max number of messages to return (1-100). defaults to 50", + description: "max number of messages to return (1-100). defaults to 50", }, }, responses: { @@ -95,14 +88,9 @@ router.get( const before = req.query.before ? `${req.query.before}` : undefined; const after = req.query.after ? `${req.query.after}` : undefined; const limit = Number(req.query.limit) || 50; - if (limit < 1 || limit > 100) - throw new HTTPError("limit must be between 1 and 100", 422); + if (limit < 1 || limit > 100) throw new HTTPError("limit must be between 1 and 100", 422); - const permissions = await getPermission( - req.user_id, - channel.guild_id, - channel_id, - ); + const permissions = await getPermission(req.user_id, channel.guild_id, channel_id); permissions.hasThrow("VIEW_CHANNEL"); if (!permissions.has("READ_MESSAGE_HISTORY")) return res.json([]); @@ -148,12 +136,10 @@ router.get( } } else { if (after) { - if (BigInt(after) > BigInt(Snowflake.generate())) - return res.status(422); + if (BigInt(after) > BigInt(Snowflake.generate())) return res.status(422); query.where.id = MoreThan(after); } else if (before) { - if (BigInt(before) > BigInt(Snowflake.generate())) - return res.status(422); + if (BigInt(before) > BigInt(Snowflake.generate())) return res.status(422); query.where.id = LessThan(before); } @@ -180,12 +166,8 @@ router.get( }); x.attachments?.forEach((y: Attachment) => { // dynamically set attachment proxy_url in case the endpoint changed - const uri = y.proxy_url.startsWith("http") - ? y.proxy_url - : `https://example.org${y.proxy_url}`; - y.proxy_url = `${endpoint == null ? "" : endpoint}${ - new URL(uri).pathname - }`; + const uri = y.proxy_url.startsWith("http") ? y.proxy_url : `https://example.org${y.proxy_url}`; + y.proxy_url = `${endpoint == null ? "" : endpoint}${new URL(uri).pathname}`; }); /** @@ -202,7 +184,7 @@ router.get( }); return res.json(ret); - }, + } ); // TODO: config max upload size @@ -258,10 +240,7 @@ router.post( relations: ["recipients", "recipients.user"], }); if (!channel.isWritable()) { - throw new HTTPError( - `Cannot send messages to channel of type ${channel.type}`, - 400, - ); + throw new HTTPError(`Cannot send messages to channel of type ${channel.type}`, 400); } if (body.nonce) { @@ -283,12 +262,7 @@ router.post( const count = await Message.count({ where: { channel_id, - timestamp: MoreThan( - new Date( - Date.now() - - limits.absoluteRate.sendMessage.window, - ), - ), + timestamp: MoreThan(new Date(Date.now() - limits.absoluteRate.sendMessage.window)), }, }); @@ -305,13 +279,8 @@ router.post( const files = (req.files as Express.Multer.File[]) ?? []; for (const currFile of files) { try { - const file = await uploadFile( - `/attachments/${channel.id}`, - currFile, - ); - attachments.push( - Attachment.create({ ...file, proxy_url: file.url }), - ); + const file = await uploadFile(`/attachments/${channel.id}`, currFile); + attachments.push(Attachment.create({ ...file, proxy_url: file.url })); } catch (error) { return res.status(400).json({ message: error?.toString() }); } @@ -347,14 +316,12 @@ router.post( recipient.save(), emitEvent({ event: "CHANNEL_CREATE", - data: channel_dto.excludedRecipients([ - recipient.user_id, - ]), + data: channel_dto.excludedRecipients([recipient.user_id]), user_id: recipient.user_id, }), ]); } - }) || [], + }) || [] ); } @@ -370,16 +337,13 @@ router.post( // eslint-disable-next-line @typescript-eslint/ban-ts-comment //@ts-ignore - message.member.roles = message.member.roles - .filter((x) => x.id != x.guild_id) - .map((x) => x.id); + message.member.roles = message.member.roles.filter((x) => x.id != x.guild_id).map((x) => x.id); } let read_state = await ReadState.findOne({ where: { user_id: req.user_id, channel_id }, }); - if (!read_state) - read_state = ReadState.create({ user_id: req.user_id, channel_id }); + if (!read_state) read_state = ReadState.create({ user_id: req.user_id, channel_id }); read_state.last_message_id = message.id; await Promise.all([ @@ -391,21 +355,16 @@ router.post( data: message, } as MessageCreateEvent), message.guild_id - ? Member.update( - { id: req.user_id, guild_id: message.guild_id }, - { last_message_id: message.id }, - ) + ? Member.update({ id: req.user_id, guild_id: message.guild_id }, { last_message_id: message.id }) : null, channel.save(), ]); // no await as it shouldnt block the message send function and silently catch error - postHandleMessage(message).catch((e) => - console.error("[Message] post-message handler failed", e), - ); + postHandleMessage(message).catch((e) => console.error("[Message] post-message handler failed", e)); return res.json(message); - }, + } ); export default router; diff --git a/src/api/routes/channels/#channel_id/permissions.ts b/src/api/routes/channels/#channel_id/permissions.ts index d3edb0fa..a9c28c0c 100644 --- a/src/api/routes/channels/#channel_id/permissions.ts +++ b/src/api/routes/channels/#channel_id/permissions.ts @@ -55,15 +55,14 @@ router.put( if (!channel.guild_id) throw new HTTPError("Channel not found", 404); if (body.type === 0) { - if (!(await Role.count({ where: { id: overwrite_id } }))) - throw new HTTPError("role not found", 404); + if (!(await Role.count({ where: { id: overwrite_id } }))) throw new HTTPError("role not found", 404); } else if (body.type === 1) { - if (!(await Member.count({ where: { id: overwrite_id } }))) - throw new HTTPError("user not found", 404); + if (!(await Member.count({ where: { id: overwrite_id } }))) throw new HTTPError("user not found", 404); } else throw new HTTPError("type not supported", 501); - let overwrite: ChannelPermissionOverwrite | undefined = - channel.permission_overwrites?.find((x) => x.id === overwrite_id); + let overwrite: ChannelPermissionOverwrite | undefined = channel.permission_overwrites?.find( + (x) => x.id === overwrite_id + ); if (!overwrite) { overwrite = { id: overwrite_id, @@ -73,14 +72,8 @@ router.put( }; channel.permission_overwrites?.push(overwrite); } - overwrite.allow = String( - (req.permission?.bitfield || 0n) & - (BigInt(body.allow) || BigInt("0")), - ); - overwrite.deny = String( - (req.permission?.bitfield || 0n) & - (BigInt(body.deny) || BigInt("0")), - ); + overwrite.allow = String((req.permission?.bitfield || 0n) & (BigInt(body.allow) || BigInt("0"))); + overwrite.deny = String((req.permission?.bitfield || 0n) & (BigInt(body.deny) || BigInt("0"))); await Promise.all([ channel.save(), @@ -92,7 +85,7 @@ router.put( ]); return res.sendStatus(204); - }, + } ); // TODO: check permission hierarchy @@ -107,9 +100,7 @@ router.delete( }); if (!channel.guild_id) throw new HTTPError("Channel not found", 404); - channel.permission_overwrites = channel.permission_overwrites?.filter( - (x) => x.id === overwrite_id, - ); + channel.permission_overwrites = channel.permission_overwrites?.filter((x) => x.id === overwrite_id); await Promise.all([ channel.save(), @@ -121,7 +112,7 @@ router.delete( ]); return res.sendStatus(204); - }, + } ); export default router; diff --git a/src/api/routes/channels/#channel_id/pins.ts b/src/api/routes/channels/#channel_id/pins.ts index 724ebffd..597d735c 100644 --- a/src/api/routes/channels/#channel_id/pins.ts +++ b/src/api/routes/channels/#channel_id/pins.ts @@ -57,8 +57,7 @@ router.put( where: { channel: { id: channel_id }, pinned: true }, }); const { maxPins } = Config.get().limits.channel; - if (pinned_count >= maxPins) - throw DiscordApiErrors.MAXIMUM_PINS.withParams(maxPins); + if (pinned_count >= maxPins) throw DiscordApiErrors.MAXIMUM_PINS.withParams(maxPins); await Promise.all([ Message.update({ id: message_id }, { pinned: true }), @@ -79,7 +78,7 @@ router.put( ]); res.sendStatus(204); - }, + } ); router.delete( @@ -129,7 +128,7 @@ router.delete( ]); res.sendStatus(204); - }, + } ); router.get( @@ -153,7 +152,7 @@ router.get( }); res.send(pins); - }, + } ); export default router; diff --git a/src/api/routes/channels/#channel_id/purge.ts b/src/api/routes/channels/#channel_id/purge.ts index 012fec1c..c473f9aa 100644 --- a/src/api/routes/channels/#channel_id/purge.ts +++ b/src/api/routes/channels/#channel_id/purge.ts @@ -57,17 +57,12 @@ router.post( where: { id: channel_id }, }); - if (!channel.guild_id) - throw new HTTPError("Can't purge dm channels", 400); + if (!channel.guild_id) throw new HTTPError("Can't purge dm channels", 400); isTextChannel(channel.type); const rights = await getRights(req.user_id); if (!rights.has("MANAGE_MESSAGES")) { - const permissions = await getPermission( - req.user_id, - channel.guild_id, - channel_id, - ); + const permissions = await getPermission(req.user_id, channel.guild_id, channel_id); permissions.hasThrow("MANAGE_MESSAGES"); permissions.hasThrow("MANAGE_CHANNELS"); } @@ -84,9 +79,7 @@ router.post( where: { channel_id, id: Between(after, before), // the right way around - author_id: rights.has("SELF_DELETE_MESSAGES") - ? undefined - : Not(req.user_id), + author_id: rights.has("SELF_DELETE_MESSAGES") ? undefined : Not(req.user_id), // if you lack the right of self-deletion, you can't delete your own messages, even in purges }, relations: [ @@ -121,5 +114,5 @@ router.post( } as MessageDeleteBulkEvent); res.sendStatus(204); - }, + } ); diff --git a/src/api/routes/channels/#channel_id/recipients.ts b/src/api/routes/channels/#channel_id/recipients.ts index 569bb5cd..c1377269 100644 --- a/src/api/routes/channels/#channel_id/recipients.ts +++ b/src/api/routes/channels/#channel_id/recipients.ts @@ -48,24 +48,16 @@ router.put( }); if (channel.type !== ChannelType.GROUP_DM) { - const recipients = [ - ...(channel.recipients?.map((r) => r.user_id) || []), - user_id, - ].unique(); + const recipients = [...(channel.recipients?.map((r) => r.user_id) || []), user_id].unique(); - const new_channel = await Channel.createDMChannel( - recipients, - req.user_id, - ); + const new_channel = await Channel.createDMChannel(recipients, req.user_id); return res.status(201).json(new_channel); } else { if (channel.recipients?.map((r) => r.user_id).includes(user_id)) { throw DiscordApiErrors.INVALID_RECIPIENT; //TODO is this the right error? } - channel.recipients?.push( - Recipient.create({ channel_id: channel_id, user_id: user_id }), - ); + channel.recipients?.push(Recipient.create({ channel_id: channel_id, user_id: user_id })); await channel.save(); await emitEvent({ @@ -87,7 +79,7 @@ router.put( } as ChannelRecipientAddEvent); return res.sendStatus(204); } - }, + } ); router.delete( @@ -104,12 +96,7 @@ router.delete( where: { id: channel_id }, relations: ["recipients"], }); - if ( - !( - channel.type === ChannelType.GROUP_DM && - (channel.owner_id === req.user_id || user_id === req.user_id) - ) - ) + if (!(channel.type === ChannelType.GROUP_DM && (channel.owner_id === req.user_id || user_id === req.user_id))) throw DiscordApiErrors.MISSING_PERMISSIONS; if (!channel.recipients?.map((r) => r.user_id).includes(user_id)) { @@ -119,7 +106,7 @@ router.delete( await Channel.removeRecipientFromChannel(channel, user_id); return res.sendStatus(204); - }, + } ); export default router; diff --git a/src/api/routes/channels/#channel_id/typing.ts b/src/api/routes/channels/#channel_id/typing.ts index 90e78175..4563b689 100644 --- a/src/api/routes/channels/#channel_id/typing.ts +++ b/src/api/routes/channels/#channel_id/typing.ts @@ -64,7 +64,7 @@ router.post( } as TypingStartEvent); res.sendStatus(204); - }, + } ); export default router; diff --git a/src/api/routes/channels/#channel_id/webhooks.ts b/src/api/routes/channels/#channel_id/webhooks.ts index d54756a1..864fe834 100644 --- a/src/api/routes/channels/#channel_id/webhooks.ts +++ b/src/api/routes/channels/#channel_id/webhooks.ts @@ -47,7 +47,7 @@ router.get( }), async (req: Request, res: Response) => { res.json([]); - }, + } ); // TODO: use Image Data Type for avatar instead of String @@ -77,8 +77,7 @@ router.post( const webhook_count = await Webhook.count({ where: { channel_id } }); const { maxWebhooks } = Config.get().limits.channel; - if (maxWebhooks && webhook_count > maxWebhooks) - throw DiscordApiErrors.MAXIMUM_WEBHOOKS.withParams(maxWebhooks); + if (maxWebhooks && webhook_count > maxWebhooks) throw DiscordApiErrors.MAXIMUM_WEBHOOKS.withParams(maxWebhooks); let { avatar, name } = req.body as WebhookCreateSchema; name = trimSpecial(name); @@ -105,7 +104,7 @@ router.post( ...hook, user: user, }); - }, + } ); export default router; diff --git a/src/api/routes/connections/#connection_name/authorize.ts b/src/api/routes/connections/#connection_name/authorize.ts index b43f46d7..c3a435cd 100644 --- a/src/api/routes/connections/#connection_name/authorize.ts +++ b/src/api/routes/connections/#connection_name/authorize.ts @@ -30,9 +30,7 @@ router.get("/", route({}), async (req: Request, res: Response) => { provider_id: { code: "BASE_TYPE_CHOICES", message: req.t("common:field.BASE_TYPE_CHOICES", { - types: Array.from(ConnectionStore.connections.keys()).join( - ", ", - ), + types: Array.from(ConnectionStore.connections.keys()).join(", "), }), }, }); diff --git a/src/api/routes/connections/#connection_name/callback.ts b/src/api/routes/connections/#connection_name/callback.ts index ee0db94a..f47c48f3 100644 --- a/src/api/routes/connections/#connection_name/callback.ts +++ b/src/api/routes/connections/#connection_name/callback.ts @@ -17,55 +17,44 @@ */ import { route } from "@spacebar/api"; -import { - ConnectionCallbackSchema, - ConnectionStore, - emitEvent, - FieldErrors, -} from "@spacebar/util"; +import { ConnectionCallbackSchema, ConnectionStore, emitEvent, FieldErrors } from "@spacebar/util"; import { Request, Response, Router } from "express"; const router = Router(); -router.post( - "/", - route({ requestBody: "ConnectionCallbackSchema" }), - async (req: Request, res: Response) => { - const { connection_name } = req.params; - const connection = ConnectionStore.connections.get(connection_name); - if (!connection) - throw FieldErrors({ - provider_id: { - code: "BASE_TYPE_CHOICES", - message: req.t("common:field.BASE_TYPE_CHOICES", { - types: Array.from( - ConnectionStore.connections.keys(), - ).join(", "), - }), - }, - }); - - if (!connection.settings.enabled) - throw FieldErrors({ - provider_id: { - message: "This connection has been disabled server-side.", - }, - }); - - const body = req.body as ConnectionCallbackSchema; - const userId = connection.getUserId(body.state); - const connectedAccnt = await connection.handleCallback(body); - - // whether we should emit a connections update event, only used when a connection doesnt already exist - if (connectedAccnt) - emitEvent({ - event: "USER_CONNECTIONS_UPDATE", - data: { ...connectedAccnt, token_data: undefined }, - user_id: userId, - }); - - res.sendStatus(204); - }, -); +router.post("/", route({ requestBody: "ConnectionCallbackSchema" }), async (req: Request, res: Response) => { + const { connection_name } = req.params; + const connection = ConnectionStore.connections.get(connection_name); + if (!connection) + throw FieldErrors({ + provider_id: { + code: "BASE_TYPE_CHOICES", + message: req.t("common:field.BASE_TYPE_CHOICES", { + types: Array.from(ConnectionStore.connections.keys()).join(", "), + }), + }, + }); + + if (!connection.settings.enabled) + throw FieldErrors({ + provider_id: { + message: "This connection has been disabled server-side.", + }, + }); + + const body = req.body as ConnectionCallbackSchema; + const userId = connection.getUserId(body.state); + const connectedAccnt = await connection.handleCallback(body); + + // whether we should emit a connections update event, only used when a connection doesnt already exist + if (connectedAccnt) + emitEvent({ + event: "USER_CONNECTIONS_UPDATE", + data: { ...connectedAccnt, token_data: undefined }, + user_id: userId, + }); + + res.sendStatus(204); +}); export default router; diff --git a/src/api/routes/discoverable-guilds.ts b/src/api/routes/discoverable-guilds.ts index b8c6a386..e2a47cd7 100644 --- a/src/api/routes/discoverable-guilds.ts +++ b/src/api/routes/discoverable-guilds.ts @@ -70,7 +70,7 @@ router.get( offset: Number(offset || Config.get().guild.discovery.offset), limit: Number(limit || configLimit), }); - }, + } ); export default router; diff --git a/src/api/routes/discovery.ts b/src/api/routes/discovery.ts index a045c191..e4e7dbf7 100644 --- a/src/api/routes/discovery.ts +++ b/src/api/routes/discovery.ts @@ -38,12 +38,10 @@ router.get( // const { locale, primary_only } = req.query; const { primary_only } = req.query; - const out = primary_only - ? await Categories.find() - : await Categories.find({ where: { is_primary: true } }); + const out = primary_only ? await Categories.find() : await Categories.find({ where: { is_primary: true } }); res.send(out); - }, + } ); export default router; diff --git a/src/api/routes/download.ts b/src/api/routes/download.ts index 85fb41be..6bb6d61c 100644 --- a/src/api/routes/download.ts +++ b/src/api/routes/download.ts @@ -52,7 +52,7 @@ router.get( }); res.redirect(release.url); - }, + } ); export default router; diff --git a/src/api/routes/gateway/bot.ts b/src/api/routes/gateway/bot.ts index d9101159..af12d424 100644 --- a/src/api/routes/gateway/bot.ts +++ b/src/api/routes/gateway/bot.ts @@ -43,7 +43,7 @@ router.get( max_concurrency: 1, }, }); - }, + } ); export default router; diff --git a/src/api/routes/gateway/index.ts b/src/api/routes/gateway/index.ts index 9100d5ee..4ef16818 100644 --- a/src/api/routes/gateway/index.ts +++ b/src/api/routes/gateway/index.ts @@ -36,7 +36,7 @@ router.get( res.json({ url: endpointPublic || process.env.GATEWAY || "ws://localhost:3001", }); - }, + } ); export default router; diff --git a/src/api/routes/gifs/search.ts b/src/api/routes/gifs/search.ts index 305a2a48..b4628753 100644 --- a/src/api/routes/gifs/search.ts +++ b/src/api/routes/gifs/search.ts @@ -36,9 +36,7 @@ router.get( media_format: { type: "string", description: "Media format", - values: Object.keys(TenorMediaTypes).filter((key) => - isNaN(Number(key)), - ), + values: Object.keys(TenorMediaTypes).filter((key) => isNaN(Number(key))), }, locale: { type: "string", @@ -65,13 +63,13 @@ router.get( agent, method: "get", headers: { "Content-Type": "application/json" }, - }, + } ); const { results } = await response.json(); res.json(results.map(parseGifResult)).status(200); - }, + } ); export default router; diff --git a/src/api/routes/gifs/trending-gifs.ts b/src/api/routes/gifs/trending-gifs.ts index 77a61efc..c2aec7c3 100644 --- a/src/api/routes/gifs/trending-gifs.ts +++ b/src/api/routes/gifs/trending-gifs.ts @@ -31,9 +31,7 @@ router.get( media_format: { type: "string", description: "Media format", - values: Object.keys(TenorMediaTypes).filter((key) => - isNaN(Number(key)), - ), + values: Object.keys(TenorMediaTypes).filter((key) => isNaN(Number(key))), }, locale: { type: "string", @@ -60,13 +58,13 @@ router.get( agent, method: "get", headers: { "Content-Type": "application/json" }, - }, + } ); const { results } = await response.json(); res.json(results.map(parseGifResult)).status(200); - }, + } ); export default router; diff --git a/src/api/routes/gifs/trending.ts b/src/api/routes/gifs/trending.ts index fe726842..ebf42629 100644 --- a/src/api/routes/gifs/trending.ts +++ b/src/api/routes/gifs/trending.ts @@ -17,12 +17,7 @@ */ import { route } from "@spacebar/api"; -import { - TenorCategoriesResults, - TenorTrendingResults, - getGifApiKey, - parseGifResult, -} from "@spacebar/util"; +import { TenorCategoriesResults, TenorTrendingResults, getGifApiKey, parseGifResult } from "@spacebar/util"; import { Request, Response, Router } from "express"; import fetch from "node-fetch"; import { ProxyAgent } from "proxy-agent"; @@ -55,28 +50,20 @@ router.get( const agent = new ProxyAgent(); const [responseSource, trendGifSource] = await Promise.all([ - fetch( - `https://g.tenor.com/v1/categories?locale=${locale}&key=${apiKey}`, - { - agent, - method: "get", - headers: { "Content-Type": "application/json" }, - }, - ), - fetch( - `https://g.tenor.com/v1/trending?locale=${locale}&key=${apiKey}`, - { - agent, - method: "get", - headers: { "Content-Type": "application/json" }, - }, - ), + fetch(`https://g.tenor.com/v1/categories?locale=${locale}&key=${apiKey}`, { + agent, + method: "get", + headers: { "Content-Type": "application/json" }, + }), + fetch(`https://g.tenor.com/v1/trending?locale=${locale}&key=${apiKey}`, { + agent, + method: "get", + headers: { "Content-Type": "application/json" }, + }), ]); - const { tags } = - (await responseSource.json()) as TenorCategoriesResults; - const { results } = - (await trendGifSource.json()) as TenorTrendingResults; + const { tags } = (await responseSource.json()) as TenorCategoriesResults; + const { results } = (await trendGifSource.json()) as TenorTrendingResults; res.json({ categories: tags.map((x) => ({ @@ -85,7 +72,7 @@ router.get( })), gifs: [parseGifResult(results[0])], }).status(200); - }, + } ); export default router; diff --git a/src/api/routes/guild-recommendations.ts b/src/api/routes/guild-recommendations.ts index 876780df..14f0dfbc 100644 --- a/src/api/routes/guild-recommendations.ts +++ b/src/api/routes/guild-recommendations.ts @@ -39,9 +39,7 @@ router.get( const showAllGuilds = Config.get().guild.discovery.showAllGuilds; const genLoadId = (size: number) => - [...Array(size)] - .map(() => Math.floor(Math.random() * 16).toString(16)) - .join(""); + [...Array(size)].map(() => Math.floor(Math.random() * 16).toString(16)).join(""); const guilds = showAllGuilds ? await Guild.find({ take: Math.abs(Number(limit || 24)) }) @@ -53,7 +51,7 @@ router.get( recommended_guilds: guilds, load_id: `server_recs/${genLoadId(32)}`, }).status(200); - }, + } ); export default router; diff --git a/src/api/routes/guilds/#guild_id/bans.ts b/src/api/routes/guilds/#guild_id/bans.ts index 0776ab62..1fcc6806 100644 --- a/src/api/routes/guilds/#guild_id/bans.ts +++ b/src/api/routes/guilds/#guild_id/bans.ts @@ -78,7 +78,7 @@ router.get( }); return res.json(bansObj); - }, + } ); router.get( @@ -115,7 +115,7 @@ router.get( delete ban.ip; return res.json(ban); - }, + } ); router.put( @@ -139,14 +139,8 @@ router.put( const { guild_id } = req.params; const banned_user_id = req.params.user_id; - 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.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); @@ -175,7 +169,7 @@ router.put( ]); return res.json(ban); - }, + } ); router.put( @@ -200,10 +194,7 @@ router.put( 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, - ); + throw new HTTPError("You are the guild owner, hence can't ban yourself", 403); const ban = Ban.create({ user_id: req.params.user_id, @@ -227,7 +218,7 @@ router.put( ]); return res.json(ban); - }, + } ); router.delete( @@ -273,7 +264,7 @@ router.delete( ]); return res.status(204).send(); - }, + } ); export default router; diff --git a/src/api/routes/guilds/#guild_id/channels.ts b/src/api/routes/guilds/#guild_id/channels.ts index 68208fee..0ad3e252 100644 --- a/src/api/routes/guilds/#guild_id/channels.ts +++ b/src/api/routes/guilds/#guild_id/channels.ts @@ -42,7 +42,7 @@ router.get( const channels = await Channel.find({ where: { guild_id } }); res.json(channels); - }, + } ); router.post( @@ -67,13 +67,10 @@ router.post( const { guild_id } = req.params; const body = req.body as ChannelModifySchema; - const channel = await Channel.createChannel( - { ...body, guild_id }, - req.user_id, - ); + const channel = await Channel.createChannel({ ...body, guild_id }, req.user_id); res.status(201).json(channel); - }, + } ); router.patch( @@ -102,9 +99,7 @@ router.patch( }); // The channels not listed for this query - const notMentioned = guild.channel_ordering.filter( - (x) => !body.find((c) => c.id == x), - ); + const notMentioned = guild.channel_ordering.filter((x) => !body.find((c) => c.id == x)); const withParents = body.filter((x) => x.parent_id != undefined); const withPositions = body.filter((x) => x.position != undefined); @@ -124,7 +119,7 @@ router.patch( channel_id: channel.id, guild_id, } as ChannelUpdateEvent); - }), + }) ); // have to do the parents after the positions @@ -141,10 +136,7 @@ router.patch( ]); if (opt.lock_permissions) - await Channel.update( - { id: channel.id }, - { permission_overwrites: parent.permission_overwrites }, - ); + await Channel.update({ id: channel.id }, { permission_overwrites: parent.permission_overwrites }); const parentPos = notMentioned.indexOf(parent.id); notMentioned.splice(parentPos + 1, 0, channel.id); @@ -156,16 +148,13 @@ router.patch( channel_id: channel.id, guild_id, } as ChannelUpdateEvent); - }), + }) ); - await Guild.update( - { id: guild_id }, - { channel_ordering: notMentioned }, - ); + await Guild.update({ id: guild_id }, { channel_ordering: notMentioned }); return res.sendStatus(204); - }, + } ); export default router; diff --git a/src/api/routes/guilds/#guild_id/delete.ts b/src/api/routes/guilds/#guild_id/delete.ts index dee52c81..9f874a5c 100644 --- a/src/api/routes/guilds/#guild_id/delete.ts +++ b/src/api/routes/guilds/#guild_id/delete.ts @@ -45,8 +45,7 @@ router.post( 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); + if (guild.owner_id !== req.user_id) throw new HTTPError("You are not the owner of this guild", 401); await Promise.all([ Guild.delete({ id: guild_id }), // this will also delete all guild related data @@ -60,7 +59,7 @@ router.post( ]); return res.sendStatus(204); - }, + } ); export default router; diff --git a/src/api/routes/guilds/#guild_id/discovery-requirements.ts b/src/api/routes/guilds/#guild_id/discovery-requirements.ts index 741fa9b3..6de571c5 100644 --- a/src/api/routes/guilds/#guild_id/discovery-requirements.ts +++ b/src/api/routes/guilds/#guild_id/discovery-requirements.ts @@ -59,7 +59,7 @@ router.get( }, minimum_size: 0, }); - }, + } ); export default router; diff --git a/src/api/routes/guilds/#guild_id/emojis.ts b/src/api/routes/guilds/#guild_id/emojis.ts index ef28f989..fa821cf0 100644 --- a/src/api/routes/guilds/#guild_id/emojis.ts +++ b/src/api/routes/guilds/#guild_id/emojis.ts @@ -57,7 +57,7 @@ router.get( }); return res.json(emojis); - }, + } ); router.get( @@ -86,7 +86,7 @@ router.get( }); return res.json(emoji); - }, + } ); router.post( @@ -116,10 +116,7 @@ router.post( }); const { maxEmojis } = Config.get().limits.guild; - if (emoji_count >= maxEmojis) - throw DiscordApiErrors.MAXIMUM_NUMBER_OF_EMOJIS_REACHED.withParams( - maxEmojis, - ); + if (emoji_count >= maxEmojis) throw DiscordApiErrors.MAXIMUM_NUMBER_OF_EMOJIS_REACHED.withParams(maxEmojis); if (body.require_colons == null) body.require_colons = true; const user = await User.findOneOrFail({ where: { id: req.user_id } }); @@ -147,7 +144,7 @@ router.post( } as GuildEmojisUpdateEvent); return res.status(201).json(emoji); - }, + } ); router.patch( @@ -184,7 +181,7 @@ router.patch( } as GuildEmojisUpdateEvent); return res.json(emoji); - }, + } ); router.delete( @@ -216,7 +213,7 @@ router.delete( } as GuildEmojisUpdateEvent); res.sendStatus(204); - }, + } ); export default router; diff --git a/src/api/routes/guilds/#guild_id/index.ts b/src/api/routes/guilds/#guild_id/index.ts index 839ec363..87388abc 100644 --- a/src/api/routes/guilds/#guild_id/index.ts +++ b/src/api/routes/guilds/#guild_id/index.ts @@ -58,17 +58,13 @@ router.get( Guild.findOneOrFail({ where: { id: guild_id } }), Member.findOne({ where: { 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, - ); + if (!member) throw new HTTPError("You are not a member of the guild you are trying to access", 401); return res.send({ ...guild, joined_at: member?.joined_at, }); - }, + } ); router.patch( @@ -99,9 +95,7 @@ router.patch( const permission = await getPermission(req.user_id, guild_id); if (!rights.has("MANAGE_GUILDS") && !permission.has("MANAGE_GUILD")) - throw DiscordApiErrors.MISSING_PERMISSIONS.withParams( - "MANAGE_GUILDS", - ); + throw DiscordApiErrors.MISSING_PERMISSIONS.withParams("MANAGE_GUILDS"); const guild = await Guild.findOneOrFail({ where: { id: guild_id }, @@ -110,47 +104,29 @@ router.patch( // TODO: guild update check image - if (body.icon && body.icon != guild.icon) - body.icon = await handleFile(`/icons/${guild_id}`, body.icon); + if (body.icon && body.icon != guild.icon) body.icon = await handleFile(`/icons/${guild_id}`, body.icon); if (body.banner && body.banner !== guild.banner) body.banner = await handleFile(`/banners/${guild_id}`, body.banner); if (body.splash && body.splash !== guild.splash) - body.splash = await handleFile( - `/splashes/${guild_id}`, - body.splash, - ); + body.splash = await handleFile(`/splashes/${guild_id}`, body.splash); - if ( - body.discovery_splash && - body.discovery_splash !== guild.discovery_splash - ) - body.discovery_splash = await handleFile( - `/discovery-splashes/${guild_id}`, - body.discovery_splash, - ); + if (body.discovery_splash && body.discovery_splash !== guild.discovery_splash) + body.discovery_splash = await handleFile(`/discovery-splashes/${guild_id}`, body.discovery_splash); if (body.features) { const diff = guild.features .filter((x) => !body.features?.includes(x)) - .concat( - body.features.filter((x) => !guild.features.includes(x)), - ); + .concat(body.features.filter((x) => !guild.features.includes(x))); // TODO move these - const MUTABLE_FEATURES = [ - "COMMUNITY", - "INVITES_DISABLED", - "DISCOVERABLE", - ]; + const MUTABLE_FEATURES = ["COMMUNITY", "INVITES_DISABLED", "DISCOVERABLE"]; for (const feature of diff) { if (MUTABLE_FEATURES.includes(feature)) continue; - throw SpacebarApiErrors.FEATURE_IS_IMMUTABLE.withParams( - feature, - ); + throw SpacebarApiErrors.FEATURE_IS_IMMUTABLE.withParams(feature); } // for some reason, they don't update in the assign. @@ -179,7 +155,7 @@ router.patch( ], }, undefined, - { skipPermissionCheck: true }, + { skipPermissionCheck: true } ); await Guild.insertChannelInOrder(guild.id, channel.id, 0, guild); @@ -212,7 +188,7 @@ router.patch( ], }, undefined, - { skipPermissionCheck: true }, + { skipPermissionCheck: true } ); await Guild.insertChannelInOrder(guild.id, channel.id, 0, guild); @@ -242,7 +218,7 @@ router.patch( ]); return res.json(data); - }, + } ); export default router; diff --git a/src/api/routes/guilds/#guild_id/invites.ts b/src/api/routes/guilds/#guild_id/invites.ts index a0ffa3f4..5311a77f 100644 --- a/src/api/routes/guilds/#guild_id/invites.ts +++ b/src/api/routes/guilds/#guild_id/invites.ts @@ -41,7 +41,7 @@ router.get( }); return res.json(invites); - }, + } ); export default router; diff --git a/src/api/routes/guilds/#guild_id/member-verification.ts b/src/api/routes/guilds/#guild_id/member-verification.ts index 2c39093e..b30c379d 100644 --- a/src/api/routes/guilds/#guild_id/member-verification.ts +++ b/src/api/routes/guilds/#guild_id/member-verification.ts @@ -36,7 +36,7 @@ router.get( message: "Unknown Guild Member Verification Form", code: 10068, }); - }, + } ); export default router; diff --git a/src/api/routes/guilds/#guild_id/members/#member_id/index.ts b/src/api/routes/guilds/#guild_id/members/#member_id/index.ts index c168f2dc..5dd6f2b8 100644 --- a/src/api/routes/guilds/#guild_id/members/#member_id/index.ts +++ b/src/api/routes/guilds/#guild_id/members/#member_id/index.ts @@ -62,13 +62,9 @@ router.get( select: { index: true, // only grab public member props - ...Object.fromEntries( - PublicMemberProjection.map((x) => [x, true]), - ), + ...Object.fromEntries(PublicMemberProjection.map((x) => [x, true])), // and public user props - user: Object.fromEntries( - PublicUserProjection.map((x) => [x, true]), - ), + user: Object.fromEntries(PublicUserProjection.map((x) => [x, true])), roles: { id: true, }, @@ -80,7 +76,7 @@ router.get( user: member.user.toPublicUser(), roles: member.roles.map((x) => x.id), }); - }, + } ); router.patch( @@ -104,8 +100,7 @@ router.patch( }), async (req: Request, res: Response) => { const { guild_id } = req.params; - const member_id = - req.params.member_id === "@me" ? req.user_id : req.params.member_id; + const member_id = req.params.member_id === "@me" ? req.user_id : req.params.member_id; const body = req.body as MemberChangeSchema; const member = await Member.findOneOrFail({ @@ -128,19 +123,13 @@ router.patch( } } - if ( - ("bio" in body || "avatar" in body) && - req.params.member_id != "@me" - ) { + if (("bio" in body || "avatar" in body) && req.params.member_id != "@me") { const rights = await getRights(req.user_id); rights.hasThrow("MANAGE_USERS"); } if (body.avatar) - body.avatar = await handleFile( - `/guilds/${guild_id}/users/${member_id}/avatars`, - body.avatar as string, - ); + body.avatar = await handleFile(`/guilds/${guild_id}/users/${member_id}/avatars`, body.avatar as string); member.assign(body); @@ -152,8 +141,7 @@ router.patch( body.roles = body.roles || []; body.roles.filter((x) => !!x); - if (body.roles.indexOf(everyone.id) === -1) - body.roles.push(everyone.id); + if (body.roles.indexOf(everyone.id) === -1) body.roles.push(everyone.id); // foreign key constraint will fail if role doesn't exist member.roles = body.roles.map((x) => Role.create({ id: x })); } @@ -170,7 +158,7 @@ router.patch( } as GuildMemberUpdateEvent); res.json(member); - }, + } ); router.put( @@ -222,7 +210,7 @@ router.put( await Member.addToGuild(member_id, guild_id); res.send({ ...guild, emojis: emoji, roles: roles, stickers: stickers }); - }, + } ); router.delete( @@ -249,7 +237,7 @@ router.delete( await Member.removeFromGuild(member_id, guild_id); res.sendStatus(204); - }, + } ); export default router; diff --git a/src/api/routes/guilds/#guild_id/members/#member_id/nick.ts b/src/api/routes/guilds/#guild_id/members/#member_id/nick.ts index 7b8e44d3..8162f36b 100644 --- a/src/api/routes/guilds/#guild_id/members/#member_id/nick.ts +++ b/src/api/routes/guilds/#guild_id/members/#member_id/nick.ts @@ -49,7 +49,7 @@ router.patch( await Member.changeNickname(member_id, guild_id, req.body.nick); res.status(200).send(); - }, + } ); export default router; diff --git a/src/api/routes/guilds/#guild_id/members/#member_id/roles/#role_id/index.ts b/src/api/routes/guilds/#guild_id/members/#member_id/roles/#role_id/index.ts index 46dd70bb..da28e312 100644 --- a/src/api/routes/guilds/#guild_id/members/#member_id/roles/#role_id/index.ts +++ b/src/api/routes/guilds/#guild_id/members/#member_id/roles/#role_id/index.ts @@ -38,7 +38,7 @@ router.delete( await Member.removeRole(member_id, guild_id, role_id); res.sendStatus(204); - }, + } ); router.put( @@ -55,7 +55,7 @@ router.put( await Member.addRole(member_id, guild_id, role_id); res.sendStatus(204); - }, + } ); export default router; diff --git a/src/api/routes/guilds/#guild_id/members/index.ts b/src/api/routes/guilds/#guild_id/members/index.ts index 9260308d..8ea590d0 100644 --- a/src/api/routes/guilds/#guild_id/members/index.ts +++ b/src/api/routes/guilds/#guild_id/members/index.ts @@ -33,8 +33,7 @@ router.get( query: { limit: { type: "number", - description: - "max number of members to return (1-1000). default 1", + description: "max number of members to return (1-1000). default 1", }, after: { type: "string", @@ -52,8 +51,7 @@ router.get( async (req: Request, res: Response) => { const { guild_id } = req.params; const limit = Number(req.query.limit) || 1; - if (limit > 1000 || limit < 1) - throw new HTTPError("Limit must be between 1 and 1000"); + if (limit > 1000 || limit < 1) throw new HTTPError("Limit must be between 1 and 1000"); const after = `${req.query.after}`; const query = after ? { id: MoreThan(after) } : {}; @@ -67,7 +65,7 @@ router.get( }); return res.json(members); - }, + } ); export default router; diff --git a/src/api/routes/guilds/#guild_id/messages/search.ts b/src/api/routes/guilds/#guild_id/messages/search.ts index 637d1e43..aec36f85 100644 --- a/src/api/routes/guilds/#guild_id/messages/search.ts +++ b/src/api/routes/guilds/#guild_id/messages/search.ts @@ -54,14 +54,10 @@ router.get( } = req.query; const parsedLimit = Number(limit) || 50; - if (parsedLimit < 1 || parsedLimit > 100) - throw new HTTPError("limit must be between 1 and 100", 422); + if (parsedLimit < 1 || parsedLimit > 100) throw new HTTPError("limit must be between 1 and 100", 422); if (sort_order) { - if ( - typeof sort_order != "string" || - ["desc", "asc"].indexOf(sort_order) == -1 - ) + if (typeof sort_order != "string" || ["desc", "asc"].indexOf(sort_order) == -1) throw FieldErrors({ sort_order: { message: "Value must be one of ('desc', 'asc').", @@ -70,20 +66,13 @@ router.get( }); // todo this is wrong } - const permissions = await getPermission( - req.user_id, - req.params.guild_id, - channel_id as string | undefined, - ); + const permissions = await getPermission(req.user_id, req.params.guild_id, channel_id as string | undefined); permissions.hasThrow("VIEW_CHANNEL"); - if (!permissions.has("READ_MESSAGE_HISTORY")) - return res.json({ messages: [], total_results: 0 }); + if (!permissions.has("READ_MESSAGE_HISTORY")) return res.json({ messages: [], total_results: 0 }); const query: FindManyOptions<Message> = { order: { - timestamp: sort_order - ? (sort_order.toUpperCase() as "ASC" | "DESC") - : "DESC", + timestamp: sort_order ? (sort_order.toUpperCase() as "ASC" | "DESC") : "DESC", }, take: parsedLimit || 0, where: { @@ -114,16 +103,8 @@ router.get( const ids = []; for (const channel of channels) { - const perm = await getPermission( - req.user_id, - req.params.guild_id, - channel.id, - ); - if ( - !perm.has("VIEW_CHANNEL") || - !perm.has("READ_MESSAGE_HISTORY") - ) - continue; + const perm = await getPermission(req.user_id, req.params.guild_id, channel.id); + if (!perm.has("VIEW_CHANNEL") || !perm.has("READ_MESSAGE_HISTORY")) continue; ids.push(channel.id); } @@ -170,7 +151,7 @@ router.get( messages: messagesDto, total_results: messages.length, }); - }, + } ); export default router; diff --git a/src/api/routes/guilds/#guild_id/profile/index.ts b/src/api/routes/guilds/#guild_id/profile/index.ts index 60526259..e34136a4 100644 --- a/src/api/routes/guilds/#guild_id/profile/index.ts +++ b/src/api/routes/guilds/#guild_id/profile/index.ts @@ -57,10 +57,7 @@ router.patch( }); if (body.banner) - body.banner = await handleFile( - `/guilds/${guild_id}/users/${req.user_id}/avatars`, - body.banner as string, - ); + body.banner = await handleFile(`/guilds/${guild_id}/users/${req.user_id}/avatars`, body.banner as string); member = await OrmUtils.mergeDeep(member, body); @@ -74,7 +71,7 @@ router.patch( } as GuildMemberUpdateEvent); res.json(member); - }, + } ); export default router; diff --git a/src/api/routes/guilds/#guild_id/prune.ts b/src/api/routes/guilds/#guild_id/prune.ts index 2c77340d..7fa31ed2 100644 --- a/src/api/routes/guilds/#guild_id/prune.ts +++ b/src/api/routes/guilds/#guild_id/prune.ts @@ -23,12 +23,7 @@ import { IsNull, LessThan } from "typeorm"; const router = Router(); //Returns all inactive members, respecting role hierarchy -const inactiveMembers = async ( - guild_id: string, - user_id: string, - days: number, - roles: string[] = [], -) => { +const inactiveMembers = async (guild_id: string, user_id: string, days: number, roles: string[] = []) => { const date = new Date(); date.setDate(date.getDate() - days); //Snowflake should have `generateFromTime` method? Or similar? @@ -55,9 +50,7 @@ const inactiveMembers = async ( //I'm sure I can do this in the above db query ( and it would probably be better to do so ), but oh well. if (roles.length && members.length) - members = members.filter((user) => - user.roles?.some((role) => roles.includes(role.id)), - ); + members = members.filter((user) => user.roles?.some((role) => roles.includes(role.id))); const me = await Member.findOneOrFail({ where: { id: user_id, guild_id }, @@ -73,8 +66,8 @@ const inactiveMembers = async ( member.roles?.some( (role) => role.position < myHighestRole || //roles higher than me can't be kicked - me.id === guild.owner_id, //owner can kick anyone - ), + me.id === guild.owner_id //owner can kick anyone + ) ); return members; @@ -95,15 +88,10 @@ router.get( let roles = req.query.include_roles; if (typeof roles === "string") roles = [roles]; //express will return array otherwise - const members = await inactiveMembers( - req.params.guild_id, - req.user_id, - days, - roles as string[], - ); + const members = await inactiveMembers(req.params.guild_id, req.user_id, days, roles as string[]); res.send({ pruned: members.length }); - }, + } ); router.post( @@ -127,19 +115,12 @@ router.post( if (typeof roles === "string") roles = [roles]; const { guild_id } = req.params; - const members = await inactiveMembers( - guild_id, - req.user_id, - days, - roles as string[], - ); + const members = await inactiveMembers(guild_id, req.user_id, days, roles as string[]); - await Promise.all( - members.map((x) => Member.removeFromGuild(x.id, guild_id)), - ); + await Promise.all(members.map((x) => Member.removeFromGuild(x.id, guild_id))); res.send({ purged: members.length }); - }, + } ); export default router; diff --git a/src/api/routes/guilds/#guild_id/regions.ts b/src/api/routes/guilds/#guild_id/regions.ts index b0ae0602..e40a73e2 100644 --- a/src/api/routes/guilds/#guild_id/regions.ts +++ b/src/api/routes/guilds/#guild_id/regions.ts @@ -38,13 +38,8 @@ router.get( const { guild_id } = req.params; const guild = await Guild.findOneOrFail({ where: { id: guild_id } }); //TODO we should use an enum for guild's features and not hardcoded strings - return res.json( - await getVoiceRegions( - getIpAdress(req), - guild.features.includes("VIP_REGIONS"), - ), - ); - }, + return res.json(await getVoiceRegions(getIpAdress(req), guild.features.includes("VIP_REGIONS"))); + } ); export default router; 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 index ea1a782a..ae10addf 100644 --- a/src/api/routes/guilds/#guild_id/roles/#role_id/index.ts +++ b/src/api/routes/guilds/#guild_id/roles/#role_id/index.ts @@ -53,7 +53,7 @@ router.get( where: { guild_id, id: role_id }, }); return res.json(role); - }, + } ); router.delete( @@ -75,8 +75,7 @@ router.delete( }), 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"); + if (role_id === guild_id) throw new HTTPError("You can't delete the @everyone role"); await Promise.all([ Role.delete({ @@ -94,7 +93,7 @@ router.delete( ]); res.sendStatus(204); - }, + } ); // TODO: check role hierarchy @@ -123,11 +122,7 @@ router.patch( 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, - ); + if (body.icon && body.icon.length) body.icon = await handleFile(`/role-icons/${role_id}`, body.icon as string); else body.icon = undefined; const role = await Role.findOneOrFail({ @@ -135,10 +130,7 @@ router.patch( }); role.assign({ ...body, - permissions: String( - (req.permission?.bitfield || 0n) & - BigInt(body.permissions || "0"), - ), + permissions: String((req.permission?.bitfield || 0n) & BigInt(body.permissions || "0")), }); await Promise.all([ @@ -154,7 +146,7 @@ router.patch( ]); res.json(role); - }, + } ); export default router; diff --git a/src/api/routes/guilds/#guild_id/roles/#role_id/members.ts b/src/api/routes/guilds/#guild_id/roles/#role_id/members.ts index 539cd5d8..a34908a6 100644 --- a/src/api/routes/guilds/#guild_id/roles/#role_id/members.ts +++ b/src/api/routes/guilds/#guild_id/roles/#role_id/members.ts @@ -22,41 +22,31 @@ import { route } from "@spacebar/api"; const router = Router(); -router.patch( - "/", - route({ permission: "MANAGE_ROLES" }), - async (req: Request, res: Response) => { - // Payload is JSON containing a list of member_ids, the new list of members to have the role - const { guild_id, role_id } = req.params; - const { member_ids } = req.body; - - // don't mess with @everyone - if (role_id == guild_id) throw DiscordApiErrors.INVALID_ROLE; - - const members = await Member.find({ - where: { guild_id }, - relations: ["roles"], - }); - - const [add, remove] = partition( - members, - (member) => - member_ids.includes(member.id) && - !member.roles.map((role) => role.id).includes(role_id), - ); - - // TODO (erkin): have a bulk add/remove function that adds the roles in a single txn - await Promise.all([ - ...add.map((member) => - Member.addRole(member.id, guild_id, role_id), - ), - ...remove.map((member) => - Member.removeRole(member.id, guild_id, role_id), - ), - ]); - - res.sendStatus(204); - }, -); +router.patch("/", route({ permission: "MANAGE_ROLES" }), async (req: Request, res: Response) => { + // Payload is JSON containing a list of member_ids, the new list of members to have the role + const { guild_id, role_id } = req.params; + const { member_ids } = req.body; + + // don't mess with @everyone + if (role_id == guild_id) throw DiscordApiErrors.INVALID_ROLE; + + const members = await Member.find({ + where: { guild_id }, + relations: ["roles"], + }); + + const [add, remove] = partition( + members, + (member) => member_ids.includes(member.id) && !member.roles.map((role) => role.id).includes(role_id) + ); + + // TODO (erkin): have a bulk add/remove function that adds the roles in a single txn + await Promise.all([ + ...add.map((member) => Member.addRole(member.id, guild_id, role_id)), + ...remove.map((member) => Member.removeRole(member.id, guild_id, role_id)), + ]); + + res.sendStatus(204); +}); 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 index e2c34e7f..1e60c2cf 100644 --- a/src/api/routes/guilds/#guild_id/roles/index.ts +++ b/src/api/routes/guilds/#guild_id/roles/index.ts @@ -68,8 +68,7 @@ router.post( 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); + if (role_count > maxRoles) throw DiscordApiErrors.MAXIMUM_ROLES.withParams(maxRoles); const role = Role.create({ // values before ...body are default and can be overriden @@ -80,10 +79,7 @@ router.post( ...body, guild_id: guild_id, managed: false, - permissions: String( - (req.permission?.bitfield || 0n) & - BigInt(body.permissions || "0"), - ), + permissions: String((req.permission?.bitfield || 0n) & BigInt(body.permissions || "0")), tags: undefined, icon: undefined, unicode_emoji: undefined, @@ -112,7 +108,7 @@ router.post( ]); res.json(role); - }, + } ); router.patch( @@ -136,11 +132,7 @@ router.patch( const { guild_id } = req.params; const body = req.body as RolePositionUpdateSchema; - await Promise.all( - body.map(async (x) => - Role.update({ guild_id, id: x.id }, { position: x.position }), - ), - ); + 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 })), @@ -155,12 +147,12 @@ router.patch( guild_id, role: x, }, - } as GuildRoleUpdateEvent), - ), + } as GuildRoleUpdateEvent) + ) ); res.json(roles); - }, + } ); export default router; diff --git a/src/api/routes/guilds/#guild_id/stickers.ts b/src/api/routes/guilds/#guild_id/stickers.ts index 88f9a40e..92b09aab 100644 --- a/src/api/routes/guilds/#guild_id/stickers.ts +++ b/src/api/routes/guilds/#guild_id/stickers.ts @@ -50,7 +50,7 @@ router.get( await Member.IsInGuildOrFail(req.user_id, guild_id); res.json(await Sticker.find({ where: { guild_id } })); - }, + } ); const bodyParser = multer({ @@ -102,7 +102,7 @@ router.post( await sendStickerUpdateEvent(guild_id); res.json(sticker); - }, + } ); function getStickerFormat(mime_type: string) { @@ -116,9 +116,7 @@ function getStickerFormat(mime_type: string) { case "image/gif": return StickerFormatType.GIF; default: - throw new HTTPError( - "invalid sticker format: must be png, apng or lottie", - ); + throw new HTTPError("invalid sticker format: must be png, apng or lottie"); } } @@ -141,9 +139,9 @@ router.get( res.json( await Sticker.findOneOrFail({ where: { guild_id, id: sticker_id }, - }), + }) ); - }, + } ); router.patch( @@ -175,7 +173,7 @@ router.patch( await sendStickerUpdateEvent(guild_id); return res.json(sticker); - }, + } ); async function sendStickerUpdateEvent(guild_id: string) { @@ -207,7 +205,7 @@ router.delete( await sendStickerUpdateEvent(guild_id); return res.sendStatus(204); - }, + } ); export default router; diff --git a/src/api/routes/guilds/#guild_id/templates.ts b/src/api/routes/guilds/#guild_id/templates.ts index 85ae0ac9..ae40377e 100644 --- a/src/api/routes/guilds/#guild_id/templates.ts +++ b/src/api/routes/guilds/#guild_id/templates.ts @@ -57,7 +57,7 @@ router.get( }); return res.json(templates); - }, + } ); router.post( @@ -102,7 +102,7 @@ router.post( }).save(); res.json(template); - }, + } ); router.delete( @@ -123,7 +123,7 @@ router.delete( }); res.json(template); - }, + } ); router.put( @@ -148,7 +148,7 @@ router.put( }).save(); res.json(template); - }, + } ); router.patch( @@ -173,7 +173,7 @@ router.patch( }).save(); res.json(template); - }, + } ); export default router; diff --git a/src/api/routes/guilds/#guild_id/vanity-url.ts b/src/api/routes/guilds/#guild_id/vanity-url.ts index a64ae2c9..1cfa9883 100644 --- a/src/api/routes/guilds/#guild_id/vanity-url.ts +++ b/src/api/routes/guilds/#guild_id/vanity-url.ts @@ -17,13 +17,7 @@ */ import { route } from "@spacebar/api"; -import { - Channel, - ChannelType, - Guild, - Invite, - VanityUrlSchema, -} from "@spacebar/util"; +import { Channel, ChannelType, Guild, Invite, VanityUrlSchema } from "@spacebar/util"; import { Request, Response, Router } from "express"; import { HTTPError } from "lambert-server"; @@ -64,11 +58,9 @@ router.get( }); if (!invite || invite.length == 0) return res.json({ code: null }); - return res.json( - invite.map((x) => ({ code: x.code, uses: x.uses })), - ); + return res.json(invite.map((x) => ({ code: x.code, uses: x.uses }))); } - }, + } ); router.patch( @@ -94,11 +86,9 @@ router.patch( const code = body.code?.replace(InviteRegex, ""); const guild = await Guild.findOneOrFail({ where: { id: guild_id } }); - if (!guild.features.includes("VANITY_URL")) - throw new HTTPError("Your guild doesn't support vanity urls"); + if (!guild.features.includes("VANITY_URL")) throw new HTTPError("Your guild doesn't support vanity urls"); - if (!code || code.length === 0) - throw new HTTPError("Code cannot be null or empty"); + if (!code || code.length === 0) throw new HTTPError("Code cannot be null or empty"); const invite = await Invite.findOne({ where: { code } }); if (invite) throw new HTTPError("Invite already exists"); @@ -112,7 +102,7 @@ router.patch( { guild_id }, { code: code, - }, + } ); return res.json({ code }); @@ -132,7 +122,7 @@ router.patch( }).save(); return res.json({ code: code }); - }, + } ); export default router; diff --git a/src/api/routes/guilds/#guild_id/voice-states/#user_id/index.ts b/src/api/routes/guilds/#guild_id/voice-states/#user_id/index.ts index 60c69075..c13d053b 100644 --- a/src/api/routes/guilds/#guild_id/voice-states/#user_id/index.ts +++ b/src/api/routes/guilds/#guild_id/voice-states/#user_id/index.ts @@ -52,14 +52,9 @@ router.patch( async (req: Request, res: Response) => { const body = req.body as VoiceStateUpdateSchema; const { guild_id } = req.params; - const user_id = - req.params.user_id === "@me" ? req.user_id : req.params.user_id; + const user_id = req.params.user_id === "@me" ? req.user_id : req.params.user_id; - const perms = await getPermission( - req.user_id, - guild_id, - body.channel_id, - ); + const perms = await getPermission(req.user_id, guild_id, body.channel_id); /* From https://discord.com/developers/docs/resources/guild#modify-current-user-voice-state @@ -98,7 +93,7 @@ router.patch( } as VoiceStateUpdateEvent), ]); return res.sendStatus(204); - }, + } ); export default router; diff --git a/src/api/routes/guilds/#guild_id/welcome-screen.ts b/src/api/routes/guilds/#guild_id/welcome-screen.ts index 81000b4b..74565a13 100644 --- a/src/api/routes/guilds/#guild_id/welcome-screen.ts +++ b/src/api/routes/guilds/#guild_id/welcome-screen.ts @@ -17,12 +17,7 @@ */ import { route } from "@spacebar/api"; -import { - Channel, - Guild, - GuildUpdateWelcomeScreenSchema, - Member, -} from "@spacebar/util"; +import { Channel, Guild, GuildUpdateWelcomeScreenSchema, Member } from "@spacebar/util"; import { Request, Response, Router } from "express"; const router: Router = Router(); @@ -46,7 +41,7 @@ router.get( await Member.IsInGuildOrFail(req.user_id, guild_id); res.json(guild.welcome_screen); - }, + } ); router.patch( @@ -70,11 +65,9 @@ router.patch( const guild = await Guild.findOneOrFail({ where: { id: guild_id } }); - if (body.enabled != undefined) - guild.welcome_screen.enabled = body.enabled; + if (body.enabled != undefined) guild.welcome_screen.enabled = body.enabled; - if (body.description != undefined) - guild.welcome_screen.description = body.description; + if (body.description != undefined) guild.welcome_screen.description = body.description; if (body.welcome_channels != undefined) { // Ensure channels exist within the guild @@ -83,8 +76,8 @@ router.patch( Channel.findOneOrFail({ where: { id: channel_id, guild_id }, select: { id: true }, - }), - ) || [], + }) + ) || [] ); guild.welcome_screen.welcome_channels = body.welcome_channels; } @@ -92,7 +85,7 @@ router.patch( await guild.save(); res.status(200).json(guild.welcome_screen); - }, + } ); export default router; diff --git a/src/api/routes/guilds/#guild_id/widget.json.ts b/src/api/routes/guilds/#guild_id/widget.json.ts index 39f49804..c2450699 100644 --- a/src/api/routes/guilds/#guild_id/widget.json.ts +++ b/src/api/routes/guilds/#guild_id/widget.json.ts @@ -81,10 +81,8 @@ router.get( // 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 + Permissions.channelPermission(doc.permission_overwrites, Permissions.FLAGS.CONNECT) === + Permissions.FLAGS.CONNECT ) { channels.push({ id: doc.id, @@ -110,7 +108,7 @@ router.get( res.set("Cache-Control", "public, max-age=300"); return res.json(data); - }, + } ); export default router; diff --git a/src/api/routes/guilds/#guild_id/widget.png.ts b/src/api/routes/guilds/#guild_id/widget.png.ts index c9ba8afc..c5080709 100644 --- a/src/api/routes/guilds/#guild_id/widget.png.ts +++ b/src/api/routes/guilds/#guild_id/widget.png.ts @@ -57,15 +57,8 @@ router.get( // Fetch parameter const style = req.query.style?.toString() || "shield"; - if ( - !["shield", "banner1", "banner2", "banner3", "banner4"].includes( - style, - ) - ) { - throw new HTTPError( - "Value must be one of ('shield', 'banner1', 'banner2', 'banner3', 'banner4').", - 400, - ); + if (!["shield", "banner1", "banner2", "banner3", "banner4"].includes(style)) { + throw new HTTPError("Value must be one of ('shield', 'banner1', 'banner2', 'banner3', 'banner4').", 400); } // Setup canvas @@ -74,17 +67,7 @@ router.get( const sizeOf = require("image-size"); // TODO: Widget style templates need Spacebar branding - const source = path.join( - __dirname, - "..", - "..", - "..", - "..", - "..", - "assets", - "widget", - `${style}.png`, - ); + const source = path.join(__dirname, "..", "..", "..", "..", "..", "assets", "widget", `${style}.png`); if (!fs.existsSync(source)) { throw new HTTPError("Widget template does not exist.", 400); } @@ -100,99 +83,32 @@ router.get( switch (style) { case "shield": ctx.textAlign = "center"; - await drawText( - ctx, - 73, - 13, - "#FFFFFF", - "thin 10px Verdana", - presence, - ); + await drawText(ctx, 73, 13, "#FFFFFF", "thin 10px Verdana", presence); break; case "banner1": if (icon) await drawIcon(ctx, 20, 27, 50, icon); - await drawText( - ctx, - 83, - 51, - "#FFFFFF", - "12px Verdana", - name, - 22, - ); - await drawText( - ctx, - 83, - 66, - "#C9D2F0FF", - "thin 11px Verdana", - presence, - ); + await drawText(ctx, 83, 51, "#FFFFFF", "12px Verdana", name, 22); + await drawText(ctx, 83, 66, "#C9D2F0FF", "thin 11px Verdana", presence); break; case "banner2": if (icon) await drawIcon(ctx, 13, 19, 36, icon); - await drawText( - ctx, - 62, - 34, - "#FFFFFF", - "12px Verdana", - name, - 15, - ); - await drawText( - ctx, - 62, - 49, - "#C9D2F0FF", - "thin 11px Verdana", - presence, - ); + await drawText(ctx, 62, 34, "#FFFFFF", "12px Verdana", name, 15); + await drawText(ctx, 62, 49, "#C9D2F0FF", "thin 11px Verdana", presence); break; case "banner3": if (icon) await drawIcon(ctx, 20, 20, 50, icon); - await drawText( - ctx, - 83, - 44, - "#FFFFFF", - "12px Verdana", - name, - 27, - ); - await drawText( - ctx, - 83, - 58, - "#C9D2F0FF", - "thin 11px Verdana", - presence, - ); + await drawText(ctx, 83, 44, "#FFFFFF", "12px Verdana", name, 27); + await drawText(ctx, 83, 58, "#C9D2F0FF", "thin 11px Verdana", presence); break; case "banner4": if (icon) await drawIcon(ctx, 21, 136, 50, icon); - await drawText( - ctx, - 84, - 156, - "#FFFFFF", - "13px Verdana", - name, - 27, - ); - await drawText( - ctx, - 84, - 171, - "#C9D2F0FF", - "thin 12px Verdana", - presence, - ); + await drawText(ctx, 84, 156, "#FFFFFF", "13px Verdana", name, 27); + await drawText(ctx, 84, 171, "#C9D2F0FF", "thin 12px Verdana", presence); break; default: throw new HTTPError( "Value must be one of ('shield', 'banner1', 'banner2', 'banner3', 'banner4').", - 400, + 400 ); } @@ -201,16 +117,10 @@ router.get( res.set("Content-Type", "image/png"); res.set("Cache-Control", "public, max-age=3600"); return res.send(buffer); - }, + } ); -async function drawIcon( - canvas: any, - x: number, - y: number, - scale: number, - icon: string, -) { +async function drawIcon(canvas: any, x: number, y: number, scale: number, icon: string) { const img = new (require("canvas").Image)(); img.src = icon; @@ -234,12 +144,11 @@ async function drawText( color: string, font: string, text: string, - maxcharacters?: number, + maxcharacters?: number ) { canvas.fillStyle = color; canvas.font = font; - if (text.length > (maxcharacters || 0) && maxcharacters) - text = text.slice(0, maxcharacters) + "..."; + if (text.length > (maxcharacters || 0) && maxcharacters) text = text.slice(0, maxcharacters) + "..."; canvas.fillText(text, x, y); } diff --git a/src/api/routes/guilds/#guild_id/widget.ts b/src/api/routes/guilds/#guild_id/widget.ts index cae0d6be..17667f29 100644 --- a/src/api/routes/guilds/#guild_id/widget.ts +++ b/src/api/routes/guilds/#guild_id/widget.ts @@ -44,7 +44,7 @@ router.get( enabled: guild.widget_enabled || false, channel_id: guild.widget_channel_id || null, }); - }, + } ); // https://discord.com/developers/docs/resources/guild#modify-guild-widget @@ -74,12 +74,12 @@ router.patch( { widget_enabled: body.enabled, widget_channel_id: body.channel_id, - }, + } ); // Widget invite for the widget_channel_id gets created as part of the /guilds/{guild.id}/widget.json request return res.json(body); - }, + } ); export default router; diff --git a/src/api/routes/guilds/index.ts b/src/api/routes/guilds/index.ts index 545beb18..a0d2f33d 100644 --- a/src/api/routes/guilds/index.ts +++ b/src/api/routes/guilds/index.ts @@ -17,14 +17,7 @@ */ import { route } from "@spacebar/api"; -import { - Config, - DiscordApiErrors, - Guild, - GuildCreateSchema, - Member, - getRights, -} from "@spacebar/util"; +import { Config, DiscordApiErrors, Guild, GuildCreateSchema, Member, getRights } from "@spacebar/util"; import { Request, Response, Router } from "express"; const router: Router = Router(); @@ -73,7 +66,7 @@ router.post( await Member.addToGuild(req.user_id, guild.id); res.status(201).json(guild); - }, + } ); export default router; diff --git a/src/api/routes/guilds/templates/index.ts b/src/api/routes/guilds/templates/index.ts index 8f718a21..693c8dcb 100644 --- a/src/api/routes/guilds/templates/index.ts +++ b/src/api/routes/guilds/templates/index.ts @@ -47,13 +47,11 @@ router.get( }, }), async (req: Request, res: Response) => { - const { allowDiscordTemplates, allowRaws, enabled } = - Config.get().templates; + const { allowDiscordTemplates, allowRaws, enabled } = Config.get().templates; if (!enabled) res.json({ code: 403, - message: - "Template creation & usage is disabled on this instance.", + message: "Template creation & usage is disabled on this instance.", }).sendStatus(403); const { code } = req.params; @@ -63,8 +61,7 @@ router.get( return res .json({ code: 403, - message: - "Discord templates cannot be used on this instance.", + message: "Discord templates cannot be used on this instance.", }) .sendStatus(403); const discordTemplateID = code.split("discord:", 2)[1]; @@ -74,7 +71,7 @@ router.get( { method: "get", headers: { "Content-Type": "application/json" }, - }, + } ); return res.json(await discordTemplateData.json()); } @@ -95,75 +92,70 @@ router.get( where: { code: code }, }); res.json(template); - }, + } ); -router.post( - "/:code", - route({ requestBody: "GuildTemplateCreateSchema" }), - async (req: Request, res: Response) => { - const { - enabled, - allowTemplateCreation, - // allowDiscordTemplates, - // allowRaws, - } = Config.get().templates; - if (!enabled) - return res - .json({ - code: 403, - message: - "Template creation & usage is disabled on this instance.", - }) - .sendStatus(403); - if (!allowTemplateCreation) - return res - .json({ - code: 403, - message: "Template creation is disabled on this instance.", - }) - .sendStatus(403); - - const { code } = req.params; - const body = req.body as GuildTemplateCreateSchema; - - const { maxGuilds } = Config.get().limits.user; - - const guild_count = await Member.count({ where: { id: req.user_id } }); - if (guild_count >= maxGuilds) { - throw DiscordApiErrors.MAXIMUM_GUILDS.withParams(maxGuilds); - } - - const template = await Template.findOneOrFail({ - where: { code: code }, - }); - - const guild_id = Snowflake.generate(); - - const [guild] = await Promise.all([ - Guild.create({ - ...body, - ...template.serialized_source_guild, - id: guild_id, - owner_id: req.user_id, - }).save(), - Role.create({ - id: guild_id, - guild_id: guild_id, - color: 0, - hoist: false, - managed: true, - mentionable: true, - name: "@everyone", - permissions: BigInt("2251804225").toString(), // TODO: where did this come from? - position: 0, - }).save(), - ]); - - await Member.addToGuild(req.user_id, guild_id); - - res.status(201).json({ id: guild.id }); - }, -); +router.post("/:code", route({ requestBody: "GuildTemplateCreateSchema" }), async (req: Request, res: Response) => { + const { + enabled, + allowTemplateCreation, + // allowDiscordTemplates, + // allowRaws, + } = Config.get().templates; + if (!enabled) + return res + .json({ + code: 403, + message: "Template creation & usage is disabled on this instance.", + }) + .sendStatus(403); + if (!allowTemplateCreation) + return res + .json({ + code: 403, + message: "Template creation is disabled on this instance.", + }) + .sendStatus(403); + + const { code } = req.params; + const body = req.body as GuildTemplateCreateSchema; + + const { maxGuilds } = Config.get().limits.user; + + const guild_count = await Member.count({ where: { id: req.user_id } }); + if (guild_count >= maxGuilds) { + throw DiscordApiErrors.MAXIMUM_GUILDS.withParams(maxGuilds); + } + + const template = await Template.findOneOrFail({ + where: { code: code }, + }); + + const guild_id = Snowflake.generate(); + + const [guild] = await Promise.all([ + Guild.create({ + ...body, + ...template.serialized_source_guild, + id: guild_id, + owner_id: req.user_id, + }).save(), + Role.create({ + id: guild_id, + guild_id: guild_id, + color: 0, + hoist: false, + managed: true, + mentionable: true, + name: "@everyone", + permissions: BigInt("2251804225").toString(), // TODO: where did this come from? + position: 0, + }).save(), + ]); + + await Member.addToGuild(req.user_id, guild_id); + + res.status(201).json({ id: guild.id }); +}); export default router; diff --git a/src/api/routes/invites/index.ts b/src/api/routes/invites/index.ts index 28a3b429..661b1f7c 100644 --- a/src/api/routes/invites/index.ts +++ b/src/api/routes/invites/index.ts @@ -53,7 +53,7 @@ router.get( }); res.status(200).send(invite); - }, + } ); router.post( @@ -89,21 +89,14 @@ router.post( where: { id: req.user_id }, }); - if ( - features.includes("INTERNAL_EMPLOYEE_ONLY") && - (public_flags & 1) !== 1 - ) - throw new HTTPError( - "Only intended for the staff of this server.", - 401, - ); - if (features.includes("INVITES_DISABLED")) - throw new HTTPError("Sorry, this guild has joins closed.", 403); + if (features.includes("INTERNAL_EMPLOYEE_ONLY") && (public_flags & 1) !== 1) + throw new HTTPError("Only intended for the staff of this server.", 401); + if (features.includes("INVITES_DISABLED")) throw new HTTPError("Sorry, this guild has joins closed.", 403); const invite = await Invite.joinGuild(req.user_id, code); res.json(invite); - }, + } ); // * cant use permission of route() function because path doesn't have guild_id/channel_id @@ -127,20 +120,10 @@ router.delete( const invite = await Invite.findOneOrFail({ where: { code } }); const { guild_id, channel_id } = invite; - const permission = await getPermission( - req.user_id, - guild_id, - channel_id, - ); - - if ( - !permission.has("MANAGE_GUILD") && - !permission.has("MANAGE_CHANNELS") - ) - throw new HTTPError( - "You missing the MANAGE_GUILD or MANAGE_CHANNELS permission", - 401, - ); + const permission = await getPermission(req.user_id, guild_id, channel_id); + + if (!permission.has("MANAGE_GUILD") && !permission.has("MANAGE_CHANNELS")) + throw new HTTPError("You missing the MANAGE_GUILD or MANAGE_CHANNELS permission", 401); await Promise.all([ Invite.delete({ code }), @@ -156,7 +139,7 @@ router.delete( ]); res.json({ invite: invite }); - }, + } ); export default router; diff --git a/src/api/routes/oauth2/applications/@me.ts b/src/api/routes/oauth2/applications/@me.ts index 0c23bdb1..3c404d25 100644 --- a/src/api/routes/oauth2/applications/@me.ts +++ b/src/api/routes/oauth2/applications/@me.ts @@ -17,11 +17,7 @@ */ import { route } from "@spacebar/api"; -import { - Application, - DiscordApiErrors, - PublicUserProjection, -} from "@spacebar/util"; +import { Application, DiscordApiErrors, PublicUserProjection } from "@spacebar/util"; import { Request, Response, Router } from "express"; const router: Router = Router(); @@ -40,9 +36,7 @@ router.get( where: { id: req.params.id }, relations: ["bot", "owner"], select: { - owner: Object.fromEntries( - PublicUserProjection.map((x) => [x, true]), - ), + owner: Object.fromEntries(PublicUserProjection.map((x) => [x, true])), }, }); @@ -51,9 +45,8 @@ router.get( res.json({ ...app, owner: app.owner.toPublicUser(), - install_params: - app.install_params !== null ? app.install_params : undefined, + install_params: app.install_params !== null ? app.install_params : undefined, }); - }, + } ); export default router; diff --git a/src/api/routes/oauth2/authorize.ts b/src/api/routes/oauth2/authorize.ts index 2f2351f3..bdb12455 100644 --- a/src/api/routes/oauth2/authorize.ts +++ b/src/api/routes/oauth2/authorize.ts @@ -84,13 +84,7 @@ router.get( id: req.user_id, bot: false, }, - select: [ - "id", - "username", - "avatar", - "discriminator", - "public_flags", - ], + select: ["id", "username", "avatar", "discriminator", "public_flags"], }); const guilds = await Member.find({ @@ -165,7 +159,7 @@ router.get( }, authorized: false, }); - }, + } ); router.post( @@ -210,17 +204,9 @@ router.post( // TODO: captcha verification // TODO: MFA verification - const perms = await getPermission( - req.user_id, - body.guild_id, - undefined, - { member_relations: ["user"] }, - ); + const perms = await getPermission(req.user_id, body.guild_id, undefined, { member_relations: ["user"] }); // getPermission cache won't exist if we're owner - if ( - Object.keys(perms.cache || {}).length > 0 && - perms.cache.member?.user.bot - ) + if (Object.keys(perms.cache || {}).length > 0 && perms.cache.member?.user.bot) throw DiscordApiErrors.UNAUTHORIZED; perms.hasThrow("MANAGE_GUILD"); @@ -234,19 +220,14 @@ router.post( // TODO: use DiscordApiErrors // findOneOrFail throws code 404 if (!app) throw new ApiError("Unknown Application", 10002, 404); - if (!app.bot) - throw new ApiError( - "OAuth2 application does not have a bot", - 50010, - 400, - ); + if (!app.bot) throw new ApiError("OAuth2 application does not have a bot", 50010, 400); await Member.addToGuild(app.id, body.guild_id); return res.json({ location: "/oauth2/authorized", // redirect URL }); - }, + } ); export default router; diff --git a/src/api/routes/ping.ts b/src/api/routes/ping.ts index 73330239..3161eb2c 100644 --- a/src/api/routes/ping.ts +++ b/src/api/routes/ping.ts @@ -48,7 +48,7 @@ router.get( tosPage: general.tosPage, }, }); - }, + } ); export default router; diff --git a/src/api/routes/policies/instance/domains.ts b/src/api/routes/policies/instance/domains.ts index afeb0e85..5ddd2114 100644 --- a/src/api/routes/policies/instance/domains.ts +++ b/src/api/routes/policies/instance/domains.ts @@ -34,20 +34,14 @@ router.get( const { cdn, gateway, api } = Config.get(); const IdentityForm = { - cdn: - cdn.endpointPublic || - process.env.CDN || - "http://localhost:3001", - gateway: - gateway.endpointPublic || - process.env.GATEWAY || - "ws://localhost:3001", + cdn: cdn.endpointPublic || process.env.CDN || "http://localhost:3001", + gateway: gateway.endpointPublic || process.env.GATEWAY || "ws://localhost:3001", defaultApiVersion: api.defaultVersion ?? 9, apiEndpoint: api.endpointPublic ?? "http://localhost:3001/api/", }; res.json(IdentityForm); - }, + } ); export default router; diff --git a/src/api/routes/policies/instance/index.ts b/src/api/routes/policies/instance/index.ts index 6e269a5c..9ac3f869 100644 --- a/src/api/routes/policies/instance/index.ts +++ b/src/api/routes/policies/instance/index.ts @@ -33,7 +33,7 @@ router.get( async (req: Request, res: Response) => { const { general } = Config.get(); res.json(general); - }, + } ); export default router; diff --git a/src/api/routes/policies/instance/limits.ts b/src/api/routes/policies/instance/limits.ts index 9852459d..79139d96 100644 --- a/src/api/routes/policies/instance/limits.ts +++ b/src/api/routes/policies/instance/limits.ts @@ -33,7 +33,7 @@ router.get( async (req: Request, res: Response) => { const { limits } = Config.get(); res.json(limits); - }, + } ); export default router; diff --git a/src/api/routes/policies/stats.ts b/src/api/routes/policies/stats.ts index b2cd3d5a..615ca6ba 100644 --- a/src/api/routes/policies/stats.ts +++ b/src/api/routes/policies/stats.ts @@ -17,14 +17,7 @@ */ import { route } from "@spacebar/api"; -import { - Config, - getRights, - Guild, - Member, - Message, - User, -} from "@spacebar/util"; +import { Config, getRights, Guild, Member, Message, User } from "@spacebar/util"; import { Request, Response, Router } from "express"; const router = Router(); @@ -54,7 +47,7 @@ router.get( members: await Member.count(), }, }); - }, + } ); export default router; diff --git a/src/api/routes/read-states/ack-bulk.ts b/src/api/routes/read-states/ack-bulk.ts index 3ee25d1a..d93b0450 100644 --- a/src/api/routes/read-states/ack-bulk.ts +++ b/src/api/routes/read-states/ack-bulk.ts @@ -61,7 +61,7 @@ router.post( ]); return res.status(204); - }, + } ); export default router; diff --git a/src/api/routes/scheduled-maintenances/upcoming_json.ts b/src/api/routes/scheduled-maintenances/upcoming_json.ts index c1fc0ff3..3b0bd500 100644 --- a/src/api/routes/scheduled-maintenances/upcoming_json.ts +++ b/src/api/routes/scheduled-maintenances/upcoming_json.ts @@ -20,15 +20,11 @@ import { Router, Request, Response } from "express"; import { route } from "@spacebar/api"; const router = Router(); -router.get( - "/scheduled-maintenances/upcoming.json", - route({}), - async (req: Request, res: Response) => { - res.json({ - page: {}, - scheduled_maintenances: {}, - }); - }, -); +router.get("/scheduled-maintenances/upcoming.json", route({}), async (req: Request, res: Response) => { + res.json({ + page: {}, + scheduled_maintenances: {}, + }); +}); export default router; diff --git a/src/api/routes/science.ts b/src/api/routes/science.ts index d5cdc173..6eb4a8e9 100644 --- a/src/api/routes/science.ts +++ b/src/api/routes/science.ts @@ -31,7 +31,7 @@ router.post( (req: Request, res: Response) => { // TODO: res.sendStatus(204); - }, + } ); export default router; diff --git a/src/api/routes/sticker-packs/index.ts b/src/api/routes/sticker-packs/index.ts index 569d1104..ec12e30f 100644 --- a/src/api/routes/sticker-packs/index.ts +++ b/src/api/routes/sticker-packs/index.ts @@ -37,7 +37,7 @@ router.get( }); res.json({ sticker_packs }); - }, + } ); export default router; diff --git a/src/api/routes/stickers/#sticker_id/index.ts b/src/api/routes/stickers/#sticker_id/index.ts index 2ea81bf9..72765652 100644 --- a/src/api/routes/stickers/#sticker_id/index.ts +++ b/src/api/routes/stickers/#sticker_id/index.ts @@ -34,7 +34,7 @@ router.get( const { sticker_id } = req.params; res.json(await Sticker.find({ where: { id: sticker_id } })); - }, + } ); export default router; diff --git a/src/api/routes/stop.ts b/src/api/routes/stop.ts index 79e132d7..392c2d72 100644 --- a/src/api/routes/stop.ts +++ b/src/api/routes/stop.ts @@ -36,7 +36,7 @@ router.post( console.log(`/stop was called by ${req.user_id} at ${new Date()}`); res.sendStatus(200); process.kill(process.pid, "SIGTERM"); - }, + } ); export default router; diff --git a/src/api/routes/updates.ts b/src/api/routes/updates.ts index 101bd3bc..bddf4ca0 100644 --- a/src/api/routes/updates.ts +++ b/src/api/routes/updates.ts @@ -62,7 +62,7 @@ router.get( url: release.url, notes: release.notes, }); - }, + } ); export default router; diff --git a/src/api/routes/users/#id/delete.ts b/src/api/routes/users/#id/delete.ts index 5b1a682c..b1888d06 100644 --- a/src/api/routes/users/#id/delete.ts +++ b/src/api/routes/users/#id/delete.ts @@ -17,13 +17,7 @@ */ import { route } from "@spacebar/api"; -import { - emitEvent, - Member, - PrivateUserProjection, - User, - UserDeleteEvent, -} from "@spacebar/util"; +import { emitEvent, Member, PrivateUserProjection, User, UserDeleteEvent } from "@spacebar/util"; import { Request, Response, Router } from "express"; const router = Router(); @@ -47,10 +41,7 @@ router.post( where: { id: req.params.id }, select: [...PrivateUserProjection, "data"], }); - await Promise.all([ - Member.delete({ id: req.params.id }), - User.delete({ id: req.params.id }), - ]); + await Promise.all([Member.delete({ id: req.params.id }), User.delete({ id: req.params.id })]); // TODO: respect intents as USER_DELETE has potential to cause privacy issues await emitEvent({ @@ -60,7 +51,7 @@ router.post( } as UserDeleteEvent); res.sendStatus(204); - }, + } ); export default router; diff --git a/src/api/routes/users/#id/index.ts b/src/api/routes/users/#id/index.ts index 1bd413d3..b6fee65e 100644 --- a/src/api/routes/users/#id/index.ts +++ b/src/api/routes/users/#id/index.ts @@ -35,7 +35,7 @@ router.get( const { id } = req.params; res.json(await User.getPublicUser(id)); - }, + } ); export default router; diff --git a/src/api/routes/users/#id/profile.ts b/src/api/routes/users/#id/profile.ts index eecec0f3..4a4965d8 100644 --- a/src/api/routes/users/#id/profile.ts +++ b/src/api/routes/users/#id/profile.ts @@ -30,129 +30,115 @@ import { Request, Response, Router } from "express"; const router: Router = Router(); -router.get( - "/", - route({ responses: { 200: { body: "UserProfileResponse" } } }), - async (req: Request, res: Response) => { - if (req.params.id === "@me") req.params.id = req.user_id; +router.get("/", route({ responses: { 200: { body: "UserProfileResponse" } } }), async (req: Request, res: Response) => { + if (req.params.id === "@me") req.params.id = req.user_id; - const { guild_id, with_mutual_guilds } = req.query; + const { guild_id, with_mutual_guilds } = req.query; - const user = await User.getPublicUser(req.params.id, { - relations: ["connected_accounts"], + const user = await User.getPublicUser(req.params.id, { + relations: ["connected_accounts"], + }); + + const mutual_guilds: object[] = []; + let premium_guild_since; + + if (with_mutual_guilds == "true") { + const requested_member = await Member.find({ + where: { id: req.params.id }, + }); + const self_member = await Member.find({ + where: { id: req.user_id }, }); - const mutual_guilds: object[] = []; - let premium_guild_since; - - if (with_mutual_guilds == "true") { - const requested_member = await Member.find({ - where: { id: req.params.id }, - }); - const self_member = await Member.find({ - where: { 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 { + 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, - }); - } + } + for (const smem of self_member) { + if (smem.guild_id === rmem.guild_id) { + mutual_guilds.push({ + id: rmem.guild_id, + nick: rmem.nick, + }); } } } - - const guild_member = - guild_id && typeof guild_id == "string" - ? await Member.findOneOrFail({ - where: { id: req.params.id, guild_id: guild_id }, - relations: ["roles"], - }) - : undefined; - - // TODO: make proper DTO's in util? - - const userProfile = { - bio: req.user_bot ? null : user.bio, - accent_color: user.accent_color, - banner: user.banner, - pronouns: user.pronouns, - theme_colors: user.theme_colors, - }; - - const guildMemberProfile = { - accent_color: null, - banner: guild_member?.banner || null, - bio: guild_member?.bio || "", - guild_id, - }; - res.json({ - connected_accounts: user.connected_accounts.filter( - (x) => x.visibility != 0, - ), - 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: user.toPublicUser(), - premium_type: user.premium_type, - profile_themes_experiment_bucket: 4, // TODO: This doesn't make it available, for some reason? - user_profile: userProfile, - guild_member: guild_member?.toPublicMember(), - guild_member_profile: guild_id && guildMemberProfile, - }); - }, -); - -router.patch( - "/", - route({ requestBody: "UserProfileModifySchema" }), - async (req: Request, res: Response) => { - const body = req.body as UserProfileModifySchema; - - if (body.banner) - body.banner = await handleFile( - `/banners/${req.user_id}`, - body.banner as string, - ); - const user = await User.findOneOrFail({ - where: { id: req.user_id }, - select: [...PrivateUserProjection, "data"], - }); - - user.assign(body); - await user.save(); - - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - delete user.data; - - // TODO: send update member list event in gateway - await emitEvent({ - event: "USER_UPDATE", - user_id: req.user_id, - data: user, - } as UserUpdateEvent); - - res.json({ - accent_color: user.accent_color, - bio: user.bio, - banner: user.banner, - theme_colors: user.theme_colors, - pronouns: user.pronouns, - }); - }, -); + } + + const guild_member = + guild_id && typeof guild_id == "string" + ? await Member.findOneOrFail({ + where: { id: req.params.id, guild_id: guild_id }, + relations: ["roles"], + }) + : undefined; + + // TODO: make proper DTO's in util? + + const userProfile = { + bio: req.user_bot ? null : user.bio, + accent_color: user.accent_color, + banner: user.banner, + pronouns: user.pronouns, + theme_colors: user.theme_colors, + }; + + const guildMemberProfile = { + accent_color: null, + banner: guild_member?.banner || null, + bio: guild_member?.bio || "", + guild_id, + }; + res.json({ + connected_accounts: user.connected_accounts.filter((x) => x.visibility != 0), + 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: user.toPublicUser(), + premium_type: user.premium_type, + profile_themes_experiment_bucket: 4, // TODO: This doesn't make it available, for some reason? + user_profile: userProfile, + guild_member: guild_member?.toPublicMember(), + guild_member_profile: guild_id && guildMemberProfile, + }); +}); + +router.patch("/", route({ requestBody: "UserProfileModifySchema" }), async (req: Request, res: Response) => { + const body = req.body as UserProfileModifySchema; + + if (body.banner) body.banner = await handleFile(`/banners/${req.user_id}`, body.banner as string); + const user = await User.findOneOrFail({ + where: { id: req.user_id }, + select: [...PrivateUserProjection, "data"], + }); + + user.assign(body); + await user.save(); + + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + delete user.data; + + // TODO: send update member list event in gateway + await emitEvent({ + event: "USER_UPDATE", + user_id: req.user_id, + data: user, + } as UserUpdateEvent); + + res.json({ + accent_color: user.accent_color, + bio: user.bio, + banner: user.banner, + theme_colors: user.theme_colors, + pronouns: user.pronouns, + }); +}); export default router; diff --git a/src/api/routes/users/#id/relationships.ts b/src/api/routes/users/#id/relationships.ts index 3737ca00..c4c128a8 100644 --- a/src/api/routes/users/#id/relationships.ts +++ b/src/api/routes/users/#id/relationships.ts @@ -46,11 +46,7 @@ router.get( for (const rmem of requested_relations.relationships) { for (const smem of self_relations.relationships) - if ( - rmem.to_id === smem.to_id && - rmem.type === 1 && - rmem.to_id !== req.user_id - ) { + if (rmem.to_id === smem.to_id && rmem.type === 1 && rmem.to_id !== req.user_id) { const relation_user = await User.getPublicUser(rmem.to_id); mutual_relations.push({ @@ -64,7 +60,7 @@ router.get( } res.json(mutual_relations); - }, + } ); export default router; diff --git a/src/api/routes/users/@me/channels.ts b/src/api/routes/users/@me/channels.ts index 8a8fadd9..ee7fefa7 100644 --- a/src/api/routes/users/@me/channels.ts +++ b/src/api/routes/users/@me/channels.ts @@ -17,12 +17,7 @@ */ import { route } from "@spacebar/api"; -import { - Channel, - DmChannelCreateSchema, - DmChannelDTO, - Recipient, -} from "@spacebar/util"; +import { Channel, DmChannelCreateSchema, DmChannelDTO, Recipient } from "@spacebar/util"; import { Request, Response, Router } from "express"; const router: Router = Router(); @@ -41,14 +36,8 @@ router.get( where: { user_id: req.user_id, closed: false }, relations: ["channel", "channel.recipients"], }); - res.json( - await Promise.all( - recipients.map((r) => - DmChannelDTO.from(r.channel, [req.user_id]), - ), - ), - ); - }, + res.json(await Promise.all(recipients.map((r) => DmChannelDTO.from(r.channel, [req.user_id])))); + } ); router.post( @@ -63,14 +52,8 @@ router.post( }), async (req: Request, res: Response) => { const body = req.body as DmChannelCreateSchema; - res.json( - await Channel.createDMChannel( - body.recipients, - req.user_id, - body.name, - ), - ); - }, + res.json(await Channel.createDMChannel(body.recipients, req.user_id, body.name)); + } ); export default router; diff --git a/src/api/routes/users/@me/connections/#connection_name/#connection_id/access-token.ts b/src/api/routes/users/@me/connections/#connection_name/#connection_id/access-token.ts index 789a7878..97c03efd 100644 --- a/src/api/routes/users/@me/connections/#connection_name/#connection_id/access-token.ts +++ b/src/api/routes/users/@me/connections/#connection_name/#connection_id/access-token.ts @@ -77,18 +77,13 @@ router.get("/", route({}), async (req: Request, res: Response) => { }); if (!connectedAccount) throw DiscordApiErrors.UNKNOWN_CONNECTION; if (connectedAccount.revoked) throw DiscordApiErrors.CONNECTION_REVOKED; - if (!connectedAccount.token_data) - throw new ApiError("No token data", 0, 400); + if (!connectedAccount.token_data) throw new ApiError("No token data", 0, 400); let access_token = connectedAccount.token_data.access_token; const { expires_at, expires_in, fetched_at } = connectedAccount.token_data; - if ( - (expires_at && expires_at < Date.now()) || - (expires_in && fetched_at + expires_in * 1000 < Date.now()) - ) { - if (!(connection instanceof RefreshableConnection)) - throw new ApiError("Access token expired", 0, 400); + if ((expires_at && expires_at < Date.now()) || (expires_in && fetched_at + expires_in * 1000 < Date.now())) { + if (!(connection instanceof RefreshableConnection)) throw new ApiError("Access token expired", 0, 400); const tokenData = await connection.refresh(connectedAccount); access_token = tokenData.access_token; } diff --git a/src/api/routes/users/@me/connections/#connection_name/#connection_id/index.ts b/src/api/routes/users/@me/connections/#connection_name/#connection_id/index.ts index 351ec99a..afb5b2e9 100644 --- a/src/api/routes/users/@me/connections/#connection_name/#connection_id/index.ts +++ b/src/api/routes/users/@me/connections/#connection_name/#connection_id/index.ts @@ -17,68 +17,59 @@ */ import { route } from "@spacebar/api"; -import { - ConnectedAccount, - ConnectionUpdateSchema, - DiscordApiErrors, - emitEvent, -} from "@spacebar/util"; +import { ConnectedAccount, ConnectionUpdateSchema, DiscordApiErrors, emitEvent } from "@spacebar/util"; import { Request, Response, Router } from "express"; const router = Router(); // TODO: connection update schema -router.patch( - "/", - route({ requestBody: "ConnectionUpdateSchema" }), - async (req: Request, res: Response) => { - const { connection_name, connection_id } = req.params; - const body = req.body as ConnectionUpdateSchema; +router.patch("/", route({ requestBody: "ConnectionUpdateSchema" }), async (req: Request, res: Response) => { + const { connection_name, connection_id } = req.params; + const body = req.body as ConnectionUpdateSchema; - const connection = await ConnectedAccount.findOne({ - where: { - user_id: req.user_id, - external_id: connection_id, - type: connection_name, - }, - select: [ - "external_id", - "type", - "name", - "verified", - "visibility", - "show_activity", - "revoked", - "friend_sync", - "integrations", - ], - }); + const connection = await ConnectedAccount.findOne({ + where: { + user_id: req.user_id, + external_id: connection_id, + type: connection_name, + }, + select: [ + "external_id", + "type", + "name", + "verified", + "visibility", + "show_activity", + "revoked", + "friend_sync", + "integrations", + ], + }); - if (!connection) return DiscordApiErrors.UNKNOWN_CONNECTION; - // TODO: do we need to do anything if the connection is revoked? + if (!connection) return DiscordApiErrors.UNKNOWN_CONNECTION; + // TODO: do we need to do anything if the connection is revoked? - if (typeof body.visibility === "boolean") - //@ts-expect-error For some reason the client sends this as a boolean, even tho docs say its a number? - body.visibility = body.visibility ? 1 : 0; - if (typeof body.show_activity === "boolean") - //@ts-expect-error For some reason the client sends this as a boolean, even tho docs say its a number? - body.show_activity = body.show_activity ? 1 : 0; - if (typeof body.metadata_visibility === "boolean") - //@ts-expect-error For some reason the client sends this as a boolean, even tho docs say its a number? - body.metadata_visibility = body.metadata_visibility ? 1 : 0; + if (typeof body.visibility === "boolean") + //@ts-expect-error For some reason the client sends this as a boolean, even tho docs say its a number? + body.visibility = body.visibility ? 1 : 0; + if (typeof body.show_activity === "boolean") + //@ts-expect-error For some reason the client sends this as a boolean, even tho docs say its a number? + body.show_activity = body.show_activity ? 1 : 0; + if (typeof body.metadata_visibility === "boolean") + //@ts-expect-error For some reason the client sends this as a boolean, even tho docs say its a number? + body.metadata_visibility = body.metadata_visibility ? 1 : 0; - connection.assign(req.body); + connection.assign(req.body); - await ConnectedAccount.update( - { - user_id: req.user_id, - external_id: connection_id, - type: connection_name, - }, - connection, - ); - res.json(connection.toJSON()); - }, -); + await ConnectedAccount.update( + { + user_id: req.user_id, + external_id: connection_id, + type: connection_name, + }, + connection + ); + res.json(connection.toJSON()); +}); router.delete("/", route({}), async (req: Request, res: Response) => { const { connection_name, connection_id } = req.params; diff --git a/src/api/routes/users/@me/delete.ts b/src/api/routes/users/@me/delete.ts index e36a1e92..a8e043f6 100644 --- a/src/api/routes/users/@me/delete.ts +++ b/src/api/routes/users/@me/delete.ts @@ -46,10 +46,7 @@ router.post( if (user.data.hash) { // guest accounts can delete accounts without password - correctpass = await bcrypt.compare( - req.body.password, - user.data.hash, - ); + correctpass = await bcrypt.compare(req.body.password, user.data.hash); if (!correctpass) { throw new HTTPError(req.t("auth:login.INVALID_PASSWORD")); } @@ -58,16 +55,13 @@ router.post( // TODO: decrement guild member count if (correctpass) { - await Promise.all([ - User.delete({ id: req.user_id }), - Member.delete({ id: req.user_id }), - ]); + await Promise.all([User.delete({ id: req.user_id }), Member.delete({ id: req.user_id })]); res.sendStatus(204); } else { res.sendStatus(401); } - }, + } ); export default router; diff --git a/src/api/routes/users/@me/disable.ts b/src/api/routes/users/@me/disable.ts index b4d03e62..8d9e161c 100644 --- a/src/api/routes/users/@me/disable.ts +++ b/src/api/routes/users/@me/disable.ts @@ -45,10 +45,7 @@ router.post( if (user.data.hash) { // guest accounts can delete accounts without password - correctpass = await bcrypt.compare( - req.body.password, - user.data.hash, - ); //Not sure if user typed right password :/ + correctpass = await bcrypt.compare(req.body.password, user.data.hash); //Not sure if user typed right password :/ } if (correctpass) { @@ -61,7 +58,7 @@ router.post( code: 50018, }); } - }, + } ); export default router; diff --git a/src/api/routes/users/@me/guilds.ts b/src/api/routes/users/@me/guilds.ts index 0bce432b..1d2f79ce 100644 --- a/src/api/routes/users/@me/guilds.ts +++ b/src/api/routes/users/@me/guilds.ts @@ -17,15 +17,7 @@ */ import { route } from "@spacebar/api"; -import { - Config, - Guild, - GuildDeleteEvent, - GuildMemberRemoveEvent, - Member, - User, - emitEvent, -} from "@spacebar/util"; +import { Config, Guild, GuildDeleteEvent, GuildMemberRemoveEvent, Member, User, emitEvent } from "@spacebar/util"; import { Request, Response, Router } from "express"; import { HTTPError } from "lambert-server"; @@ -53,7 +45,7 @@ router.get( } res.json(guild); - }, + } ); // user send to leave a certain guild @@ -79,17 +71,9 @@ router.delete( }); if (!guild) throw new HTTPError("Guild doesn't exist", 404); - if (guild.owner_id === req.user_id) - throw new HTTPError("You can't leave your own guild", 400); - if ( - autoJoin.enabled && - autoJoin.guilds.includes(guild_id) && - !autoJoin.canLeave - ) { - throw new HTTPError( - "You can't leave instance auto join guilds", - 400, - ); + if (guild.owner_id === req.user_id) throw new HTTPError("You can't leave your own guild", 400); + if (autoJoin.enabled && autoJoin.guilds.includes(guild_id) && !autoJoin.canLeave) { + throw new HTTPError("You can't leave instance auto join guilds", 400); } await Promise.all([ @@ -115,7 +99,7 @@ router.delete( } as GuildMemberRemoveEvent); return res.sendStatus(204); - }, + } ); export default router; diff --git a/src/api/routes/users/@me/guilds/#guild_id/settings.ts b/src/api/routes/users/@me/guilds/#guild_id/settings.ts index ac6586ce..ae5f3922 100644 --- a/src/api/routes/users/@me/guilds/#guild_id/settings.ts +++ b/src/api/routes/users/@me/guilds/#guild_id/settings.ts @@ -17,12 +17,7 @@ */ import { route } from "@spacebar/api"; -import { - Channel, - Member, - OrmUtils, - UserGuildSettingsSchema, -} from "@spacebar/util"; +import { Channel, Member, OrmUtils, UserGuildSettingsSchema } from "@spacebar/util"; import { Request, Response, Router } from "express"; const router = Router(); @@ -42,7 +37,7 @@ router.get( select: ["settings"], }); return res.json(user.settings); - }, + } ); router.patch( @@ -76,7 +71,7 @@ router.patch( Member.update({ id: req.user_id, guild_id: req.params.guild_id }, user); res.json(user.settings); - }, + } ); export default router; diff --git a/src/api/routes/users/@me/index.ts b/src/api/routes/users/@me/index.ts index ad11a428..606f33bb 100644 --- a/src/api/routes/users/@me/index.ts +++ b/src/api/routes/users/@me/index.ts @@ -47,9 +47,9 @@ router.get( await User.findOne({ select: PrivateUserProjection, where: { id: req.user_id }, - }), + }) ); - }, + } ); router.patch( @@ -79,23 +79,12 @@ router.patch( // Populated on password change let newToken: string | undefined; - if (body.avatar) - body.avatar = await handleFile( - `/avatars/${req.user_id}`, - body.avatar as string, - ); - if (body.banner) - body.banner = await handleFile( - `/banners/${req.user_id}`, - body.banner as string, - ); + if (body.avatar) body.avatar = await handleFile(`/avatars/${req.user_id}`, body.avatar as string); + if (body.banner) body.banner = await handleFile(`/banners/${req.user_id}`, body.banner as string); if (body.password) { if (user.data?.hash) { - const same_password = await bcrypt.compare( - body.password, - user.data.hash || "", - ); + const same_password = await bcrypt.compare(body.password, user.data.hash || ""); if (!same_password) { throw FieldErrors({ password: { @@ -199,7 +188,7 @@ router.patch( ...user, newToken, }); - }, + } ); export default router; diff --git a/src/api/routes/users/@me/mfa/codes-verification.ts b/src/api/routes/users/@me/mfa/codes-verification.ts index f71704a9..f7083b53 100644 --- a/src/api/routes/users/@me/mfa/codes-verification.ts +++ b/src/api/routes/users/@me/mfa/codes-verification.ts @@ -17,13 +17,7 @@ */ import { route } from "@spacebar/api"; -import { - BackupCode, - CodesVerificationSchema, - DiscordApiErrors, - User, - generateMfaBackupCodes, -} from "@spacebar/util"; +import { BackupCode, CodesVerificationSchema, DiscordApiErrors, User, generateMfaBackupCodes } from "@spacebar/util"; import { Request, Response, Router } from "express"; const router = Router(); @@ -52,15 +46,11 @@ router.post( // Once that's done, this route can verify `key` // const user = await User.findOneOrFail({ where: { id: req.user_id } }); - if ((await User.count({ where: { id: req.user_id } })) === 0) - throw DiscordApiErrors.UNKNOWN_USER; + if ((await User.count({ where: { id: req.user_id } })) === 0) throw DiscordApiErrors.UNKNOWN_USER; let codes: BackupCode[]; if (regenerate) { - await BackupCode.update( - { user: { id: req.user_id } }, - { expired: true }, - ); + await BackupCode.update({ user: { id: req.user_id } }, { expired: true }); codes = generateMfaBackupCodes(req.user_id); await Promise.all(codes.map((x) => x.save())); @@ -78,7 +68,7 @@ router.post( return res.json({ backup_codes: codes.map((x) => ({ ...x, expired: undefined })), }); - }, + } ); export default router; diff --git a/src/api/routes/users/@me/mfa/codes.ts b/src/api/routes/users/@me/mfa/codes.ts index f9cfc4c4..d6e5a481 100644 --- a/src/api/routes/users/@me/mfa/codes.ts +++ b/src/api/routes/users/@me/mfa/codes.ts @@ -17,13 +17,7 @@ */ import { route } from "@spacebar/api"; -import { - BackupCode, - FieldErrors, - generateMfaBackupCodes, - MfaCodesSchema, - User, -} from "@spacebar/util"; +import { BackupCode, FieldErrors, generateMfaBackupCodes, MfaCodesSchema, User } from "@spacebar/util"; import bcrypt from "bcrypt"; import { Request, Response, Router } from "express"; @@ -36,8 +30,7 @@ router.post( route({ requestBody: "MfaCodesSchema", deprecated: true, - description: - "This route is replaced with users/@me/mfa/codes-verification in newer clients", + description: "This route is replaced with users/@me/mfa/codes-verification in newer clients", responses: { 200: { body: "APIBackupCodeArray", @@ -69,10 +62,7 @@ router.post( let codes: BackupCode[]; if (regenerate) { - await BackupCode.update( - { user: { id: req.user_id } }, - { expired: true }, - ); + await BackupCode.update({ user: { id: req.user_id } }, { expired: true }); codes = generateMfaBackupCodes(req.user_id); await Promise.all(codes.map((x) => x.save())); @@ -90,7 +80,7 @@ router.post( return res.json({ backup_codes: codes.map((x) => ({ ...x, expired: undefined })), }); - }, + } ); export default router; diff --git a/src/api/routes/users/@me/mfa/totp/disable.ts b/src/api/routes/users/@me/mfa/totp/disable.ts index 362152d7..6a0960d8 100644 --- a/src/api/routes/users/@me/mfa/totp/disable.ts +++ b/src/api/routes/users/@me/mfa/totp/disable.ts @@ -17,12 +17,7 @@ */ import { route } from "@spacebar/api"; -import { - BackupCode, - TotpDisableSchema, - User, - generateToken, -} from "@spacebar/util"; +import { BackupCode, TotpDisableSchema, User, generateToken } from "@spacebar/util"; import { Request, Response, Router } from "express"; import { HTTPError } from "lambert-server"; import { verifyToken } from "node-2fa"; @@ -53,11 +48,7 @@ router.post( const backup = await BackupCode.findOne({ where: { code: body.code } }); if (!backup) { const ret = verifyToken(user.totp_secret || "", body.code); - if (!ret || ret.delta != 0) - throw new HTTPError( - req.t("auth:login.INVALID_TOTP_CODE"), - 60008, - ); + if (!ret || ret.delta != 0) throw new HTTPError(req.t("auth:login.INVALID_TOTP_CODE"), 60008); } await User.update( @@ -65,20 +56,20 @@ router.post( { mfa_enabled: false, totp_secret: "", - }, + } ); await BackupCode.update( { user: { id: req.user_id } }, { expired: true, - }, + } ); return res.json({ token: await generateToken(user.id), }); - }, + } ); export default router; diff --git a/src/api/routes/users/@me/mfa/totp/enable.ts b/src/api/routes/users/@me/mfa/totp/enable.ts index 19836e4d..6d66fb95 100644 --- a/src/api/routes/users/@me/mfa/totp/enable.ts +++ b/src/api/routes/users/@me/mfa/totp/enable.ts @@ -17,12 +17,7 @@ */ import { route } from "@spacebar/api"; -import { - TotpEnableSchema, - User, - generateMfaBackupCodes, - generateToken, -} from "@spacebar/util"; +import { TotpEnableSchema, User, generateMfaBackupCodes, generateToken } from "@spacebar/util"; import bcrypt from "bcrypt"; import { Request, Response, Router } from "express"; import { HTTPError } from "lambert-server"; @@ -61,21 +56,16 @@ router.post( } } - if (!body.secret) - throw new HTTPError(req.t("auth:login.INVALID_TOTP_SECRET"), 60005); + if (!body.secret) throw new HTTPError(req.t("auth:login.INVALID_TOTP_SECRET"), 60005); - if (!body.code) - throw new HTTPError(req.t("auth:login.INVALID_TOTP_CODE"), 60008); + if (!body.code) throw new HTTPError(req.t("auth:login.INVALID_TOTP_CODE"), 60008); if (verifyToken(body.secret, body.code)?.delta != 0) throw new HTTPError(req.t("auth:login.INVALID_TOTP_CODE"), 60008); const backup_codes = generateMfaBackupCodes(req.user_id); await Promise.all(backup_codes.map((x) => x.save())); - await User.update( - { id: req.user_id }, - { mfa_enabled: true, totp_secret: body.secret }, - ); + await User.update({ id: req.user_id }, { mfa_enabled: true, totp_secret: body.secret }); res.send({ token: await generateToken(user.id), @@ -84,7 +74,7 @@ router.post( expired: undefined, })), }); - }, + } ); export default router; diff --git a/src/api/routes/users/@me/mfa/webauthn/credentials/#key_id/index.ts b/src/api/routes/users/@me/mfa/webauthn/credentials/#key_id/index.ts index 9cf42def..ba5df994 100644 --- a/src/api/routes/users/@me/mfa/webauthn/credentials/#key_id/index.ts +++ b/src/api/routes/users/@me/mfa/webauthn/credentials/#key_id/index.ts @@ -41,11 +41,10 @@ router.delete( }); // disable webauthn if there are no keys left - if (keys === 0) - await User.update({ id: req.user_id }, { webauthn_enabled: false }); + if (keys === 0) await User.update({ id: req.user_id }, { webauthn_enabled: false }); res.sendStatus(204); - }, + } ); export default router; diff --git a/src/api/routes/users/@me/mfa/webauthn/credentials/index.ts b/src/api/routes/users/@me/mfa/webauthn/credentials/index.ts index f383ffb7..b8e33da7 100644 --- a/src/api/routes/users/@me/mfa/webauthn/credentials/index.ts +++ b/src/api/routes/users/@me/mfa/webauthn/credentials/index.ts @@ -35,15 +35,11 @@ import { ExpectedAttestationResult } from "fido2-lib"; import { HTTPError } from "lambert-server"; const router = Router(); -const isGenerateSchema = ( - body: WebAuthnPostSchema, -): body is GenerateWebAuthnCredentialsSchema => { +const isGenerateSchema = (body: WebAuthnPostSchema): body is GenerateWebAuthnCredentialsSchema => { return "password" in body; }; -const isCreateSchema = ( - body: WebAuthnPostSchema, -): body is CreateWebAuthnCredentialSchema => { +const isCreateSchema = (body: WebAuthnPostSchema): body is CreateWebAuthnCredentialSchema => { return "credential" in body; }; @@ -67,7 +63,7 @@ router.get("/", route({}), async (req: Request, res: Response) => { securityKeys.map((key) => ({ id: key.id, name: key.name, - })), + })) ); }); @@ -94,24 +90,13 @@ router.post( where: { id: req.user_id, }, - select: [ - "data", - "id", - "disabled", - "deleted", - "totp_secret", - "mfa_enabled", - "username", - ], + select: ["data", "id", "disabled", "deleted", "totp_secret", "mfa_enabled", "username"], relations: ["settings"], }); if (isGenerateSchema(req.body)) { const { password } = req.body; - const same_password = await bcrypt.compare( - password, - user.data.hash || "", - ); + const same_password = await bcrypt.compare(password, user.data.hash || ""); if (!same_password) { throw FieldErrors({ password: { @@ -121,14 +106,11 @@ router.post( }); } - const registrationOptions = - await WebAuthn.fido2.attestationOptions(); + const registrationOptions = await WebAuthn.fido2.attestationOptions(); const challenge = JSON.stringify({ publicKey: { ...registrationOptions, - challenge: Buffer.from( - registrationOptions.challenge, - ).toString("base64"), + challenge: Buffer.from(registrationOptions.challenge).toString("base64"), user: { id: user.id, name: user.username, @@ -151,35 +133,22 @@ router.post( const clientAttestationResponse = JSON.parse(credential); - if (!clientAttestationResponse.rawId) - throw new HTTPError("Missing rawId", 400); + if (!clientAttestationResponse.rawId) throw new HTTPError("Missing rawId", 400); - const rawIdBuffer = Buffer.from( - clientAttestationResponse.rawId, - "base64", - ); + const rawIdBuffer = Buffer.from(clientAttestationResponse.rawId, "base64"); clientAttestationResponse.rawId = toArrayBuffer(rawIdBuffer); - const attestationExpectations: ExpectedAttestationResult = - JSON.parse( - Buffer.from( - clientAttestationResponse.response.clientDataJSON, - "base64", - ).toString(), - ); - - const regResult = await WebAuthn.fido2.attestationResult( - clientAttestationResponse, - { - ...attestationExpectations, - factor: "second", - }, + const attestationExpectations: ExpectedAttestationResult = JSON.parse( + Buffer.from(clientAttestationResponse.response.clientDataJSON, "base64").toString() ); + const regResult = await WebAuthn.fido2.attestationResult(clientAttestationResponse, { + ...attestationExpectations, + factor: "second", + }); + const authnrData = regResult.authnrData; - const keyId = Buffer.from(authnrData.get("credId")).toString( - "base64", - ); + const keyId = Buffer.from(authnrData.get("credId")).toString("base64"); const counter = authnrData.get("counter"); const publicKey = authnrData.get("credentialPublicKeyPem"); @@ -191,10 +160,7 @@ router.post( key_id: keyId, }); - await Promise.all([ - securityKey.save(), - User.update({ id: req.user_id }, { webauthn_enabled: true }), - ]); + await Promise.all([securityKey.save(), User.update({ id: req.user_id }, { webauthn_enabled: true })]); return res.json({ name, @@ -203,7 +169,7 @@ router.post( } else { throw DiscordApiErrors.INVALID_AUTHENTICATION_TOKEN; } - }, + } ); export default router; diff --git a/src/api/routes/users/@me/notes.ts b/src/api/routes/users/@me/notes.ts index 248e61f9..51dcbd7f 100644 --- a/src/api/routes/users/@me/notes.ts +++ b/src/api/routes/users/@me/notes.ts @@ -49,7 +49,7 @@ router.get( note_user_id: id, user_id: req.user_id, }); - }, + } ); router.put( @@ -79,10 +79,7 @@ router.put( }, }) ) { - Note.update( - { owner: { id: owner.id }, target: { id: target.id } }, - { owner, target, content: note }, - ); + Note.update({ owner: { id: owner.id }, target: { id: target.id } }, { owner, target, content: note }); } else { Note.insert({ id: Snowflake.generate(), @@ -108,7 +105,7 @@ router.put( }); return res.status(204); - }, + } ); export default router; diff --git a/src/api/routes/users/@me/relationships.ts b/src/api/routes/users/@me/relationships.ts index bce0a654..9bee19a3 100644 --- a/src/api/routes/users/@me/relationships.ts +++ b/src/api/routes/users/@me/relationships.ts @@ -33,10 +33,7 @@ import { HTTPError } from "lambert-server"; const router = Router(); -const userProjection: (keyof User)[] = [ - "relationships", - ...PublicUserProjection, -]; +const userProjection: (keyof User)[] = ["relationships", ...PublicUserProjection]; router.get( "/", @@ -68,7 +65,7 @@ router.get( }); return res.json(related_users); - }, + } ); router.put( @@ -94,9 +91,9 @@ router.put( relations: ["relationships", "relationships.to"], select: userProjection, }), - req.body.type ?? RelationshipType.friends, + req.body.type ?? RelationshipType.friends ); - }, + } ); router.post( @@ -121,16 +118,13 @@ router.post( relations: ["relationships", "relationships.to"], select: userProjection, where: { - discriminator: String(req.body.discriminator).padStart( - 4, - "0", - ), //Discord send the discriminator as integer, we need to add leading zeroes + discriminator: String(req.body.discriminator).padStart(4, "0"), //Discord send the discriminator as integer, we need to add leading zeroes username: req.body.username, }, }), - req.body.type, + req.body.type ); - }, + } ); router.delete( @@ -148,8 +142,7 @@ router.delete( }), async (req: Request, res: Response) => { const { id } = req.params; - if (id === req.user_id) - throw new HTTPError("You can't remove yourself as a friend"); + if (id === req.user_id) throw new HTTPError("You can't remove yourself as a friend"); const user = await User.findOneOrFail({ where: { id: req.user_id }, @@ -163,12 +156,9 @@ router.delete( }); const relationship = user.relationships.find((x) => x.to_id === id); - const friendRequest = friend.relationships.find( - (x) => x.to_id === req.user_id, - ); + const friendRequest = friend.relationships.find((x) => x.to_id === req.user_id); - if (!relationship) - throw new HTTPError("You are not friends with the user", 404); + if (!relationship) throw new HTTPError("You are not friends with the user", 404); if (relationship?.type === RelationshipType.blocked) { // unblock user @@ -203,20 +193,14 @@ router.delete( ]); return res.sendStatus(204); - }, + } ); export default router; -async function updateRelationship( - req: Request, - res: Response, - friend: User, - type: RelationshipType, -) { +async function updateRelationship(req: Request, res: Response, friend: User, type: RelationshipType) { const id = friend.id; - if (id === req.user_id) - throw new HTTPError("You can't add yourself as a friend"); + if (id === req.user_id) throw new HTTPError("You can't add yourself as a friend"); const user = await User.findOneOrFail({ where: { id: req.user_id }, @@ -225,15 +209,12 @@ async function updateRelationship( }); let relationship = user.relationships.find((x) => x.to_id === id); - const friendRequest = friend.relationships.find( - (x) => x.to_id === req.user_id, - ); + const friendRequest = friend.relationships.find((x) => x.to_id === req.user_id); // TODO: you can add infinitely many blocked users (should this be prevented?) if (type === RelationshipType.blocked) { if (relationship) { - if (relationship.type === RelationshipType.blocked) - throw new HTTPError("You already blocked the user"); + if (relationship.type === RelationshipType.blocked) throw new HTTPError("You already blocked the user"); relationship.type = RelationshipType.blocked; await relationship.save(); } else { @@ -265,8 +246,7 @@ async function updateRelationship( } const { maxFriends } = Config.get().limits.user; - if (user.relationships.length >= maxFriends) - throw DiscordApiErrors.MAXIMUM_FRIENDS.withParams(maxFriends); + if (user.relationships.length >= maxFriends) throw DiscordApiErrors.MAXIMUM_FRIENDS.withParams(maxFriends); let incoming_relationship = Relationship.create({ nickname: undefined, @@ -282,8 +262,7 @@ async function updateRelationship( }); if (friendRequest) { - if (friendRequest.type === RelationshipType.blocked) - throw new HTTPError("The user blocked you"); + if (friendRequest.type === RelationshipType.blocked) throw new HTTPError("The user blocked you"); if (friendRequest.type === RelationshipType.friends) throw new HTTPError("You are already friends with the user"); // accept friend request @@ -292,12 +271,9 @@ async function updateRelationship( } if (relationship) { - if (relationship.type === RelationshipType.outgoing) - throw new HTTPError("You already sent a friend request"); + if (relationship.type === RelationshipType.outgoing) throw new HTTPError("You already sent a friend request"); if (relationship.type === RelationshipType.blocked) - throw new HTTPError( - "Unblock the user before sending a friend request", - ); + throw new HTTPError("Unblock the user before sending a friend request"); if (relationship.type === RelationshipType.friends) throw new HTTPError("You are already friends with the user"); outgoing_relationship = relationship; diff --git a/src/api/routes/users/@me/settings.ts b/src/api/routes/users/@me/settings.ts index d22d6de1..a6e2f92a 100644 --- a/src/api/routes/users/@me/settings.ts +++ b/src/api/routes/users/@me/settings.ts @@ -40,7 +40,7 @@ router.get( relations: ["settings"], }); return res.json(user.settings); - }, + } ); router.patch( @@ -73,7 +73,7 @@ router.patch( await user.settings.save(); res.json({ ...user.settings, index: undefined }); - }, + } ); export default router; diff --git a/src/api/routes/voice/regions.ts b/src/api/routes/voice/regions.ts index 10a8b21d..064b6021 100644 --- a/src/api/routes/voice/regions.ts +++ b/src/api/routes/voice/regions.ts @@ -32,7 +32,7 @@ router.get( }), async (req: Request, res: Response) => { res.json(await getVoiceRegions(getIpAdress(req), true)); //vip true? - }, + } ); export default router; |