livekit-client 2.0.10 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/livekit-client.e2ee.worker.js +1 -1
- package/dist/livekit-client.e2ee.worker.js.map +1 -1
- package/dist/livekit-client.e2ee.worker.mjs +203 -140
- package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
- package/dist/livekit-client.esm.mjs +3876 -6838
- package/dist/livekit-client.esm.mjs.map +1 -1
- package/dist/livekit-client.umd.js +1 -1
- package/dist/livekit-client.umd.js.map +1 -1
- package/dist/src/api/SignalClient.d.ts +2 -1
- package/dist/src/api/SignalClient.d.ts.map +1 -1
- package/dist/src/connectionHelper/ConnectionCheck.d.ts +3 -2
- package/dist/src/connectionHelper/ConnectionCheck.d.ts.map +1 -1
- package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
- package/dist/src/index.d.ts +3 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts +1 -0
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/events.d.ts +5 -1
- package/dist/src/room/events.d.ts.map +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts +1 -0
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/participant/publishUtils.d.ts.map +1 -1
- package/dist/src/room/track/LocalAudioTrack.d.ts +7 -0
- package/dist/src/room/track/LocalAudioTrack.d.ts.map +1 -1
- package/dist/src/room/track/LocalTrackPublication.d.ts +3 -2
- package/dist/src/room/track/LocalTrackPublication.d.ts.map +1 -1
- package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -1
- package/dist/src/room/track/Track.d.ts +2 -1
- package/dist/src/room/track/Track.d.ts.map +1 -1
- package/dist/src/room/track/options.d.ts +1 -1
- package/dist/src/room/track/options.d.ts.map +1 -1
- package/dist/src/room/utils.d.ts +3 -0
- package/dist/src/room/utils.d.ts.map +1 -1
- package/dist/ts4.2/src/api/SignalClient.d.ts +2 -1
- package/dist/ts4.2/src/connectionHelper/ConnectionCheck.d.ts +3 -2
- package/dist/ts4.2/src/index.d.ts +3 -2
- package/dist/ts4.2/src/room/RTCEngine.d.ts +1 -0
- package/dist/ts4.2/src/room/events.d.ts +5 -1
- package/dist/ts4.2/src/room/participant/LocalParticipant.d.ts +1 -0
- package/dist/ts4.2/src/room/track/LocalAudioTrack.d.ts +7 -0
- package/dist/ts4.2/src/room/track/LocalTrackPublication.d.ts +3 -2
- package/dist/ts4.2/src/room/track/Track.d.ts +2 -1
- package/dist/ts4.2/src/room/track/options.d.ts +1 -1
- package/dist/ts4.2/src/room/utils.d.ts +3 -0
- package/package.json +10 -10
- package/src/api/SignalClient.ts +9 -0
- package/src/connectionHelper/ConnectionCheck.ts +6 -3
- package/src/e2ee/worker/FrameCryptor.ts +0 -1
- package/src/e2ee/worker/e2ee.worker.ts +3 -1
- package/src/index.ts +3 -0
- package/src/room/RTCEngine.ts +11 -1
- package/src/room/events.ts +5 -0
- package/src/room/participant/LocalParticipant.ts +14 -0
- package/src/room/participant/publishUtils.ts +2 -1
- package/src/room/track/LocalAudioTrack.ts +40 -0
- package/src/room/track/LocalTrackPublication.ts +28 -2
- package/src/room/track/LocalVideoTrack.ts +7 -3
- package/src/room/track/Track.ts +13 -0
- package/src/room/track/options.ts +22 -1
- package/src/room/utils.ts +3 -0
@@ -55,6 +55,8 @@ var loglevel = {exports: {}};
|
|
55
55
|
var undefinedType = "undefined";
|
56
56
|
var isIE = typeof window !== undefinedType && typeof window.navigator !== undefinedType && /Trident\/|MSIE /.test(window.navigator.userAgent);
|
57
57
|
var logMethods = ["trace", "debug", "info", "warn", "error"];
|
58
|
+
var _loggersByName = {};
|
59
|
+
var defaultLogger = null;
|
58
60
|
|
59
61
|
// Cross-browser bind equivalent that works at least back to IE6
|
60
62
|
function bindMethod(obj, methodName) {
|
@@ -107,23 +109,31 @@ var loglevel = {exports: {}};
|
|
107
109
|
|
108
110
|
// These private functions always need `this` to be set properly
|
109
111
|
|
110
|
-
function replaceLoggingMethods(
|
112
|
+
function replaceLoggingMethods() {
|
111
113
|
/*jshint validthis:true */
|
114
|
+
var level = this.getLevel();
|
115
|
+
|
116
|
+
// Replace the actual methods.
|
112
117
|
for (var i = 0; i < logMethods.length; i++) {
|
113
118
|
var methodName = logMethods[i];
|
114
|
-
this[methodName] = i < level ? noop : this.methodFactory(methodName, level,
|
119
|
+
this[methodName] = i < level ? noop : this.methodFactory(methodName, level, this.name);
|
115
120
|
}
|
116
121
|
|
117
122
|
// Define log.log as an alias for log.debug
|
118
123
|
this.log = this.debug;
|
124
|
+
|
125
|
+
// Return any important warnings.
|
126
|
+
if (typeof console === undefinedType && level < this.levels.SILENT) {
|
127
|
+
return "No console available for logging";
|
128
|
+
}
|
119
129
|
}
|
120
130
|
|
121
131
|
// In old IE versions, the console isn't present until you first open it.
|
122
132
|
// We build realMethod() replacements here that regenerate logging methods
|
123
|
-
function enableLoggingWhenConsoleArrives(methodName
|
133
|
+
function enableLoggingWhenConsoleArrives(methodName) {
|
124
134
|
return function () {
|
125
135
|
if (typeof console !== undefinedType) {
|
126
|
-
replaceLoggingMethods.call(this
|
136
|
+
replaceLoggingMethods.call(this);
|
127
137
|
this[methodName].apply(this, arguments);
|
128
138
|
}
|
129
139
|
};
|
@@ -131,14 +141,34 @@ var loglevel = {exports: {}};
|
|
131
141
|
|
132
142
|
// By default, we use closely bound real methods wherever possible, and
|
133
143
|
// otherwise we wait for a console to appear, and then try again.
|
134
|
-
function defaultMethodFactory(methodName,
|
144
|
+
function defaultMethodFactory(methodName, _level, _loggerName) {
|
135
145
|
/*jshint validthis:true */
|
136
146
|
return realMethod(methodName) || enableLoggingWhenConsoleArrives.apply(this, arguments);
|
137
147
|
}
|
138
|
-
function Logger(name,
|
148
|
+
function Logger(name, factory) {
|
149
|
+
// Private instance variables.
|
139
150
|
var self = this;
|
140
|
-
|
141
|
-
|
151
|
+
/**
|
152
|
+
* The level inherited from a parent logger (or a global default). We
|
153
|
+
* cache this here rather than delegating to the parent so that it stays
|
154
|
+
* in sync with the actual logging methods that we have installed (the
|
155
|
+
* parent could change levels but we might not have rebuilt the loggers
|
156
|
+
* in this child yet).
|
157
|
+
* @type {number}
|
158
|
+
*/
|
159
|
+
var inheritedLevel;
|
160
|
+
/**
|
161
|
+
* The default level for this logger, if any. If set, this overrides
|
162
|
+
* `inheritedLevel`.
|
163
|
+
* @type {number|null}
|
164
|
+
*/
|
165
|
+
var defaultLevel;
|
166
|
+
/**
|
167
|
+
* A user-specific level for this logger. If set, this overrides
|
168
|
+
* `defaultLevel`.
|
169
|
+
* @type {number|null}
|
170
|
+
*/
|
171
|
+
var userLevel;
|
142
172
|
var storageKey = "loglevel";
|
143
173
|
if (typeof name === "string") {
|
144
174
|
storageKey += ":" + name;
|
@@ -171,9 +201,10 @@ var loglevel = {exports: {}};
|
|
171
201
|
if (typeof storedLevel === undefinedType) {
|
172
202
|
try {
|
173
203
|
var cookie = window.document.cookie;
|
174
|
-
var
|
204
|
+
var cookieName = encodeURIComponent(storageKey);
|
205
|
+
var location = cookie.indexOf(cookieName + "=");
|
175
206
|
if (location !== -1) {
|
176
|
-
storedLevel = /^([^;]+)/.exec(cookie.slice(location))[1];
|
207
|
+
storedLevel = /^([^;]+)/.exec(cookie.slice(location + cookieName.length + 1))[1];
|
177
208
|
}
|
178
209
|
} catch (ignore) {}
|
179
210
|
}
|
@@ -190,7 +221,6 @@ var loglevel = {exports: {}};
|
|
190
221
|
// Use localStorage if available
|
191
222
|
try {
|
192
223
|
window.localStorage.removeItem(storageKey);
|
193
|
-
return;
|
194
224
|
} catch (ignore) {}
|
195
225
|
|
196
226
|
// Use session cookie as fallback
|
@@ -198,6 +228,17 @@ var loglevel = {exports: {}};
|
|
198
228
|
window.document.cookie = encodeURIComponent(storageKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC";
|
199
229
|
} catch (ignore) {}
|
200
230
|
}
|
231
|
+
function normalizeLevel(input) {
|
232
|
+
var level = input;
|
233
|
+
if (typeof level === "string" && self.levels[level.toUpperCase()] !== undefined) {
|
234
|
+
level = self.levels[level.toUpperCase()];
|
235
|
+
}
|
236
|
+
if (typeof level === "number" && level >= 0 && level <= self.levels.SILENT) {
|
237
|
+
return level;
|
238
|
+
} else {
|
239
|
+
throw new TypeError("log.setLevel() called with invalid level: " + input);
|
240
|
+
}
|
241
|
+
}
|
201
242
|
|
202
243
|
/*
|
203
244
|
*
|
@@ -216,35 +257,34 @@ var loglevel = {exports: {}};
|
|
216
257
|
};
|
217
258
|
self.methodFactory = factory || defaultMethodFactory;
|
218
259
|
self.getLevel = function () {
|
219
|
-
|
260
|
+
if (userLevel != null) {
|
261
|
+
return userLevel;
|
262
|
+
} else if (defaultLevel != null) {
|
263
|
+
return defaultLevel;
|
264
|
+
} else {
|
265
|
+
return inheritedLevel;
|
266
|
+
}
|
220
267
|
};
|
221
268
|
self.setLevel = function (level, persist) {
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
currentLevel = level;
|
227
|
-
if (persist !== false) {
|
228
|
-
// defaults to true
|
229
|
-
persistLevelIfPossible(level);
|
230
|
-
}
|
231
|
-
replaceLoggingMethods.call(self, level, name);
|
232
|
-
if (typeof console === undefinedType && level < self.levels.SILENT) {
|
233
|
-
return "No console available for logging";
|
234
|
-
}
|
235
|
-
} else {
|
236
|
-
throw "log.setLevel() called with invalid level: " + level;
|
269
|
+
userLevel = normalizeLevel(level);
|
270
|
+
if (persist !== false) {
|
271
|
+
// defaults to true
|
272
|
+
persistLevelIfPossible(userLevel);
|
237
273
|
}
|
274
|
+
|
275
|
+
// NOTE: in v2, this should call rebuild(), which updates children.
|
276
|
+
return replaceLoggingMethods.call(self);
|
238
277
|
};
|
239
278
|
self.setDefaultLevel = function (level) {
|
240
|
-
defaultLevel = level;
|
279
|
+
defaultLevel = normalizeLevel(level);
|
241
280
|
if (!getPersistedLevel()) {
|
242
281
|
self.setLevel(level, false);
|
243
282
|
}
|
244
283
|
};
|
245
284
|
self.resetLevel = function () {
|
246
|
-
|
285
|
+
userLevel = null;
|
247
286
|
clearPersistedLevel();
|
287
|
+
replaceLoggingMethods.call(self);
|
248
288
|
};
|
249
289
|
self.enableAll = function (persist) {
|
250
290
|
self.setLevel(self.levels.TRACE, persist);
|
@@ -252,13 +292,25 @@ var loglevel = {exports: {}};
|
|
252
292
|
self.disableAll = function (persist) {
|
253
293
|
self.setLevel(self.levels.SILENT, persist);
|
254
294
|
};
|
295
|
+
self.rebuild = function () {
|
296
|
+
if (defaultLogger !== self) {
|
297
|
+
inheritedLevel = normalizeLevel(defaultLogger.getLevel());
|
298
|
+
}
|
299
|
+
replaceLoggingMethods.call(self);
|
300
|
+
if (defaultLogger === self) {
|
301
|
+
for (var childName in _loggersByName) {
|
302
|
+
_loggersByName[childName].rebuild();
|
303
|
+
}
|
304
|
+
}
|
305
|
+
};
|
255
306
|
|
256
|
-
// Initialize
|
307
|
+
// Initialize all the internal levels.
|
308
|
+
inheritedLevel = normalizeLevel(defaultLogger ? defaultLogger.getLevel() : "WARN");
|
257
309
|
var initialLevel = getPersistedLevel();
|
258
|
-
if (initialLevel
|
259
|
-
|
310
|
+
if (initialLevel != null) {
|
311
|
+
userLevel = normalizeLevel(initialLevel);
|
260
312
|
}
|
261
|
-
|
313
|
+
replaceLoggingMethods.call(self);
|
262
314
|
}
|
263
315
|
|
264
316
|
/*
|
@@ -267,15 +319,14 @@ var loglevel = {exports: {}};
|
|
267
319
|
*
|
268
320
|
*/
|
269
321
|
|
270
|
-
|
271
|
-
var _loggersByName = {};
|
322
|
+
defaultLogger = new Logger();
|
272
323
|
defaultLogger.getLogger = function getLogger(name) {
|
273
324
|
if (typeof name !== "symbol" && typeof name !== "string" || name === "") {
|
274
325
|
throw new TypeError("You must supply a name when creating a logger.");
|
275
326
|
}
|
276
327
|
var logger = _loggersByName[name];
|
277
328
|
if (!logger) {
|
278
|
-
logger = _loggersByName[name] = new Logger(name, defaultLogger.
|
329
|
+
logger = _loggersByName[name] = new Logger(name, defaultLogger.methodFactory);
|
279
330
|
}
|
280
331
|
return logger;
|
281
332
|
};
|
@@ -811,14 +862,16 @@ var eventsExports = events.exports;
|
|
811
862
|
function isVideoFrame(frame) {
|
812
863
|
return 'type' in frame;
|
813
864
|
}
|
814
|
-
function importKey(
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
865
|
+
function importKey(keyBytes_1) {
|
866
|
+
return __awaiter(this, arguments, void 0, function (keyBytes) {
|
867
|
+
let algorithm = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
|
868
|
+
name: ENCRYPTION_ALGORITHM
|
869
|
+
};
|
870
|
+
let usage = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'encrypt';
|
871
|
+
return function* () {
|
872
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey
|
873
|
+
return crypto.subtle.importKey('raw', keyBytes, algorithm, false, usage === 'derive' ? ['deriveBits', 'deriveKey'] : ['encrypt', 'decrypt']);
|
874
|
+
}();
|
822
875
|
});
|
823
876
|
}
|
824
877
|
function getAlgoOptions(algorithmName, salt) {
|
@@ -1091,8 +1144,8 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
1091
1144
|
* 9) Enqueue the encrypted frame for sending.
|
1092
1145
|
*/
|
1093
1146
|
encodeFunction(encodedFrame, controller) {
|
1094
|
-
var _a;
|
1095
1147
|
return __awaiter(this, void 0, void 0, function* () {
|
1148
|
+
var _a;
|
1096
1149
|
if (!this.isEnabled() ||
|
1097
1150
|
// skip for encryption for empty dtx frames
|
1098
1151
|
encodedFrame.data.byteLength === 0) {
|
@@ -1210,89 +1263,92 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
1210
1263
|
* Function that will decrypt the given encoded frame. If the decryption fails, it will
|
1211
1264
|
* ratchet the key for up to RATCHET_WINDOW_SIZE times.
|
1212
1265
|
*/
|
1213
|
-
decryptFrame(
|
1214
|
-
|
1215
|
-
|
1216
|
-
|
1217
|
-
|
1218
|
-
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
|
1224
|
-
|
1225
|
-
// Construct frame trailer. Similar to the frame header described in
|
1226
|
-
// https://tools.ietf.org/html/draft-omara-sframe-00#section-4.2
|
1227
|
-
// but we put it at the end.
|
1228
|
-
//
|
1229
|
-
// ---------+-------------------------+-+---------+----
|
1230
|
-
// payload |IV...(length = IV_LENGTH)|R|IV_LENGTH|KID |
|
1231
|
-
// ---------+-------------------------+-+---------+----
|
1232
|
-
try {
|
1233
|
-
const frameHeader = new Uint8Array(encodedFrame.data, 0, frameInfo.unencryptedBytes);
|
1234
|
-
var encryptedData = new Uint8Array(encodedFrame.data, frameHeader.length, encodedFrame.data.byteLength - frameHeader.length);
|
1235
|
-
if (frameInfo.isH264 && needsRbspUnescaping(encryptedData)) {
|
1236
|
-
encryptedData = parseRbsp(encryptedData);
|
1237
|
-
const newUint8 = new Uint8Array(frameHeader.byteLength + encryptedData.byteLength);
|
1238
|
-
newUint8.set(frameHeader);
|
1239
|
-
newUint8.set(encryptedData, frameHeader.byteLength);
|
1240
|
-
encodedFrame.data = newUint8.buffer;
|
1266
|
+
decryptFrame(encodedFrame_1, keyIndex_1) {
|
1267
|
+
return __awaiter(this, arguments, void 0, function (encodedFrame, keyIndex) {
|
1268
|
+
var _this = this;
|
1269
|
+
let initialMaterial = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;
|
1270
|
+
let ratchetOpts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {
|
1271
|
+
ratchetCount: 0
|
1272
|
+
};
|
1273
|
+
return function* () {
|
1274
|
+
var _a;
|
1275
|
+
const keySet = _this.keys.getKeySet(keyIndex);
|
1276
|
+
if (!ratchetOpts.encryptionKey && !keySet) {
|
1277
|
+
throw new TypeError("no encryption key found for decryption of ".concat(_this.participantIdentity));
|
1241
1278
|
}
|
1242
|
-
|
1243
|
-
|
1244
|
-
|
1245
|
-
|
1246
|
-
|
1247
|
-
|
1248
|
-
|
1249
|
-
|
1250
|
-
|
1251
|
-
|
1252
|
-
|
1253
|
-
|
1254
|
-
|
1255
|
-
|
1256
|
-
|
1257
|
-
|
1258
|
-
|
1259
|
-
|
1260
|
-
|
1261
|
-
|
1262
|
-
|
1263
|
-
|
1264
|
-
|
1265
|
-
|
1266
|
-
|
1267
|
-
|
1268
|
-
|
1269
|
-
|
1270
|
-
|
1271
|
-
|
1272
|
-
|
1273
|
-
|
1274
|
-
|
1275
|
-
|
1276
|
-
|
1277
|
-
|
1278
|
-
|
1279
|
-
|
1279
|
+
let frameInfo = _this.getUnencryptedBytes(encodedFrame);
|
1280
|
+
// Construct frame trailer. Similar to the frame header described in
|
1281
|
+
// https://tools.ietf.org/html/draft-omara-sframe-00#section-4.2
|
1282
|
+
// but we put it at the end.
|
1283
|
+
//
|
1284
|
+
// ---------+-------------------------+-+---------+----
|
1285
|
+
// payload |IV...(length = IV_LENGTH)|R|IV_LENGTH|KID |
|
1286
|
+
// ---------+-------------------------+-+---------+----
|
1287
|
+
try {
|
1288
|
+
const frameHeader = new Uint8Array(encodedFrame.data, 0, frameInfo.unencryptedBytes);
|
1289
|
+
var encryptedData = new Uint8Array(encodedFrame.data, frameHeader.length, encodedFrame.data.byteLength - frameHeader.length);
|
1290
|
+
if (frameInfo.isH264 && needsRbspUnescaping(encryptedData)) {
|
1291
|
+
encryptedData = parseRbsp(encryptedData);
|
1292
|
+
const newUint8 = new Uint8Array(frameHeader.byteLength + encryptedData.byteLength);
|
1293
|
+
newUint8.set(frameHeader);
|
1294
|
+
newUint8.set(encryptedData, frameHeader.byteLength);
|
1295
|
+
encodedFrame.data = newUint8.buffer;
|
1296
|
+
}
|
1297
|
+
const frameTrailer = new Uint8Array(encodedFrame.data, encodedFrame.data.byteLength - 2, 2);
|
1298
|
+
const ivLength = frameTrailer[0];
|
1299
|
+
const iv = new Uint8Array(encodedFrame.data, encodedFrame.data.byteLength - ivLength - frameTrailer.byteLength, ivLength);
|
1300
|
+
const cipherTextStart = frameHeader.byteLength;
|
1301
|
+
const cipherTextLength = encodedFrame.data.byteLength - (frameHeader.byteLength + ivLength + frameTrailer.byteLength);
|
1302
|
+
const plainText = yield crypto.subtle.decrypt({
|
1303
|
+
name: ENCRYPTION_ALGORITHM,
|
1304
|
+
iv,
|
1305
|
+
additionalData: new Uint8Array(encodedFrame.data, 0, frameHeader.byteLength)
|
1306
|
+
}, (_a = ratchetOpts.encryptionKey) !== null && _a !== void 0 ? _a : keySet.encryptionKey, new Uint8Array(encodedFrame.data, cipherTextStart, cipherTextLength));
|
1307
|
+
const newData = new ArrayBuffer(frameHeader.byteLength + plainText.byteLength);
|
1308
|
+
const newUint8 = new Uint8Array(newData);
|
1309
|
+
newUint8.set(new Uint8Array(encodedFrame.data, 0, frameHeader.byteLength));
|
1310
|
+
newUint8.set(new Uint8Array(plainText), frameHeader.byteLength);
|
1311
|
+
encodedFrame.data = newData;
|
1312
|
+
return encodedFrame;
|
1313
|
+
} catch (error) {
|
1314
|
+
if (_this.keyProviderOptions.ratchetWindowSize > 0) {
|
1315
|
+
if (ratchetOpts.ratchetCount < _this.keyProviderOptions.ratchetWindowSize) {
|
1316
|
+
workerLogger.debug("ratcheting key attempt ".concat(ratchetOpts.ratchetCount, " of ").concat(_this.keyProviderOptions.ratchetWindowSize, ", for kind ").concat(encodedFrame instanceof RTCEncodedAudioFrame ? 'audio' : 'video'));
|
1317
|
+
let ratchetedKeySet;
|
1318
|
+
if ((initialMaterial !== null && initialMaterial !== void 0 ? initialMaterial : keySet) === _this.keys.getKeySet(keyIndex)) {
|
1319
|
+
// only ratchet if the currently set key is still the same as the one used to decrypt this frame
|
1320
|
+
// if not, it might be that a different frame has already ratcheted and we try with that one first
|
1321
|
+
const newMaterial = yield _this.keys.ratchetKey(keyIndex, false);
|
1322
|
+
ratchetedKeySet = yield deriveKeys(newMaterial, _this.keyProviderOptions.ratchetSalt);
|
1280
1323
|
}
|
1324
|
+
const frame = yield _this.decryptFrame(encodedFrame, keyIndex, initialMaterial || keySet, {
|
1325
|
+
ratchetCount: ratchetOpts.ratchetCount + 1,
|
1326
|
+
encryptionKey: ratchetedKeySet === null || ratchetedKeySet === void 0 ? void 0 : ratchetedKeySet.encryptionKey
|
1327
|
+
});
|
1328
|
+
if (frame && ratchetedKeySet) {
|
1329
|
+
// before updating the keys, make sure that the keySet used for this frame is still the same as the currently set key
|
1330
|
+
// if it's not, a new key might have been set already, which we don't want to override
|
1331
|
+
if ((initialMaterial !== null && initialMaterial !== void 0 ? initialMaterial : keySet) === _this.keys.getKeySet(keyIndex)) {
|
1332
|
+
_this.keys.setKeySet(ratchetedKeySet, keyIndex, true);
|
1333
|
+
// decryption was successful, set the new key index to reflect the ratcheted key set
|
1334
|
+
_this.keys.setCurrentKeyIndex(keyIndex);
|
1335
|
+
}
|
1336
|
+
}
|
1337
|
+
return frame;
|
1338
|
+
} else {
|
1339
|
+
/**
|
1340
|
+
* Because we only set a new key once decryption has been successful,
|
1341
|
+
* we can be sure that we don't need to reset the key to the initial material at this point
|
1342
|
+
* as the key has not been updated on the keyHandler instance
|
1343
|
+
*/
|
1344
|
+
workerLogger.warn('maximum ratchet attempts exceeded');
|
1345
|
+
throw new CryptorError("valid key missing for participant ".concat(_this.participantIdentity), CryptorErrorReason.InvalidKey);
|
1281
1346
|
}
|
1282
|
-
return frame;
|
1283
1347
|
} else {
|
1284
|
-
|
1285
|
-
* Because we only set a new key once decryption has been successful,
|
1286
|
-
* we can be sure that we don't need to reset the key to the initial material at this point
|
1287
|
-
* as the key has not been updated on the keyHandler instance
|
1288
|
-
*/
|
1289
|
-
workerLogger.warn('maximum ratchet attempts exceeded');
|
1290
|
-
throw new CryptorError("valid key missing for participant ".concat(this.participantIdentity), CryptorErrorReason.InvalidKey);
|
1348
|
+
throw new CryptorError("Decryption failed: ".concat(error.message), CryptorErrorReason.InvalidKey);
|
1291
1349
|
}
|
1292
|
-
} else {
|
1293
|
-
throw new CryptorError("Decryption failed: ".concat(error.message), CryptorErrorReason.InvalidKey);
|
1294
1350
|
}
|
1295
|
-
}
|
1351
|
+
}();
|
1296
1352
|
});
|
1297
1353
|
}
|
1298
1354
|
/**
|
@@ -1388,7 +1444,6 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
1388
1444
|
if (this.rtpMap.size === 0) {
|
1389
1445
|
return undefined;
|
1390
1446
|
}
|
1391
|
-
// @ts-expect-error payloadType is not yet part of the typescript definition and currently not supported in Safari
|
1392
1447
|
const payloadType = frame.getMetadata().payloadType;
|
1393
1448
|
const codec = payloadType ? this.rtpMap.get(payloadType) : undefined;
|
1394
1449
|
return codec;
|
@@ -1572,11 +1627,14 @@ class ParticipantKeyHandler extends eventsExports.EventEmitter {
|
|
1572
1627
|
* together with the material
|
1573
1628
|
* also resets the valid key property and updates the currentKeyIndex
|
1574
1629
|
*/
|
1575
|
-
setKey(
|
1576
|
-
|
1577
|
-
|
1578
|
-
|
1579
|
-
|
1630
|
+
setKey(material_1) {
|
1631
|
+
return __awaiter(this, arguments, void 0, function (material) {
|
1632
|
+
var _this = this;
|
1633
|
+
let keyIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
1634
|
+
return function* () {
|
1635
|
+
yield _this.setKeyFromMaterial(material, keyIndex);
|
1636
|
+
_this.resetKeyStatus();
|
1637
|
+
}();
|
1580
1638
|
});
|
1581
1639
|
}
|
1582
1640
|
/**
|
@@ -1585,18 +1643,21 @@ class ParticipantKeyHandler extends eventsExports.EventEmitter {
|
|
1585
1643
|
* together with the material
|
1586
1644
|
* also updates the currentKeyIndex
|
1587
1645
|
*/
|
1588
|
-
setKeyFromMaterial(
|
1589
|
-
|
1590
|
-
|
1591
|
-
|
1592
|
-
|
1593
|
-
|
1594
|
-
|
1595
|
-
|
1596
|
-
|
1597
|
-
|
1598
|
-
|
1599
|
-
|
1646
|
+
setKeyFromMaterial(material_1, keyIndex_1) {
|
1647
|
+
return __awaiter(this, arguments, void 0, function (material, keyIndex) {
|
1648
|
+
var _this2 = this;
|
1649
|
+
let emitRatchetEvent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
1650
|
+
return function* () {
|
1651
|
+
const keySet = yield deriveKeys(material, _this2.keyProviderOptions.ratchetSalt);
|
1652
|
+
const newIndex = keyIndex >= 0 ? keyIndex % _this2.cryptoKeyRing.length : _this2.currentKeyIndex;
|
1653
|
+
workerLogger.debug("setting new key with index ".concat(keyIndex), {
|
1654
|
+
usage: material.usages,
|
1655
|
+
algorithm: material.algorithm,
|
1656
|
+
ratchetSalt: _this2.keyProviderOptions.ratchetSalt
|
1657
|
+
});
|
1658
|
+
_this2.setKeySet(keySet, newIndex, emitRatchetEvent);
|
1659
|
+
if (newIndex >= 0) _this2.currentKeyIndex = newIndex;
|
1660
|
+
}();
|
1600
1661
|
});
|
1601
1662
|
}
|
1602
1663
|
setKeySet(keySet, keyIndex) {
|
@@ -1831,8 +1892,10 @@ if (self.RTCTransformEvent) {
|
|
1831
1892
|
workerLogger.debug('setup transform event');
|
1832
1893
|
// @ts-ignore
|
1833
1894
|
self.onrtctransform = event => {
|
1895
|
+
// @ts-ignore .transformer property is part of RTCTransformEvent
|
1834
1896
|
const transformer = event.transformer;
|
1835
1897
|
workerLogger.debug('transformer', transformer);
|
1898
|
+
// @ts-ignore monkey patching non standard flag
|
1836
1899
|
transformer.handled = true;
|
1837
1900
|
const {
|
1838
1901
|
kind,
|