@matrix-widget-toolkit/api 3.2.0 → 3.2.2

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.
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var matrixWidgetApi = require('matrix-widget-api');
4
- var qs = require('qs');
5
4
  var rxjs = require('rxjs');
5
+ var qs = require('qs');
6
6
 
7
7
  /*
8
8
  * Copyright 2022 Nordeck IT + Consulting GmbH
@@ -19,112 +19,92 @@ var rxjs = require('rxjs');
19
19
  * See the License for the specific language governing permissions and
20
20
  * limitations under the License.
21
21
  */
22
+ var __assign$1 = (undefined && undefined.__assign) || function () {
23
+ __assign$1 = Object.assign || function(t) {
24
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
25
+ s = arguments[i];
26
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
27
+ t[p] = s[p];
28
+ }
29
+ return t;
30
+ };
31
+ return __assign$1.apply(this, arguments);
32
+ };
22
33
  /**
23
- * Generate a list of capabilities to access the timeline of other rooms.
24
- * If enabled, all previously or future capabilities will apply to _all_
25
- * selected rooms.
26
- * If `Symbols.AnyRoom` is passed, this is expanded to all joined
27
- * or invited rooms the client is able to see, current and future.
28
- *
29
- * @param roomIds - a list of room ids or `@link Symbols.AnyRoom`.
30
- * @returns the generated capabilities.
34
+ * Extract the parameters used to initialize the widget API from the current
35
+ * `window.location`.
36
+ * @returns The parameters required for initializing the widget API.
31
37
  */
