summary refs log tree commit diff
path: root/src/api/routes/users/@me
diff options
context:
space:
mode:
authorMadeline <46743919+MaddyUnderStars@users.noreply.github.com>2022-08-22 22:12:00 +1000
committerMadeline <46743919+MaddyUnderStars@users.noreply.github.com>2022-08-22 22:12:00 +1000
commitafefa5d64bd6cde7d6efa3a9a5a3ec67a6ca29a8 (patch)
tree07779150eba77c27bf75bc0c7890f4a3f976716e /src/api/routes/users/@me
parentremoved char joiners as they are actually useful, added page break (diff)
parentMerge remote-tracking branch 'Puyodead1/patch/prettier-config' into staging (diff)
downloadserver-afefa5d64bd6cde7d6efa3a9a5a3ec67a6ca29a8.tar.xz
Merge remote-tracking branch 'upstream/staging' into fix/categoryNames
Diffstat (limited to '')
-rw-r--r--src/api/routes/users/@me/activities/statistics/applications.ts (renamed from api/src/routes/users/@me/activities/statistics/applications.ts)0
-rw-r--r--src/api/routes/users/@me/affinities/guilds.ts (renamed from api/src/routes/users/@me/affinities/guilds.ts)0
-rw-r--r--src/api/routes/users/@me/affinities/users.ts (renamed from api/src/routes/users/@me/affinities/users.ts)0
-rw-r--r--src/api/routes/users/@me/applications/#app_id/entitlements.ts (renamed from api/src/routes/users/@me/applications/#app_id/entitlements.ts)0
-rw-r--r--src/api/routes/users/@me/billing/country-code.ts (renamed from api/src/routes/users/@me/billing/country-code.ts)0
-rw-r--r--src/api/routes/users/@me/billing/payment-sources.ts (renamed from api/src/routes/users/@me/billing/payment-sources.ts)0
-rw-r--r--src/api/routes/users/@me/billing/subscriptions.ts (renamed from api/src/routes/users/@me/billing/subscriptions.ts)0
-rw-r--r--src/api/routes/users/@me/channels.ts (renamed from api/src/routes/users/@me/channels.ts)7
-rw-r--r--src/api/routes/users/@me/connections.ts (renamed from api/src/routes/users/@me/connections.ts)0
-rw-r--r--src/api/routes/users/@me/delete.ts (renamed from api/src/routes/users/@me/delete.ts)2
-rw-r--r--src/api/routes/users/@me/devices.ts (renamed from api/src/routes/users/@me/devices.ts)0
-rw-r--r--src/api/routes/users/@me/disable.ts (renamed from api/src/routes/users/@me/disable.ts)0
-rw-r--r--src/api/routes/users/@me/email-settings.ts (renamed from api/src/routes/users/@me/email-settings.ts)0
-rw-r--r--src/api/routes/users/@me/entitlements.ts (renamed from api/src/routes/users/@me/entitlements.ts)0
-rw-r--r--src/api/routes/users/@me/guilds.ts (renamed from api/src/routes/users/@me/guilds.ts)2
-rw-r--r--src/api/routes/users/@me/guilds/premium/subscription-slots.ts (renamed from api/src/routes/users/@me/guilds/premium/subscription-slots.ts)0
-rw-r--r--src/api/routes/users/@me/index.ts (renamed from api/src/routes/users/@me/index.ts)38
-rw-r--r--src/api/routes/users/@me/library.ts (renamed from api/src/routes/users/@me/library.ts)0
-rw-r--r--src/api/routes/users/@me/mfa/codes.ts45
-rw-r--r--src/api/routes/users/@me/mfa/totp/disable.ts41
-rw-r--r--src/api/routes/users/@me/mfa/totp/enable.ts48
-rw-r--r--src/api/routes/users/@me/notes.ts60
-rw-r--r--src/api/routes/users/@me/relationships.ts (renamed from api/src/routes/users/@me/relationships.ts)39
-rw-r--r--src/api/routes/users/@me/settings.ts (renamed from api/src/routes/users/@me/settings.ts)6
24 files changed, 228 insertions, 60 deletions
diff --git a/api/src/routes/users/@me/activities/statistics/applications.ts b/src/api/routes/users/@me/activities/statistics/applications.ts

