@unwanted/matrix-sdk-mini 34.12.0-1 → 34.12.0-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.
Files changed (185) hide show
  1. package/git-revision.txt +1 -1
  2. package/lib/@types/event.d.ts +0 -19
  3. package/lib/@types/event.d.ts.map +1 -1
  4. package/lib/@types/event.js.map +1 -1
  5. package/lib/client.d.ts +2 -50
  6. package/lib/client.d.ts.map +1 -1
  7. package/lib/client.js +391 -501
  8. package/lib/client.js.map +1 -1
  9. package/lib/embedded.d.ts.map +1 -1
  10. package/lib/embedded.js +0 -1
  11. package/lib/embedded.js.map +1 -1
  12. package/lib/matrix.d.ts +0 -6
  13. package/lib/matrix.d.ts.map +1 -1
  14. package/lib/matrix.js +1 -5
  15. package/lib/matrix.js.map +1 -1
  16. package/package.json +1 -1
  17. package/src/@types/event.ts +2 -36
  18. package/src/client.ts +1 -150
  19. package/src/embedded.ts +0 -2
  20. package/src/matrix.ts +0 -13
  21. package/lib/matrixrtc/CallMembership.d.ts +0 -66
  22. package/lib/matrixrtc/CallMembership.d.ts.map +0 -1
  23. package/lib/matrixrtc/CallMembership.js +0 -197
  24. package/lib/matrixrtc/CallMembership.js.map +0 -1
  25. package/lib/matrixrtc/LivekitFocus.d.ts +0 -16
  26. package/lib/matrixrtc/LivekitFocus.d.ts.map +0 -1
  27. package/lib/matrixrtc/LivekitFocus.js +0 -20
  28. package/lib/matrixrtc/LivekitFocus.js.map +0 -1
  29. package/lib/matrixrtc/MatrixRTCSession.d.ts +0 -295
  30. package/lib/matrixrtc/MatrixRTCSession.d.ts.map +0 -1
  31. package/lib/matrixrtc/MatrixRTCSession.js +0 -1043
  32. package/lib/matrixrtc/MatrixRTCSession.js.map +0 -1
  33. package/lib/matrixrtc/MatrixRTCSessionManager.d.ts +0 -40
  34. package/lib/matrixrtc/MatrixRTCSessionManager.d.ts.map +0 -1
  35. package/lib/matrixrtc/MatrixRTCSessionManager.js +0 -146
  36. package/lib/matrixrtc/MatrixRTCSessionManager.js.map +0 -1
  37. package/lib/matrixrtc/focus.d.ts +0 -10
  38. package/lib/matrixrtc/focus.d.ts.map +0 -1
  39. package/lib/matrixrtc/focus.js +0 -1
  40. package/lib/matrixrtc/focus.js.map +0 -1
  41. package/lib/matrixrtc/index.d.ts +0 -7
  42. package/lib/matrixrtc/index.d.ts.map +0 -1
  43. package/lib/matrixrtc/index.js +0 -21
  44. package/lib/matrixrtc/index.js.map +0 -1
  45. package/lib/matrixrtc/types.d.ts +0 -19
  46. package/lib/matrixrtc/types.d.ts.map +0 -1
  47. package/lib/matrixrtc/types.js +0 -1
  48. package/lib/matrixrtc/types.js.map +0 -1
  49. package/lib/webrtc/audioContext.d.ts +0 -15
  50. package/lib/webrtc/audioContext.d.ts.map +0 -1
  51. package/lib/webrtc/audioContext.js +0 -46
  52. package/lib/webrtc/audioContext.js.map +0 -1
  53. package/lib/webrtc/call.d.ts +0 -560
  54. package/lib/webrtc/call.d.ts.map +0 -1
  55. package/lib/webrtc/call.js +0 -2541
  56. package/lib/webrtc/call.js.map +0 -1
  57. package/lib/webrtc/callEventHandler.d.ts +0 -37
  58. package/lib/webrtc/callEventHandler.d.ts.map +0 -1
  59. package/lib/webrtc/callEventHandler.js +0 -344
  60. package/lib/webrtc/callEventHandler.js.map +0 -1
  61. package/lib/webrtc/callEventTypes.d.ts +0 -73
  62. package/lib/webrtc/callEventTypes.d.ts.map +0 -1
  63. package/lib/webrtc/callEventTypes.js +0 -13
  64. package/lib/webrtc/callEventTypes.js.map +0 -1
  65. package/lib/webrtc/callFeed.d.ts +0 -128
  66. package/lib/webrtc/callFeed.d.ts.map +0 -1
  67. package/lib/webrtc/callFeed.js +0 -289
  68. package/lib/webrtc/callFeed.js.map +0 -1
  69. package/lib/webrtc/groupCall.d.ts +0 -323
  70. package/lib/webrtc/groupCall.d.ts.map +0 -1
  71. package/lib/webrtc/groupCall.js +0 -1337
  72. package/lib/webrtc/groupCall.js.map +0 -1
  73. package/lib/webrtc/groupCallEventHandler.d.ts +0 -31
  74. package/lib/webrtc/groupCallEventHandler.d.ts.map +0 -1
  75. package/lib/webrtc/groupCallEventHandler.js +0 -178
  76. package/lib/webrtc/groupCallEventHandler.js.map +0 -1
  77. package/lib/webrtc/mediaHandler.d.ts +0 -89
  78. package/lib/webrtc/mediaHandler.d.ts.map +0 -1
  79. package/lib/webrtc/mediaHandler.js +0 -437
  80. package/lib/webrtc/mediaHandler.js.map +0 -1
  81. package/lib/webrtc/stats/callFeedStatsReporter.d.ts +0 -8
  82. package/lib/webrtc/stats/callFeedStatsReporter.d.ts.map +0 -1
  83. package/lib/webrtc/stats/callFeedStatsReporter.js +0 -82
  84. package/lib/webrtc/stats/callFeedStatsReporter.js.map +0 -1
  85. package/lib/webrtc/stats/callStatsReportGatherer.d.ts +0 -25
  86. package/lib/webrtc/stats/callStatsReportGatherer.d.ts.map +0 -1
  87. package/lib/webrtc/stats/callStatsReportGatherer.js +0 -199
  88. package/lib/webrtc/stats/callStatsReportGatherer.js.map +0 -1
  89. package/lib/webrtc/stats/callStatsReportSummary.d.ts +0 -17
  90. package/lib/webrtc/stats/callStatsReportSummary.d.ts.map +0 -1
  91. package/lib/webrtc/stats/callStatsReportSummary.js +0 -1
  92. package/lib/webrtc/stats/callStatsReportSummary.js.map +0 -1
  93. package/lib/webrtc/stats/connectionStats.d.ts +0 -28
  94. package/lib/webrtc/stats/connectionStats.d.ts.map +0 -1
  95. package/lib/webrtc/stats/connectionStats.js +0 -26
  96. package/lib/webrtc/stats/connectionStats.js.map +0 -1
  97. package/lib/webrtc/stats/connectionStatsBuilder.d.ts +0 -5
  98. package/lib/webrtc/stats/connectionStatsBuilder.d.ts.map +0 -1
  99. package/lib/webrtc/stats/connectionStatsBuilder.js +0 -27
  100. package/lib/webrtc/stats/connectionStatsBuilder.js.map +0 -1
  101. package/lib/webrtc/stats/connectionStatsReportBuilder.d.ts +0 -7
  102. package/lib/webrtc/stats/connectionStatsReportBuilder.d.ts.map +0 -1
  103. package/lib/webrtc/stats/connectionStatsReportBuilder.js +0 -121
  104. package/lib/webrtc/stats/connectionStatsReportBuilder.js.map +0 -1
  105. package/lib/webrtc/stats/groupCallStats.d.ts +0 -22
  106. package/lib/webrtc/stats/groupCallStats.d.ts.map +0 -1
  107. package/lib/webrtc/stats/groupCallStats.js +0 -78
  108. package/lib/webrtc/stats/groupCallStats.js.map +0 -1
  109. package/lib/webrtc/stats/media/mediaSsrcHandler.d.ts +0 -10
  110. package/lib/webrtc/stats/media/mediaSsrcHandler.d.ts.map +0 -1
  111. package/lib/webrtc/stats/media/mediaSsrcHandler.js +0 -57
  112. package/lib/webrtc/stats/media/mediaSsrcHandler.js.map +0 -1
  113. package/lib/webrtc/stats/media/mediaTrackHandler.d.ts +0 -12
  114. package/lib/webrtc/stats/media/mediaTrackHandler.d.ts.map +0 -1
  115. package/lib/webrtc/stats/media/mediaTrackHandler.js +0 -62
  116. package/lib/webrtc/stats/media/mediaTrackHandler.js.map +0 -1
  117. package/lib/webrtc/stats/media/mediaTrackStats.d.ts +0 -86
  118. package/lib/webrtc/stats/media/mediaTrackStats.d.ts.map +0 -1
  119. package/lib/webrtc/stats/media/mediaTrackStats.js +0 -142
  120. package/lib/webrtc/stats/media/mediaTrackStats.js.map +0 -1
  121. package/lib/webrtc/stats/media/mediaTrackStatsHandler.d.ts +0 -22
  122. package/lib/webrtc/stats/media/mediaTrackStatsHandler.d.ts.map +0 -1
  123. package/lib/webrtc/stats/media/mediaTrackStatsHandler.js +0 -76
  124. package/lib/webrtc/stats/media/mediaTrackStatsHandler.js.map +0 -1
  125. package/lib/webrtc/stats/statsReport.d.ts +0 -99
  126. package/lib/webrtc/stats/statsReport.d.ts.map +0 -1
  127. package/lib/webrtc/stats/statsReport.js +0 -32
  128. package/lib/webrtc/stats/statsReport.js.map +0 -1
  129. package/lib/webrtc/stats/statsReportEmitter.d.ts +0 -15
  130. package/lib/webrtc/stats/statsReportEmitter.d.ts.map +0 -1
  131. package/lib/webrtc/stats/statsReportEmitter.js +0 -33
  132. package/lib/webrtc/stats/statsReportEmitter.js.map +0 -1
  133. package/lib/webrtc/stats/summaryStatsReportGatherer.d.ts +0 -16
  134. package/lib/webrtc/stats/summaryStatsReportGatherer.d.ts.map +0 -1
  135. package/lib/webrtc/stats/summaryStatsReportGatherer.js +0 -116
  136. package/lib/webrtc/stats/summaryStatsReportGatherer.js.map +0 -1
  137. package/lib/webrtc/stats/trackStatsBuilder.d.ts +0 -19
  138. package/lib/webrtc/stats/trackStatsBuilder.d.ts.map +0 -1
  139. package/lib/webrtc/stats/trackStatsBuilder.js +0 -168
  140. package/lib/webrtc/stats/trackStatsBuilder.js.map +0 -1
  141. package/lib/webrtc/stats/transportStats.d.ts +0 -11
  142. package/lib/webrtc/stats/transportStats.d.ts.map +0 -1
  143. package/lib/webrtc/stats/transportStats.js +0 -1
  144. package/lib/webrtc/stats/transportStats.js.map +0 -1
  145. package/lib/webrtc/stats/transportStatsBuilder.d.ts +0 -5
  146. package/lib/webrtc/stats/transportStatsBuilder.d.ts.map +0 -1
  147. package/lib/webrtc/stats/transportStatsBuilder.js +0 -34
  148. package/lib/webrtc/stats/transportStatsBuilder.js.map +0 -1
  149. package/lib/webrtc/stats/valueFormatter.d.ts +0 -4
  150. package/lib/webrtc/stats/valueFormatter.d.ts.map +0 -1
  151. package/lib/webrtc/stats/valueFormatter.js +0 -25
  152. package/lib/webrtc/stats/valueFormatter.js.map +0 -1
  153. package/src/matrixrtc/CallMembership.ts +0 -247
  154. package/src/matrixrtc/LivekitFocus.ts +0 -39
  155. package/src/matrixrtc/MatrixRTCSession.ts +0 -1319
  156. package/src/matrixrtc/MatrixRTCSessionManager.ts +0 -166
  157. package/src/matrixrtc/focus.ts +0 -25
  158. package/src/matrixrtc/index.ts +0 -22
  159. package/src/matrixrtc/types.ts +0 -36
  160. package/src/webrtc/audioContext.ts +0 -44
  161. package/src/webrtc/call.ts +0 -3074
  162. package/src/webrtc/callEventHandler.ts +0 -425
  163. package/src/webrtc/callEventTypes.ts +0 -93
  164. package/src/webrtc/callFeed.ts +0 -364
  165. package/src/webrtc/groupCall.ts +0 -1735
  166. package/src/webrtc/groupCallEventHandler.ts +0 -234
  167. package/src/webrtc/mediaHandler.ts +0 -484
  168. package/src/webrtc/stats/callFeedStatsReporter.ts +0 -94
  169. package/src/webrtc/stats/callStatsReportGatherer.ts +0 -219
  170. package/src/webrtc/stats/callStatsReportSummary.ts +0 -30
  171. package/src/webrtc/stats/connectionStats.ts +0 -47
  172. package/src/webrtc/stats/connectionStatsBuilder.ts +0 -28
  173. package/src/webrtc/stats/connectionStatsReportBuilder.ts +0 -140
  174. package/src/webrtc/stats/groupCallStats.ts +0 -93
  175. package/src/webrtc/stats/media/mediaSsrcHandler.ts +0 -57
  176. package/src/webrtc/stats/media/mediaTrackHandler.ts +0 -76
  177. package/src/webrtc/stats/media/mediaTrackStats.ts +0 -176
  178. package/src/webrtc/stats/media/mediaTrackStatsHandler.ts +0 -90
  179. package/src/webrtc/stats/statsReport.ts +0 -133
  180. package/src/webrtc/stats/statsReportEmitter.ts +0 -49
  181. package/src/webrtc/stats/summaryStatsReportGatherer.ts +0 -148
  182. package/src/webrtc/stats/trackStatsBuilder.ts +0 -207
  183. package/src/webrtc/stats/transportStats.ts +0 -26
  184. package/src/webrtc/stats/transportStatsBuilder.ts +0 -48
  185. package/src/webrtc/stats/valueFormatter.ts +0 -27
