polfan-server-js-client 0.2.72 → 0.2.74
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.idea/workspace.xml +44 -50
- package/build/index.cjs.js +5 -3
- package/build/index.cjs.js.map +1 -1
- package/build/index.umd.js +1 -1
- package/build/index.umd.js.map +1 -1
- package/package.json +43 -43
- package/src/state-tracker/PermissionsManager.ts +315 -308
|
@@ -1,309 +1,316 @@
|
|
|
1
|
-
import {ChatStateTracker} from "./ChatStateTracker";
|
|
2
|
-
import {
|
|
3
|
-
ChatLocation,
|
|
4
|
-
PermissionOverwrites, PermissionOverwritesTarget,
|
|
5
|
-
PermissionOverwritesUpdated,
|
|
6
|
-
PermissionOverwritesValue,
|
|
7
|
-
RoleDeleted,
|
|
8
|
-
RoomDeleted,
|
|
9
|
-
RoomLeft, RoomMember, RoomMemberUpdated, Session,
|
|
10
|
-
SpaceDeleted,
|
|
11
|
-
SpaceLeft, SpaceMember,
|
|
12
|
-
SpaceMemberUpdated,
|
|
13
|
-
TopicDeleted,
|
|
14
|
-
} from "../types/src";
|
|
15
|
-
import {EventHandler, EventTarget} from "../EventTarget";
|
|
16
|
-
import {IndexedCollection} from "../IndexedObjectCollection";
|
|
17
|
-
import {Permissions} from "../Permissions";
|
|
18
|
-
import {PromiseRegistry} from "./AsyncUtils";
|
|
19
|
-
|
|
20
|
-
const getOvId = (
|
|
21
|
-
location: ChatLocation,
|
|
22
|
-
target?: PermissionOverwritesTarget,
|
|
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
|
-
this.tracker.client.on('
|
|
52
|
-
this.tracker.client.on('
|
|
53
|
-
this.tracker.client.on('
|
|
54
|
-
this.tracker.client.on('
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
this.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
this.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
permissionNames.
|
|
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
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
if (userRoles.length) {
|
|
138
|
-
promises.push(this.collectRoleOverwrites(
|
|
139
|
-
}
|
|
140
|
-
promises.push(this.getOverwrites(
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
private
|
|
182
|
-
if (ev.userId === this.tracker.me?.id) {
|
|
183
|
-
// User roles in
|
|
184
|
-
this.emit('change');
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
1
|
+
import {ChatStateTracker} from "./ChatStateTracker";
|
|
2
|
+
import {
|
|
3
|
+
ChatLocation,
|
|
4
|
+
PermissionOverwrites, PermissionOverwritesTarget,
|
|
5
|
+
PermissionOverwritesUpdated,
|
|
6
|
+
PermissionOverwritesValue,
|
|
7
|
+
RoleDeleted,
|
|
8
|
+
RoomDeleted,
|
|
9
|
+
RoomLeft, RoomMember, RoomMemberUpdated, Session,
|
|
10
|
+
SpaceDeleted,
|
|
11
|
+
SpaceLeft, SpaceMember,
|
|
12
|
+
SpaceMemberUpdated,
|
|
13
|
+
TopicDeleted,
|
|
14
|
+
} from "../types/src";
|
|
15
|
+
import {EventHandler, EventTarget} from "../EventTarget";
|
|
16
|
+
import {IndexedCollection} from "../IndexedObjectCollection";
|
|
17
|
+
import {Permissions} from "../Permissions";
|
|
18
|
+
import {PromiseRegistry} from "./AsyncUtils";
|
|
19
|
+
|
|
20
|
+
const getOvId = (
|
|
21
|
+
location: ChatLocation,
|
|
22
|
+
target?: PermissionOverwritesTarget,
|
|
23
|
+
) => [
|
|
24
|
+
location.roomId ? null : location.spaceId, // unify declaration of both space and room level overwrites
|
|
25
|
+
location.roomId,
|
|
26
|
+
location.topicId,
|
|
27
|
+
target?.type,
|
|
28
|
+
target?.userId,
|
|
29
|
+
target?.roleId,
|
|
30
|
+
].filter(Boolean).join('/');
|
|
31
|
+
|
|
32
|
+
const getOvIdByObject
|
|
33
|
+
= (overwrites: PermissionOverwrites | PermissionOverwritesUpdated): string => getOvId(overwrites.location, overwrites.target);
|
|
34
|
+
|
|
35
|
+
interface CheckPermissionsResult {
|
|
36
|
+
/**
|
|
37
|
+
* @deprecated Use `hasAll` instead.
|
|
38
|
+
*/
|
|
39
|
+
ok: boolean;
|
|
40
|
+
hasAll: boolean;
|
|
41
|
+
hasAny: boolean;
|
|
42
|
+
missing: string[];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export class PermissionsManager extends EventTarget {
|
|
46
|
+
private readonly overwrites = new IndexedCollection<string, PermissionOverwrites>();
|
|
47
|
+
private readonly overwritesPromises = new PromiseRegistry();
|
|
48
|
+
|
|
49
|
+
public constructor(private tracker: ChatStateTracker) {
|
|
50
|
+
super();
|
|
51
|
+
this.tracker.client.on('PermissionOverwrites', ev => this.handlePermissionOverwrites(ev));
|
|
52
|
+
this.tracker.client.on('PermissionOverwritesUpdated', ev => this.handlePermissionOverwrites(ev));
|
|
53
|
+
this.tracker.client.on('SpaceDeleted', ev => this.handleSpaceDeleted(ev));
|
|
54
|
+
this.tracker.client.on('SpaceLeft', ev => this.handleSpaceDeleted(ev));
|
|
55
|
+
this.tracker.client.on('RoomDeleted', ev => this.handleRoomDeleted(ev));
|
|
56
|
+
this.tracker.client.on('RoomLeft', ev => this.handleRoomDeleted(ev));
|
|
57
|
+
this.tracker.client.on('TopicDeleted', ev => this.handleTopicDeleted(ev));
|
|
58
|
+
this.tracker.client.on('RoleDeleted', ev => this.handleRoleDeleted(ev));
|
|
59
|
+
this.tracker.client.on('SpaceMemberUpdated', ev => this.handleSpaceMemberUpdated(ev));
|
|
60
|
+
this.tracker.client.on('RoomMemberUpdated', ev => this.handleRoomMemberUpdated(ev));
|
|
61
|
+
this.tracker.client.on('Session', ev => this.handleSession(ev));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public async getOverwrites(
|
|
65
|
+
location: ChatLocation,
|
|
66
|
+
target: PermissionOverwritesTarget,
|
|
67
|
+
): Promise<PermissionOverwrites | undefined> {
|
|
68
|
+
this.validateLocation(location);
|
|
69
|
+
|
|
70
|
+
const id = getOvId(location, target);
|
|
71
|
+
|
|
72
|
+
if (this.overwritesPromises.notExist(id)) {
|
|
73
|
+
this.overwritesPromises.registerByFunction(async () => {
|
|
74
|
+
const result = await this.tracker.client.send(
|
|
75
|
+
'GetPermissionOverwrites',
|
|
76
|
+
{location, target},
|
|
77
|
+
);
|
|
78
|
+
if (result.error) {
|
|
79
|
+
throw result.error;
|
|
80
|
+
}
|
|
81
|
+
this.handlePermissionOverwrites(result.data);
|
|
82
|
+
}, id);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
await this.overwritesPromises.get(id);
|
|
86
|
+
return this.overwrites.get(id);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
public on(eventName: 'change', handler: EventHandler<any>): this {
|
|
90
|
+
return super.on(eventName, handler);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public async check(
|
|
94
|
+
permissionNames: (keyof typeof Permissions.list)[],
|
|
95
|
+
location: ChatLocation,
|
|
96
|
+
): Promise<CheckPermissionsResult> {
|
|
97
|
+
if (! permissionNames.length) {
|
|
98
|
+
throw new Error('Permission names array cannot be empty');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const ownedPermissions = await this.calculatePermissions(location);
|
|
102
|
+
const missing: string[] = [];
|
|
103
|
+
|
|
104
|
+
permissionNames.forEach(name => {
|
|
105
|
+
if (~ ownedPermissions & Permissions.getByName(name).value) {
|
|
106
|
+
missing.push(name as string);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
ok: missing.length === 0,
|
|
112
|
+
hasAll: missing.length === 0,
|
|
113
|
+
hasAny: missing.length < permissionNames.length,
|
|
114
|
+
missing,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
public async calculatePermissions(location: ChatLocation): Promise<number> {
|
|
119
|
+
this.validateLocation(location);
|
|
120
|
+
|
|
121
|
+
const userId = (await this.tracker.getMe()).id;
|
|
122
|
+
const [spaceMember, roomMember] = await this.fetchMembersOrFail(location);
|
|
123
|
+
const userRoles: string[] = [...(spaceMember?.roles ?? []), ...(roomMember?.roles ?? [])];
|
|
124
|
+
const promises: Promise<PermissionOverwritesValue>[] = [
|
|
125
|
+
// Global user overwrites
|
|
126
|
+
this.getOverwrites({}, { type: 'User', userId }).then(v => v.overwrites),
|
|
127
|
+
];
|
|
128
|
+
|
|
129
|
+
if (location.spaceId && (await this.tracker.spaces.get())?.has(location.spaceId)) {
|
|
130
|
+
const filterLocation: ChatLocation = {spaceId: location.spaceId};
|
|
131
|
+
promises.push(this.collectRoleOverwrites(filterLocation, userRoles));
|
|
132
|
+
promises.push(this.getOverwrites(filterLocation, { type: 'User', userId }).then(v => v.overwrites));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (location.roomId && (await this.tracker.rooms.get())?.has(location.roomId)) {
|
|
136
|
+
const filterLocation: ChatLocation = {spaceId: location.spaceId, roomId: location.roomId};
|
|
137
|
+
if (userRoles.length) {
|
|
138
|
+
promises.push(this.collectRoleOverwrites(filterLocation, userRoles));
|
|
139
|
+
}
|
|
140
|
+
promises.push(this.getOverwrites(filterLocation, { type: 'User', userId }).then(v => v.overwrites));
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (location.topicId && (await this.tracker.rooms.getTopics(location.roomId))?.has(location.topicId)) {
|
|
144
|
+
if (userRoles.length) {
|
|
145
|
+
promises.push(this.collectRoleOverwrites(location, userRoles));
|
|
146
|
+
}
|
|
147
|
+
promises.push(this.getOverwrites(location, { type: 'User', userId }).then(v => v.overwrites));
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return this.resolveOverwritesHierarchy(await Promise.all(promises));
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
private handlePermissionOverwrites(ev: PermissionOverwritesUpdated | PermissionOverwrites): void {
|
|
154
|
+
this.overwrites.set([getOvIdByObject(ev), ev]);
|
|
155
|
+
this.emit('change');
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
private handleSpaceDeleted(ev: SpaceDeleted | SpaceLeft): void {
|
|
159
|
+
const ids = this.deleteOverwritesByIdPrefix(getOvId({spaceId: ev.id}));
|
|
160
|
+
this.overwritesPromises.forget(...ids);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
private async handleRoomDeleted(ev: RoomDeleted | RoomLeft): Promise<void> {
|
|
164
|
+
const room = (await this.tracker.rooms.get()).get(ev.id);
|
|
165
|
+
if (room) {
|
|
166
|
+
const ids = this.deleteOverwritesByIdPrefix(getOvId({spaceId: room.spaceId, roomId: room.id}));
|
|
167
|
+
this.overwritesPromises.forget(...ids);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
private handleTopicDeleted(ev: TopicDeleted): void {
|
|
172
|
+
const ids = this.deleteOverwritesByIdPrefix(getOvId(ev.location));
|
|
173
|
+
this.overwritesPromises.forget(...ids);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
private handleRoleDeleted(ev: RoleDeleted): void {
|
|
177
|
+
const ids = this.deleteOverwritesByIdPrefix(getOvId({spaceId: ev.spaceId}, { type: 'Role', roleId: ev.id }));
|
|
178
|
+
this.overwritesPromises.forget(...ids);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
private handleSpaceMemberUpdated(ev: SpaceMemberUpdated): void {
|
|
182
|
+
if (ev.userId === this.tracker.me?.id) {
|
|
183
|
+
// User roles in space could potentially have changed
|
|
184
|
+
this.emit('change');
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
private handleRoomMemberUpdated(ev: RoomMemberUpdated): void {
|
|
189
|
+
if (ev.userId === this.tracker.me?.id) {
|
|
190
|
+
// User roles in room could potentially have changed
|
|
191
|
+
this.emit('change');
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* @return Matched and deleted ids
|
|
197
|
+
*/
|
|
198
|
+
private deleteOverwritesByIdPrefix(prefix: string): string[] {
|
|
199
|
+
const ids: string[] = [];
|
|
200
|
+
this.overwrites.items.forEach((overwrites) => {
|
|
201
|
+
const id = getOvIdByObject(overwrites);
|
|
202
|
+
if (id.startsWith(prefix)) {
|
|
203
|
+
ids.push(id);
|
|
204
|
+
this.overwrites.delete(id);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
return ids;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
private async collectRoleOverwrites(
|
|
211
|
+
location: ChatLocation,
|
|
212
|
+
userRoles: string[],
|
|
213
|
+
): Promise<PermissionOverwritesValue> {
|
|
214
|
+
const roleOverwrites = await Promise.all(userRoles.map(
|
|
215
|
+
roleId => this.getOverwrites(location, { type: 'Role', roleId }),
|
|
216
|
+
));
|
|
217
|
+
|
|
218
|
+
return this.resolveOverwritesFromRolesByOrder(location.spaceId, roleOverwrites);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
private async resolveOverwritesFromRolesByOrder(
|
|
222
|
+
spaceId: string,
|
|
223
|
+
overwrites: PermissionOverwrites[],
|
|
224
|
+
): Promise<PermissionOverwritesValue> {
|
|
225
|
+
let allows = 0, denies = 0;
|
|
226
|
+
const roles = await this.tracker.spaces.getRoles(spaceId);
|
|
227
|
+
const sortedOverwrites = overwrites.sort(
|
|
228
|
+
(a, b) =>
|
|
229
|
+
roles.get(a.target.roleId).priority - roles.get(b.target.roleId).priority
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
// Max length of bit word
|
|
233
|
+
const permissionsLength = overwrites.reduce(
|
|
234
|
+
(previousValue: number, currentValue: PermissionOverwrites) =>
|
|
235
|
+
Math.max(
|
|
236
|
+
previousValue,
|
|
237
|
+
currentValue.overwrites.allow?.toString(2).length ?? 0,
|
|
238
|
+
currentValue.overwrites.deny?.toString(2).length ?? 0,
|
|
239
|
+
),
|
|
240
|
+
0,
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
sortedOverwrites.forEach(overwriteEvent => {
|
|
244
|
+
const overwrites = overwriteEvent.overwrites;
|
|
245
|
+
const revDecDenies = overwrites.deny?.toString(2).split('').reverse().join('') ?? '';
|
|
246
|
+
const revDecAllows = overwrites.allow?.toString(2).split('').reverse().join('') ?? '';
|
|
247
|
+
|
|
248
|
+
for (let i = 0; i < permissionsLength; i++) {
|
|
249
|
+
const deny = parseInt(revDecDenies[i] ?? '0');
|
|
250
|
+
const allow = parseInt(revDecAllows[i] ?? '0');
|
|
251
|
+
|
|
252
|
+
if (deny) {
|
|
253
|
+
denies |= 1 << i;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (allow) {
|
|
257
|
+
allows |= 1 << i;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
return {allow: allows, deny: denies};
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
private resolveOverwritesHierarchy(permissionOverwritesValues: PermissionOverwritesValue[]): number {
|
|
266
|
+
let result = 0;
|
|
267
|
+
|
|
268
|
+
for (const value of permissionOverwritesValues) {
|
|
269
|
+
if (value.allow & Permissions.getByName('Root').value) {
|
|
270
|
+
return this.getRootAccessValue();
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
result = (result & ~value.deny) | value.allow;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
return result;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
private getRootAccessValue(): number {
|
|
280
|
+
let result = 0;
|
|
281
|
+
|
|
282
|
+
for (const name of Permissions.getNames()) {
|
|
283
|
+
result |= Permissions.getByName(name).value;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
return result;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
private async fetchMembersOrFail(location: ChatLocation): Promise<[SpaceMember | null, RoomMember | null]> {
|
|
290
|
+
const results = await Promise.all([
|
|
291
|
+
location.spaceId ? this.tracker.spaces.getMe(location.spaceId) : null,
|
|
292
|
+
location.roomId ? this.tracker.rooms.getMe(location.roomId) : null,
|
|
293
|
+
]);
|
|
294
|
+
|
|
295
|
+
const spaceFail = location.spaceId && ! results[0];
|
|
296
|
+
const roomFail = location.roomId && ! results[1];
|
|
297
|
+
|
|
298
|
+
if (spaceFail || roomFail) {
|
|
299
|
+
const layer = spaceFail ? `space (${location.spaceId})` : `room (${location.roomId})`;
|
|
300
|
+
throw new Error(`Attempting to calculate permissions for a ${layer} that the user does not belong to`);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
return results;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
private validateLocation(location: ChatLocation): void {
|
|
307
|
+
if (location.topicId && ! location.roomId) {
|
|
308
|
+
throw new Error('Corrupted arguments hierarchy');
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
private handleSession(ev: Session): void {
|
|
313
|
+
this.overwrites.deleteAll();
|
|
314
|
+
this.overwritesPromises.forgetAll();
|
|
315
|
+
}
|
|
309
316
|
}
|