index 014df8af..014df8af 100644 --- a/api/src/routes/users/@me/activities/statistics/applications.ts +++ b/src/api/routes/users/@me/activities/statistics/applications.ts
diff --git a/api/src/routes/users/@me/affinities/guilds.ts b/src/api/routes/users/@me/affinities/guilds.ts
index 8d744744..8d744744 100644 --- a/api/src/routes/users/@me/affinities/guilds.ts +++ b/src/api/routes/users/@me/affinities/guilds.ts
diff --git a/api/src/routes/users/@me/affinities/users.ts b/src/api/routes/users/@me/affinities/users.ts
index 6d4e4991..6d4e4991 100644 --- a/api/src/routes/users/@me/affinities/users.ts +++ b/src/api/routes/users/@me/affinities/users.ts
diff --git a/api/src/routes/users/@me/applications/#app_id/entitlements.ts b/src/api/routes/users/@me/applications/#app_id/entitlements.ts
index 411e95bf..411e95bf 100644 --- a/api/src/routes/users/@me/applications/#app_id/entitlements.ts +++ b/src/api/routes/users/@me/applications/#app_id/entitlements.ts
diff --git a/api/src/routes/users/@me/billing/country-code.ts b/src/api/routes/users/@me/billing/country-code.ts
index 33d40796..33d40796 100644 --- a/api/src/routes/users/@me/billing/country-code.ts +++ b/src/api/routes/users/@me/billing/country-code.ts
diff --git a/api/src/routes/users/@me/billing/payment-sources.ts b/src/api/routes/users/@me/billing/payment-sources.ts
index 014df8af..014df8af 100644 --- a/api/src/routes/users/@me/billing/payment-sources.ts +++ b/src/api/routes/users/@me/billing/payment-sources.ts
diff --git a/api/src/routes/users/@me/billing/subscriptions.ts b/src/api/routes/users/@me/billing/subscriptions.ts
index 411e95bf..411e95bf 100644 --- a/api/src/routes/users/@me/billing/subscriptions.ts +++ b/src/api/routes/users/@me/billing/subscriptions.ts
diff --git a/api/src/routes/users/@me/channels.ts b/src/api/routes/users/@me/channels.ts
index 78f531e1..ad483529 100644 --- a/api/src/routes/users/@me/channels.ts +++ b/src/api/routes/users/@me/channels.ts
@@ -1,5 +1,5 @@ import { Request, Response, Router } from "express"; -import { Recipient, DmChannelDTO, Channel } from "@fosscord/util"; +import { Recipient, DmChannelDTO, Channel, DmChannelCreateSchema } from "@fosscord/util"; import { route } from "@fosscord/api"; const router: Router = Router(); @@ -12,11 +12,6 @@ router.get("/", route({}), async (req: Request, res: Response) => { res.json(await Promise.all(recipients.map((r) => DmChannelDTO.from(r.channel, [req.user_id])))); }); -export interface DmChannelCreateSchema { - name?: string; - recipients: string[]; -} - router.post("/", route({ body: "DmChannelCreateSchema" }), async (req: Request, res: Response) => { const body = req.body as DmChannelCreateSchema; res.json(await Channel.createDMChannel(body.recipients, req.user_id, body.name)); diff --git a/api/src/routes/users/@me/connections.ts b/src/api/routes/users/@me/connections.ts
index 411e95bf..411e95bf 100644 --- a/api/src/routes/users/@me/connections.ts +++ b/src/api/routes/users/@me/connections.ts
diff --git a/api/src/routes/users/@me/delete.ts b/src/api/routes/users/@me/delete.ts
index c24c3f1e..1d81c2b9 100644 --- a/api/src/routes/users/@me/delete.ts +++ b/src/api/routes/users/@me/delete.ts
@@ -2,7 +2,7 @@ import { Router, Request, Response } from "express"; import { Guild, Member, User } from "@fosscord/util"; import { route } from "@fosscord/api"; import bcrypt from "bcrypt"; -import { HTTPError } from "lambert-server"; +import { HTTPError } from "@fosscord/util"; const router = Router(); diff --git a/api/src/routes/users/@me/devices.ts b/src/api/routes/users/@me/devices.ts
index 8556a3ad..8556a3ad 100644 --- a/api/src/routes/users/@me/devices.ts +++ b/src/api/routes/users/@me/devices.ts
diff --git a/api/src/routes/users/@me/disable.ts b/src/api/routes/users/@me/disable.ts
index 4aff3774..4aff3774 100644 --- a/api/src/routes/users/@me/disable.ts +++ b/src/api/routes/users/@me/disable.ts
diff --git a/api/src/routes/users/@me/email-settings.ts b/src/api/routes/users/@me/email-settings.ts
index 3114984e..3114984e 100644 --- a/api/src/routes/users/@me/email-settings.ts +++ b/src/api/routes/users/@me/email-settings.ts
diff --git a/api/src/routes/users/@me/entitlements.ts b/src/api/routes/users/@me/entitlements.ts
index 341e2b4c..341e2b4c 100644 --- a/api/src/routes/users/@me/entitlements.ts +++ b/src/api/routes/users/@me/entitlements.ts
diff --git a/api/src/routes/users/@me/guilds.ts b/src/api/routes/users/@me/guilds.ts
index 754a240e..4d4fccd4 100644 --- a/api/src/routes/users/@me/guilds.ts +++ b/src/api/routes/users/@me/guilds.ts
@@ -1,6 +1,6 @@ import { Router, Request, Response } from "express"; import { Guild, Member, User, GuildDeleteEvent, GuildMemberRemoveEvent, emitEvent, Config } from "@fosscord/util"; -import { HTTPError } from "lambert-server"; +import { HTTPError } from "@fosscord/util"; import { route } from "@fosscord/api"; const router: Router = Router(); diff --git a/api/src/routes/users/@me/guilds/premium/subscription-slots.ts b/src/api/routes/users/@me/guilds/premium/subscription-slots.ts
index 014df8af..014df8af 100644 --- a/api/src/routes/users/@me/guilds/premium/subscription-slots.ts +++ b/src/api/routes/users/@me/guilds/premium/subscription-slots.ts
diff --git a/api/src/routes/users/@me/index.ts b/src/api/routes/users/@me/index.ts
index 1af413c4..7d095451 100644 --- a/api/src/routes/users/@me/index.ts +++ b/src/api/routes/users/@me/index.ts
@@ -1,39 +1,22 @@ import { Router, Request, Response } from "express"; -import { User, PrivateUserProjection, emitEvent, UserUpdateEvent, handleFile, FieldErrors } from "@fosscord/util"; +import { User, PrivateUserProjection, emitEvent, UserUpdateEvent, handleFile, FieldErrors, UserModifySchema } from "@fosscord/util"; import { route } from "@fosscord/api"; import bcrypt from "bcrypt"; +import { OrmUtils, generateToken } from "@fosscord/util"; const router: Router = Router(); -export interface UserModifySchema { - /** - * @minLength 1 - * @maxLength 100 - */ - username?: string; - avatar?: string | null; - /** - * @maxLength 1024 - */ - bio?: string; - accent_color?: number; - banner?: string | null; - password?: string; - new_password?: string; - code?: string; -} - router.get("/", route({}), async (req: Request, res: Response) => { res.json(await User.findOne({ select: PrivateUserProjection, where: { id: req.user_id } })); }); router.patch("/", route({ body: "UserModifySchema" }), async (req: Request, res: Response) => { + var token = null as any; const body = req.body as UserModifySchema; 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); - - const user = await User.findOneOrFail({ where: { id: req.user_id }, select: [...PrivateUserProjection, "data"] }); + let user = await User.findOneOrFail({ where: { id: req.user_id }, select: [...PrivateUserProjection, "data"] }); if (body.password) { if (user.data?.hash) { @@ -53,10 +36,12 @@ router.patch("/", route({ body: "UserModifySchema" }), async (req: Request, res: }); } user.data.hash = await bcrypt.hash(body.new_password, 12); + user.data.valid_tokens_since = new Date(); + token = await generateToken(user.id) as string; } if(body.username){ - var check_username = body?.username?.replace(/\s/g, ''); + let check_username = body?.username?.replace(/\s/g, ''); if(!check_username) { throw FieldErrors({ username: { code: "BASE_TYPE_REQUIRED", message: req.t("common:field.BASE_TYPE_REQUIRED") } @@ -64,7 +49,7 @@ router.patch("/", route({ body: "UserModifySchema" }), async (req: Request, res: } } - user.assign(body); + user = OrmUtils.mergeDeep(user, body); await user.save(); // @ts-ignore @@ -76,8 +61,11 @@ router.patch("/", route({ body: "UserModifySchema" }), async (req: Request, res: user_id: req.user_id, data: user } as UserUpdateEvent); - - res.json(user); + + res.json({ + ...user, + token + }); }); export default router; diff --git a/api/src/routes/users/@me/library.ts b/src/api/routes/users/@me/library.ts
index 7ac13bae..7ac13bae 100644 --- a/api/src/routes/users/@me/library.ts +++ b/src/api/routes/users/@me/library.ts
diff --git a/src/api/routes/users/@me/mfa/codes.ts b/src/api/routes/users/@me/mfa/codes.ts new file mode 100644
index 00000000..4224a1c0 --- /dev/null +++ b/src/api/routes/users/@me/mfa/codes.ts
@@ -0,0 +1,45 @@ +import { Router, Request, Response } from "express"; +import { route } from "@fosscord/api"; +import { BackupCode, Config, FieldErrors, generateMfaBackupCodes, MfaCodesSchema, User } from "@fosscord/util"; +import bcrypt from "bcrypt"; + +const router = Router(); + +// TODO: This route is replaced with users/@me/mfa/codes-verification in newer clients + +router.post("/", route({ body: "MfaCodesSchema" }), async (req: Request, res: Response) => { + const { password, regenerate } = req.body as MfaCodesSchema; + + const user = await User.findOneOrFail({ where: { id: req.user_id }, select: ["data"] }); + + if (!await bcrypt.compare(password, user.data.hash || "")) { + throw FieldErrors({ password: { message: req.t("auth:login.INVALID_PASSWORD"), code: "INVALID_PASSWORD" } }); + } + + var codes: BackupCode[]; + if (regenerate && Config.get().security.twoFactor.generateBackupCodes) { + await BackupCode.update( + { user: { id: req.user_id } }, + { expired: true } + ); + + codes = generateMfaBackupCodes(req.user_id); + await Promise.all(codes.map(x => x.save())); + } + else { + codes = await BackupCode.find({ + where: { + user: { + id: req.user_id, + }, + expired: false + } + }); + } + + 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 new file mode 100644
index 00000000..2fe9355c --- /dev/null +++ b/src/api/routes/users/@me/mfa/totp/disable.ts
@@ -0,0 +1,41 @@ +import { Router, Request, Response } from "express"; +import { route } from "@fosscord/api"; +import { verifyToken } from 'node-2fa'; +import { HTTPError } from "lambert-server"; +import { User, generateToken, BackupCode, TotpDisableSchema } from "@fosscord/util"; + +const router = Router(); + +router.post("/", route({ body: "TotpDisableSchema" }), async (req: Request, res: Response) => { + const body = req.body as TotpDisableSchema; + + const user = await User.findOneOrFail({ where: { id: req.user_id }, select: ["totp_secret"] }); + + 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); + } + + await User.update( + { id: req.user_id }, + { + 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; \ No newline at end of file diff --git a/src/api/routes/users/@me/mfa/totp/enable.ts b/src/api/routes/users/@me/mfa/totp/enable.ts new file mode 100644
index 00000000..ac668d1d --- /dev/null +++ b/src/api/routes/users/@me/mfa/totp/enable.ts
@@ -0,0 +1,48 @@ +import { Router, Request, Response } from "express"; +import { User, generateToken, BackupCode, generateMfaBackupCodes, Config, TotpEnableSchema } from "@fosscord/util"; +import { route } from "@fosscord/api"; +import bcrypt from "bcrypt"; +import { HTTPError } from "lambert-server"; +import { verifyToken } from 'node-2fa'; + +const router = Router(); + +router.post("/", route({ body: "TotpEnableSchema" }), async (req: Request, res: Response) => { + const body = req.body as TotpEnableSchema; + + const user = await User.findOneOrFail({ where: { id: req.user_id }, select: ["data"] }); + + // TODO: Are guests allowed to enable 2fa? + if (user.data.hash) { + if (!await bcrypt.compare(body.password, user.data.hash)) { + throw new HTTPError(req.t("auth:login.INVALID_PASSWORD")); + } + } + + 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 (verifyToken(body.secret, body.code)?.delta != 0) + throw new HTTPError(req.t("auth:login.INVALID_TOTP_CODE"), 60008); + + let backup_codes: BackupCode[] = []; + if (Config.get().security.twoFactor.generateBackupCodes) { + 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 } + ); + + res.send({ + token: await generateToken(user.id), + backup_codes: backup_codes.map(x => ({ ...x, expired: undefined })), + }); +}); + +export default router; \ No newline at end of file diff --git a/src/api/routes/users/@me/notes.ts b/src/api/routes/users/@me/notes.ts new file mode 100644
index 00000000..f938f088 --- /dev/null +++ b/src/api/routes/users/@me/notes.ts
@@ -0,0 +1,60 @@ +import { Request, Response, Router } from "express"; +import { route } from "@fosscord/api"; +import { User, Note, emitEvent, Snowflake } from "@fosscord/util"; + +const router: Router = Router(); + +router.get("/:id", route({}), async (req: Request, res: Response) => { + const { id } = req.params; + + const note = await Note.findOneOrFail({ + where: { + owner: { id: req.user_id }, + target: { id: id }, + } + }); + + return res.json({ + note: note?.content, + note_user_id: id, + user_id: req.user_id, + }); +}); + +router.put("/:id", route({}), async (req: Request, res: Response) => { + const { id } = req.params; + const owner = await User.findOneOrFail({ where: { id: req.user_id } }); + const target = await User.findOneOrFail({ where: { id: id } }); //if noted user does not exist throw + const { note } = req.body; + + if (note && note.length) { + // upsert a note + if (await Note.findOne({ where: { owner: { id: owner.id }, target: { id: target.id } } })) { + Note.update( + { owner: { id: owner.id }, target: { id: target.id } }, + { owner, target, content: note } + ); + } + else { + Note.insert( + { id: Snowflake.generate(), owner, target, content: note } + ); + } + } + else { + await Note.delete({ owner: { id: owner.id }, target: { id: target.id } }); + } + + await emitEvent({ + event: "USER_NOTE_UPDATE", + data: { + note: note, + id: target.id + }, + user_id: owner.id, + }); + + return res.status(204); +}); + +export default router; diff --git a/api/src/routes/users/@me/relationships.ts b/src/api/routes/users/@me/relationships.ts
index 0c13cdba..f7464b99 100644 --- a/api/src/routes/users/@me/relationships.ts +++ b/src/api/routes/users/@me/relationships.ts
@@ -9,9 +9,10 @@ import { Config } from "@fosscord/util"; import { Router, Response, Request } from "express"; -import { HTTPError } from "lambert-server"; +import { HTTPError } from "@fosscord/util"; import { DiscordApiErrors } from "@fosscord/util"; import { route } from "@fosscord/api"; +import { OrmUtils } from "@fosscord/util"; const router = Router(); @@ -37,24 +38,15 @@ router.get("/", route({}), async (req: Request, res: Response) => { return res.json(related_users); }); -export interface RelationshipPutSchema { - type?: RelationshipType; -} - router.put("/:id", route({ body: "RelationshipPutSchema" }), async (req: Request, res: Response) => { return await updateRelationship( req, res, - await User.findOneOrFail({ id: req.params.id }, { relations: ["relationships", "relationships.to"], select: userProjection }), + await User.findOneOrFail({ where: { id: req.params.id }, relations: ["relationships", "relationships.to"], select: userProjection }), req.body.type ?? RelationshipType.friends ); }); -export interface RelationshipPostSchema { - discriminator: string; - username: string; -} - router.post("/", route({ body: "RelationshipPostSchema" }), async (req: Request, res: Response) => { return await updateRelationship( req, @@ -75,8 +67,8 @@ router.delete("/:id", route({}), 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"); - const user = await User.findOneOrFail({ id: req.user_id }, { select: userProjection, relations: ["relationships"] }); - const friend = await User.findOneOrFail({ id: id }, { select: userProjection, relations: ["relationships"] }); + const user = await User.findOneOrFail({ where: { id: req.user_id }, select: userProjection, relations: ["relationships"] }); + const friend = await User.findOneOrFail({ where: { id: id }, select: userProjection, relations: ["relationships"] }); const relationship = user.relationships.find((x) => x.to_id === id); const friendRequest = friend.relationships.find((x) => x.to_id === req.user_id); @@ -124,12 +116,13 @@ async function updateRelationship(req: Request, res: Response, friend: User, typ const id = friend.id; if (id === req.user_id) throw new HTTPError("You can't add yourself as a friend"); - const user = await User.findOneOrFail( - { id: req.user_id }, - { relations: ["relationships", "relationships.to"], select: userProjection } - ); + const user = await User.findOneOrFail({ + where: { id: req.user_id }, + relations: ["relationships", "relationships.to"], + select: userProjection + }); - var relationship = user.relationships.find((x) => x.to_id === id); + let relationship = user.relationships.find((x) => x.to_id === 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?) @@ -139,7 +132,7 @@ async function updateRelationship(req: Request, res: Response, friend: User, typ relationship.type = RelationshipType.blocked; await relationship.save(); } else { - relationship = await new Relationship({ to_id: id, type: RelationshipType.blocked, from_id: req.user_id }).save(); + relationship = await (OrmUtils.mergeDeep(new Relationship(), { to_id: id, type: RelationshipType.blocked, from_id: req.user_id }) as Relationship).save(); } if (friendRequest && friendRequest.type !== RelationshipType.blocked) { @@ -165,8 +158,8 @@ async function updateRelationship(req: Request, res: Response, friend: User, typ const { maxFriends } = Config.get().limits.user; if (user.relationships.length >= maxFriends) throw DiscordApiErrors.MAXIMUM_FRIENDS.withParams(maxFriends); - var incoming_relationship = new Relationship({ nickname: undefined, type: RelationshipType.incoming, to: user, from: friend }); - var outgoing_relationship = new Relationship({ + let incoming_relationship = OrmUtils.mergeDeep(new Relationship(), { nickname: undefined, type: RelationshipType.incoming, to: user, from: friend }); + let outgoing_relationship = OrmUtils.mergeDeep(new Relationship(), { nickname: undefined, type: RelationshipType.outgoing, to: friend, @@ -177,7 +170,7 @@ async function updateRelationship(req: Request, res: Response, friend: User, typ 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 - incoming_relationship = friendRequest; + incoming_relationship = friendRequest as any; //TODO: checkme, any cast incoming_relationship.type = RelationshipType.friends; } @@ -185,7 +178,7 @@ async function updateRelationship(req: Request, res: Response, friend: User, typ 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"); if (relationship.type === RelationshipType.friends) throw new HTTPError("You are already friends with the user"); - outgoing_relationship = relationship; + outgoing_relationship = relationship as any; //TODO: checkme, any cast outgoing_relationship.type = RelationshipType.friends; } diff --git a/api/src/routes/users/@me/settings.ts b/src/api/routes/users/@me/settings.ts
index b22b72fb..7578d36e 100644 --- a/api/src/routes/users/@me/settings.ts +++ b/src/api/routes/users/@me/settings.ts
@@ -4,14 +4,12 @@ import { route } from "@fosscord/api"; const router = Router(); -export interface UserSettingsSchema extends Partial<UserSettings> {} - router.patch("/", route({ body: "UserSettingsSchema" }), async (req: Request, res: Response) => { const body = req.body as UserSettings; if (body.locale === "en") body.locale = "en-US"; // fix discord client crash on unkown locale - const user = await User.findOneOrFail({ id: req.user_id, bot: false }); - user.settings = { ...user.settings, ...body }; + const user = await User.findOneOrFail({ where: { id: req.user_id, bot: false }, relations: ["settings"] }); + user.settings = { ...user.settings, ...body } as UserSettings; await user.save(); res.sendStatus(204);