@@ -1,1043 +0,0 @@
1
- import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
2
- import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
- function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
4
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
5
- /*
6
- Copyright 2023 - 2024 The Matrix.org Foundation C.I.C.
7
-
8
- Licensed under the Apache License, Version 2.0 (the "License");
9
- you may not use this file except in compliance with the License.
10
- You may obtain a copy of the License at
11
-
12
- http://www.apache.org/licenses/LICENSE-2.0
13
-
14
- Unless required by applicable law or agreed to in writing, software
15
- distributed under the License is distributed on an "AS IS" BASIS,
16
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
- See the License for the specific language governing permissions and
18
- limitations under the License.
19
- */
20
-
21
- import { logger as rootLogger } from "../logger.js";
22
- import { TypedEventEmitter } from "../models/typed-event-emitter.js";
23
- import { EventTimeline } from "../models/event-timeline.js";
24
- import { EventType } from "../@types/event.js";
25
- import { UpdateDelayedEventAction } from "../@types/requests.js";
26
- import { CallMembership, isLegacyCallMembershipData } from "./CallMembership.js";
27
- import { RoomStateEvent } from "../models/room-state.js";
28
- import { randomString, secureRandomBase64Url } from "../randomstring.js";
29
- import { decodeBase64, encodeUnpaddedBase64 } from "../base64.js";
30
- import { KnownMembership } from "../@types/membership.js";
31
- import { HTTPError, MatrixError, safeGetRetryAfterMs } from "../http-api/errors.js";
32
- import { isLivekitFocusActive } from "./LivekitFocus.js";
33
- import { sleep } from "../utils.js";
34
- var logger = rootLogger.getChild("MatrixRTCSession");
35
- var getParticipantId = (userId, deviceId) => "".concat(userId, ":").concat(deviceId);
36
- var getParticipantIdFromMembership = m => getParticipantId(m.sender, m.deviceId);
37
- function keysEqual(a, b) {
38
- if (a === b) return true;
39
- return !!a && !!b && a.length === b.length && a.every((x, i) => x === b[i]);
40
- }
41
- export var MatrixRTCSessionEvent = /*#__PURE__*/function (MatrixRTCSessionEvent) {
42
- MatrixRTCSessionEvent["MembershipsChanged"] = "memberships_changed";
43
- MatrixRTCSessionEvent["JoinStateChanged"] = "join_state_changed";
44
- MatrixRTCSessionEvent["EncryptionKeyChanged"] = "encryption_key_changed";
45
- return MatrixRTCSessionEvent;
46
- }({});
47
- /**
48
- * A MatrixRTCSession manages the membership & properties of a MatrixRTC session.
49
- * This class doesn't deal with media at all, just membership & properties of a session.
50
- */
51
- export class MatrixRTCSession extends TypedEventEmitter {
52
- get membershipExpiryTimeout() {
53
- var _this$joinConfig$memb, _this$joinConfig;
54
- return (_this$joinConfig$memb = (_this$joinConfig = this.joinConfig) === null || _this$joinConfig === void 0 ? void 0 : _this$joinConfig.membershipExpiryTimeout) !== null && _this$joinConfig$memb !== void 0 ? _this$joinConfig$memb : 60 * 60 * 1000;
55
- }
56
- get memberEventCheckPeriod() {
57
- var _this$joinConfig$memb2, _this$joinConfig2;
58
- return (_this$joinConfig$memb2 = (_this$joinConfig2 = this.joinConfig) === null || _this$joinConfig2 === void 0 ? void 0 : _this$joinConfig2.memberEventCheckPeriod) !== null && _this$joinConfig$memb2 !== void 0 ? _this$joinConfig$memb2 : 2 * 60 * 1000;
59
- }
60
- get callMemberEventRetryDelayMinimum() {
61
- var _this$joinConfig$call, _this$joinConfig3;
62
- return (_this$joinConfig$call = (_this$joinConfig3 = this.joinConfig) === null || _this$joinConfig3 === void 0 ? void 0 : _this$joinConfig3.callMemberEventRetryDelayMinimum) !== null && _this$joinConfig$call !== void 0 ? _this$joinConfig$call : 3000;
63
- }
64
- get updateEncryptionKeyThrottle() {
65
- var _this$joinConfig$upda, _this$joinConfig4;
66
- return (_this$joinConfig$upda = (_this$joinConfig4 = this.joinConfig) === null || _this$joinConfig4 === void 0 ? void 0 : _this$joinConfig4.updateEncryptionKeyThrottle) !== null && _this$joinConfig$upda !== void 0 ? _this$joinConfig$upda : 3000;
67
- }
68
- get makeKeyDelay() {
69
- var _this$joinConfig$make, _this$joinConfig5;
70
- return (_this$joinConfig$make = (_this$joinConfig5 = this.joinConfig) === null || _this$joinConfig5 === void 0 ? void 0 : _this$joinConfig5.makeKeyDelay) !== null && _this$joinConfig$make !== void 0 ? _this$joinConfig$make : 3000;
71
- }
72
- get useKeyDelay() {
73
- var _this$joinConfig$useK, _this$joinConfig6;
74
- return (_this$joinConfig$useK = (_this$joinConfig6 = this.joinConfig) === null || _this$joinConfig6 === void 0 ? void 0 : _this$joinConfig6.useKeyDelay) !== null && _this$joinConfig$useK !== void 0 ? _this$joinConfig$useK : 5000;
75
- }
76
-
77
- /**
78
- * If the server disallows the configured {@link membershipServerSideExpiryTimeout},
79
- * this stores a delay that the server does allow.
80
- */
81
-
82
- get membershipServerSideExpiryTimeout() {
83
- var _ref, _this$membershipServe, _this$joinConfig7;
84
- return (_ref = (_this$membershipServe = this.membershipServerSideExpiryTimeoutOverride) !== null && _this$membershipServe !== void 0 ? _this$membershipServe : (_this$joinConfig7 = this.joinConfig) === null || _this$joinConfig7 === void 0 ? void 0 : _this$joinConfig7.membershipServerSideExpiryTimeout) !== null && _ref !== void 0 ? _ref : 8000;
85
- }
86
- get membershipKeepAlivePeriod() {
87
- var _this$joinConfig$memb3, _this$joinConfig8;
88
- return (_this$joinConfig$memb3 = (_this$joinConfig8 = this.joinConfig) === null || _this$joinConfig8 === void 0 ? void 0 : _this$joinConfig8.membershipKeepAlivePeriod) !== null && _this$joinConfig$memb3 !== void 0 ? _this$joinConfig$memb3 : 5000;
89
- }
90
- get callMemberEventRetryJitter() {
91
- var _this$joinConfig$call2, _this$joinConfig9;
92
- return (_this$joinConfig$call2 = (_this$joinConfig9 = this.joinConfig) === null || _this$joinConfig9 === void 0 ? void 0 : _this$joinConfig9.callMemberEventRetryJitter) !== null && _this$joinConfig$call2 !== void 0 ? _this$joinConfig$call2 : 2000;
93
- }
94
-
95
- // An identifier for our membership of the call. This will allow us to easily recognise
96
- // whether a membership was sent by this session or is stale from some other time.
97
- // It also forces our membership events to be unique, because otherwise we could try
98
- // to overwrite a membership from a previous session but it would do nothing because the
99
- // event content would be identical. We need the origin_server_ts to update though, so
100
- // forcing unique content fixes this.
101
-
102
- /**
103
- * The callId (sessionId) of the call.
104
- *
105
- * It can be undefined since the callId is only known once the first membership joins.
106
- * The callId is the property that, per definition, groups memberships into one call.
107
- */
108
- get callId() {
109
- return this._callId;
110
- }
111
- /**
112
- * Returns all the call memberships for a room, oldest first
113
- */
114
- static callMembershipsForRoom(room) {
115
- var roomState = room.getLiveTimeline().getState(EventTimeline.FORWARDS);
116
- if (!roomState) {
117
- logger.warn("Couldn't get state for room " + room.roomId);
118
- throw new Error("Could't get state for room " + room.roomId);
119
- }
120
- var callMemberEvents = roomState.getStateEvents(EventType.GroupCallMemberPrefix);
121
- var callMemberships = [];
122
- for (var memberEvent of callMemberEvents) {
123
- var content = memberEvent.getContent();
124
- var eventKeysCount = Object.keys(content).length;
125
- // Dont even bother about empty events (saves us from costly type/"key in" checks in bigger rooms)
126
- if (eventKeysCount === 0) continue;
127
- var membershipContents = [];
128
-
129
- // We first decide if its a MSC4143 event (per device state key)
130
- if (eventKeysCount > 1 && "focus_active" in content) {
131
- // We have a MSC4143 event membership event
132
- membershipContents.push(content);
133
- } else if (eventKeysCount === 1 && "memberships" in content) {
134
- // we have a legacy (one event for all devices) event
135
- if (!Array.isArray(content["memberships"])) {
136
- logger.warn("Malformed member event from ".concat(memberEvent.getSender(), ": memberships is not an array"));
137
- continue;
138
- }
139
- membershipContents = content["memberships"];
140
- }
141
- if (membershipContents.length === 0) continue;
142
- for (var membershipData of membershipContents) {
143
- try {
144
- var _membership$sender;
145
- var membership = new CallMembership(memberEvent, membershipData);
146
- if (membership.callId !== "" || membership.scope !== "m.room") {
147
- // for now, just ignore anything that isn't a room scope call
148
- logger.info("Ignoring user-scoped call");
149
- continue;
150
- }
151
- if (membership.isExpired()) {
152
- logger.info("Ignoring expired device membership ".concat(membership.sender, "/").concat(membership.deviceId));
153
- continue;
154
- }
155
- if (!room.hasMembershipState((_membership$sender = membership.sender) !== null && _membership$sender !== void 0 ? _membership$sender : "", KnownMembership.Join)) {
156
- logger.info("Ignoring membership of user ".concat(membership.sender, " who is not in the room."));
157
- continue;
158
- }
159
- callMemberships.push(membership);
160
- } catch (e) {
161
- logger.warn("Couldn't construct call membership: ", e);
162
- }
163
- }
164
- }
165
- callMemberships.sort((a, b) => a.createdTs() - b.createdTs());
166
- if (callMemberships.length > 1) {
167
- logger.debug("Call memberships in room ".concat(room.roomId, ", in order: "), callMemberships.map(m => [m.createdTs(), m.sender]));
168
- }
169
- return callMemberships;
170
- }
171
-
172
- /**
173
- * Return the MatrixRTC session for the room, whether there are currently active members or not
174
- */
175
- static roomSessionForRoom(client, room) {
176
- var callMemberships = MatrixRTCSession.callMembershipsForRoom(room);
177
- return new MatrixRTCSession(client, room, callMemberships);
178
- }
179
- constructor(client, room, memberships) {
180
- var _this, _memberships$;
181
- super();
182
- _this = this;
183
- this.client = client;
184
- this.room = room;
185
- this.memberships = memberships;
186
- // The session Id of the call, this is the call_id of the call Member event.
187
- _defineProperty(this, "_callId", void 0);
188
- _defineProperty(this, "relativeExpiry", void 0);
189
- // undefined means not yet joined
190
- _defineProperty(this, "joinConfig", void 0);
191
- _defineProperty(this, "membershipServerSideExpiryTimeoutOverride", void 0);
192
- _defineProperty(this, "membershipId", void 0);
193
- _defineProperty(this, "memberEventTimeout", void 0);
194
- _defineProperty(this, "expiryTimeout", void 0);
195
- _defineProperty(this, "keysEventUpdateTimeout", void 0);
196
- _defineProperty(this, "makeNewKeyTimeout", void 0);
197
- _defineProperty(this, "setNewKeyTimeouts", new Set());
198
- // This is a Focus with the specified fields for an ActiveFocus (e.g. LivekitFocusActive for type="livekit")
199
- _defineProperty(this, "ownFocusActive", void 0);
200
- // This is a Foci array that contains the Focus objects this user is aware of and proposes to use.
201
- _defineProperty(this, "ownFociPreferred", void 0);
202
- _defineProperty(this, "updateCallMembershipRunning", false);
203
- _defineProperty(this, "needCallMembershipUpdate", false);
204
- _defineProperty(this, "manageMediaKeys", false);
205
- _defineProperty(this, "useLegacyMemberEvents", true);
206
- // userId:deviceId => array of (key, timestamp)
207
- _defineProperty(this, "encryptionKeys", new Map());
208
- _defineProperty(this, "lastEncryptionKeyUpdateRequest", void 0);
209
- _defineProperty(this, "disconnectDelayId", void 0);
210
- // We use this to store the last membership fingerprints we saw, so we can proactively re-send encryption keys
211
- // if it looks like a membership has been updated.
212
- _defineProperty(this, "lastMembershipFingerprints", void 0);
213
- _defineProperty(this, "currentEncryptionKeyIndex", -1);
214
- /**
215
- * The statistics for this session.
216
- */
217
- _defineProperty(this, "statistics", {
218
- counters: {
219
- /**
220
- * The number of times we have sent a room event containing encryption keys.
221
- */
222
- roomEventEncryptionKeysSent: 0,
223
- /**
224
- * The number of times we have received a room event containing encryption keys.
225
- */
226
- roomEventEncryptionKeysReceived: 0
227
- },
228
- totals: {
229
- /**
230
- * The total age (in milliseconds) of all room events containing encryption keys that we have received.
231
- * We track the total age so that we can later calculate the average age of all keys received.
232
- */
233
- roomEventEncryptionKeysReceivedTotalAge: 0
234
- }
235
- });
236
- /**
237
- * Re-sends the encryption keys room event
238
- */
239
- _defineProperty(this, "sendEncryptionKeysEvent", /*#__PURE__*/function () {
240
- var _ref2 = _asyncToGenerator(function* (indexToSend) {
241
- if (_this.keysEventUpdateTimeout !== undefined) {
242
- clearTimeout(_this.keysEventUpdateTimeout);
243
- _this.keysEventUpdateTimeout = undefined;
244
- }
245
- _this.lastEncryptionKeyUpdateRequest = Date.now();
246
- if (!_this.isJoined()) return;
247
- logger.info("Sending encryption keys event. indexToSend=".concat(indexToSend));
248
- var userId = _this.client.getUserId();
249
- var deviceId = _this.client.getDeviceId();
250
- if (!userId) throw new Error("No userId");
251
- if (!deviceId) throw new Error("No deviceId");
252
- var myKeys = _this.getKeysForParticipant(userId, deviceId);
253
- if (!myKeys) {
254
- logger.warn("Tried to send encryption keys event but no keys found!");
255
- return;
256
- }
257
- if (typeof indexToSend !== "number" && _this.currentEncryptionKeyIndex === -1) {
258
- logger.warn("Tried to send encryption keys event but no current key index found!");
259
- return;
260
- }
261
- var keyIndexToSend = indexToSend !== null && indexToSend !== void 0 ? indexToSend : _this.currentEncryptionKeyIndex;
262
- var keyToSend = myKeys[keyIndexToSend];
263
- try {
264
- var content = {
265
- keys: [{
266
- index: keyIndexToSend,
267
- key: encodeUnpaddedBase64(keyToSend)
268
- }],
269
- device_id: deviceId,
270
- call_id: "",
271
- sent_ts: Date.now()
272
- };
273
- _this.statistics.counters.roomEventEncryptionKeysSent += 1;
274
- yield _this.client.sendEvent(_this.room.roomId, EventType.CallEncryptionKeysPrefix, content);
275
- logger.debug("Embedded-E2EE-LOG updateEncryptionKeyEvent participantId=".concat(userId, ":").concat(deviceId, " numKeys=").concat(myKeys.length, " currentKeyIndex=").concat(_this.currentEncryptionKeyIndex, " keyIndexToSend=").concat(keyIndexToSend), _this.encryptionKeys);
276
- } catch (error) {
277
- var matrixError = error;
278
- if (matrixError.event) {
279
- // cancel the pending event: we'll just generate a new one with our latest
280
- // keys when we resend
281
- _this.client.cancelPendingEvent(matrixError.event);
282
- }
283
- if (_this.keysEventUpdateTimeout === undefined) {
284
- var resendDelay = safeGetRetryAfterMs(matrixError, 5000);
285
- logger.warn("Failed to send m.call.encryption_key, retrying in ".concat(resendDelay), error);
286
- _this.keysEventUpdateTimeout = setTimeout(_this.sendEncryptionKeysEvent, resendDelay);
287
- } else {
288
- logger.info("Not scheduling key resend as another re-send is already pending");
289
- }
290
- }
291
- });
292
- return function (_x) {
293
- return _ref2.apply(this, arguments);
294
- };
295
- }());
296
- /**
297
- * Process `m.call.encryption_keys` events to track the encryption keys for call participants.
298
- * This should be called each time the relevant event is received from a room timeline.
299
- * If the event is malformed then it will be logged and ignored.
300
- *
301
- * @param event the event to process
302
- */
303
- _defineProperty(this, "onCallEncryption", event => {
304
- var userId = event.getSender();
305
- var content = event.getContent();
306
- var deviceId = content["device_id"];
307
- var callId = content["call_id"];
308
- if (!userId) {
309
- logger.warn("Received m.call.encryption_keys with no userId: callId=".concat(callId));
310
- return;
311
- }
312
-
313
- // We currently only handle callId = "" (which is the default for room scoped calls)
314
- if (callId !== "") {
315
- logger.warn("Received m.call.encryption_keys with unsupported callId: userId=".concat(userId, ", deviceId=").concat(deviceId, ", callId=").concat(callId));
316
- return;
317
- }
318
- if (!Array.isArray(content.keys)) {
319
- logger.warn("Received m.call.encryption_keys where keys wasn't an array: callId=".concat(callId));
320
- return;
321
- }
322
- if (userId === this.client.getUserId() && deviceId === this.client.getDeviceId()) {
323
- // We store our own sender key in the same set along with keys from others, so it's
324
- // important we don't allow our own keys to be set by one of these events (apart from
325
- // the fact that we don't need it anyway because we already know our own keys).
326
- logger.info("Ignoring our own keys event");
327
- return;
328
- }
329
- this.statistics.counters.roomEventEncryptionKeysReceived += 1;
330
- var age = Date.now() - (typeof content.sent_ts === "number" ? content.sent_ts : event.getTs());
331
- this.statistics.totals.roomEventEncryptionKeysReceivedTotalAge += age;
332
- for (var key of content.keys) {
333
- if (!key) {
334
- logger.info("Ignoring false-y key in keys event");
335
- continue;
336
- }
337
- var encryptionKey = key.key;
338
- var encryptionKeyIndex = key.index;
339
- if (!encryptionKey || encryptionKeyIndex === undefined || encryptionKeyIndex === null || callId === undefined || callId === null || typeof deviceId !== "string" || typeof callId !== "string" || typeof encryptionKey !== "string" || typeof encryptionKeyIndex !== "number") {
340
- logger.warn("Malformed call encryption_key: userId=".concat(userId, ", deviceId=").concat(deviceId, ", encryptionKeyIndex=").concat(encryptionKeyIndex, " callId=").concat(callId));
341
- } else {
342
- logger.debug("Embedded-E2EE-LOG onCallEncryption userId=".concat(userId, ":").concat(deviceId, " encryptionKeyIndex=").concat(encryptionKeyIndex, " age=").concat(age, "ms"), this.encryptionKeys);
343
- this.setEncryptionKey(userId, deviceId, encryptionKeyIndex, encryptionKey, event.getTs());
344
- }
345
- }
346
- });
347
- _defineProperty(this, "isMyMembership", m => m.sender === this.client.getUserId() && m.deviceId === this.client.getDeviceId());
348
- /**
349
- * Examines the latest call memberships and handles any encryption key sending or rotation that is needed.
350
- *
351
- * This function should be called when the room members or call memberships might have changed.
352
- */
353
- _defineProperty(this, "onMembershipUpdate", () => {
354
- var _this$_callId, _this$memberships$;
355
- var oldMemberships = this.memberships;
356
- this.memberships = MatrixRTCSession.callMembershipsForRoom(this.room);
357
- this._callId = (_this$_callId = this._callId) !== null && _this$_callId !== void 0 ? _this$_callId : (_this$memberships$ = this.memberships[0]) === null || _this$memberships$ === void 0 ? void 0 : _this$memberships$.callId;
358
- var changed = oldMemberships.length != this.memberships.length || oldMemberships.some((m, i) => !CallMembership.equal(m, this.memberships[i]));
359
- if (changed) {
360
- logger.info("Memberships for call in room ".concat(this.room.roomId, " have changed: emitting"));
361
- this.emit(MatrixRTCSessionEvent.MembershipsChanged, oldMemberships, this.memberships);
362
- if (this.isJoined() && !this.memberships.some(this.isMyMembership)) {
363
- logger.warn("Missing own membership: force re-join");
364
- // TODO: Should this be awaited? And is there anything to tell the focus?
365
- this.triggerCallMembershipEventUpdate();
366
- }
367
- }
368
- if (this.manageMediaKeys && this.isJoined() && this.makeNewKeyTimeout === undefined) {
369
- var oldMembershipIds = new Set(oldMemberships.filter(m => !this.isMyMembership(m)).map(getParticipantIdFromMembership));
370
- var newMembershipIds = new Set(this.memberships.filter(m => !this.isMyMembership(m)).map(getParticipantIdFromMembership));
371
-
372
- // We can use https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/symmetricDifference
373
- // for this once available
374
- var anyLeft = Array.from(oldMembershipIds).some(x => !newMembershipIds.has(x));
375
- var anyJoined = Array.from(newMembershipIds).some(x => !oldMembershipIds.has(x));
376
- var oldFingerprints = this.lastMembershipFingerprints;
377
- // always store the fingerprints of these latest memberships
378
- this.storeLastMembershipFingerprints();
379
- if (anyLeft) {
380
- logger.debug("Member(s) have left: queueing sender key rotation");
381
- this.makeNewKeyTimeout = setTimeout(this.onRotateKeyTimeout, this.makeKeyDelay);
382
- } else if (anyJoined) {
383
- logger.debug("New member(s) have joined: re-sending keys");
384
- this.requestSendCurrentKey();
385
- } else if (oldFingerprints) {
386
- // does it look like any of the members have updated their memberships?
387
- var newFingerprints = this.lastMembershipFingerprints;
388
-
389
- // We can use https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/symmetricDifference
390
- // for this once available
391
- var candidateUpdates = Array.from(oldFingerprints).some(x => !newFingerprints.has(x)) || Array.from(newFingerprints).some(x => !oldFingerprints.has(x));
392
- if (candidateUpdates) {
393
- logger.debug("Member(s) have updated/reconnected: re-sending keys to everyone");
394
- this.requestSendCurrentKey();
395
- }
396
- }
397
- }
398
- this.setExpiryTimer();
399
- });
400
- _defineProperty(this, "triggerCallMembershipEventUpdate", /*#__PURE__*/_asyncToGenerator(function* () {
401
- // TODO: Should this await on a shared promise?
402
- if (_this.updateCallMembershipRunning) {
403
- _this.needCallMembershipUpdate = true;
404
- return;
405
- }
406
- _this.updateCallMembershipRunning = true;
407
- try {
408
- // if anything triggers an update while the update is running, do another update afterwards
409
- do {
410
- _this.needCallMembershipUpdate = false;
411
- yield _this.updateCallMembershipEvent();
412
- } while (_this.needCallMembershipUpdate);
413
- } finally {
414
- _this.updateCallMembershipRunning = false;
415
- }
416
- }));
417
- _defineProperty(this, "delayDisconnection", /*#__PURE__*/_asyncToGenerator(function* () {
418
- try {
419
- var knownDisconnectDelayId = _this.disconnectDelayId;
420
- yield resendIfRateLimited(() => _this.client._unstable_updateDelayedEvent(knownDisconnectDelayId, UpdateDelayedEventAction.Restart));
421
- _this.scheduleDelayDisconnection();
422
- } catch (e) {
423
- logger.error("Failed to delay our disconnection event:", e);
424
- }
425
- }));
426
- _defineProperty(this, "onRotateKeyTimeout", () => {
427
- if (!this.manageMediaKeys) return;
428
- this.makeNewKeyTimeout = undefined;
429
- logger.info("Making new sender key for key rotation");
430
- var newKeyIndex = this.makeNewSenderKey(true);
431
- // send immediately: if we're about to start sending with a new key, it's
432
- // important we get it out to others as soon as we can.
433
- this.sendEncryptionKeysEvent(newKeyIndex);
434
- });
435
- this._callId = (_memberships$ = memberships[0]) === null || _memberships$ === void 0 ? void 0 : _memberships$.callId;
436
- var roomState = this.room.getLiveTimeline().getState(EventTimeline.FORWARDS);
437
- roomState === null || roomState === void 0 || roomState.on(RoomStateEvent.Members, this.onMembershipUpdate);
438
- this.setExpiryTimer();
439
- }
440
-
441
- /*
442
- * Returns true if we intend to be participating in the MatrixRTC session.
443
- * This is determined by checking if the relativeExpiry has been set.
444
- */
445
- isJoined() {
446
- return this.relativeExpiry !== undefined;
447
- }
448
-
449
- /**
450
- * Performs cleanup & removes timers for client shutdown
451
- */
452
- stop() {
453
- var _this2 = this;
454
- return _asyncToGenerator(function* () {
455
- yield _this2.leaveRoomSession(1000);
456
- if (_this2.expiryTimeout) {
457
- clearTimeout(_this2.expiryTimeout);
458
- _this2.expiryTimeout = undefined;
459
- }
460
- if (_this2.memberEventTimeout) {
461
- clearTimeout(_this2.memberEventTimeout);
462
- _this2.memberEventTimeout = undefined;
463
- }
464
- var roomState = _this2.room.getLiveTimeline().getState(EventTimeline.FORWARDS);
465
- roomState === null || roomState === void 0 || roomState.off(RoomStateEvent.Members, _this2.onMembershipUpdate);
466
- })();
467
- }
468
-
469
- /**
470
- * Announces this user and device as joined to the MatrixRTC session,
471
- * and continues to update the membership event to keep it valid until
472
- * leaveRoomSession() is called
473
- * This will not subscribe to updates: remember to call subscribe() separately if
474
- * desired.
475
- * This method will return immediately and the session will be joined in the background.
476
- *
477
- * @param fociActive - The object representing the active focus. (This depends on the focus type.)
478
- * @param fociPreferred - The list of preferred foci this member proposes to use/knows/has access to.
479
- * For the livekit case this is a list of foci generated from the homeserver well-known, the current rtc session,
480
- * or optionally other room members homeserver well known.
481
- * @param joinConfig - Additional configuration for the joined session.
482
- */
483
- joinRoomSession(fociPreferred, fociActive, joinConfig) {
484
- var _joinConfig$manageMed, _joinConfig$useLegacy;
485
- if (this.isJoined()) {
486
- logger.info("Already joined to session in room ".concat(this.room.roomId, ": ignoring join call"));
487
- return;
488
- }
489
- this.ownFocusActive = fociActive;
490
- this.ownFociPreferred = fociPreferred;
491
- this.joinConfig = joinConfig;
492
- this.relativeExpiry = this.membershipExpiryTimeout;
493
- this.manageMediaKeys = (_joinConfig$manageMed = joinConfig === null || joinConfig === void 0 ? void 0 : joinConfig.manageMediaKeys) !== null && _joinConfig$manageMed !== void 0 ? _joinConfig$manageMed : this.manageMediaKeys;
494
- this.useLegacyMemberEvents = (_joinConfig$useLegacy = joinConfig === null || joinConfig === void 0 ? void 0 : joinConfig.useLegacyMemberEvents) !== null && _joinConfig$useLegacy !== void 0 ? _joinConfig$useLegacy : this.useLegacyMemberEvents;
495
- this.membershipId = randomString(5);
496
- logger.info("Joining call session in room ".concat(this.room.roomId, " with manageMediaKeys=").concat(this.manageMediaKeys));
497
- if (joinConfig !== null && joinConfig !== void 0 && joinConfig.manageMediaKeys) {
498
- this.makeNewSenderKey();
499
- this.requestSendCurrentKey();
500
- }
501
- // We don't wait for this, mostly because it may fail and schedule a retry, so this
502
- // function returning doesn't really mean anything at all.
503
- this.triggerCallMembershipEventUpdate();
504
- this.emit(MatrixRTCSessionEvent.JoinStateChanged, true);
505
- }
506
-
507
- /**
508
- * Announces this user and device as having left the MatrixRTC session
509
- * and stops scheduled updates.
510
- * This will not unsubscribe from updates: remember to call unsubscribe() separately if
511
- * desired.
512
- * The membership update required to leave the session will retry if it fails.
513
- * Without network connection the promise will never resolve.
514
- * A timeout can be provided so that there is a guarantee for the promise to resolve.
515
- * @returns Whether the membership update was attempted and did not time out.
516
- */
517
- leaveRoomSession() {
518
- var _arguments = arguments,
519
- _this3 = this;
520
- return _asyncToGenerator(function* () {
521
- var timeout = _arguments.length > 0 && _arguments[0] !== undefined ? _arguments[0] : undefined;
522
- if (!_this3.isJoined()) {
523
- logger.info("Not joined to session in room ".concat(_this3.room.roomId, ": ignoring leave call"));
524
- return false;
525
- }
526
- var userId = _this3.client.getUserId();
527
- var deviceId = _this3.client.getDeviceId();
528
- if (!userId) throw new Error("No userId");
529
- if (!deviceId) throw new Error("No deviceId");
530
-
531
- // clear our encryption keys as we're done with them now (we'll
532
- // make new keys if we rejoin). We leave keys for other participants
533
- // as they may still be using the same ones.
534
- _this3.encryptionKeys.set(getParticipantId(userId, deviceId), []);
535
- if (_this3.makeNewKeyTimeout !== undefined) {
536
- clearTimeout(_this3.makeNewKeyTimeout);
537
- _this3.makeNewKeyTimeout = undefined;
538
- }
539
- for (var t of _this3.setNewKeyTimeouts) {
540
- clearTimeout(t);
541
- }
542
- _this3.setNewKeyTimeouts.clear();
543
- logger.info("Leaving call session in room ".concat(_this3.room.roomId));
544
- _this3.joinConfig = undefined;
545
- _this3.relativeExpiry = undefined;
546
- _this3.ownFocusActive = undefined;
547
- _this3.manageMediaKeys = false;
548
- _this3.membershipId = undefined;
549
- _this3.emit(MatrixRTCSessionEvent.JoinStateChanged, false);
550
- if (timeout) {
551
- // The sleep promise returns the string 'timeout' and the membership update void
552
- // A success implies that the membership update was quicker then the timeout.
553
- var raceResult = yield Promise.race([_this3.triggerCallMembershipEventUpdate(), sleep(timeout, "timeout")]);
554
- return raceResult !== "timeout";
555
- } else {
556
- yield _this3.triggerCallMembershipEventUpdate();
557
- return true;
558
- }
559
- })();
560
- }
561
- getActiveFocus() {
562
- if (this.ownFocusActive && isLivekitFocusActive(this.ownFocusActive)) {
563
- // A livekit active focus
564
- if (this.ownFocusActive.focus_selection === "oldest_membership") {
565
- var oldestMembership = this.getOldestMembership();
566
- return oldestMembership === null || oldestMembership === void 0 ? void 0 : oldestMembership.getPreferredFoci()[0];
567
- }
568
- }
569
- if (!this.ownFocusActive) {
570
- // we use the legacy call.member events so default to oldest member
571
- var _oldestMembership = this.getOldestMembership();
572
- return _oldestMembership === null || _oldestMembership === void 0 ? void 0 : _oldestMembership.getPreferredFoci()[0];
573
- }
574
- }
575
-
576
- /**
577
- * Re-emit an EncryptionKeyChanged event for each tracked encryption key. This can be used to export
578
- * the keys.
579
- */
580
- reemitEncryptionKeys() {
581
- this.encryptionKeys.forEach((keys, participantId) => {
582
- keys.forEach((key, index) => {
583
- this.emit(MatrixRTCSessionEvent.EncryptionKeyChanged, key.key, index, participantId);
584
- });
585
- });
586
- }
587
-
588
- /**
589
- * Get the known encryption keys for a given participant device.
590
- *
591
- * @param userId the user ID of the participant
592
- * @param deviceId the device ID of the participant
593
- * @returns The encryption keys for the given participant, or undefined if they are not known.
594
- *
595
- * @deprecated This will be made private in a future release.
596
- */
597
- getKeysForParticipant(userId, deviceId) {
598
- return this.getKeysForParticipantInternal(userId, deviceId);
599
- }
600
- getKeysForParticipantInternal(userId, deviceId) {
601
- var _this$encryptionKeys$;
602
- return (_this$encryptionKeys$ = this.encryptionKeys.get(getParticipantId(userId, deviceId))) === null || _this$encryptionKeys$ === void 0 ? void 0 : _this$encryptionKeys$.map(entry => entry.key);
603
- }
604
-
605
- /**
606
- * A map of keys used to encrypt and decrypt (we are using a symmetric
607
- * cipher) given participant's media. This also includes our own key
608
- *
609
- * @deprecated This will be made private in a future release.
610
- */
611
- getEncryptionKeys() {
612
- // the returned array doesn't contain the timestamps
613
- return Array.from(this.encryptionKeys.entries()).map(_ref5 => {
614
- var [participantId, keys] = _ref5;
615
- return [participantId, keys.map(k => k.key)];
616
- }).values();
617
- }
618
- getNewEncryptionKeyIndex() {
619
- if (this.currentEncryptionKeyIndex === -1) {
620
- return 0;
621
- }
622
-
623
- // maximum key index is 255
624
- return (this.currentEncryptionKeyIndex + 1) % 256;
625
- }
626
-
627
- /**
628
- * Sets an encryption key at a specified index for a participant.
629
- * The encryption keys for the local participant are also stored here under the
630
- * user and device ID of the local participant.
631
- * If the key is older than the existing key at the index, it will be ignored.
632
- * @param userId - The user ID of the participant
633
- * @param deviceId - Device ID of the participant
634
- * @param encryptionKeyIndex - The index of the key to set
635
- * @param encryptionKeyString - The string representation of the key to set in base64
636
- * @param timestamp - The timestamp of the key. We assume that these are monotonic for each participant device.
637
- * @param delayBeforeUse - If true, delay before emitting a key changed event. Useful when setting
638
- * encryption keys for the local participant to allow time for the key to
639
- * be distributed.
640
- */
641
- setEncryptionKey(userId, deviceId, encryptionKeyIndex, encryptionKeyString, timestamp) {
642
- var delayBeforeUse = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false;
643
- var keyBin = decodeBase64(encryptionKeyString);
644
- var participantId = getParticipantId(userId, deviceId);
645
- if (!this.encryptionKeys.has(participantId)) {
646
- this.encryptionKeys.set(participantId, []);
647
- }
648
- var participantKeys = this.encryptionKeys.get(participantId);
649
- var existingKeyAtIndex = participantKeys[encryptionKeyIndex];
650
- if (existingKeyAtIndex) {
651
- if (existingKeyAtIndex.timestamp > timestamp) {
652
- logger.info("Ignoring new key at index ".concat(encryptionKeyIndex, " for ").concat(participantId, " as it is older than existing known key"));
653
- return;
654
- }
655
- if (keysEqual(existingKeyAtIndex.key, keyBin)) {
656
- existingKeyAtIndex.timestamp = timestamp;
657
- return;
658
- }
659
- }
660
- participantKeys[encryptionKeyIndex] = {
661
- key: keyBin,
662
- timestamp
663
- };
664
- if (delayBeforeUse) {
665
- var useKeyTimeout = setTimeout(() => {
666
- this.setNewKeyTimeouts.delete(useKeyTimeout);
667
- logger.info("Delayed-emitting key changed event for ".concat(participantId, " idx ").concat(encryptionKeyIndex));
668
- if (userId === this.client.getUserId() && deviceId === this.client.getDeviceId()) {
669
- this.currentEncryptionKeyIndex = encryptionKeyIndex;
670
- }
671
- this.emit(MatrixRTCSessionEvent.EncryptionKeyChanged, keyBin, encryptionKeyIndex, participantId);
672
- }, this.useKeyDelay);
673
- this.setNewKeyTimeouts.add(useKeyTimeout);
674
- } else {
675
- if (userId === this.client.getUserId() && deviceId === this.client.getDeviceId()) {
676
- this.currentEncryptionKeyIndex = encryptionKeyIndex;
677
- }
678
- this.emit(MatrixRTCSessionEvent.EncryptionKeyChanged, keyBin, encryptionKeyIndex, participantId);
679
- }
680
- }
681
-
682
- /**
683
- * Generate a new sender key and add it at the next available index
684
- * @param delayBeforeUse - If true, wait for a short period before setting the key for the
685
- * media encryptor to use. If false, set the key immediately.
686
- * @returns The index of the new key
687
- */
688
- makeNewSenderKey() {
689
- var delayBeforeUse = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
690
- var userId = this.client.getUserId();
691
- var deviceId = this.client.getDeviceId();
692
- if (!userId) throw new Error("No userId");
693
- if (!deviceId) throw new Error("No deviceId");
694
- var encryptionKey = secureRandomBase64Url(16);
695
- var encryptionKeyIndex = this.getNewEncryptionKeyIndex();
696
- logger.info("Generated new key at index " + encryptionKeyIndex);
697
- this.setEncryptionKey(userId, deviceId, encryptionKeyIndex, encryptionKey, Date.now(), delayBeforeUse);
698
- return encryptionKeyIndex;
699
- }
700
-
701
- /**
702
- * Requests that we resend our current keys to the room. May send a keys event immediately
703
- * or queue for alter if one has already been sent recently.
704
- */
705
- requestSendCurrentKey() {
706
- if (!this.manageMediaKeys) return;
707
- if (this.lastEncryptionKeyUpdateRequest && this.lastEncryptionKeyUpdateRequest + this.updateEncryptionKeyThrottle > Date.now()) {
708
- logger.info("Last encryption key event sent too recently: postponing");
709
- if (this.keysEventUpdateTimeout === undefined) {
710
- this.keysEventUpdateTimeout = setTimeout(this.sendEncryptionKeysEvent, this.updateEncryptionKeyThrottle);
711
- }
712
- return;
713
- }
714
- this.sendEncryptionKeysEvent();
715
- }
716
- /**
717
- * Sets a timer for the soonest membership expiry
718
- */
719
- setExpiryTimer() {
720
- if (this.expiryTimeout) {
721
- clearTimeout(this.expiryTimeout);
722
- this.expiryTimeout = undefined;
723
- }
724
- var soonestExpiry;
725
- for (var membership of this.memberships) {
726
- var thisExpiry = membership.getMsUntilExpiry();
727
- // If getMsUntilExpiry is undefined we have a MSC4143 (MatrixRTC) compliant event - it never expires
728
- // but will be reliably resent on disconnect.
729
- if (thisExpiry !== undefined && (soonestExpiry === undefined || thisExpiry < soonestExpiry)) {
730
- soonestExpiry = thisExpiry;
731
- }
732
- }
733
- if (soonestExpiry != undefined) {
734
- this.expiryTimeout = setTimeout(this.onMembershipUpdate, soonestExpiry);
735
- }
736
- }
737
- getOldestMembership() {
738
- return this.memberships[0];
739
- }
740
- getFocusInUse() {
741
- var oldestMembership = this.getOldestMembership();
742
- if ((oldestMembership === null || oldestMembership === void 0 ? void 0 : oldestMembership.getFocusSelection()) === "oldest_membership") {
743
- return oldestMembership.getPreferredFoci()[0];
744
- }
745
- }
746
- storeLastMembershipFingerprints() {
747
- this.lastMembershipFingerprints = new Set(this.memberships.filter(m => !this.isMyMembership(m)).map(m => "".concat(getParticipantIdFromMembership(m), ":").concat(m.membershipID, ":").concat(m.createdTs())));
748
- }
749
-
750
- /**
751
- * Constructs our own membership
752
- * @param prevMembership - The previous value of our call membership, if any
753
- */
754
- makeMyMembershipLegacy(deviceId, prevMembership) {
755
- if (this.relativeExpiry === undefined) {
756
- throw new Error("Tried to create our own membership event when we're not joined!");
757
- }
758
- if (this.membershipId === undefined) {
759
- throw new Error("Tried to create our own membership event when we have no membership ID!");
760
- }
761
- var createdTs = prevMembership === null || prevMembership === void 0 ? void 0 : prevMembership.createdTs();
762
- return _objectSpread({
763
- call_id: "",
764
- scope: "m.room",
765
- application: "m.call",
766
- device_id: deviceId,
767
- expires: this.relativeExpiry,
768
- // TODO: Date.now() should be the origin_server_ts (now).
769
- expires_ts: this.relativeExpiry + (createdTs !== null && createdTs !== void 0 ? createdTs : Date.now()),
770
- // we use the fociPreferred since this is the list of foci.
771
- // it is named wrong in the Legacy events.
772
- foci_active: this.ownFociPreferred,
773
- membershipID: this.membershipId
774
- }, createdTs ? {
775
- created_ts: createdTs
776
- } : {});
777
- }
778
- /**
779
- * Constructs our own membership
780
- */
781
- makeMyMembership(deviceId) {
782
- var _this$ownFociPreferre;
783
- return {
784
- call_id: "",
785
- scope: "m.room",
786
- application: "m.call",
787
- device_id: deviceId,
788
- focus_active: {
789
- type: "livekit",
790
- focus_selection: "oldest_membership"
791
- },
792
- foci_preferred: (_this$ownFociPreferre = this.ownFociPreferred) !== null && _this$ownFociPreferre !== void 0 ? _this$ownFociPreferre : []
793
- };
794
- }
795
-
796
- /**
797
- * Returns true if our membership event needs to be updated
798
- */
799
- membershipEventNeedsUpdate(myPrevMembershipData, myPrevMembership) {
800
- if (myPrevMembership && myPrevMembership.getMsUntilExpiry() === undefined) return false;
801
-
802
- // Need to update if there's a membership for us but we're not joined (valid or otherwise)
803
- if (!this.isJoined()) return !!myPrevMembershipData;
804
-
805
- // ...or if we are joined, but there's no valid membership event
806
- if (!myPrevMembership) return true;
807
- var expiryTime = myPrevMembership.getMsUntilExpiry();
808
- if (expiryTime !== undefined && expiryTime < this.membershipExpiryTimeout / 2) {
809
- // ...or if the expiry time needs bumping
810
- this.relativeExpiry += this.membershipExpiryTimeout;
811
- return true;
812
- }
813
- return false;
814
- }
815
- makeNewMembership(deviceId) {
816
- // If we're joined, add our own
817
- if (this.isJoined()) {
818
- return this.makeMyMembership(deviceId);
819
- }
820
- return {};
821
- }
822
- /**
823
- * Makes a new membership list given the old list along with this user's previous membership event
824
- * (if any) and this device's previous membership (if any)
825
- */
826
- makeNewLegacyMemberships(oldMemberships, localDeviceId, myCallMemberEvent, myPrevMembership) {
827
- var filterExpired = m => {
828
- var membershipObj;
829
- try {
830
- membershipObj = new CallMembership(myCallMemberEvent, m);
831
- } catch (_unused) {
832
- return false;
833
- }
834
- return !membershipObj.isExpired();
835
- };
836
- var transformMemberships = m => {
837
- if (m.created_ts === undefined) {
838
- // we need to fill this in with the origin_server_ts from its original event
839
- m.created_ts = myCallMemberEvent.getTs();
840
- }
841
- return m;
842
- };
843
-
844
- // Filter our any invalid or expired memberships, and also our own - we'll add that back in next
845
- var newMemberships = oldMemberships.filter(filterExpired).filter(m => m.device_id !== localDeviceId);
846
-
847
- // Fix up any memberships that need their created_ts adding
848
- newMemberships = newMemberships.map(transformMemberships);
849
-
850
- // If we're joined, add our own
851
- if (this.isJoined()) {
852
- newMemberships.push(this.makeMyMembershipLegacy(localDeviceId, myPrevMembership));
853
- }
854
- return {
855
- memberships: newMemberships
856
- };
857
- }
858
- updateCallMembershipEvent() {
859
- var _this4 = this;
860
- return _asyncToGenerator(function* () {
861
- if (_this4.memberEventTimeout) {
862
- clearTimeout(_this4.memberEventTimeout);
863
- _this4.memberEventTimeout = undefined;
864
- }
865
- var roomState = _this4.room.getLiveTimeline().getState(EventTimeline.FORWARDS);
866
- if (!roomState) throw new Error("Couldn't get room state for room " + _this4.room.roomId);
867
- var localUserId = _this4.client.getUserId();
868
- var localDeviceId = _this4.client.getDeviceId();
869
- if (!localUserId || !localDeviceId) throw new Error("User ID or device ID was null!");
870
- var callMemberEvents = roomState.events.get(EventType.GroupCallMemberPrefix);
871
- var legacy = _this4.stateEventsContainOngoingLegacySession(callMemberEvents);
872
- var newContent = {};
873
- if (legacy) {
874
- var _myCallMemberEvent$ge;
875
- var myCallMemberEvent = callMemberEvents === null || callMemberEvents === void 0 ? void 0 : callMemberEvents.get(localUserId);
876
- var content = (_myCallMemberEvent$ge = myCallMemberEvent === null || myCallMemberEvent === void 0 ? void 0 : myCallMemberEvent.getContent()) !== null && _myCallMemberEvent$ge !== void 0 ? _myCallMemberEvent$ge : {};
877
- var myPrevMembership;
878
- // We know its CallMembershipDataLegacy
879
- var _memberships = Array.isArray(content["memberships"]) ? content["memberships"] : [];
880
- var myPrevMembershipData = _memberships.find(m => m.device_id === localDeviceId);
881
- try {
882
- if (myCallMemberEvent && myPrevMembershipData && isLegacyCallMembershipData(myPrevMembershipData) && myPrevMembershipData.membershipID === _this4.membershipId) {
883
- myPrevMembership = new CallMembership(myCallMemberEvent, myPrevMembershipData);
884
- }
885
- } catch (e) {
886
- // This would indicate a bug or something weird if our own call membership
887
- // wasn't valid
888
- logger.warn("Our previous call membership was invalid - this shouldn't happen.", e);
889
- }
890
- if (myPrevMembership) {
891
- logger.debug("".concat(myPrevMembership.getMsUntilExpiry(), " until our membership expires"));
892
- }
893
- if (!_this4.membershipEventNeedsUpdate(myPrevMembershipData, myPrevMembership)) {
894
- // nothing to do - reschedule the check again
895
- _this4.memberEventTimeout = setTimeout(_this4.triggerCallMembershipEventUpdate, _this4.memberEventCheckPeriod);
896
- return;
897
- }
898
- newContent = _this4.makeNewLegacyMemberships(_memberships, localDeviceId, myCallMemberEvent, myPrevMembership);
899
- } else {
900
- newContent = _this4.makeNewMembership(localDeviceId);
901
- }
902
- try {
903
- if (legacy) {
904
- yield _this4.client.sendStateEvent(_this4.room.roomId, EventType.GroupCallMemberPrefix, newContent, localUserId);
905
- if (_this4.isJoined()) {
906
- // check periodically to see if we need to refresh our member event
907
- _this4.memberEventTimeout = setTimeout(_this4.triggerCallMembershipEventUpdate, _this4.memberEventCheckPeriod);
908
- }
909
- } else if (_this4.isJoined()) {
910
- var stateKey = _this4.makeMembershipStateKey(localUserId, localDeviceId);
911
- var _prepareDelayedDisconnection = /*#__PURE__*/function () {
912
- var _ref6 = _asyncToGenerator(function* () {
913
- try {
914
- var res = yield resendIfRateLimited(() => _this4.client._unstable_sendDelayedStateEvent(_this4.room.roomId, {
915
- delay: _this4.membershipServerSideExpiryTimeout
916
- }, EventType.GroupCallMemberPrefix, {},
917
- // leave event
918
- stateKey));
919
- _this4.disconnectDelayId = res.delay_id;
920
- } catch (e) {
921
- if (e instanceof MatrixError && e.errcode === "M_UNKNOWN" && e.data["org.matrix.msc4140.errcode"] === "M_MAX_DELAY_EXCEEDED") {
922
- var maxDelayAllowed = e.data["org.matrix.msc4140.max_delay"];
923
- if (typeof maxDelayAllowed === "number" && _this4.membershipServerSideExpiryTimeout > maxDelayAllowed) {
924
- _this4.membershipServerSideExpiryTimeoutOverride = maxDelayAllowed;
925
- return _prepareDelayedDisconnection();
926
- }
927
- }
928
- logger.error("Failed to prepare delayed disconnection event:", e);
929
- }
930
- });
931
- return function prepareDelayedDisconnection() {
932
- return _ref6.apply(this, arguments);
933
- };
934
- }();
935
- yield _prepareDelayedDisconnection();
936
- // Send join event _after_ preparing the delayed disconnection event
937
- yield resendIfRateLimited(() => _this4.client.sendStateEvent(_this4.room.roomId, EventType.GroupCallMemberPrefix, newContent, stateKey));
938
- // If sending state cancels your own delayed state, prepare another delayed state
939
- // TODO: Remove this once MSC4140 is stable & doesn't cancel own delayed state
940
- if (_this4.disconnectDelayId !== undefined) {
941
- try {
942
- var knownDisconnectDelayId = _this4.disconnectDelayId;
943
- yield resendIfRateLimited(() => _this4.client._unstable_updateDelayedEvent(knownDisconnectDelayId, UpdateDelayedEventAction.Restart));
944
- } catch (e) {
945
- logger.warn("Failed to update delayed disconnection event, prepare it again:", e);
946
- _this4.disconnectDelayId = undefined;
947
- yield _prepareDelayedDisconnection();
948
- }
949
- }
950
- if (_this4.disconnectDelayId !== undefined) {
951
- _this4.scheduleDelayDisconnection();
952
- }
953
- } else {
954
- var sentDelayedDisconnect = false;
955
- if (_this4.disconnectDelayId !== undefined) {
956
- try {
957
- var _knownDisconnectDelayId = _this4.disconnectDelayId;
958
- yield resendIfRateLimited(() => _this4.client._unstable_updateDelayedEvent(_knownDisconnectDelayId, UpdateDelayedEventAction.Send));
959
- sentDelayedDisconnect = true;
960
- } catch (e) {
961
- logger.error("Failed to send our delayed disconnection event:", e);
962
- }
963
- _this4.disconnectDelayId = undefined;
964
- }
965
- if (!sentDelayedDisconnect) {
966
- yield resendIfRateLimited(() => _this4.client.sendStateEvent(_this4.room.roomId, EventType.GroupCallMemberPrefix, {}, _this4.makeMembershipStateKey(localUserId, localDeviceId)));
967
- }
968
- }
969
- logger.info("Sent updated call member event.");
970
- } catch (e) {
971
- var resendDelay = _this4.callMemberEventRetryDelayMinimum + Math.random() * _this4.callMemberEventRetryJitter;
972
- logger.warn("Failed to send call member event (retrying in ".concat(resendDelay, "): ").concat(e));
973
- yield sleep(resendDelay);
974
- yield _this4.triggerCallMembershipEventUpdate();
975
- }
976
- })();
977
- }
978
- scheduleDelayDisconnection() {
979
- this.memberEventTimeout = setTimeout(this.delayDisconnection, this.membershipKeepAlivePeriod);
980
- }
981
- stateEventsContainOngoingLegacySession(callMemberEvents) {
982
- if (!(callMemberEvents !== null && callMemberEvents !== void 0 && callMemberEvents.size)) {
983
- return this.useLegacyMemberEvents;
984
- }
985
- var containsAnyOngoingSession = false;
986
- var containsUnknownOngoingSession = false;
987
- for (var callMemberEvent of callMemberEvents.values()) {
988
- var content = callMemberEvent.getContent();
989
- if (Array.isArray(content["memberships"])) {
990
- for (var membership of content.memberships) {
991
- if (!new CallMembership(callMemberEvent, membership).isExpired()) {
992
- return true;
993
- }
994
- }
995
- } else if (Object.keys(content).length > 0) {
996
- containsAnyOngoingSession || (containsAnyOngoingSession = true);
997
- containsUnknownOngoingSession || (containsUnknownOngoingSession = !("focus_active" in content));
998
- }
999
- }
1000
- return containsAnyOngoingSession && !containsUnknownOngoingSession ? false : this.useLegacyMemberEvents;
1001
- }
1002
- makeMembershipStateKey(localUserId, localDeviceId) {
1003
- var stateKey = "".concat(localUserId, "_").concat(localDeviceId);
1004
- if (/^org\.matrix\.msc(3757|3779)\b/.exec(this.room.getVersion())) {
1005
- return stateKey;
1006
- } else {
1007
- return "_".concat(stateKey);
1008
- }
1009
- }
1010
- }
1011
- function resendIfRateLimited(_x2) {
1012
- return _resendIfRateLimited.apply(this, arguments);
1013
- }
1014
- function _resendIfRateLimited() {
1015
- _resendIfRateLimited = _asyncToGenerator(function* (func) {
1016
- var numRetriesAllowed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
1017
- // eslint-disable-next-line no-constant-condition
1018
- while (true) {
1019
- try {
1020
- return yield func();
1021
- } catch (e) {
1022
- if (numRetriesAllowed > 0 && e instanceof HTTPError && e.isRateLimitError()) {
1023
- numRetriesAllowed--;
1024
- var resendDelay = void 0;
1025
- var defaultMs = 5000;
1026
- try {
1027
- var _e$getRetryAfterMs;
1028
- resendDelay = (_e$getRetryAfterMs = e.getRetryAfterMs()) !== null && _e$getRetryAfterMs !== void 0 ? _e$getRetryAfterMs : defaultMs;
1029
- logger.info("Rate limited by server, retrying in ".concat(resendDelay, "ms"));
1030
- } catch (e) {
1031
- logger.warn("Error while retrieving a rate-limit retry delay, retrying after default delay of ".concat(defaultMs), e);
1032
- resendDelay = defaultMs;
1033
- }
1034
- yield sleep(resendDelay);
1035
- } else {
1036
- throw e;
1037
- }
1038
- }
1039
- }
1040
- });
1041
- return _resendIfRateLimited.apply(this, arguments);
1042
- }
1043
- //# sourceMappingURL=MatrixRTCSession.js.map