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 {
Guild,
GuildCreateEvent,
GuildDeleteEvent,
GuildMemberAddEvent,
GuildMemberRemoveEvent,
GuildModel,
MemberModel,
UserModel,
} from "fosscord-server-util";
import { HTTPError } from "lambert-server";
import Config from "./Config";
import { emitEvent } from "./Event";
import { getPublicUser } from "./User";
export const PublicMemberProjection = {
id: true,
guild_id: true,
nick: true,
roles: true,
joined_at: true,
pending: true,
deaf: true,
mute: true,
premium_since: true,
};
export async function addMember(user_id: string, guild_id: string, cache?: { guild?: Guild }) {
const user = await getPublicUser(user_id, { guilds: true });
const guildSize = user.guilds.length;
const { maxGuilds } = Config.get().limits.user;
if (guildSize >= maxGuilds) {
throw new HTTPError(`You are at the ${maxGuilds} server limit.`, 403);
}
const guild = cache?.guild || (await GuildModel.findOne({ id: guild_id }).exec());
const member = {
id: user_id,
guild_id: guild_id,
nick: undefined,
roles: [guild_id], // @everyone role
joined_at: new Date(),
premium_since: undefined,
deaf: false,
mute: false,
pending: false,
};
return Promise.all([
new MemberModel({
...member,
settings: {
channel_overrides: [],
message_notifications: 0,
mobile_push: true,
mute_config: null,
muted: false,
suppress_everyone: false,
suppress_roles: false,
version: 0,
},
}).save(),
UserModel.updateOne({ id: user_id }, { $push: { guilds: guild_id } }).exec(),
GuildModel.updateOne({ id: guild_id }, { $inc: { member_count: 1 } }).exec(),
emitEvent({
event: "GUILD_MEMBER_ADD",
data: {
...member,
user,
guild_id: guild_id,
},
guild_id: guild_id,
} as GuildMemberAddEvent),
emitEvent({
event: "GUILD_CREATE",
data: guild,
guild_id: guild_id,
} as GuildCreateEvent),
]);
}
export async function removeMember(user_id: string, guild_id: string) {
const user = await getPublicUser(user_id);
const guild = await GuildModel.findOne({ id: guild_id }, { owner_id: true }).exec();
if (!guild) throw new HTTPError("Guild not found", 404);
if (guild.owner_id === user_id) throw new Error("The owner cannot be removed of the guild");
// use promise all to execute all promises at the same time -> save time
return Promise.all([
MemberModel.deleteOne({
id: user_id,
guild_id: guild_id,
}).exec(),
UserModel.updateOne({ id: user.id }, { $pull: { guilds: guild_id } }).exec(),
GuildModel.updateOne({ id: guild_id }, { $inc: { member_count: -1 } }).exec(),
emitEvent({
event: "GUILD_DELETE",
data: {
id: guild_id,
},
user_id: user_id,
} as GuildDeleteEvent),
emitEvent({
event: "GUILD_MEMBER_REMOVE",
data: {
guild_id: guild_id,
user: user,
},
guild_id: guild_id,
} as GuildMemberRemoveEvent),
]);
}
|