-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Expand file tree
/
Copy pathaddUserToRoom.ts
More file actions
130 lines (107 loc) · 3.97 KB
/
addUserToRoom.ts
File metadata and controls
130 lines (107 loc) · 3.97 KB
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
120
121
122
123
124
125
126
127
128
129
130
import { Apps, AppEvents } from '@rocket.chat/apps';
import { AppsEngineException } from '@rocket.chat/apps-engine/definition/exceptions';
import { Team, Room } from '@rocket.chat/core-services';
import { isRoomNativeFederated, type IUser } from '@rocket.chat/core-typings';
import { Subscriptions, Users, Rooms } from '@rocket.chat/models';
import { Meteor } from 'meteor/meteor';
import { RoomMemberActions } from '../../../../definition/IRoomTypeConfig';
import { callbacks } from '../../../../lib/callbacks';
import { beforeAddUserToRoom } from '../../../../lib/callbacks/beforeAddUserToRoom';
import { roomCoordinator } from '../../../../server/lib/rooms/roomCoordinator';
import { settings } from '../../../settings/server';
import { notifyOnRoomChangedById } from '../lib/notifyListener';
/**
* This function adds user to the given room.
* Caution - It does not validates if the user has permission to join room
*/
export const addUserToRoom = async (
rid: string,
user: Pick<IUser, '_id' | 'username'>,
inviter?: Pick<IUser, '_id' | 'username'>,
{
skipSystemMessage,
skipAlertSound,
createAsHidden = false,
}: {
skipSystemMessage?: boolean;
skipAlertSound?: boolean;
createAsHidden?: boolean;
} = {},
): Promise<boolean | undefined> => {
const now = new Date();
const room = await Rooms.findOneById(rid);
if (!room) {
throw new Meteor.Error('error-invalid-room', 'Invalid room', {
method: 'addUserToRoom',
});
}
const userToBeAdded = await Users.findOneById(user._id);
const roomDirectives = roomCoordinator.getRoomDirectives(room.t);
if (!userToBeAdded) {
throw new Meteor.Error('user-not-found');
}
// Check if user is already in room
const subscription = await Subscriptions.findOneByRoomIdAndUserId(rid, userToBeAdded._id);
if (subscription) {
return;
}
if (
!(await roomDirectives.allowMemberAction(room, RoomMemberActions.JOIN, userToBeAdded._id)) &&
!(await roomDirectives.allowMemberAction(room, RoomMemberActions.INVITE, userToBeAdded._id))
) {
return;
}
try {
await beforeAddUserToRoom.run({ user: userToBeAdded, inviter: (inviter && (await Users.findOneById(inviter._id))) || undefined }, room);
} catch (error) {
throw new Meteor.Error((error as any)?.message);
}
// TODO: are we calling this twice?
await callbacks.run('beforeAddedToRoom', { user: userToBeAdded, inviter });
try {
await Apps.self?.triggerEvent(AppEvents.IPreRoomUserJoined, room, userToBeAdded, inviter);
} catch (error: any) {
if (error.name === AppsEngineException.name) {
throw new Meteor.Error('error-app-prevented', error.message);
}
throw error;
}
// for federation rooms we stop here since everything else will be handled by the federation invite flow
if (isRoomNativeFederated(room)) {
return;
}
// TODO: are we calling this twice?
if (room.t === 'c' || room.t === 'p' || room.t === 'l') {
// Add a new event, with an optional inviter
await callbacks.run('beforeAddedToRoom', { user: userToBeAdded, inviter }, room);
// Keep the current event
await callbacks.run('beforeJoinRoom', userToBeAdded, room);
}
await Room.createUserSubscription({
room,
ts: now,
inviter,
userToBeAdded,
createAsHidden,
skipAlertSound,
skipSystemMessage,
});
if (room.t === 'c' || room.t === 'p') {
process.nextTick(async () => {
// Add a new event, with an optional inviter
await callbacks.run('afterAddedToRoom', { user: userToBeAdded, inviter }, room);
// Keep the current event
await callbacks.run('afterJoinRoom', userToBeAdded, room);
void Apps.self?.triggerEvent(AppEvents.IPostRoomUserJoined, room, userToBeAdded, inviter);
});
}
if (room.teamMain && room.teamId) {
// if user is joining to main team channel, create a membership
await Team.addMember(inviter || userToBeAdded, userToBeAdded._id, room.teamId);
}
if (room.encrypted && settings.get('E2E_Enable') && userToBeAdded.e2e?.public_key) {
await Rooms.addUserIdToE2EEQueueByRoomIds([room._id], userToBeAdded._id);
}
void notifyOnRoomChangedById(rid);
return true;
};