summary refs log tree commit diff
path: root/src/api/routes/users/#id/profile.ts
blob: ebea805b823c397356a5e829c6f9cc93c18fd1c5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import { Router, Request, Response } from "express";
import {
	PublicConnectedAccount,
	PublicUser,
	User,
	UserPublic,
	Member,
	Guild,
} from "@fosscord/util";
import { route } from "@fosscord/api";

const router: Router = Router();

export interface UserProfileResponse {
	user: UserPublic;
	connected_accounts: PublicConnectedAccount;
	premium_guild_since?: Date;
	premium_since?: Date;
}

router.get(
	"/",
	route({ test: { response: { 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 user = await User.getPublicUser(req.params.id, {
			relations: ["connected_accounts"],
		});

		var mutual_guilds: object[] = [];
		var 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 {
						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,
						});
					}
				}
			}
		}

		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 userDto = {
			username: user.username,
			discriminator: user.discriminator,
			id: user.id,
			public_flags: user.public_flags,
			avatar: user.avatar,
			accent_color: user.accent_color,
			banner: user.banner,
			bio: req.user_bot ? null : user.bio,
			bot: user.bot,
		};

		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
					deaf: guild_member.deaf,
					flags: user.flags,
					is_pending: guild_member.pending,
					pending: guild_member.pending, // why is this here twice, discord?
					joined_at: guild_member.joined_at,
					mute: guild_member.mute,
					nick: guild_member.nick,
					premium_since: guild_member.premium_since,
					roles: guild_member.roles
						.map((x) => x.id)
						.filter((id) => id != guild_id),
					user: userDto,
			  }
			: undefined;

		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,
		});
	},
);

export default router;