@unwanted/matrix-sdk-mini 34.12.0-1 → 34.12.0-2

Sign up to get free protection for your applications and to get access to all the features.
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