32
- function generateRoomTimelineCapabilities(roomIds) {
33
- if (roomIds === matrixWidgetApi.Symbols.AnyRoom) {
34
- return ['org.matrix.msc2762.timeline:*'];
38
+ function extractWidgetApiParameters() {
39
+ var query = qs.parse(window.location.search, { ignoreQueryPrefix: true });
40
+ // If either parentUrl or widgetId is missing, we have no element context and
41
+ // want to inform the user that the widget only works inside of element.
42
+ if (typeof query.parentUrl !== 'string') {
43
+ throw Error('Missing parameter "parentUrl"');
35
44
  }
36
- if (Array.isArray(roomIds)) {
37
- return roomIds.map(function (id) { return "org.matrix.msc2762.timeline:".concat(id); });
45
+ var clientOrigin = new URL(query.parentUrl).origin;
46
+ if (typeof query.widgetId !== 'string') {
47
+ throw Error('Missing parameter "widgetId"');
38
48
  }
39
- return [];
49
+ var widgetId = query.widgetId;
50
+ return { widgetId: widgetId, clientOrigin: clientOrigin };
40
51
  }
41
-
42
- /*
43
- * Copyright 2022 Nordeck IT + Consulting GmbH
44
- *
45
- * Licensed under the Apache License, Version 2.0 (the "License");
46
- * you may not use this file except in compliance with the License.
47
- * You may obtain a copy of the License at
48
- *
49
- * http://www.apache.org/licenses/LICENSE-2.0
50
- *
51
- * Unless required by applicable law or agreed to in writing, software
52
- * distributed under the License is distributed on an "AS IS" BASIS,
53
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
54
- * See the License for the specific language governing permissions and
55
- * limitations under the License.
56
- */
57
52
  /**
58
- * Generate a unique displayname of a user that is consistent across Matrix clients.
59
- *
60
- * @remarks The algorithm is based on https://spec.matrix.org/v1.1/client-server-api/#calculating-the-display-name-for-a-user
61
- *
62
- * @param member - the member to generate a name for.
63
- * @param allRoomMembers - a list of all members of the same room.
64
- * @returns the displayname that is unique in given the set of all room members.
53
+ * Extract the widget parameters from the current `window.location`.
54
+ * @returns The all unprocessed raw widget parameters.
65
55
  */
66
- function getRoomMemberDisplayName(member, allRoomMembers) {
67
- if (allRoomMembers === void 0) { allRoomMembers = []; }
68
- // If the m.room.member state event has no displayname field, or if that field
69
- // has a null value, use the raw user id as the display name.
70
- if (typeof member.content.displayname !== 'string') {
71
- return member.state_key;
72
- }
73
- // If the m.room.member event has a displayname which is unique among members of
74
- // the room with membership: join or membership: invite, ...
75
- var hasDuplicateDisplayName = allRoomMembers.some(function (m) {
76
- // same room
77
- return m.room_id === member.room_id &&
78
- // not the own event
79
- m.state_key !== member.state_key &&
80
- // only join or invite state
81
- ['join', 'invite'].includes(m.content.membership) &&
82
- // same displayname
83
- m.content.displayname === member.content.displayname;
84
- });
85
- if (!hasDuplicateDisplayName) {
86
- // ... use the given displayname as the user-visible display name.
87
- return member.content.displayname;
88
- }
89
- else {
90
- // The m.room.member event has a non-unique displayname. This should be
91
- // disambiguated using the user id, for example “display name (@id:homeserver.org)”.
92
- return "".concat(member.content.displayname, " (").concat(member.state_key, ")");
93
- }
56
+ function extractRawWidgetParameters() {
57
+ var hash = window.location.hash.substring(window.location.hash.indexOf('?') + 1);
58
+ var params = __assign$1(__assign$1({}, qs.parse(window.location.search, { ignoreQueryPrefix: true })), qs.parse(hash));
59
+ return Object.fromEntries(Object.entries(params).filter(
60
+ // For now only use simple values, don't allow them to be specified more
61
+ // than once.
62
+ function (e) { return typeof e[1] === 'string'; }));
94
63
  }
95
-
96
- /*
97
- * Copyright 2022 Nordeck IT + Consulting GmbH
98
- *
99
- * Licensed under the Apache License, Version 2.0 (the "License");
100
- * you may not use this file except in compliance with the License.
101
- * You may obtain a copy of the License at
102
- *
103
- * http://www.apache.org/licenses/LICENSE-2.0
104
- *
105
- * Unless required by applicable law or agreed to in writing, software
106
- * distributed under the License is distributed on an "AS IS" BASIS,
107
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
108
- * See the License for the specific language governing permissions and
109
- * limitations under the License.
110
- */
111
64
  /**
112
- * Check if the given event is a {@link StateEvent}.
113
- *
114
- * @param event - An event that is either a {@link RoomEvent} or a {@link StateEvent}.
115
- * @returns True, if the event is a {@link StateEvent}.
65
+ * Extract the widget parameters from the current `window.location`.
66
+ * @returns The widget parameters.
116
67
  */
117
- function isStateEvent(event) {
118
- return 'state_key' in event && typeof event.state_key === 'string';
68
+ function extractWidgetParameters() {
69
+ var params = extractRawWidgetParameters();
70
+ // This is a hack to detect whether we are in a mobile client that supports widgets,
71
+ // but not the widget API. Mobile clients are not passing the parameters required for
72
+ // the widget API (like widgetId), but are passing the replaced placeholder values for
73
+ // the widget parameters.
74
+ var roomId = params['matrix_room_id'];
75
+ var isOpenedByClient = typeof roomId === 'string' && roomId !== '$matrix_room_id';
76
+ return {
77
+ userId: params['matrix_user_id'],
78
+ displayName: params['matrix_display_name'],
79
+ avatarUrl: params['matrix_avatar_url'],
80
+ roomId: roomId,
81
+ theme: params['theme'],
82
+ clientId: params['matrix_client_id'],
83
+ clientLanguage: params['matrix_client_language'],
84
+ isOpenedByClient: isOpenedByClient,
85
+ };
119
86
  }
120
87
  /**
121
- * Check if the given event is a {@link RoomEvent}.
122
- *
123
- * @param event - An event that is either a {@link RoomEvent} or a {@link StateEvent}.
124
- * @returns True, if the event is a {@link RoomEvent}.
88
+ * Parse a widget id into the individual fields.
89
+ * @param widgetId - The widget id to parse.
90
+ * @returns The individual fields encoded inside a widget id.
125
91
  */
126
- function isRoomEvent(event) {
127
- return !('state_key' in event);
92
+ function parseWidgetId(widgetId) {
93
+ // TODO: Is this whole parsing still working for user widgets?
94
+ var mainWidgetId = decodeURIComponent(widgetId).replace(/^modal_/, '');
95
+ var roomId = mainWidgetId.indexOf('_')
96
+ ? decodeURIComponent(mainWidgetId.split('_')[0])
97
+ : undefined;
98
+ var creator = (mainWidgetId.match(/_/g) || []).length > 1
99
+ ? decodeURIComponent(mainWidgetId.split('_')[1])
100
+ : undefined;
101
+ var isModal = decodeURIComponent(widgetId).startsWith('modal_');
102
+ return {
103
+ mainWidgetId: mainWidgetId,
104
+ roomId: roomId,
105
+ creator: creator,
106
+ isModal: isModal,
107
+ };
128
108
  }
129
109
 
130
110
  /*
@@ -142,6 +122,17 @@ function isRoomEvent(event) {
142
122
  * See the License for the specific language governing permissions and
143
123
  * limitations under the License.
144
124
  */
125
+ var __assign = (undefined && undefined.__assign) || function () {
126
+ __assign = Object.assign || function(t) {
127
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
128
+ s = arguments[i];
129
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
130
+ t[p] = s[p];
131
+ }
132
+ return t;
133
+ };
134
+ return __assign.apply(this, arguments);
135
+ };
145
136
  var __awaiter$3 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
146
137
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
147
138
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -157,7 +148,7 @@ var __generator$3 = (undefined && undefined.__generator) || function (thisArg, b
157
148
  function verb(n) { return function (v) { return step([n, v]); }; }
158
149
  function step(op) {
159
150
  if (f) throw new TypeError("Generator is already executing.");
160
- while (_) try {
151
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
161
152
  if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
162
153
  if (y = 0, t) op = [op[0] & 2, t.value];
163
154
  switch (op[0]) {
@@ -178,63 +169,124 @@ var __generator$3 = (undefined && undefined.__generator) || function (thisArg, b
178
169
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
179
170
  }
180
171
  };
172
+ var __rest = (undefined && undefined.__rest) || function (s, e) {
173
+ var t = {};
174
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
175
+ t[p] = s[p];
176
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
177
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
178
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
179
+ t[p[i]] = s[p[i]];
180
+ }
181
+ return t;
182
+ };
181
183
  /**
182
- * The capability that needs to be requested in order to navigate to another room.
183
- */
184
- var WIDGET_CAPABILITY_NAVIGATE = 'org.matrix.msc2931.navigate';
185
- /**
186
- * Navigate the client to another matrix room.
187
- *
188
- * @remarks This requires the {@link WIDGET_CAPABILITY_NAVIGATE} capability.
184
+ * Checks whether all widget parameters were provided to the widget.
189
185
  *
190
- * @param widgetApi - the {@link WidgetApi} instance.
191
- * @param roomId - the room ID.
192
- * @param opts - {@link NavigateToRoomOptions}
186
+ * @param widgetApi - The widget api to read the parameters from
187
+ * @returns True, if all parameters were provided.
193
188
  */
194
- function navigateToRoom(widgetApi, roomId, opts) {
195
- if (opts === void 0) { opts = {}; }
196
- return __awaiter$3(this, void 0, void 0, function () {
197
- var _a, via, params, url;
198
- return __generator$3(this, function (_b) {
199
- switch (_b.label) {
200
- case 0:
201
- _a = opts.via, via = _a === void 0 ? [] : _a;
202
- params = qs.stringify({ via: via }, { addQueryPrefix: true, arrayFormat: 'repeat' });
203
- url = "https://matrix.to/#/".concat(encodeURIComponent(roomId)).concat(params);
204
- return [4 /*yield*/, widgetApi.navigateTo(url)];
205
- case 1:
206
- _b.sent();
207
- return [2 /*return*/];
208
- }
209
- });
210
- });
189
+ function hasRequiredWidgetParameters(widgetApi) {
190
+ return (typeof widgetApi.widgetParameters.userId === 'string' &&
191
+ typeof widgetApi.widgetParameters.displayName === 'string' &&
192
+ typeof widgetApi.widgetParameters.avatarUrl === 'string' &&
193
+ typeof widgetApi.widgetParameters.roomId === 'string' &&
194
+ typeof widgetApi.widgetParameters.theme === 'string' &&
195
+ typeof widgetApi.widgetParameters.clientId === 'string' &&
196
+ typeof widgetApi.widgetParameters.clientLanguage === 'string');
211
197
  }
212
-
213
- /*
214
- * Copyright 2022 Nordeck IT + Consulting GmbH
215
- *
216
- * Licensed under the Apache License, Version 2.0 (the "License");
217
- * you may not use this file except in compliance with the License.
218
- * You may obtain a copy of the License at
219
- *
220
- * http://www.apache.org/licenses/LICENSE-2.0
221
- *
222
- * Unless required by applicable law or agreed to in writing, software
223
- * distributed under the License is distributed on an "AS IS" BASIS,
224
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
225
- * See the License for the specific language governing permissions and
226
- * limitations under the License.
227
- */
228
198
  /**
229
- * Compares two room events by their origin server timestamp.
230
- *
231
- * @param a - A room event
232
- * @param b - A room event
233
- * @returns Either zero if the timestamp is equal, \>0 if a is newer, or \<0 if
234
- * b is newer.
199
+ * Generate a registration URL for the widget based on the current URL and
200
+ * include all widget parameters (and their placeholders).
201
+ * @param options - Options for generating the URL.
202
+ * Use `pathName` to include an optional sub path in the URL.
203
+ * Use `includeParameters` to append the widget parameters to
204
+ * the URL, defaults to `true`.
205
+ * @returns The generated URL.
235
206
  */
236
- function compareOriginServerTS(a, b) {
237
- return a.origin_server_ts - b.origin_server_ts;
207
+ function generateWidgetRegistrationUrl(options) {
208
+ var _a, _b, _c, _d, _e, _f, _g;
209
+ if (options === void 0) { options = {}; }
210
+ var pathName = options.pathName, _h = options.includeParameters, includeParameters = _h === void 0 ? true : _h, widgetParameters = options.widgetParameters;
211
+ // don't forward widgetId and parentUrl as they will be generated by the client
212
+ var _j = extractRawWidgetParameters(); _j.widgetId; _j.parentUrl; var rawWidgetParameters = __rest(_j, ["widgetId", "parentUrl"]);
213
+ var parameters = Object.entries(__assign(__assign({}, rawWidgetParameters), { theme: (_a = widgetParameters === null || widgetParameters === void 0 ? void 0 : widgetParameters.theme) !== null && _a !== void 0 ? _a : '$org.matrix.msc2873.client_theme', matrix_user_id: (_b = widgetParameters === null || widgetParameters === void 0 ? void 0 : widgetParameters.userId) !== null && _b !== void 0 ? _b : '$matrix_user_id', matrix_display_name: (_c = widgetParameters === null || widgetParameters === void 0 ? void 0 : widgetParameters.displayName) !== null && _c !== void 0 ? _c : '$matrix_display_name', matrix_avatar_url: (_d = widgetParameters === null || widgetParameters === void 0 ? void 0 : widgetParameters.avatarUrl) !== null && _d !== void 0 ? _d : '$matrix_avatar_url', matrix_room_id: (_e = widgetParameters === null || widgetParameters === void 0 ? void 0 : widgetParameters.roomId) !== null && _e !== void 0 ? _e : '$matrix_room_id', matrix_client_id: (_f = widgetParameters === null || widgetParameters === void 0 ? void 0 : widgetParameters.clientId) !== null && _f !== void 0 ? _f : '$org.matrix.msc2873.client_id', matrix_client_language: (_g = widgetParameters === null || widgetParameters === void 0 ? void 0 : widgetParameters.clientLanguage) !== null && _g !== void 0 ? _g : '$org.matrix.msc2873.client_language' }))
214
+ .map(function (_a) {
215
+ var k = _a[0], v = _a[1];
216
+ return "".concat(k, "=").concat(v);
217
+ })
218
+ .join('&');
219
+ var url = new URL(window.location.href);
220
+ if (pathName) {
221
+ url.pathname = pathName;
222
+ }
223
+ else {
224
+ // ensure trailing '/'
225
+ url.pathname = url.pathname.replace(/\/?$/, '/');
226
+ }
227
+ url.search = '';
228
+ url.hash = includeParameters ? "#/?".concat(parameters) : '';
229
+ return url.toString();
230
+ }
231
+ var STATE_EVENT_WIDGETS = 'im.vector.modular.widgets';
232
+ /**
233
+ * Repair/configure the registration of the current widget.
234
+ * This steps make sure to include all the required widget parameters in the
235
+ * URL. Support setting a widget name and additional parameters.
236
+ *
237
+ * @param widgetApi - The widget api of the current widget.
238
+ * @param registration - Optional configuration options for the widget
239
+ * registration, like the display name of the widget.
240
+ */
241
+ function repairWidgetRegistration(widgetApi, registration) {
242
+ if (registration === void 0) { registration = {}; }
243
+ return __awaiter$3(this, void 0, void 0, function () {
244
+ var readResult, url, name, type, data;
245
+ return __generator$3(this, function (_a) {
246
+ switch (_a.label) {
247
+ case 0: return [4 /*yield*/, widgetApi.requestCapabilities([
248
+ matrixWidgetApi.WidgetEventCapability.forStateEvent(matrixWidgetApi.EventDirection.Send, STATE_EVENT_WIDGETS, widgetApi.widgetId),
249
+ matrixWidgetApi.WidgetEventCapability.forStateEvent(matrixWidgetApi.EventDirection.Receive, STATE_EVENT_WIDGETS, widgetApi.widgetId),
250
+ ])];
251
+ case 1:
252
+ _a.sent();
253
+ return [4 /*yield*/, widgetApi.receiveSingleStateEvent(STATE_EVENT_WIDGETS, widgetApi.widgetId)];
254
+ case 2:
255
+ readResult = _a.sent();
256
+ if (!readResult) {
257
+ throw new Error("Error while repairing registration, can't find existing registration.");
258
+ }
259
+ url = generateWidgetRegistrationUrl();
260
+ name = registration.name &&
261
+ (!readResult.content.name ||
262
+ readResult.content.name === 'Custom Widget' ||
263
+ readResult.content.name === 'Custom')
264
+ ? registration.name
265
+ : readResult.content.name;
266
+ type = registration.type &&
267
+ (!readResult.content.type || readResult.content.type === 'm.custom')
268
+ ? registration.type
269
+ : readResult.content.type;
270
+ data = registration.data
271
+ ? __assign(__assign({}, readResult.content.data), registration.data) : readResult.content.data;
272
+ // This is a workaround because changing the widget config is breaking the
273
+ // widget API communication. However we need to fail in case the power level
274
+ // for this change is missing. As the error happens quite fast, we just wait
275
+ // a moment and then consider the operation as succeeded.
276
+ return [4 /*yield*/, Promise.race([
277
+ widgetApi.sendStateEvent(STATE_EVENT_WIDGETS, __assign(__assign({}, readResult.content), { url: url.toString(), name: name, type: type, data: data }), { stateKey: widgetApi.widgetId }),
278
+ new Promise(function (resolve) { return setTimeout(resolve, 1000); }),
279
+ ])];
280
+ case 3:
281
+ // This is a workaround because changing the widget config is breaking the
282
+ // widget API communication. However we need to fail in case the power level
283
+ // for this change is missing. As the error happens quite fast, we just wait
284
+ // a moment and then consider the operation as succeeded.
285
+ _a.sent();
286
+ return [2 /*return*/];
287
+ }
288
+ });
289
+ });
238
290
  }
239
291
 
240
292
  /*
@@ -252,192 +304,47 @@ function compareOriginServerTS(a, b) {
252
304
  * See the License for the specific language governing permissions and
253
305
  * limitations under the License.
254
306
  */
255
- /**
256
- * The name of the power levels state event.
257
- */
258
- var STATE_EVENT_POWER_LEVELS = 'm.room.power_levels';
259
- function isNumberOrUndefined(value) {
260
- return value === undefined || typeof value === 'number';
307
+ function convertToRawCapabilities(rawCapabilities) {
308
+ return rawCapabilities.map(function (c) { return (typeof c === 'string' ? c : c.raw); });
261
309
  }
262
- function isStringToNumberMapOrUndefined(value) {
263
- return (value === undefined ||
264
- (value !== null &&
265
- typeof value === 'object' &&
266
- Object.entries(value).every(function (_a) {
267
- var k = _a[0], v = _a[1];
268
- return typeof k === 'string' && typeof v === 'number';
269
- })));
310
+ function isDefined(arg) {
311
+ return arg !== null && arg !== undefined;
270
312
  }
271
- /**
272
- * Validates that `event` is has a valid structure for a
273
- * {@link PowerLevelsStateEvent}.
274
- * @param event - The event to validate.
275
- * @returns True, if the event is valid.
276
- */
277
- function isValidPowerLevelStateEvent(event) {
278
- if (event.type !== STATE_EVENT_POWER_LEVELS ||
279
- typeof event.content !== 'object') {
280
- return false;
281
- }
282
- var content = event.content;
283
- if (!isStringToNumberMapOrUndefined(content.events)) {
284
- return false;
285
- }
286
- if (!isNumberOrUndefined(content.state_default)) {
287
- return false;
288
- }
289
- if (!isNumberOrUndefined(content.events_default)) {
290
- return false;
291
- }
292
- if (!isStringToNumberMapOrUndefined(content.users)) {
293
- return false;
294
- }
295
- if (!isNumberOrUndefined(content.users_default)) {
296
- return false;
297
- }
298
- if (!isNumberOrUndefined(content.ban)) {
299
- return false;
300
- }
301
- if (!isNumberOrUndefined(content.invite)) {
302
- return false;
303
- }
304
- if (!isNumberOrUndefined(content.kick)) {
305
- return false;
306
- }
307
- if (!isNumberOrUndefined(content.redact)) {
308
- return false;
309
- }
310
- return true;
313
+ function unique(items) {
314
+ return Array.from(new Set(items));
311
315
  }
312
- /**
313
- * Check if a user has the power to send a specific room event.
314
- *
315
- * @param powerLevelStateEvent - the content of the `m.room.power_levels` event
316
- * @param userId - the id of the user
317
- * @param eventType - the type of room event
318
- * @returns if true, the user has the power
319
- */
320
- function hasRoomEventPower(powerLevelStateEvent, userId, eventType) {
321
- if (!powerLevelStateEvent) {
322
- // See https://github.com/matrix-org/matrix-spec/blob/203b9756f52adfc2a3b63d664f18cdbf9f8bf126/data/event-schemas/schema/m.room.power_levels.yaml#L36-L43
323
- return true;
324
- }
325
- var userLevel = calculateUserPowerLevel(powerLevelStateEvent, userId);
326
- var eventLevel = calculateRoomEventPowerLevel(powerLevelStateEvent, eventType);
327
- return userLevel >= eventLevel;
316
+ function subtractSet(as, bs) {
317
+ var result = new Set(as);
318
+ bs.forEach(function (v) { return result.delete(v); });
319
+ return result;
328
320
  }
329
- /**
330
- * Check if a user has the power to send a specific state event.
331
- *
332
- * @param powerLevelStateEvent - the content of the `m.room.power_levels` event
333
- * @param userId - the id of the user
334
- * @param eventType - the type of state event
335
- * @returns if true, the user has the power
336
- */
337
- function hasStateEventPower(powerLevelStateEvent, userId, eventType) {
338
- if (!powerLevelStateEvent) {
339
- // See https://github.com/matrix-org/matrix-spec/blob/203b9756f52adfc2a3b63d664f18cdbf9f8bf126/data/event-schemas/schema/m.room.power_levels.yaml#L36-L43
340
- return true;
321
+ function isInRoom(matrixEvent, currentRoomId, roomIds) {
322
+ if (!roomIds) {
323
+ return matrixEvent.room_id === currentRoomId;
341
324
  }
342
- var userLevel = calculateUserPowerLevel(powerLevelStateEvent, userId);
343
- var eventLevel = calculateStateEventPowerLevel(powerLevelStateEvent, eventType);
344
- return userLevel >= eventLevel;
345
- }
346
- /**
347
- * Check if a user has the power to perform a specific action.
348
- *
349
- * Supported actions:
350
- * * invite: Invite a new user into the room
351
- * * kick: Kick a user from the room
352
- * * ban: Ban a user from the room
353
- * * redact: Redact a message from another user
354
- *
355
- * @param powerLevelStateEvent - the content of the `m.room.power_levels` event
356
- * @param userId - the id of the user
357
- * @param action - the action
358
- * @returns if true, the user has the power
359
- */
360
- function hasActionPower(powerLevelStateEvent, userId, action) {
361
- if (!powerLevelStateEvent) {
362
- // See https://github.com/matrix-org/matrix-spec/blob/203b9756f52adfc2a3b63d664f18cdbf9f8bf126/data/event-schemas/schema/m.room.power_levels.yaml#L36-L43
325
+ if (typeof roomIds === 'string') {
326
+ if (roomIds !== matrixWidgetApi.Symbols.AnyRoom) {
327
+ throw Error("Unknown room id symbol: ".concat(roomIds));
328
+ }
363
329
  return true;
364
330
  }
365
- var userLevel = calculateUserPowerLevel(powerLevelStateEvent, userId);
366
- var eventLevel = calculateActionPowerLevel(powerLevelStateEvent, action);
367
- return userLevel >= eventLevel;
331
+ return roomIds.includes(matrixEvent.room_id);
368
332
  }
369
- /**
370
- * Calculate the power level of the user based on a `m.room.power_levels` event.
333
+
334
+ /*
335
+ * Copyright 2022 Nordeck IT + Consulting GmbH
371
336
  *
372
- * @param powerLevelStateEvent - the content of the `m.room.power_levels` event.
373
- * @param userId - the ID of the user.
374
- * @returns the power level of the user.
375
- */
376
- function calculateUserPowerLevel(powerLevelStateEvent, userId) {
377
- var _a, _b, _c;
378
- // See https://github.com/matrix-org/matrix-spec/blob/203b9756f52adfc2a3b63d664f18cdbf9f8bf126/data/event-schemas/schema/m.room.power_levels.yaml#L8-L12
379
- return ((_c = (_b = (userId ? (_a = powerLevelStateEvent.users) === null || _a === void 0 ? void 0 : _a[userId] : undefined)) !== null && _b !== void 0 ? _b : powerLevelStateEvent.users_default) !== null && _c !== void 0 ? _c : 0);
380
- }
381
- /**
382
- * Calculate the power level that a user needs send a specific room event.
337
+ * Licensed under the Apache License, Version 2.0 (the "License");
338
+ * you may not use this file except in compliance with the License.
339
+ * You may obtain a copy of the License at
383
340
  *
384
- * @param powerLevelStateEvent - the content of the `m.room.power_levels` event
385
- * @param eventType - the type of room event
386
- * @returns the power level that is needed
387
- */
388
- function calculateRoomEventPowerLevel(powerLevelStateEvent, eventType) {
389
- var _a, _b, _c;
390
- // See https://github.com/matrix-org/matrix-spec/blob/203b9756f52adfc2a3b63d664f18cdbf9f8bf126/data/event-schemas/schema/m.room.power_levels.yaml#L14-L19
391
- return ((_c = (_b = (_a = powerLevelStateEvent.events) === null || _a === void 0 ? void 0 : _a[eventType]) !== null && _b !== void 0 ? _b : powerLevelStateEvent.events_default) !== null && _c !== void 0 ? _c : 0);
392
- }
393
- /**
394
- * Calculate the power level that a user needs send a specific state event.
341
+ * http://www.apache.org/licenses/LICENSE-2.0
395
342
  *
396
- * @param powerLevelStateEvent - the content of the `m.room.power_levels` event
397
- * @param eventType - the type of state event
398
- * @returns the power level that is needed
399
- */
400
- function calculateStateEventPowerLevel(powerLevelStateEvent, eventType) {
401
- var _a, _b, _c;
402
- // See https://github.com/matrix-org/matrix-spec/blob/203b9756f52adfc2a3b63d664f18cdbf9f8bf126/data/event-schemas/schema/m.room.power_levels.yaml#L14-L19
403
- return ((_c = (_b = (_a = powerLevelStateEvent.events) === null || _a === void 0 ? void 0 : _a[eventType]) !== null && _b !== void 0 ? _b : powerLevelStateEvent.state_default) !== null && _c !== void 0 ? _c : 50);
404
- }
405
- /**
406
- * Calculate the power level that a user needs to perform an action.
407
- *
408
- * Supported actions:
409
- * * invite: Invite a new user into the room
410
- * * kick: Kick a user from the room
411
- * * ban: Ban a user from the room
412
- * * redact: Redact a message from another user
413
- *
414
- * @param powerLevelStateEvent - the content of the `m.room.power_levels` event
415
- * @param action - the action
416
- * @returns the power level that is needed
417
- */
418
- function calculateActionPowerLevel(powerLevelStateEvent, action) {
419
- var _a, _b;
420
- // See https://github.com/matrix-org/matrix-spec/blob/203b9756f52adfc2a3b63d664f18cdbf9f8bf126/data/event-schemas/schema/m.room.power_levels.yaml#L27-L32
421
- if (action === 'invite') {
422
- return (_a = powerLevelStateEvent === null || powerLevelStateEvent === void 0 ? void 0 : powerLevelStateEvent[action]) !== null && _a !== void 0 ? _a : 0;
423
- }
424
- return (_b = powerLevelStateEvent === null || powerLevelStateEvent === void 0 ? void 0 : powerLevelStateEvent[action]) !== null && _b !== void 0 ? _b : 50;
425
- }
426
-
427
- /*
428
- * Copyright 2022 Nordeck IT + Consulting GmbH
429
- *
430
- * Licensed under the Apache License, Version 2.0 (the "License");
431
- * you may not use this file except in compliance with the License.
432
- * You may obtain a copy of the License at
433
- *
434
- * http://www.apache.org/licenses/LICENSE-2.0
435
- *
436
- * Unless required by applicable law or agreed to in writing, software
437
- * distributed under the License is distributed on an "AS IS" BASIS,
438
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
439
- * See the License for the specific language governing permissions and
440
- * limitations under the License.
343
+ * Unless required by applicable law or agreed to in writing, software
344
+ * distributed under the License is distributed on an "AS IS" BASIS,
345
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
346
+ * See the License for the specific language governing permissions and
347
+ * limitations under the License.
441
348
  */
442
349
  var __awaiter$2 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
443
350
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -454,7 +361,7 @@ var __generator$2 = (undefined && undefined.__generator) || function (thisArg, b
454
361
  function verb(n) { return function (v) { return step([n, v]); }; }
455
362
  function step(op) {
456
363
  if (f) throw new TypeError("Generator is already executing.");
457
- while (_) try {
364
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
458
365
  if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
459
366
  if (y = 0, t) op = [op[0] & 2, t.value];
460
367
  switch (op[0]) {
@@ -475,704 +382,166 @@ var __generator$2 = (undefined && undefined.__generator) || function (thisArg, b
475
382
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
476
383
  }
477
384
  };
478
- /**
479
- * The name of the redaction room event.
480
- */
481
- var ROOM_EVENT_REDACTION = 'm.room.redaction';
482
- /**
483
- * Check whether the format of a redaction event is valid.
484
- * @param event - The event to check.
485
- * @returns True if the event format is valid, otherwise false.
486
- */
487
- function isValidRedactionEvent(event) {
488
- if (event.type === ROOM_EVENT_REDACTION &&
489
- typeof event.redacts === 'string') {
490
- return true;
491
- }
492
- return false;
493
- }
494
- /**
495
- * Redacts an event in the current room.
496
- * @param widgetApi - An instance of the widget API.
497
- * @param eventId - The id of the event to redact.
498
- * @returns The redaction event that was send to the room.
499
- */
500
- function redactEvent(widgetApi, eventId) {
501
- return __awaiter$2(this, void 0, void 0, function () {
502
- var result;
503
- return __generator$2(this, function (_a) {
504
- switch (_a.label) {
505
- case 0: return [4 /*yield*/, widgetApi.sendRoomEvent(ROOM_EVENT_REDACTION, { redacts: eventId })];
506
- case 1:
507
- result = _a.sent();
508
- // The redaction event is special and needs to be casted, as the widget
509
- // toolkit assumes that the content of an event is returned as we send it.
510
- // However for redactions the content is copied directly into the event to
511
- // make it available without decrypting the content.
512
- return [2 /*return*/, result];
513
- }
514
- });
515
- });
516
- }
517
- /**
518
- * Observes redaction events in the current room.
519
- * @param widgetApi - An instance of the widget API.
520
- * @returns An observable of validated redaction events.
521
- */
522
- function observeRedactionEvents(widgetApi) {
523
- return widgetApi
524
- .observeRoomEvents(ROOM_EVENT_REDACTION)
525
- .pipe(rxjs.filter(isValidRedactionEvent));
526
- }
527
-
528
- /*
529
- * Copyright 2022 Nordeck IT + Consulting GmbH
530
- *
531
- * Licensed under the Apache License, Version 2.0 (the "License");
532
- * you may not use this file except in compliance with the License.
533
- * You may obtain a copy of the License at
534
- *
535
- * http://www.apache.org/licenses/LICENSE-2.0
536
- *
537
- * Unless required by applicable law or agreed to in writing, software
538
- * distributed under the License is distributed on an "AS IS" BASIS,
539
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
540
- * See the License for the specific language governing permissions and
541
- * limitations under the License.
542
- */
543
- /**
544
- * Get the original event id, or the event id of the current event if it
545
- * doesn't relates to another event.
546
- * @param event - The room event.
547
- * @returns The event id of the original event, or the current event id.
548
- */
549
- function getOriginalEventId(event) {
550
- var _a, _b, _c;
551
- var newContentRelatesTo = event.content;
552
- if (((_a = newContentRelatesTo['m.relates_to']) === null || _a === void 0 ? void 0 : _a.rel_type) === 'm.replace') {
553
- return (_c = (_b = newContentRelatesTo['m.relates_to']) === null || _b === void 0 ? void 0 : _b.event_id) !== null && _c !== void 0 ? _c : event.event_id;
385
+ var __spreadArray = (undefined && undefined.__spreadArray) || function (to, from, pack) {
386
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
387
+ if (ar || !(i in from)) {
388
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
389
+ ar[i] = from[i];
390
+ }
554
391
  }
555
- return event.event_id;
556
- }
557
- /**
558
- * Get the content of the event, independent from whether it contains the
559
- * content directly or contains a "m.new_content" key.
560
- * @param event - The room event.
561
- * @returns Only the content of the room event.
562
- */
563
- function getContent(event) {
564
- var _a;
565
- var newContentRelatesTo = event.content;
566
- return (_a = newContentRelatesTo['m.new_content']) !== null && _a !== void 0 ? _a : event.content;
567
- }
392
+ return to.concat(ar || Array.prototype.slice.call(from));
393
+ };
568
394
  /**
569
- * Validates that `event` has a valid structure for a
570
- * {@link EventWithRelatesTo}.
571
- * @param event - The event to validate.
572
- * @returns True, if the event is valid.
573
- */
574
- function isValidEventWithRelatesTo(event) {
575
- if (!event.content || typeof event.content !== 'object') {
576
- return false;
577
- }
578
- var relatedEvent = event;
579
- if (!relatedEvent.content['m.relates_to'] ||
580
- typeof relatedEvent.content['m.relates_to'] !== 'object') {
581
- return false;
582
- }
583
- if (typeof relatedEvent.content['m.relates_to'].rel_type !== 'string' ||
584
- typeof relatedEvent.content['m.relates_to'].event_id !== 'string') {
585
- return false;
586
- }
587
- return true;
588
- }
589
-
590
- /*
591
- * Copyright 2022 Nordeck IT + Consulting GmbH
592
- *
593
- * Licensed under the Apache License, Version 2.0 (the "License");
594
- * you may not use this file except in compliance with the License.
595
- * You may obtain a copy of the License at
596
- *
597
- * http://www.apache.org/licenses/LICENSE-2.0
395
+ * Implementation of the API from the widget to the client.
598
396
  *
599
- * Unless required by applicable law or agreed to in writing, software
600
- * distributed under the License is distributed on an "AS IS" BASIS,
601
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
602
- * See the License for the specific language governing permissions and
603
- * limitations under the License.
604
- */
605
- /**
606
- * The name of the room member state event.
607
- */
608
- var STATE_EVENT_ROOM_MEMBER = 'm.room.member';
609
- function isStringUndefinedOrNull(value) {
610
- return value === undefined || value === null || typeof value === 'string';
611
- }
612
- /**
613
- * Validates that `event` is has a valid structure for a
614
- * {@link RoomMemberStateEventContent}.
615
- * @param event - The event to validate.
616
- * @returns True, if the event is valid.
397
+ * @remarks Widget API is specified here:
398
+ * https://docs.google.com/document/d/1uPF7XWY_dXTKVKV7jZQ2KmsI19wn9-kFRgQ1tFQP7wQ/edit#heading=h.9rn9lt6ctkgi
617
399
  */
618
- function isValidRoomMemberStateEvent(event) {
619
- if (event.type !== STATE_EVENT_ROOM_MEMBER ||
620
- typeof event.content !== 'object') {
621
- return false;
622
- }
623
- var content = event.content;
624
- if (typeof content.membership !== 'string') {
625
- return false;
626
- }
627
- if (!isStringUndefinedOrNull(content.displayname)) {
628
- return false;
629
- }
630
- // the avatar_url shouldn't be null, but some implementations
631
- // set it as a valid value
632
- if (!isStringUndefinedOrNull(content.avatar_url)) {
633
- return false;
400
+ var WidgetApiImpl = /** @class */ (function () {
401
+ function WidgetApiImpl(
402
+ /**
403
+ * Provide access to the underlying widget API from `matrix-widget-sdk`.
404
+ *
405
+ * @remarks Normally there is no need to use it, however if features are
406
+ * missing from `WidgetApi` it can be handy to work with the
407
+ * original API.
408
+ */
409
+ matrixWidgetApi$1,
410
+ /** {@inheritDoc WidgetApi.widgetId} */
411
+ widgetId,
412
+ /** {@inheritDoc WidgetApi.widgetParameters} */
413
+ widgetParameters, _a) {
414
+ var _this = this;
415
+ var _b = _a === void 0 ? {} : _a, _c = _b.capabilities, capabilities = _c === void 0 ? [] : _c, _d = _b.supportStandalone, supportStandalone = _d === void 0 ? false : _d;
416
+ this.matrixWidgetApi = matrixWidgetApi$1;
417
+ this.widgetId = widgetId;
418
+ this.widgetParameters = widgetParameters;
419
+ this.events$ = rxjs.fromEvent(this.matrixWidgetApi, "action:".concat(matrixWidgetApi.WidgetApiToWidgetAction.SendEvent), function (event) {
420
+ event.preventDefault();
421
+ try {
422
+ _this.matrixWidgetApi.transport.reply(event.detail, {});
423
+ }
424
+ catch (_) {
425
+ // Ignore errors while replying
426
+ }
427
+ return event;
428
+ }).pipe(rxjs.share());
429
+ this.toDeviceMessages$ = rxjs.fromEvent(this.matrixWidgetApi, 'action:send_to_device', function (event) {
430
+ event.preventDefault();
431
+ try {
432
+ matrixWidgetApi$1.transport.reply(event.detail, {});
433
+ }
434
+ catch (_) {
435
+ // Ignore errors while replying
436
+ }
437
+ return event;
438
+ }).pipe(rxjs.share());
439
+ this.initialCapabilities = __spreadArray(__spreadArray([], capabilities, true), (supportStandalone ? [] : [matrixWidgetApi.MatrixCapabilities.RequiresClient]), true);
634
440
  }
635
- return true;
636
- }
637
-
638
- /*
639
- * Copyright 2022 Nordeck IT + Consulting GmbH
640
- *
641
- * Licensed under the Apache License, Version 2.0 (the "License");
642
- * you may not use this file except in compliance with the License.
643
- * You may obtain a copy of the License at
644
- *
645
- * http://www.apache.org/licenses/LICENSE-2.0
646
- *
647
- * Unless required by applicable law or agreed to in writing, software
648
- * distributed under the License is distributed on an "AS IS" BASIS,
649
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
650
- * See the License for the specific language governing permissions and
651
- * limitations under the License.
652
- */
653
- var __assign$1 = (undefined && undefined.__assign) || function () {
654
- __assign$1 = Object.assign || function(t) {
655
- for (var s, i = 1, n = arguments.length; i < n; i++) {
656
- s = arguments[i];
657
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
658
- t[p] = s[p];
659
- }
660
- return t;
441
+ /**
442
+ * Initialize a new widget API instance and wait till it is ready.
443
+ * There should only be one instance of the widget API. The widget API should
444
+ * be created as early as possible when starting the application. This is
445
+ * required to match the timing of the API connection establishment with the
446
+ * client, especially in Safari. Therefore it is recommended to create it
447
+ * inside the entrypoint, before initializing rendering engines like react.
448
+ *
449
+ * @param param0 - {@link WidgetApiOptions}
450
+ *
451
+ * @returns A widget API instance ready to use.
452
+ */
453
+ WidgetApiImpl.create = function (_a) {
454
+ var _b = _a === void 0 ? {} : _a, _c = _b.capabilities, capabilities = _c === void 0 ? [] : _c, _d = _b.supportStandalone, supportStandalone = _d === void 0 ? false : _d;
455
+ return __awaiter$2(this, void 0, void 0, function () {
456
+ var _e, clientOrigin, widgetId, widgetParameters, matrixWidgetApi$1, widgetApi;
457
+ return __generator$2(this, function (_f) {
458
+ switch (_f.label) {
459
+ case 0:
460
+ _e = extractWidgetApiParameters(), clientOrigin = _e.clientOrigin, widgetId = _e.widgetId;
461
+ widgetParameters = extractWidgetParameters();
462
+ matrixWidgetApi$1 = new matrixWidgetApi.WidgetApi(widgetId, clientOrigin);
463
+ widgetApi = new WidgetApiImpl(matrixWidgetApi$1, widgetId, widgetParameters, { capabilities: capabilities, supportStandalone: supportStandalone });
464
+ return [4 /*yield*/, widgetApi.initialize()];
465
+ case 1:
466
+ _f.sent();
467
+ return [2 /*return*/, widgetApi];
468
+ }
469
+ });
470
+ });
661
471
  };
662
- return __assign$1.apply(this, arguments);
663
- };
664
- /**
665
- * Extract the parameters used to initialize the widget API from the current
666
- * `window.location`.
667
- * @returns The parameters required for initializing the widget API.
668
- */
669
- function extractWidgetApiParameters() {
670
- var query = qs.parse(window.location.search, { ignoreQueryPrefix: true });
671
- // If either parentUrl or widgetId is missing, we have no element context and
672
- // want to inform the user that the widget only works inside of element.
673
- if (typeof query.parentUrl !== 'string') {
674
- throw Error('Missing parameter "parentUrl"');
675
- }
676
- var clientOrigin = new URL(query.parentUrl).origin;
677
- if (typeof query.widgetId !== 'string') {
678
- throw Error('Missing parameter "widgetId"');
679
- }
680
- var widgetId = query.widgetId;
681
- return { widgetId: widgetId, clientOrigin: clientOrigin };
682
- }
683
- /**
684
- * Extract the widget parameters from the current `window.location`.
685
- * @returns The all unprocessed raw widget parameters.
686
- */
687
- function extractRawWidgetParameters() {
688
- var hash = window.location.hash.substring(window.location.hash.indexOf('?') + 1);
689
- var params = __assign$1(__assign$1({}, qs.parse(window.location.search, { ignoreQueryPrefix: true })), qs.parse(hash));
690
- return Object.fromEntries(Object.entries(params).filter(
691
- // For now only use simple values, don't allow them to be specified more
692
- // than once.
693
- function (e) { return typeof e[1] === 'string'; }));
694
- }
695
- /**
696
- * Extract the widget parameters from the current `window.location`.
697
- * @returns The widget parameters.
698
- */
699
- function extractWidgetParameters() {
700
- var params = extractRawWidgetParameters();
701
- // This is a hack to detect whether we are in a mobile client that supports widgets,
702
- // but not the widget API. Mobile clients are not passing the parameters required for
703
- // the widget API (like widgetId), but are passing the replaced placeholder values for
704
- // the widget parameters.
705
- var roomId = params['matrix_room_id'];
706
- var isOpenedByClient = typeof roomId === 'string' && roomId !== '$matrix_room_id';
707
- return {
708
- userId: params['matrix_user_id'],
709
- displayName: params['matrix_display_name'],
710
- avatarUrl: params['matrix_avatar_url'],
711
- roomId: roomId,
712
- theme: params['theme'],
713
- clientId: params['matrix_client_id'],
714
- clientLanguage: params['matrix_client_language'],
715
- isOpenedByClient: isOpenedByClient,
472
+ /**
473
+ * Initialize the widget API and wait till a connection with the client is
474
+ * fully established.
475
+ *
476
+ * Waits till the user has approved the initial set of capabilities. The
477
+ * method doesn't fail if the user doesn't approve all of them. It is
478
+ * required to check manually afterwards.
479
+ * In case of modal widgets it waits till the `widgetConfig` is received.
480
+ *
481
+ * @remarks Should only be called once during startup.
482
+ */
483
+ WidgetApiImpl.prototype.initialize = function () {
484
+ return __awaiter$2(this, void 0, void 0, function () {
485
+ var ready, isModal, configReady, rawCapabilities;
486
+ var _this = this;
487
+ return __generator$2(this, function (_a) {
488
+ switch (_a.label) {
489
+ case 0:
490
+ ready = new Promise(function (resolve) {
491
+ _this.matrixWidgetApi.once('ready', function () { return resolve(); });
492
+ });
493
+ isModal = parseWidgetId(this.widgetId).isModal;
494
+ configReady = isModal
495
+ ? (function () { return __awaiter$2(_this, void 0, void 0, function () {
496
+ var widgetConfig$, _a;
497
+ var _this = this;
498
+ return __generator$2(this, function (_b) {
499
+ switch (_b.label) {
500
+ case 0:
501
+ widgetConfig$ = rxjs.fromEvent(this.matrixWidgetApi, "action:".concat(matrixWidgetApi.WidgetApiToWidgetAction.WidgetConfig), function (ev) {
502
+ ev.preventDefault();
503
+ _this.matrixWidgetApi.transport.reply(ev.detail, {});
504
+ return ev.detail.data;
505
+ });
506
+ _a = this;
507
+ return [4 /*yield*/, rxjs.firstValueFrom(widgetConfig$)];
508
+ case 1:
509
+ _a.widgetConfig = _b.sent();
510
+ return [2 /*return*/];
511
+ }
512
+ });
513
+ }); })()
514
+ : undefined;
515
+ rawCapabilities = unique(convertToRawCapabilities(this.initialCapabilities));
516
+ this.matrixWidgetApi.requestCapabilities(rawCapabilities);
517
+ this.matrixWidgetApi.start();
518
+ return [4 /*yield*/, ready];
519
+ case 1:
520
+ _a.sent();
521
+ if (!configReady) return [3 /*break*/, 3];
522
+ return [4 /*yield*/, configReady];
523
+ case 2:
524
+ _a.sent();
525
+ _a.label = 3;
526
+ case 3: return [2 /*return*/];
527
+ }
528
+ });
529
+ });
716
530
  };
717
- }
718
- /**
719
- * Parse a widget id into the individual fields.
720
- * @param widgetId - The widget id to parse.
721
- * @returns The individual fields encoded inside a widget id.
722
- */
723
- function parseWidgetId(widgetId) {
724
- // TODO: Is this whole parsing still working for user widgets?
725
- var mainWidgetId = decodeURIComponent(widgetId).replace(/^modal_/, '');
726
- var roomId = mainWidgetId.indexOf('_')
727
- ? decodeURIComponent(mainWidgetId.split('_')[0])
728
- : undefined;
729
- var creator = (mainWidgetId.match(/_/g) || []).length > 1
730
- ? decodeURIComponent(mainWidgetId.split('_')[1])
731
- : undefined;
732
- var isModal = decodeURIComponent(widgetId).startsWith('modal_');
733
- return {
734
- mainWidgetId: mainWidgetId,
735
- roomId: roomId,
736
- creator: creator,
737
- isModal: isModal,
531
+ /** {@inheritDoc WidgetApi.getWidgetConfig} */
532
+ WidgetApiImpl.prototype.getWidgetConfig = function () {
533
+ return this.widgetConfig;
738
534
  };
739
- }
740
-
741
- /*
742
- * Copyright 2022 Nordeck IT + Consulting GmbH
743
- *
744
- * Licensed under the Apache License, Version 2.0 (the "License");
745
- * you may not use this file except in compliance with the License.
746
- * You may obtain a copy of the License at
747
- *
748
- * http://www.apache.org/licenses/LICENSE-2.0
749
- *
750
- * Unless required by applicable law or agreed to in writing, software
751
- * distributed under the License is distributed on an "AS IS" BASIS,
752
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
753
- * See the License for the specific language governing permissions and
754
- * limitations under the License.
755
- */
756
- var __assign = (undefined && undefined.__assign) || function () {
757
- __assign = Object.assign || function(t) {
758
- for (var s, i = 1, n = arguments.length; i < n; i++) {
759
- s = arguments[i];
760
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
761
- t[p] = s[p];
762
- }
763
- return t;
764
- };
765
- return __assign.apply(this, arguments);
766
- };
767
- var __awaiter$1 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
768
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
769
- return new (P || (P = Promise))(function (resolve, reject) {
770
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
771
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
772
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
773
- step((generator = generator.apply(thisArg, _arguments || [])).next());
774
- });
775
- };
776
- var __generator$1 = (undefined && undefined.__generator) || function (thisArg, body) {
777
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
778
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
779
- function verb(n) { return function (v) { return step([n, v]); }; }
780
- function step(op) {
781
- if (f) throw new TypeError("Generator is already executing.");
782
- while (_) try {
783
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
784
- if (y = 0, t) op = [op[0] & 2, t.value];
785
- switch (op[0]) {
786
- case 0: case 1: t = op; break;
787
- case 4: _.label++; return { value: op[1], done: false };
788
- case 5: _.label++; y = op[1]; op = [0]; continue;
789
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
790
- default:
791
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
792
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
793
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
794
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
795
- if (t[2]) _.ops.pop();
796
- _.trys.pop(); continue;
797
- }
798
- op = body.call(thisArg, _);
799
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
800
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
801
- }
802
- };
803
- var __rest = (undefined && undefined.__rest) || function (s, e) {
804
- var t = {};
805
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
806
- t[p] = s[p];
807
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
808
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
809
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
810
- t[p[i]] = s[p[i]];
811
- }
812
- return t;
813
- };
814
- /**
815
- * Checks whether all widget parameters were provided to the widget.
816
- *
817
- * @param widgetApi - The widget api to read the parameters from
818
- * @returns True, if all parameters were provided.
819
- */
820
- function hasRequiredWidgetParameters(widgetApi) {
821
- return (typeof widgetApi.widgetParameters.userId === 'string' &&
822
- typeof widgetApi.widgetParameters.displayName === 'string' &&
823
- typeof widgetApi.widgetParameters.avatarUrl === 'string' &&
824
- typeof widgetApi.widgetParameters.roomId === 'string' &&
825
- typeof widgetApi.widgetParameters.theme === 'string' &&
826
- typeof widgetApi.widgetParameters.clientId === 'string' &&
827
- typeof widgetApi.widgetParameters.clientLanguage === 'string');
828
- }
829
- /**
830
- * Generate a registration URL for the widget based on the current URL and
831
- * include all widget parameters (and their placeholders).
832
- * @param options - Options for generating the URL.
833
- * Use `pathName` to include an optional sub path in the URL.
834
- * Use `includeParameters` to append the widget parameters to
835
- * the URL, defaults to `true`.
836
- * @returns The generated URL.
837
- */
838
- function generateWidgetRegistrationUrl(options) {
839
- var _a, _b, _c, _d, _e, _f, _g;
840
- if (options === void 0) { options = {}; }
841
- var pathName = options.pathName, _h = options.includeParameters, includeParameters = _h === void 0 ? true : _h, widgetParameters = options.widgetParameters;
842
- // don't forward widgetId and parentUrl as they will be generated by the client
843
- var _j = extractRawWidgetParameters(); _j.widgetId; _j.parentUrl; var rawWidgetParameters = __rest(_j, ["widgetId", "parentUrl"]);
844
- var parameters = Object.entries(__assign(__assign({}, rawWidgetParameters), { theme: (_a = widgetParameters === null || widgetParameters === void 0 ? void 0 : widgetParameters.theme) !== null && _a !== void 0 ? _a : '$org.matrix.msc2873.client_theme', matrix_user_id: (_b = widgetParameters === null || widgetParameters === void 0 ? void 0 : widgetParameters.userId) !== null && _b !== void 0 ? _b : '$matrix_user_id', matrix_display_name: (_c = widgetParameters === null || widgetParameters === void 0 ? void 0 : widgetParameters.displayName) !== null && _c !== void 0 ? _c : '$matrix_display_name', matrix_avatar_url: (_d = widgetParameters === null || widgetParameters === void 0 ? void 0 : widgetParameters.avatarUrl) !== null && _d !== void 0 ? _d : '$matrix_avatar_url', matrix_room_id: (_e = widgetParameters === null || widgetParameters === void 0 ? void 0 : widgetParameters.roomId) !== null && _e !== void 0 ? _e : '$matrix_room_id', matrix_client_id: (_f = widgetParameters === null || widgetParameters === void 0 ? void 0 : widgetParameters.clientId) !== null && _f !== void 0 ? _f : '$org.matrix.msc2873.client_id', matrix_client_language: (_g = widgetParameters === null || widgetParameters === void 0 ? void 0 : widgetParameters.clientLanguage) !== null && _g !== void 0 ? _g : '$org.matrix.msc2873.client_language' }))
845
- .map(function (_a) {
846
- var k = _a[0], v = _a[1];
847
- return "".concat(k, "=").concat(v);
848
- })
849
- .join('&');
850
- var url = new URL(window.location.href);
851
- if (pathName) {
852
- url.pathname = pathName;
853
- }
854
- else {
855
- // ensure trailing '/'
856
- url.pathname = url.pathname.replace(/\/?$/, '/');
857
- }
858
- url.search = '';
859
- url.hash = includeParameters ? "#/?".concat(parameters) : '';
860
- return url.toString();
861
- }
862
- var STATE_EVENT_WIDGETS = 'im.vector.modular.widgets';
863
- /**
864
- * Repair/configure the registration of the current widget.
865
- * This steps make sure to include all the required widget parameters in the
866
- * URL. Support setting a widget name and additional parameters.
867
- *
868
- * @param widgetApi - The widget api of the current widget.
869
- * @param registration - Optional configuration options for the widget
870
- * registration, like the display name of the widget.
871
- */
872
- function repairWidgetRegistration(widgetApi, registration) {
873
- if (registration === void 0) { registration = {}; }
874
- return __awaiter$1(this, void 0, void 0, function () {
875
- var readResult, url, name, type, data;
876
- return __generator$1(this, function (_a) {
877
- switch (_a.label) {
878
- case 0: return [4 /*yield*/, widgetApi.requestCapabilities([
879
- matrixWidgetApi.WidgetEventCapability.forStateEvent(matrixWidgetApi.EventDirection.Send, STATE_EVENT_WIDGETS, widgetApi.widgetId),
880
- matrixWidgetApi.WidgetEventCapability.forStateEvent(matrixWidgetApi.EventDirection.Receive, STATE_EVENT_WIDGETS, widgetApi.widgetId),
881
- ])];
882
- case 1:
883
- _a.sent();
884
- return [4 /*yield*/, widgetApi.receiveSingleStateEvent(STATE_EVENT_WIDGETS, widgetApi.widgetId)];
885
- case 2:
886
- readResult = _a.sent();
887
- if (!readResult) {
888
- throw new Error("Error while repairing registration, can't find existing registration.");
889
- }
890
- url = generateWidgetRegistrationUrl();
891
- name = registration.name &&
892
- (!readResult.content.name ||
893
- readResult.content.name === 'Custom Widget' ||
894
- readResult.content.name === 'Custom')
895
- ? registration.name
896
- : readResult.content.name;
897
- type = registration.type &&
898
- (!readResult.content.type || readResult.content.type === 'm.custom')
899
- ? registration.type
900
- : readResult.content.type;
901
- data = registration.data
902
- ? __assign(__assign({}, readResult.content.data), registration.data) : readResult.content.data;
903
- // This is a workaround because changing the widget config is breaking the
904
- // widget API communication. However we need to fail in case the power level
905
- // for this change is missing. As the error happens quite fast, we just wait
906
- // a moment and then consider the operation as succeeded.
907
- return [4 /*yield*/, Promise.race([
908
- widgetApi.sendStateEvent(STATE_EVENT_WIDGETS, __assign(__assign({}, readResult.content), { url: url.toString(), name: name, type: type, data: data }), { stateKey: widgetApi.widgetId }),
909
- new Promise(function (resolve) { return setTimeout(resolve, 1000); }),
910
- ])];
911
- case 3:
912
- // This is a workaround because changing the widget config is breaking the
913
- // widget API communication. However we need to fail in case the power level
914
- // for this change is missing. As the error happens quite fast, we just wait
915
- // a moment and then consider the operation as succeeded.
916
- _a.sent();
917
- return [2 /*return*/];
918
- }
919
- });
920
- });
921
- }
922
-
923
- /*
924
- * Copyright 2022 Nordeck IT + Consulting GmbH
925
- *
926
- * Licensed under the Apache License, Version 2.0 (the "License");
927
- * you may not use this file except in compliance with the License.
928
- * You may obtain a copy of the License at
929
- *
930
- * http://www.apache.org/licenses/LICENSE-2.0
931
- *
932
- * Unless required by applicable law or agreed to in writing, software
933
- * distributed under the License is distributed on an "AS IS" BASIS,
934
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
935
- * See the License for the specific language governing permissions and
936
- * limitations under the License.
937
- */
938
- function convertToRawCapabilities(rawCapabilities) {
939
- return rawCapabilities.map(function (c) { return (typeof c === 'string' ? c : c.raw); });
940
- }
941
- function isDefined(arg) {
942
- return arg !== null && arg !== undefined;
943
- }
944
- function unique(items) {
945
- return Array.from(new Set(items));
946
- }
947
- function subtractSet(as, bs) {
948
- var result = new Set(as);
949
- bs.forEach(function (v) { return result.delete(v); });
950
- return result;
951
- }
952
- function isInRoom(matrixEvent, currentRoomId, roomIds) {
953
- if (!roomIds) {
954
- return matrixEvent.room_id === currentRoomId;
955
- }
956
- if (typeof roomIds === 'string') {
957
- if (roomIds !== matrixWidgetApi.Symbols.AnyRoom) {
958
- throw Error("Unknown room id symbol: ".concat(roomIds));
959
- }
960
- return true;
961
- }
962
- return roomIds.includes(matrixEvent.room_id);
963
- }
964
-
965
- /*
966
- * Copyright 2022 Nordeck IT + Consulting GmbH
967
- *
968
- * Licensed under the Apache License, Version 2.0 (the "License");
969
- * you may not use this file except in compliance with the License.
970
- * You may obtain a copy of the License at
971
- *
972
- * http://www.apache.org/licenses/LICENSE-2.0
973
- *
974
- * Unless required by applicable law or agreed to in writing, software
975
- * distributed under the License is distributed on an "AS IS" BASIS,
976
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
977
- * See the License for the specific language governing permissions and
978
- * limitations under the License.
979
- */
980
- var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
981
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
982
- return new (P || (P = Promise))(function (resolve, reject) {
983
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
984
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
985
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
986
- step((generator = generator.apply(thisArg, _arguments || [])).next());
987
- });
988
- };
989
- var __generator = (undefined && undefined.__generator) || function (thisArg, body) {
990
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
991
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
992
- function verb(n) { return function (v) { return step([n, v]); }; }
993
- function step(op) {
994
- if (f) throw new TypeError("Generator is already executing.");
995
- while (_) try {
996
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
997
- if (y = 0, t) op = [op[0] & 2, t.value];
998
- switch (op[0]) {
999
- case 0: case 1: t = op; break;
1000
- case 4: _.label++; return { value: op[1], done: false };
1001
- case 5: _.label++; y = op[1]; op = [0]; continue;
1002
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
1003
- default:
1004
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
1005
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
1006
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
1007
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
1008
- if (t[2]) _.ops.pop();
1009
- _.trys.pop(); continue;
1010
- }
1011
- op = body.call(thisArg, _);
1012
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
1013
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
1014
- }
1015
- };
1016
- var __spreadArray = (undefined && undefined.__spreadArray) || function (to, from, pack) {
1017
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
1018
- if (ar || !(i in from)) {
1019
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
1020
- ar[i] = from[i];
1021
- }
1022
- }
1023
- return to.concat(ar || Array.prototype.slice.call(from));
1024
- };
1025
- /**
1026
- * Implementation of the API from the widget to the client.
1027
- *
1028
- * @remarks Widget API is specified here:
1029
- * https://docs.google.com/document/d/1uPF7XWY_dXTKVKV7jZQ2KmsI19wn9-kFRgQ1tFQP7wQ/edit#heading=h.9rn9lt6ctkgi
1030
- */
1031
- var WidgetApiImpl = /** @class */ (function () {
1032
- function WidgetApiImpl(
1033
- /**
1034
- * Provide access to the underlying widget API from `matrix-widget-sdk`.
1035
- *
1036
- * @remarks Normally there is no need to use it, however if features are
1037
- * missing from `WidgetApi` it can be handy to work with the
1038
- * original API.
1039
- */
1040
- matrixWidgetApi$1,
1041
- /** {@inheritDoc WidgetApi.widgetId} */
1042
- widgetId,
1043
- /** {@inheritDoc WidgetApi.widgetParameters} */
1044
- widgetParameters, _a) {
1045
- var _b = _a === void 0 ? {} : _a, _c = _b.capabilities, capabilities = _c === void 0 ? [] : _c, _d = _b.supportStandalone, supportStandalone = _d === void 0 ? false : _d;
1046
- var _this = this;
1047
- this.matrixWidgetApi = matrixWidgetApi$1;
1048
- this.widgetId = widgetId;
1049
- this.widgetParameters = widgetParameters;
1050
- this.events$ = rxjs.fromEvent(this.matrixWidgetApi, "action:".concat(matrixWidgetApi.WidgetApiToWidgetAction.SendEvent), function (event) {
1051
- event.preventDefault();
1052
- try {
1053
- _this.matrixWidgetApi.transport.reply(event.detail, {});
1054
- }
1055
- catch (_) {
1056
- // Ignore errors while replying
1057
- }
1058
- return event;
1059
- }).pipe(rxjs.share());
1060
- this.toDeviceMessages$ = rxjs.fromEvent(this.matrixWidgetApi, 'action:send_to_device', function (event) {
1061
- event.preventDefault();
1062
- try {
1063
- matrixWidgetApi$1.transport.reply(event.detail, {});
1064
- }
1065
- catch (_) {
1066
- // Ignore errors while replying
1067
- }
1068
- return event;
1069
- }).pipe(rxjs.share());
1070
- this.initialCapabilities = __spreadArray(__spreadArray([], capabilities, true), (supportStandalone ? [] : [matrixWidgetApi.MatrixCapabilities.RequiresClient]), true);
1071
- }
1072
- /**
1073
- * Initialize a new widget API instance and wait till it is ready.
1074
- * There should only be one instance of the widget API. The widget API should
1075
- * be created as early as possible when starting the application. This is
1076
- * required to match the timing of the API connection establishment with the
1077
- * client, especially in Safari. Therefore it is recommended to create it
1078
- * inside the entrypoint, before initializing rendering engines like react.
1079
- *
1080
- * @param param0 - {@link WidgetApiOptions}
1081
- *
1082
- * @returns A widget API instance ready to use.
1083
- */
1084
- WidgetApiImpl.create = function (_a) {
1085
- var _b = _a === void 0 ? {} : _a, _c = _b.capabilities, capabilities = _c === void 0 ? [] : _c, _d = _b.supportStandalone, supportStandalone = _d === void 0 ? false : _d;
1086
- return __awaiter(this, void 0, void 0, function () {
1087
- var _e, clientOrigin, widgetId, widgetParameters, matrixWidgetApi$1, widgetApi;
1088
- return __generator(this, function (_f) {
1089
- switch (_f.label) {
1090
- case 0:
1091
- _e = extractWidgetApiParameters(), clientOrigin = _e.clientOrigin, widgetId = _e.widgetId;
1092
- widgetParameters = extractWidgetParameters();
1093
- matrixWidgetApi$1 = new matrixWidgetApi.WidgetApi(widgetId, clientOrigin);
1094
- widgetApi = new WidgetApiImpl(matrixWidgetApi$1, widgetId, widgetParameters, { capabilities: capabilities, supportStandalone: supportStandalone });
1095
- return [4 /*yield*/, widgetApi.initialize()];
1096
- case 1:
1097
- _f.sent();
1098
- return [2 /*return*/, widgetApi];
1099
- }
1100
- });
1101
- });
1102
- };
1103
- /**
1104
- * Initialize the widget API and wait till a connection with the client is
1105
- * fully established.
1106
- *
1107
- * Waits till the user has approved the initial set of capabilities. The
1108
- * method doesn't fail if the user doesn't approve all of them. It is
1109
- * required to check manually afterwards.
1110
- * In case of modal widgets it waits till the `widgetConfig` is received.
1111
- *
1112
- * @remarks Should only be called once during startup.
1113
- */
1114
- WidgetApiImpl.prototype.initialize = function () {
1115
- return __awaiter(this, void 0, void 0, function () {
1116
- var ready, isModal, configReady, rawCapabilities;
1117
- var _this = this;
1118
- return __generator(this, function (_a) {
1119
- switch (_a.label) {
1120
- case 0:
1121
- ready = new Promise(function (resolve) {
1122
- _this.matrixWidgetApi.once('ready', function () { return resolve(); });
1123
- });
1124
- isModal = parseWidgetId(this.widgetId).isModal;
1125
- configReady = isModal
1126
- ? (function () { return __awaiter(_this, void 0, void 0, function () {
1127
- var widgetConfig$, _a;
1128
- var _this = this;
1129
- return __generator(this, function (_b) {
1130
- switch (_b.label) {
1131
- case 0:
1132
- widgetConfig$ = rxjs.fromEvent(this.matrixWidgetApi, "action:".concat(matrixWidgetApi.WidgetApiToWidgetAction.WidgetConfig), function (ev) {
1133
- ev.preventDefault();
1134
- _this.matrixWidgetApi.transport.reply(ev.detail, {});
1135
- return ev.detail.data;
1136
- });
1137
- _a = this;
1138
- return [4 /*yield*/, rxjs.firstValueFrom(widgetConfig$)];
1139
- case 1:
1140
- _a.widgetConfig = _b.sent();
1141
- return [2 /*return*/];
1142
- }
1143
- });
1144
- }); })()
1145
- : undefined;
1146
- rawCapabilities = unique(convertToRawCapabilities(this.initialCapabilities));
1147
- this.matrixWidgetApi.requestCapabilities(rawCapabilities);
1148
- this.matrixWidgetApi.start();
1149
- return [4 /*yield*/, ready];
1150
- case 1:
1151
- _a.sent();
1152
- if (!configReady) return [3 /*break*/, 3];
1153
- return [4 /*yield*/, configReady];
1154
- case 2:
1155
- _a.sent();
1156
- _a.label = 3;
1157
- case 3: return [2 /*return*/];
1158
- }
1159
- });
1160
- });
1161
- };
1162
- /** {@inheritDoc WidgetApi.getWidgetConfig} */
1163
- WidgetApiImpl.prototype.getWidgetConfig = function () {
1164
- return this.widgetConfig;
1165
- };
1166
- /** {@inheritDoc WidgetApi.rerequestInitialCapabilities} */
1167
- WidgetApiImpl.prototype.rerequestInitialCapabilities = function () {
1168
- return __awaiter(this, void 0, void 0, function () {
1169
- return __generator(this, function (_a) {
1170
- switch (_a.label) {
1171
- case 0: return [4 /*yield*/, this.requestCapabilities(this.initialCapabilities)];
1172
- case 1: return [2 /*return*/, _a.sent()];
1173
- }
1174
- });
1175
- });
535
+ /** {@inheritDoc WidgetApi.rerequestInitialCapabilities} */
536
+ WidgetApiImpl.prototype.rerequestInitialCapabilities = function () {
537
+ return __awaiter$2(this, void 0, void 0, function () {
538
+ return __generator$2(this, function (_a) {
539
+ switch (_a.label) {
540
+ case 0: return [4 /*yield*/, this.requestCapabilities(this.initialCapabilities)];
541
+ case 1: return [2 /*return*/, _a.sent()];
542
+ }
543
+ });
544
+ });
1176
545
  };
1177
546
  /** {@inheritDoc WidgetApi.hasInitialCapabilities} */
1178
547
  WidgetApiImpl.prototype.hasInitialCapabilities = function () {
@@ -1180,8 +549,8 @@ var WidgetApiImpl = /** @class */ (function () {
1180
549
  };
1181
550
  /** {@inheritDoc WidgetApi.requestCapabilities} */
1182
551
  WidgetApiImpl.prototype.requestCapabilities = function (capabilities) {
1183
- return __awaiter(this, void 0, void 0, function () {
1184
- return __generator(this, function (_b) {
552
+ return __awaiter$2(this, void 0, void 0, function () {
553
+ return __generator$2(this, function (_b) {
1185
554
  switch (_b.label) {
1186
555
  case 0:
1187
556
  if (!this.outstandingCapabilitiesRequest) return [3 /*break*/, 4];
@@ -1212,10 +581,10 @@ var WidgetApiImpl = /** @class */ (function () {
1212
581
  });
1213
582
  };
1214
583
  WidgetApiImpl.prototype.requestCapabilitiesInternal = function (capabilities) {
1215
- return __awaiter(this, void 0, void 0, function () {
584
+ return __awaiter$2(this, void 0, void 0, function () {
1216
585
  var rawCapabilities, requestedSet, capabilities$;
1217
586
  var _this = this;
1218
- return __generator(this, function (_a) {
587
+ return __generator$2(this, function (_a) {
1219
588
  switch (_a.label) {
1220
589
  case 0:
1221
590
  rawCapabilities = unique(convertToRawCapabilities(capabilities));
@@ -1242,9 +611,9 @@ var WidgetApiImpl = /** @class */ (function () {
1242
611
  throw new Error("Capabilities rejected: ".concat(Array.from(missingSet).join(', ')));
1243
612
  }
1244
613
  }), rxjs.first());
1245
- return [4 /*yield*/, new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
614
+ return [4 /*yield*/, new Promise(function (resolve, reject) { return __awaiter$2(_this, void 0, void 0, function () {
1246
615
  var subscription, err_1;
1247
- return __generator(this, function (_a) {
616
+ return __generator$2(this, function (_a) {
1248
617
  switch (_a.label) {
1249
618
  case 0:
1250
619
  subscription = capabilities$.subscribe({
@@ -1284,9 +653,9 @@ var WidgetApiImpl = /** @class */ (function () {
1284
653
  /** {@inheritDoc WidgetApi.receiveSingleStateEvent} */
1285
654
  WidgetApiImpl.prototype.receiveSingleStateEvent = function (eventType, stateKey) {
1286
655
  if (stateKey === void 0) { stateKey = ''; }
1287
- return __awaiter(this, void 0, void 0, function () {
656
+ return __awaiter$2(this, void 0, void 0, function () {
1288
657
  var events;
1289
- return __generator(this, function (_a) {
658
+ return __generator$2(this, function (_a) {
1290
659
  switch (_a.label) {
1291
660
  case 0: return [4 /*yield*/, this.receiveStateEvents(eventType, { stateKey: stateKey })];
1292
661
  case 1:
@@ -1299,8 +668,8 @@ var WidgetApiImpl = /** @class */ (function () {
1299
668
  /** {@inheritDoc WidgetApi.receiveStateEvents} */
1300
669
  WidgetApiImpl.prototype.receiveStateEvents = function (eventType, _a) {
1301
670
  var _b = _a === void 0 ? {} : _a, stateKey = _b.stateKey, roomIds = _b.roomIds;
1302
- return __awaiter(this, void 0, void 0, function () {
1303
- return __generator(this, function (_c) {
671
+ return __awaiter$2(this, void 0, void 0, function () {
672
+ return __generator$2(this, function (_c) {
1304
673
  switch (_c.label) {
1305
674
  case 0: return [4 /*yield*/, this.matrixWidgetApi.readStateEvents(eventType, Number.MAX_SAFE_INTEGER, stateKey, typeof roomIds === 'string' ? [matrixWidgetApi.Symbols.AnyRoom] : roomIds)];
1306
675
  case 1: return [2 /*return*/, (_c.sent())];
@@ -1331,9 +700,9 @@ var WidgetApiImpl = /** @class */ (function () {
1331
700
  /** {@inheritDoc WidgetApi.sendStateEvent} */
1332
701
  WidgetApiImpl.prototype.sendStateEvent = function (eventType, content, _a) {
1333
702
  var _b = _a === void 0 ? {} : _a, roomId = _b.roomId, _c = _b.stateKey, stateKey = _c === void 0 ? '' : _c;
1334
- return __awaiter(this, void 0, void 0, function () {
703
+ return __awaiter$2(this, void 0, void 0, function () {
1335
704
  var subject, subscription, _d, event_id_1, room_id_1, event_1;
1336
- return __generator(this, function (_e) {
705
+ return __generator$2(this, function (_e) {
1337
706
  switch (_e.label) {
1338
707
  case 0:
1339
708
  subject = new rxjs.ReplaySubject();
@@ -1363,8 +732,8 @@ var WidgetApiImpl = /** @class */ (function () {
1363
732
  /** {@inheritDoc WidgetApi.receiveRoomEvents} */
1364
733
  WidgetApiImpl.prototype.receiveRoomEvents = function (eventType, _a) {
1365
734
  var _b = _a === void 0 ? {} : _a, messageType = _b.messageType, roomIds = _b.roomIds;
1366
- return __awaiter(this, void 0, void 0, function () {
1367
- return __generator(this, function (_c) {
735
+ return __awaiter$2(this, void 0, void 0, function () {
736
+ return __generator$2(this, function (_c) {
1368
737
  switch (_c.label) {
1369
738
  case 0: return [4 /*yield*/, this.matrixWidgetApi.readRoomEvents(eventType, Number.MAX_SAFE_INTEGER, messageType, typeof roomIds === 'string' ? [matrixWidgetApi.Symbols.AnyRoom] : roomIds)];
1370
739
  case 1: return [2 /*return*/, (_c.sent())];
@@ -1395,9 +764,9 @@ var WidgetApiImpl = /** @class */ (function () {
1395
764
  /** {@inheritDoc WidgetApi.sendRoomEvent} */
1396
765
  WidgetApiImpl.prototype.sendRoomEvent = function (eventType, content, _a) {
1397
766
  var _b = _a === void 0 ? {} : _a, roomId = _b.roomId;
1398
- return __awaiter(this, void 0, void 0, function () {
767
+ return __awaiter$2(this, void 0, void 0, function () {
1399
768
  var subject, subscription, _c, event_id_2, room_id_2, event_2;
1400
- return __generator(this, function (_d) {
769
+ return __generator$2(this, function (_d) {
1401
770
  switch (_d.label) {
1402
771
  case 0:
1403
772
  subject = new rxjs.ReplaySubject();
@@ -1426,9 +795,9 @@ var WidgetApiImpl = /** @class */ (function () {
1426
795
  };
1427
796
  /** {@inheritDoc WidgetApi.readEventRelations} */
1428
797
  WidgetApiImpl.prototype.readEventRelations = function (eventId, options) {
1429
- return __awaiter(this, void 0, void 0, function () {
798
+ return __awaiter$2(this, void 0, void 0, function () {
1430
799
  var _a, chunk, next_batch;
1431
- return __generator(this, function (_b) {
800
+ return __generator$2(this, function (_b) {
1432
801
  switch (_b.label) {
1433
802
  case 0: return [4 /*yield*/, this.matrixWidgetApi.readEventRelations(eventId, options === null || options === void 0 ? void 0 : options.roomId, options === null || options === void 0 ? void 0 : options.relationType, options === null || options === void 0 ? void 0 : options.eventType, options === null || options === void 0 ? void 0 : options.limit, options === null || options === void 0 ? void 0 : options.from, undefined, options === null || options === void 0 ? void 0 : options.direction)];
1434
803
  case 1:
@@ -1443,8 +812,8 @@ var WidgetApiImpl = /** @class */ (function () {
1443
812
  };
1444
813
  /** {@inheritDoc WidgetApi.sendToDeviceMessage} */
1445
814
  WidgetApiImpl.prototype.sendToDeviceMessage = function (eventType, encrypted, content) {
1446
- return __awaiter(this, void 0, void 0, function () {
1447
- return __generator(this, function (_a) {
815
+ return __awaiter$2(this, void 0, void 0, function () {
816
+ return __generator$2(this, function (_a) {
1448
817
  switch (_a.label) {
1449
818
  case 0: return [4 /*yield*/, this.matrixWidgetApi.sendToDevice(eventType, encrypted, content)];
1450
819
  case 1:
@@ -1460,10 +829,10 @@ var WidgetApiImpl = /** @class */ (function () {
1460
829
  };
1461
830
  /** {@inheritDoc WidgetApi.openModal} */
1462
831
  WidgetApiImpl.prototype.openModal = function (pathName, name, options) {
1463
- return __awaiter(this, void 0, void 0, function () {
832
+ return __awaiter$2(this, void 0, void 0, function () {
1464
833
  var isModal, url, closeModalWidget$;
1465
834
  var _this = this;
1466
- return __generator(this, function (_a) {
835
+ return __generator$2(this, function (_a) {
1467
836
  switch (_a.label) {
1468
837
  case 0:
1469
838
  isModal = parseWidgetId(this.widgetId).isModal;
@@ -1493,9 +862,9 @@ var WidgetApiImpl = /** @class */ (function () {
1493
862
  };
1494
863
  /** {@inheritDoc WidgetApi.setModalButtonEnabled} */
1495
864
  WidgetApiImpl.prototype.setModalButtonEnabled = function (buttonId, isEnabled) {
1496
- return __awaiter(this, void 0, void 0, function () {
865
+ return __awaiter$2(this, void 0, void 0, function () {
1497
866
  var isModal;
1498
- return __generator(this, function (_a) {
867
+ return __generator$2(this, function (_a) {
1499
868
  switch (_a.label) {
1500
869
  case 0:
1501
870
  isModal = parseWidgetId(this.widgetId).isModal;
@@ -1525,9 +894,9 @@ var WidgetApiImpl = /** @class */ (function () {
1525
894
  };
1526
895
  /** {@inheritDoc WidgetApi.closeModal} */
1527
896
  WidgetApiImpl.prototype.closeModal = function (data) {
1528
- return __awaiter(this, void 0, void 0, function () {
897
+ return __awaiter$2(this, void 0, void 0, function () {
1529
898
  var isModal;
1530
- return __generator(this, function (_a) {
899
+ return __generator$2(this, function (_a) {
1531
900
  switch (_a.label) {
1532
901
  case 0:
1533
902
  isModal = parseWidgetId(this.widgetId).isModal;
@@ -1544,8 +913,8 @@ var WidgetApiImpl = /** @class */ (function () {
1544
913
  };
1545
914
  /** {@inheritdoc WidgetApi.navigateTo} */
1546
915
  WidgetApiImpl.prototype.navigateTo = function (uri) {
1547
- return __awaiter(this, void 0, void 0, function () {
1548
- return __generator(this, function (_a) {
916
+ return __awaiter$2(this, void 0, void 0, function () {
917
+ return __generator$2(this, function (_a) {
1549
918
  switch (_a.label) {
1550
919
  case 0: return [4 /*yield*/, this.matrixWidgetApi.navigateTo(uri)];
1551
920
  case 1:
@@ -1557,8 +926,8 @@ var WidgetApiImpl = /** @class */ (function () {
1557
926
  };
1558
927
  /** {@inheritdoc WidgetApi.requestOpenIDConnectToken} */
1559
928
  WidgetApiImpl.prototype.requestOpenIDConnectToken = function () {
1560
- return __awaiter(this, void 0, void 0, function () {
1561
- return __generator(this, function (_b) {
929
+ return __awaiter$2(this, void 0, void 0, function () {
930
+ return __generator$2(this, function (_b) {
1562
931
  switch (_b.label) {
1563
932
  case 0:
1564
933
  if (!this.outstandingOpenIDConnectTokenRequest) return [3 /*break*/, 4];
@@ -1588,9 +957,9 @@ var WidgetApiImpl = /** @class */ (function () {
1588
957
  };
1589
958
  WidgetApiImpl.prototype.requestOpenIDConnectTokenInternal = function () {
1590
959
  var _a;
1591
- return __awaiter(this, void 0, void 0, function () {
960
+ return __awaiter$2(this, void 0, void 0, function () {
1592
961
  var leywayMilliseconds, openIdToken, err_2;
1593
- return __generator(this, function (_b) {
962
+ return __generator$2(this, function (_b) {
1594
963
  switch (_b.label) {
1595
964
  case 0:
1596
965
  leywayMilliseconds = 30 * 1000;
@@ -1617,46 +986,677 @@ var WidgetApiImpl = /** @class */ (function () {
1617
986
  }
1618
987
  });
1619
988
  });
1620
- };
1621
- /** {@inheritdoc WidgetApi.observeTurnServers} */
1622
- WidgetApiImpl.prototype.observeTurnServers = function () {
1623
- return rxjs.from(this.matrixWidgetApi.getTurnServers()).pipe(
1624
- // For some reason a different naming was chosen for the API, but
1625
- // we already convert them to the right type for WebRTC consumers.
1626
- rxjs.map(function (_a) {
1627
- var uris = _a.uris, username = _a.username, password = _a.password;
1628
- return ({
1629
- urls: uris,
1630
- username: username,
1631
- credential: password,
1632
- });
1633
- }));
1634
- };
1635
- /** {@inheritdoc WidgetApi.searchUserDirectory} */
1636
- WidgetApiImpl.prototype.searchUserDirectory = function (searchTerm, options) {
1637
- return __awaiter(this, void 0, void 0, function () {
1638
- var results;
1639
- return __generator(this, function (_a) {
1640
- switch (_a.label) {
1641
- case 0: return [4 /*yield*/, this.matrixWidgetApi.searchUserDirectory(searchTerm, options === null || options === void 0 ? void 0 : options.limit)];
1642
- case 1:
1643
- results = (_a.sent()).results;
1644
- return [2 /*return*/, {
1645
- results: results.map(function (_a) {
1646
- var user_id = _a.user_id, display_name = _a.display_name, avatar_url = _a.avatar_url;
1647
- return ({
1648
- userId: user_id,
1649
- displayName: display_name,
1650
- avatarUrl: avatar_url,
1651
- });
1652
- }),
1653
- }];
1654
- }
1655
- });
989
+ };
990
+ /** {@inheritdoc WidgetApi.observeTurnServers} */
991
+ WidgetApiImpl.prototype.observeTurnServers = function () {
992
+ return rxjs.from(this.matrixWidgetApi.getTurnServers()).pipe(
993
+ // For some reason a different naming was chosen for the API, but
994
+ // we already convert them to the right type for WebRTC consumers.
995
+ rxjs.map(function (_a) {
996
+ var uris = _a.uris, username = _a.username, password = _a.password;
997
+ return ({
998
+ urls: uris,
999
+ username: username,
1000
+ credential: password,
1001
+ });
1002
+ }));
1003
+ };
1004
+ /** {@inheritdoc WidgetApi.searchUserDirectory} */
1005
+ WidgetApiImpl.prototype.searchUserDirectory = function (searchTerm, options) {
1006
+ return __awaiter$2(this, void 0, void 0, function () {
1007
+ var results;
1008
+ return __generator$2(this, function (_a) {
1009
+ switch (_a.label) {
1010
+ case 0: return [4 /*yield*/, this.matrixWidgetApi.searchUserDirectory(searchTerm, options === null || options === void 0 ? void 0 : options.limit)];
1011
+ case 1:
1012
+ results = (_a.sent()).results;
1013
+ return [2 /*return*/, {
1014
+ results: results.map(function (_a) {
1015
+ var user_id = _a.user_id, display_name = _a.display_name, avatar_url = _a.avatar_url;
1016
+ return ({
1017
+ userId: user_id,
1018
+ displayName: display_name,
1019
+ avatarUrl: avatar_url,
1020
+ });
1021
+ }),
1022
+ }];
1023
+ }
1024
+ });
1025
+ });
1026
+ };
1027
+ return WidgetApiImpl;
1028
+ }());
1029
+
1030
+ /*
1031
+ * Copyright 2022 Nordeck IT + Consulting GmbH
1032
+ *
1033
+ * Licensed under the Apache License, Version 2.0 (the "License");
1034
+ * you may not use this file except in compliance with the License.
1035
+ * You may obtain a copy of the License at
1036
+ *
1037
+ * http://www.apache.org/licenses/LICENSE-2.0
1038
+ *
1039
+ * Unless required by applicable law or agreed to in writing, software
1040
+ * distributed under the License is distributed on an "AS IS" BASIS,
1041
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1042
+ * See the License for the specific language governing permissions and
1043
+ * limitations under the License.
1044
+ */
1045
+ /**
1046
+ * Generate a list of capabilities to access the timeline of other rooms.
1047
+ * If enabled, all previously or future capabilities will apply to _all_
1048
+ * selected rooms.
1049
+ * If `Symbols.AnyRoom` is passed, this is expanded to all joined
1050
+ * or invited rooms the client is able to see, current and future.
1051
+ *
1052
+ * @param roomIds - a list of room ids or `@link Symbols.AnyRoom`.
1053
+ * @returns the generated capabilities.
1054
+ */
1055
+ function generateRoomTimelineCapabilities(roomIds) {
1056
+ if (roomIds === matrixWidgetApi.Symbols.AnyRoom) {
1057
+ return ['org.matrix.msc2762.timeline:*'];
1058
+ }
1059
+ if (Array.isArray(roomIds)) {
1060
+ return roomIds.map(function (id) { return "org.matrix.msc2762.timeline:".concat(id); });
1061
+ }
1062
+ return [];
1063
+ }
1064
+
1065
+ /*
1066
+ * Copyright 2022 Nordeck IT + Consulting GmbH
1067
+ *
1068
+ * Licensed under the Apache License, Version 2.0 (the "License");
1069
+ * you may not use this file except in compliance with the License.
1070
+ * You may obtain a copy of the License at
1071
+ *
1072
+ * http://www.apache.org/licenses/LICENSE-2.0
1073
+ *
1074
+ * Unless required by applicable law or agreed to in writing, software
1075
+ * distributed under the License is distributed on an "AS IS" BASIS,
1076
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1077
+ * See the License for the specific language governing permissions and
1078
+ * limitations under the License.
1079
+ */
1080
+ /**
1081
+ * Generate a unique displayname of a user that is consistent across Matrix clients.
1082
+ *
1083
+ * @remarks The algorithm is based on https://spec.matrix.org/v1.1/client-server-api/#calculating-the-display-name-for-a-user
1084
+ *
1085
+ * @param member - the member to generate a name for.
1086
+ * @param allRoomMembers - a list of all members of the same room.
1087
+ * @returns the displayname that is unique in given the set of all room members.
1088
+ */
1089
+ function getRoomMemberDisplayName(member, allRoomMembers) {
1090
+ if (allRoomMembers === void 0) { allRoomMembers = []; }
1091
+ // If the m.room.member state event has no displayname field, or if that field
1092
+ // has a null value, use the raw user id as the display name.
1093
+ if (typeof member.content.displayname !== 'string') {
1094
+ return member.state_key;
1095
+ }
1096
+ // If the m.room.member event has a displayname which is unique among members of
1097
+ // the room with membership: join or membership: invite, ...
1098
+ var hasDuplicateDisplayName = allRoomMembers.some(function (m) {
1099
+ // same room
1100
+ return m.room_id === member.room_id &&
1101
+ // not the own event
1102
+ m.state_key !== member.state_key &&
1103
+ // only join or invite state
1104
+ ['join', 'invite'].includes(m.content.membership) &&
1105
+ // same displayname
1106
+ m.content.displayname === member.content.displayname;
1107
+ });
1108
+ if (!hasDuplicateDisplayName) {
1109
+ // ... use the given displayname as the user-visible display name.
1110
+ return member.content.displayname;
1111
+ }
1112
+ else {
1113
+ // The m.room.member event has a non-unique displayname. This should be
1114
+ // disambiguated using the user id, for example “display name (@id:homeserver.org)”.
1115
+ return "".concat(member.content.displayname, " (").concat(member.state_key, ")");
1116
+ }
1117
+ }
1118
+
1119
+ /*
1120
+ * Copyright 2022 Nordeck IT + Consulting GmbH
1121
+ *
1122
+ * Licensed under the Apache License, Version 2.0 (the "License");
1123
+ * you may not use this file except in compliance with the License.
1124
+ * You may obtain a copy of the License at
1125
+ *
1126
+ * http://www.apache.org/licenses/LICENSE-2.0
1127
+ *
1128
+ * Unless required by applicable law or agreed to in writing, software
1129
+ * distributed under the License is distributed on an "AS IS" BASIS,
1130
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1131
+ * See the License for the specific language governing permissions and
1132
+ * limitations under the License.
1133
+ */
1134
+ /**
1135
+ * Check if the given event is a {@link StateEvent}.
1136
+ *
1137
+ * @param event - An event that is either a {@link RoomEvent} or a {@link StateEvent}.
1138
+ * @returns True, if the event is a {@link StateEvent}.
1139
+ */
1140
+ function isStateEvent(event) {
1141
+ return 'state_key' in event && typeof event.state_key === 'string';
1142
+ }
1143
+ /**
1144
+ * Check if the given event is a {@link RoomEvent}.
1145
+ *
1146
+ * @param event - An event that is either a {@link RoomEvent} or a {@link StateEvent}.
1147
+ * @returns True, if the event is a {@link RoomEvent}.
1148
+ */
1149
+ function isRoomEvent(event) {
1150
+ return !('state_key' in event);
1151
+ }
1152
+
1153
+ /*
1154
+ * Copyright 2022 Nordeck IT + Consulting GmbH
1155
+ *
1156
+ * Licensed under the Apache License, Version 2.0 (the "License");
1157
+ * you may not use this file except in compliance with the License.
1158
+ * You may obtain a copy of the License at
1159
+ *
1160
+ * http://www.apache.org/licenses/LICENSE-2.0
1161
+ *
1162
+ * Unless required by applicable law or agreed to in writing, software
1163
+ * distributed under the License is distributed on an "AS IS" BASIS,
1164
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1165
+ * See the License for the specific language governing permissions and
1166
+ * limitations under the License.
1167
+ */
1168
+ var __awaiter$1 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
1169
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
1170
+ return new (P || (P = Promise))(function (resolve, reject) {
1171
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
1172
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
1173
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
1174
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
1175
+ });
1176
+ };
1177
+ var __generator$1 = (undefined && undefined.__generator) || function (thisArg, body) {
1178
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
1179
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
1180
+ function verb(n) { return function (v) { return step([n, v]); }; }
1181
+ function step(op) {
1182
+ if (f) throw new TypeError("Generator is already executing.");
1183
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
1184
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
1185
+ if (y = 0, t) op = [op[0] & 2, t.value];
1186
+ switch (op[0]) {
1187
+ case 0: case 1: t = op; break;
1188
+ case 4: _.label++; return { value: op[1], done: false };
1189
+ case 5: _.label++; y = op[1]; op = [0]; continue;
1190
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
1191
+ default:
1192
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
1193
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
1194
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
1195
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
1196
+ if (t[2]) _.ops.pop();
1197
+ _.trys.pop(); continue;
1198
+ }
1199
+ op = body.call(thisArg, _);
1200
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
1201
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
1202
+ }
1203
+ };
1204
+ /**
1205
+ * The capability that needs to be requested in order to navigate to another room.
1206
+ */
1207
+ var WIDGET_CAPABILITY_NAVIGATE = 'org.matrix.msc2931.navigate';
1208
+ /**
1209
+ * Navigate the client to another matrix room.
1210
+ *
1211
+ * @remarks This requires the {@link WIDGET_CAPABILITY_NAVIGATE} capability.
1212
+ *
1213
+ * @param widgetApi - the {@link WidgetApi} instance.
1214
+ * @param roomId - the room ID.
1215
+ * @param opts - {@link NavigateToRoomOptions}
1216
+ */
1217
+ function navigateToRoom(widgetApi, roomId, opts) {
1218
+ if (opts === void 0) { opts = {}; }
1219
+ return __awaiter$1(this, void 0, void 0, function () {
1220
+ var _a, via, params, url;
1221
+ return __generator$1(this, function (_b) {
1222
+ switch (_b.label) {
1223
+ case 0:
1224
+ _a = opts.via, via = _a === void 0 ? [] : _a;
1225
+ params = qs.stringify({ via: via }, { addQueryPrefix: true, arrayFormat: 'repeat' });
1226
+ url = "https://matrix.to/#/".concat(encodeURIComponent(roomId)).concat(params);
1227
+ return [4 /*yield*/, widgetApi.navigateTo(url)];
1228
+ case 1:
1229
+ _b.sent();
1230
+ return [2 /*return*/];
1231
+ }
1232
+ });
1233
+ });
1234
+ }
1235
+
1236
+ /*
1237
+ * Copyright 2022 Nordeck IT + Consulting GmbH
1238
+ *
1239
+ * Licensed under the Apache License, Version 2.0 (the "License");
1240
+ * you may not use this file except in compliance with the License.
1241
+ * You may obtain a copy of the License at
1242
+ *
1243
+ * http://www.apache.org/licenses/LICENSE-2.0
1244
+ *
1245
+ * Unless required by applicable law or agreed to in writing, software
1246
+ * distributed under the License is distributed on an "AS IS" BASIS,
1247
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1248
+ * See the License for the specific language governing permissions and
1249
+ * limitations under the License.
1250
+ */
1251
+ /**
1252
+ * Compares two room events by their origin server timestamp.
1253
+ *
1254
+ * @param a - A room event
1255
+ * @param b - A room event
1256
+ * @returns Either zero if the timestamp is equal, \>0 if a is newer, or \<0 if
1257
+ * b is newer.
1258
+ */
1259
+ function compareOriginServerTS(a, b) {
1260
+ return a.origin_server_ts - b.origin_server_ts;
1261
+ }
1262
+
1263
+ /*
1264
+ * Copyright 2022 Nordeck IT + Consulting GmbH
1265
+ *
1266
+ * Licensed under the Apache License, Version 2.0 (the "License");
1267
+ * you may not use this file except in compliance with the License.
1268
+ * You may obtain a copy of the License at
1269
+ *
1270
+ * http://www.apache.org/licenses/LICENSE-2.0
1271
+ *
1272
+ * Unless required by applicable law or agreed to in writing, software
1273
+ * distributed under the License is distributed on an "AS IS" BASIS,
1274
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1275
+ * See the License for the specific language governing permissions and
1276
+ * limitations under the License.
1277
+ */
1278
+ /**
1279
+ * The name of the power levels state event.
1280
+ */
1281
+ var STATE_EVENT_POWER_LEVELS = 'm.room.power_levels';
1282
+ function isNumberOrUndefined(value) {
1283
+ return value === undefined || typeof value === 'number';
1284
+ }
1285
+ function isStringToNumberMapOrUndefined(value) {
1286
+ return (value === undefined ||
1287
+ (value !== null &&
1288
+ typeof value === 'object' &&
1289
+ Object.entries(value).every(function (_a) {
1290
+ var k = _a[0], v = _a[1];
1291
+ return typeof k === 'string' && typeof v === 'number';
1292
+ })));
1293
+ }
1294
+ /**
1295
+ * Validates that `event` is has a valid structure for a
1296
+ * {@link PowerLevelsStateEvent}.
1297
+ * @param event - The event to validate.
1298
+ * @returns True, if the event is valid.
1299
+ */
1300
+ function isValidPowerLevelStateEvent(event) {
1301
+ if (event.type !== STATE_EVENT_POWER_LEVELS ||
1302
+ typeof event.content !== 'object') {
1303
+ return false;
1304
+ }
1305
+ var content = event.content;
1306
+ if (!isStringToNumberMapOrUndefined(content.events)) {
1307
+ return false;
1308
+ }
1309
+ if (!isNumberOrUndefined(content.state_default)) {
1310
+ return false;
1311
+ }
1312
+ if (!isNumberOrUndefined(content.events_default)) {
1313
+ return false;
1314
+ }
1315
+ if (!isStringToNumberMapOrUndefined(content.users)) {
1316
+ return false;
1317
+ }
1318
+ if (!isNumberOrUndefined(content.users_default)) {
1319
+ return false;
1320
+ }
1321
+ if (!isNumberOrUndefined(content.ban)) {
1322
+ return false;
1323
+ }
1324
+ if (!isNumberOrUndefined(content.invite)) {
1325
+ return false;
1326
+ }
1327
+ if (!isNumberOrUndefined(content.kick)) {
1328
+ return false;
1329
+ }
1330
+ if (!isNumberOrUndefined(content.redact)) {
1331
+ return false;
1332
+ }
1333
+ return true;
1334
+ }
1335
+ /**
1336
+ * Check if a user has the power to send a specific room event.
1337
+ *
1338
+ * @param powerLevelStateEvent - the content of the `m.room.power_levels` event
1339
+ * @param userId - the id of the user
1340
+ * @param eventType - the type of room event
1341
+ * @returns if true, the user has the power
1342
+ */
1343
+ function hasRoomEventPower(powerLevelStateEvent, userId, eventType) {
1344
+ if (!powerLevelStateEvent) {
1345
+ // See https://github.com/matrix-org/matrix-spec/blob/203b9756f52adfc2a3b63d664f18cdbf9f8bf126/data/event-schemas/schema/m.room.power_levels.yaml#L36-L43
1346
+ return true;
1347
+ }
1348
+ var userLevel = calculateUserPowerLevel(powerLevelStateEvent, userId);
1349
+ var eventLevel = calculateRoomEventPowerLevel(powerLevelStateEvent, eventType);
1350
+ return userLevel >= eventLevel;
1351
+ }
1352
+ /**
1353
+ * Check if a user has the power to send a specific state event.
1354
+ *
1355
+ * @param powerLevelStateEvent - the content of the `m.room.power_levels` event
1356
+ * @param userId - the id of the user
1357
+ * @param eventType - the type of state event
1358
+ * @returns if true, the user has the power
1359
+ */
1360
+ function hasStateEventPower(powerLevelStateEvent, userId, eventType) {
1361
+ if (!powerLevelStateEvent) {
1362
+ // See https://github.com/matrix-org/matrix-spec/blob/203b9756f52adfc2a3b63d664f18cdbf9f8bf126/data/event-schemas/schema/m.room.power_levels.yaml#L36-L43
1363
+ return true;
1364
+ }
1365
+ var userLevel = calculateUserPowerLevel(powerLevelStateEvent, userId);
1366
+ var eventLevel = calculateStateEventPowerLevel(powerLevelStateEvent, eventType);
1367
+ return userLevel >= eventLevel;
1368
+ }
1369
+ /**
1370
+ * Check if a user has the power to perform a specific action.
1371
+ *
1372
+ * Supported actions:
1373
+ * * invite: Invite a new user into the room
1374
+ * * kick: Kick a user from the room
1375
+ * * ban: Ban a user from the room
1376
+ * * redact: Redact a message from another user
1377
+ *
1378
+ * @param powerLevelStateEvent - the content of the `m.room.power_levels` event
1379
+ * @param userId - the id of the user
1380
+ * @param action - the action
1381
+ * @returns if true, the user has the power
1382
+ */
1383
+ function hasActionPower(powerLevelStateEvent, userId, action) {
1384
+ if (!powerLevelStateEvent) {
1385
+ // See https://github.com/matrix-org/matrix-spec/blob/203b9756f52adfc2a3b63d664f18cdbf9f8bf126/data/event-schemas/schema/m.room.power_levels.yaml#L36-L43
1386
+ return true;
1387
+ }
1388
+ var userLevel = calculateUserPowerLevel(powerLevelStateEvent, userId);
1389
+ var eventLevel = calculateActionPowerLevel(powerLevelStateEvent, action);
1390
+ return userLevel >= eventLevel;
1391
+ }
1392
+ /**
1393
+ * Calculate the power level of the user based on a `m.room.power_levels` event.
1394
+ *
1395
+ * @param powerLevelStateEvent - the content of the `m.room.power_levels` event.
1396
+ * @param userId - the ID of the user.
1397
+ * @returns the power level of the user.
1398
+ */
1399
+ function calculateUserPowerLevel(powerLevelStateEvent, userId) {
1400
+ var _a, _b, _c;
1401
+ // See https://github.com/matrix-org/matrix-spec/blob/203b9756f52adfc2a3b63d664f18cdbf9f8bf126/data/event-schemas/schema/m.room.power_levels.yaml#L8-L12
1402
+ return ((_c = (_b = (userId ? (_a = powerLevelStateEvent.users) === null || _a === void 0 ? void 0 : _a[userId] : undefined)) !== null && _b !== void 0 ? _b : powerLevelStateEvent.users_default) !== null && _c !== void 0 ? _c : 0);
1403
+ }
1404
+ /**
1405
+ * Calculate the power level that a user needs send a specific room event.
1406
+ *
1407
+ * @param powerLevelStateEvent - the content of the `m.room.power_levels` event
1408
+ * @param eventType - the type of room event
1409
+ * @returns the power level that is needed
1410
+ */
1411
+ function calculateRoomEventPowerLevel(powerLevelStateEvent, eventType) {
1412
+ var _a, _b, _c;
1413
+ // See https://github.com/matrix-org/matrix-spec/blob/203b9756f52adfc2a3b63d664f18cdbf9f8bf126/data/event-schemas/schema/m.room.power_levels.yaml#L14-L19
1414
+ return ((_c = (_b = (_a = powerLevelStateEvent.events) === null || _a === void 0 ? void 0 : _a[eventType]) !== null && _b !== void 0 ? _b : powerLevelStateEvent.events_default) !== null && _c !== void 0 ? _c : 0);
1415
+ }
1416
+ /**
1417
+ * Calculate the power level that a user needs send a specific state event.
1418
+ *
1419
+ * @param powerLevelStateEvent - the content of the `m.room.power_levels` event
1420
+ * @param eventType - the type of state event
1421
+ * @returns the power level that is needed
1422
+ */
1423
+ function calculateStateEventPowerLevel(powerLevelStateEvent, eventType) {
1424
+ var _a, _b, _c;
1425
+ // See https://github.com/matrix-org/matrix-spec/blob/203b9756f52adfc2a3b63d664f18cdbf9f8bf126/data/event-schemas/schema/m.room.power_levels.yaml#L14-L19
1426
+ return ((_c = (_b = (_a = powerLevelStateEvent.events) === null || _a === void 0 ? void 0 : _a[eventType]) !== null && _b !== void 0 ? _b : powerLevelStateEvent.state_default) !== null && _c !== void 0 ? _c : 50);
1427
+ }
1428
+ /**
1429
+ * Calculate the power level that a user needs to perform an action.
1430
+ *
1431
+ * Supported actions:
1432
+ * * invite: Invite a new user into the room
1433
+ * * kick: Kick a user from the room
1434
+ * * ban: Ban a user from the room
1435
+ * * redact: Redact a message from another user
1436
+ *
1437
+ * @param powerLevelStateEvent - the content of the `m.room.power_levels` event
1438
+ * @param action - the action
1439
+ * @returns the power level that is needed
1440
+ */
1441
+ function calculateActionPowerLevel(powerLevelStateEvent, action) {
1442
+ var _a, _b;
1443
+ // See https://github.com/matrix-org/matrix-spec/blob/203b9756f52adfc2a3b63d664f18cdbf9f8bf126/data/event-schemas/schema/m.room.power_levels.yaml#L27-L32
1444
+ if (action === 'invite') {
1445
+ return (_a = powerLevelStateEvent === null || powerLevelStateEvent === void 0 ? void 0 : powerLevelStateEvent[action]) !== null && _a !== void 0 ? _a : 0;
1446
+ }
1447
+ return (_b = powerLevelStateEvent === null || powerLevelStateEvent === void 0 ? void 0 : powerLevelStateEvent[action]) !== null && _b !== void 0 ? _b : 50;
1448
+ }
1449
+
1450
+ /*
1451
+ * Copyright 2022 Nordeck IT + Consulting GmbH
1452
+ *
1453
+ * Licensed under the Apache License, Version 2.0 (the "License");
1454
+ * you may not use this file except in compliance with the License.
1455
+ * You may obtain a copy of the License at
1456
+ *
1457
+ * http://www.apache.org/licenses/LICENSE-2.0
1458
+ *
1459
+ * Unless required by applicable law or agreed to in writing, software
1460
+ * distributed under the License is distributed on an "AS IS" BASIS,
1461
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1462
+ * See the License for the specific language governing permissions and
1463
+ * limitations under the License.
1464
+ */
1465
+ var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
1466
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
1467
+ return new (P || (P = Promise))(function (resolve, reject) {
1468
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
1469
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
1470
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
1471
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
1472
+ });
1473
+ };
1474
+ var __generator = (undefined && undefined.__generator) || function (thisArg, body) {
1475
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
1476
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
1477
+ function verb(n) { return function (v) { return step([n, v]); }; }
1478
+ function step(op) {
1479
+ if (f) throw new TypeError("Generator is already executing.");
1480
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
1481
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
1482
+ if (y = 0, t) op = [op[0] & 2, t.value];
1483
+ switch (op[0]) {
1484
+ case 0: case 1: t = op; break;
1485
+ case 4: _.label++; return { value: op[1], done: false };
1486
+ case 5: _.label++; y = op[1]; op = [0]; continue;
1487
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
1488
+ default:
1489
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
1490
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
1491
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
1492
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
1493
+ if (t[2]) _.ops.pop();
1494
+ _.trys.pop(); continue;
1495
+ }
1496
+ op = body.call(thisArg, _);
1497
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
1498
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
1499
+ }
1500
+ };
1501
+ /**
1502
+ * The name of the redaction room event.
1503
+ */
1504
+ var ROOM_EVENT_REDACTION = 'm.room.redaction';
1505
+ /**
1506
+ * Check whether the format of a redaction event is valid.
1507
+ * @param event - The event to check.
1508
+ * @returns True if the event format is valid, otherwise false.
1509
+ */
1510
+ function isValidRedactionEvent(event) {
1511
+ if (event.type === ROOM_EVENT_REDACTION &&
1512
+ typeof event.redacts === 'string') {
1513
+ return true;
1514
+ }
1515
+ return false;
1516
+ }
1517
+ /**
1518
+ * Redacts an event in the current room.
1519
+ * @param widgetApi - An instance of the widget API.
1520
+ * @param eventId - The id of the event to redact.
1521
+ * @returns The redaction event that was send to the room.
1522
+ */
1523
+ function redactEvent(widgetApi, eventId) {
1524
+ return __awaiter(this, void 0, void 0, function () {
1525
+ var result;
1526
+ return __generator(this, function (_a) {
1527
+ switch (_a.label) {
1528
+ case 0: return [4 /*yield*/, widgetApi.sendRoomEvent(ROOM_EVENT_REDACTION, { redacts: eventId })];
1529
+ case 1:
1530
+ result = _a.sent();
1531
+ // The redaction event is special and needs to be casted, as the widget
1532
+ // toolkit assumes that the content of an event is returned as we send it.
1533
+ // However for redactions the content is copied directly into the event to
1534
+ // make it available without decrypting the content.
1535
+ return [2 /*return*/, result];
1536
+ }
1656
1537
  });
1657
- };
1658
- return WidgetApiImpl;
1659
- }());
1538
+ });
1539
+ }
1540
+ /**
1541
+ * Observes redaction events in the current room.
1542
+ * @param widgetApi - An instance of the widget API.
1543
+ * @returns An observable of validated redaction events.
1544
+ */
1545
+ function observeRedactionEvents(widgetApi) {
1546
+ return widgetApi
1547
+ .observeRoomEvents(ROOM_EVENT_REDACTION)
1548
+ .pipe(rxjs.filter(isValidRedactionEvent));
1549
+ }
1550
+
1551
+ /*
1552
+ * Copyright 2022 Nordeck IT + Consulting GmbH
1553
+ *
1554
+ * Licensed under the Apache License, Version 2.0 (the "License");
1555
+ * you may not use this file except in compliance with the License.
1556
+ * You may obtain a copy of the License at
1557
+ *
1558
+ * http://www.apache.org/licenses/LICENSE-2.0
1559
+ *
1560
+ * Unless required by applicable law or agreed to in writing, software
1561
+ * distributed under the License is distributed on an "AS IS" BASIS,
1562
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1563
+ * See the License for the specific language governing permissions and
1564
+ * limitations under the License.
1565
+ */
1566
+ /**
1567
+ * Get the original event id, or the event id of the current event if it
1568
+ * doesn't relates to another event.
1569
+ * @param event - The room event.
1570
+ * @returns The event id of the original event, or the current event id.
1571
+ */
1572
+ function getOriginalEventId(event) {
1573
+ var _a, _b, _c;
1574
+ var newContentRelatesTo = event.content;
1575
+ if (((_a = newContentRelatesTo['m.relates_to']) === null || _a === void 0 ? void 0 : _a.rel_type) === 'm.replace') {
1576
+ return (_c = (_b = newContentRelatesTo['m.relates_to']) === null || _b === void 0 ? void 0 : _b.event_id) !== null && _c !== void 0 ? _c : event.event_id;
1577
+ }
1578
+ return event.event_id;
1579
+ }
1580
+ /**
1581
+ * Get the content of the event, independent from whether it contains the
1582
+ * content directly or contains a "m.new_content" key.
1583
+ * @param event - The room event.
1584
+ * @returns Only the content of the room event.
1585
+ */
1586
+ function getContent(event) {
1587
+ var _a;
1588
+ var newContentRelatesTo = event.content;
1589
+ return (_a = newContentRelatesTo['m.new_content']) !== null && _a !== void 0 ? _a : event.content;
1590
+ }
1591
+ /**
1592
+ * Validates that `event` has a valid structure for a
1593
+ * {@link EventWithRelatesTo}.
1594
+ * @param event - The event to validate.
1595
+ * @returns True, if the event is valid.
1596
+ */
1597
+ function isValidEventWithRelatesTo(event) {
1598
+ if (!event.content || typeof event.content !== 'object') {
1599
+ return false;
1600
+ }
1601
+ var relatedEvent = event;
1602
+ if (!relatedEvent.content['m.relates_to'] ||
1603
+ typeof relatedEvent.content['m.relates_to'] !== 'object') {
1604
+ return false;
1605
+ }
1606
+ if (typeof relatedEvent.content['m.relates_to'].rel_type !== 'string' ||
1607
+ typeof relatedEvent.content['m.relates_to'].event_id !== 'string') {
1608
+ return false;
1609
+ }
1610
+ return true;
1611
+ }
1612
+
1613
+ /*
1614
+ * Copyright 2022 Nordeck IT + Consulting GmbH
1615
+ *
1616
+ * Licensed under the Apache License, Version 2.0 (the "License");
1617
+ * you may not use this file except in compliance with the License.
1618
+ * You may obtain a copy of the License at
1619
+ *
1620
+ * http://www.apache.org/licenses/LICENSE-2.0
1621
+ *
1622
+ * Unless required by applicable law or agreed to in writing, software
1623
+ * distributed under the License is distributed on an "AS IS" BASIS,
1624
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1625
+ * See the License for the specific language governing permissions and
1626
+ * limitations under the License.
1627
+ */
1628
+ /**
1629
+ * The name of the room member state event.
1630
+ */
1631
+ var STATE_EVENT_ROOM_MEMBER = 'm.room.member';
1632
+ function isStringUndefinedOrNull(value) {
1633
+ return value === undefined || value === null || typeof value === 'string';
1634
+ }
1635
+ /**
1636
+ * Validates that `event` is has a valid structure for a
1637
+ * {@link RoomMemberStateEventContent}.
1638
+ * @param event - The event to validate.
1639
+ * @returns True, if the event is valid.
1640
+ */
1641
+ function isValidRoomMemberStateEvent(event) {
1642
+ if (event.type !== STATE_EVENT_ROOM_MEMBER ||
1643
+ typeof event.content !== 'object') {
1644
+ return false;
1645
+ }
1646
+ var content = event.content;
1647
+ if (typeof content.membership !== 'string') {
1648
+ return false;
1649
+ }
1650
+ if (!isStringUndefinedOrNull(content.displayname)) {
1651
+ return false;
1652
+ }
1653
+ // the avatar_url shouldn't be null, but some implementations
1654
+ // set it as a valid value
1655
+ if (!isStringUndefinedOrNull(content.avatar_url)) {
1656
+ return false;
1657
+ }
1658
+ return true;
1659
+ }
1660
1660
 
1661
1661
  exports.ROOM_EVENT_REDACTION = ROOM_EVENT_REDACTION;
1662
1662
  exports.STATE_EVENT_POWER_LEVELS = STATE_EVENT_POWER_LEVELS;