summary refs log tree commit diff
path: root/src/api/routes/users
diff options
context:
space:
mode:
Diffstat (limited to 'src/api/routes/users')
-rw-r--r--src/api/routes/users/#id/profile.ts63
-rw-r--r--src/api/routes/users/@me/mfa/codes-verification.ts41
-rw-r--r--src/api/routes/users/@me/mfa/totp/disable.ts3
-rw-r--r--src/api/routes/users/@me/mfa/totp/enable.ts3
4 files changed, 100 insertions, 10 deletions
diff --git a/src/api/routes/users/#id/profile.ts b/src/api/routes/users/#id/profile.ts
index 766c9880..541bb66a 100644
--- a/src/api/routes/users/#id/profile.ts
+++ b/src/api/routes/users/#id/profile.ts
@@ -1,5 +1,16 @@
 import { route } from "@fosscord/api";
-import { Member, PublicConnectedAccount, User, UserPublic } from "@fosscord/util";
+import {
+	emitEvent,
+	handleFile,
+	Member,
+	OrmUtils,
+	PrivateUserProjection,
+	PublicConnectedAccount,
+	User,
+	UserProfileModifySchema,
+	UserPublic,
+	UserUpdateEvent
+} from "@fosscord/util";
 import { Request, Response, Router } from "express";
 
 const router: Router = Router();
@@ -62,12 +73,18 @@ router.get("/", route({ test: { response: { body: "UserProfileResponse" } } }),
 		bot: user.bot
 	};
 
+	const userProfile = {
+		bio: req.user_bot ? null : user.bio,
+		accent_color: user.accent_color,
+		banner: user.banner
+	};
+
 	const guildMemberDto = guild_member
 		? {
-				avatar: user.avatar, // TODO
-				banner: user.banner, // TODO
-				bio: req.user_bot ? null : user.bio, // TODO
-				communication_disabled_until: null, // TODO
+				avatar: guild_member.avatar,
+				banner: guild_member.banner,
+				bio: req.user_bot ? null : guild_member.bio,
+				communication_disabled_until: guild_member.communication_disabled_until,
 				deaf: guild_member.deaf,
 				flags: user.flags,
 				is_pending: guild_member.pending,
@@ -81,13 +98,47 @@ router.get("/", route({ test: { response: { body: "UserProfileResponse" } } }),
 		  }
 		: undefined;
 
+	const guildMemberProfile = {
+		accent_color: null,
+		banner: guild_member?.banner || null,
+		bio: guild_member?.bio || "",
+		guild_id
+	};
 	res.json({
 		connected_accounts: user.connected_accounts,
 		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: userDto,
-		guild_member: guildMemberDto
+		user_profile: userProfile,
+		guild_member: guild_id && guildMemberDto,
+		guild_member_profile: guild_id && guildMemberProfile
+	});
+});
+
+router.patch("/", route({ body: "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);
+	let user = await User.findOneOrFail({ where: { id: req.user_id }, select: [...PrivateUserProjection, "data"] });
+
+	user = OrmUtils.mergeDeep(user, body);
+	await user.save();
+
+	// @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
 	});
 });
 
diff --git a/src/api/routes/users/@me/mfa/codes-verification.ts b/src/api/routes/users/@me/mfa/codes-verification.ts
new file mode 100644
index 00000000..071c71fa
--- /dev/null
+++ b/src/api/routes/users/@me/mfa/codes-verification.ts
@@ -0,0 +1,41 @@
+import { Router, Request, Response } from "express";
+import { route } from "@fosscord/api";
+import { BackupCode, generateMfaBackupCodes, User, CodesVerificationSchema } from "@fosscord/util";
+
+const router = Router();
+
+router.post("/", route({ body: "CodesVerificationSchema" }), async (req: Request, res: Response) => {
+	const { key, nonce, regenerate } = req.body as CodesVerificationSchema;
+
+	// TODO: We don't have email/etc etc, so can't send a verification code.
+	// Once that's done, this route can verify `key`
+
+	const user = await User.findOneOrFail({ where: { id: req.user_id } });
+
+	var codes: BackupCode[];
+	if (regenerate) {
+		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
index 6bc9a5c7..07fdbb05 100644
--- a/src/api/routes/users/@me/mfa/totp/disable.ts
+++ b/src/api/routes/users/@me/mfa/totp/disable.ts
@@ -1,7 +1,6 @@
 import { route } from "@fosscord/api";
-import { BackupCode, generateToken, TotpDisableSchema, User } from "@fosscord/util";
+import { BackupCode, generateToken, TotpDisableSchema, User, HTTPError } from "@fosscord/util";
 import { Request, Response, Router } from "express";
-import { HTTPError } from "lambert-server";
 import { verifyToken } from "node-2fa";
 
 const router = Router();
diff --git a/src/api/routes/users/@me/mfa/totp/enable.ts b/src/api/routes/users/@me/mfa/totp/enable.ts
index f3a73c28..adf51d6e 100644
--- a/src/api/routes/users/@me/mfa/totp/enable.ts
+++ b/src/api/routes/users/@me/mfa/totp/enable.ts
@@ -1,7 +1,6 @@
 import { route } from "@fosscord/api";
-import { BackupCode, Config, generateMfaBackupCodes, generateToken, TotpEnableSchema, User } from "@fosscord/util";
+import { BackupCode, Config, generateMfaBackupCodes, generateToken, TotpEnableSchema, User, HTTPError } from "@fosscord/util";
 import { Request, Response, Router } from "express";
-import { HTTPError } from "lambert-server";
 import { verifyToken } from "node-2fa";
 
 let bcrypt: any;