livekit-client 2.0.2 → 2.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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 +52 -17
- package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
- package/dist/livekit-client.esm.mjs +69 -40
- 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/e2ee/KeyProvider.d.ts +1 -1
- package/dist/src/e2ee/KeyProvider.d.ts.map +1 -1
- package/dist/src/e2ee/worker/FrameCryptor.d.ts +1 -0
- package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
- package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts +2 -2
- package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts +1 -0
- package/dist/src/room/Room.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/track/LocalAudioTrack.d.ts.map +1 -1
- package/dist/src/room/track/LocalTrack.d.ts +1 -0
- package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
- package/dist/src/room/track/Track.d.ts +2 -0
- package/dist/src/room/track/Track.d.ts.map +1 -1
- package/dist/ts4.2/src/e2ee/KeyProvider.d.ts +1 -1
- package/dist/ts4.2/src/e2ee/worker/FrameCryptor.d.ts +1 -0
- package/dist/ts4.2/src/e2ee/worker/ParticipantKeyHandler.d.ts +2 -2
- package/dist/ts4.2/src/room/Room.d.ts +1 -0
- package/dist/ts4.2/src/room/events.d.ts +5 -1
- package/dist/ts4.2/src/room/track/LocalTrack.d.ts +1 -0
- package/dist/ts4.2/src/room/track/Track.d.ts +2 -0
- package/package.json +1 -1
- package/src/e2ee/KeyProvider.ts +6 -1
- package/src/e2ee/worker/FrameCryptor.ts +26 -0
- package/src/e2ee/worker/ParticipantKeyHandler.ts +9 -5
- package/src/e2ee/worker/e2ee.worker.ts +16 -17
- package/src/room/Room.ts +18 -4
- package/src/room/events.ts +4 -0
- package/src/room/track/LocalAudioTrack.ts +1 -0
- package/src/room/track/LocalTrack.ts +42 -33
- package/src/room/track/Track.ts +2 -0
@@ -987,6 +987,13 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
987
987
|
this.sifTrailer = (_a = opts.sifTrailer) !== null && _a !== void 0 ? _a : Uint8Array.from([]);
|
988
988
|
this.sifGuard = new SifGuard();
|
989
989
|
}
|
990
|
+
get logContext() {
|
991
|
+
return {
|
992
|
+
identity: this.participantIdentity,
|
993
|
+
trackId: this.trackId,
|
994
|
+
fallbackCodec: this.videoCodec
|
995
|
+
};
|
996
|
+
}
|
990
997
|
/**
|
991
998
|
* Assign a different participant to the cryptor.
|
992
999
|
* useful for transceiver re-use
|
@@ -999,6 +1006,7 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
999
1006
|
this.sifGuard.reset();
|
1000
1007
|
}
|
1001
1008
|
unsetParticipant() {
|
1009
|
+
workerLogger.debug('unsetting participant', this.logContext);
|
1002
1010
|
this.participantIdentity = undefined;
|
1003
1011
|
}
|
1004
1012
|
isEnabled() {
|
@@ -1035,6 +1043,11 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
1035
1043
|
});
|
1036
1044
|
this.videoCodec = codec;
|
1037
1045
|
}
|
1046
|
+
workerLogger.debug('Setting up frame cryptor transform', Object.assign({
|
1047
|
+
operation,
|
1048
|
+
passedTrackId: trackId,
|
1049
|
+
codec
|
1050
|
+
}, this.logContext));
|
1038
1051
|
const transformFn = operation === 'encode' ? this.encodeFunction : this.decodeFunction;
|
1039
1052
|
const transformStream = new TransformStream({
|
1040
1053
|
transform: transformFn.bind(this)
|
@@ -1046,6 +1059,9 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
1046
1059
|
this.trackId = trackId;
|
1047
1060
|
}
|
1048
1061
|
setSifTrailer(trailer) {
|
1062
|
+
workerLogger.debug('setting SIF trailer', Object.assign(Object.assign({}, this.logContext), {
|
1063
|
+
trailer
|
1064
|
+
}));
|
1049
1065
|
this.sifTrailer = trailer;
|
1050
1066
|
}
|
1051
1067
|
/**
|
@@ -1089,6 +1105,7 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
1089
1105
|
if (encryptionKey) {
|
1090
1106
|
const iv = this.makeIV((_a = encodedFrame.getMetadata().synchronizationSource) !== null && _a !== void 0 ? _a : -1, encodedFrame.timestamp);
|
1091
1107
|
let frameInfo = this.getUnencryptedBytes(encodedFrame);
|
1108
|
+
workerLogger.debug('frameInfo for encoded frame', Object.assign(Object.assign({}, frameInfo), this.logContext));
|
1092
1109
|
// Thіs is not encrypted and contains the VP8 payload descriptor or the Opus TOC byte.
|
1093
1110
|
const frameHeader = new Uint8Array(encodedFrame.data, 0, frameInfo.unencryptedBytes);
|
1094
1111
|
// Frame trailer contains the R|IV_LENGTH and key index
|
@@ -1125,6 +1142,7 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
1125
1142
|
workerLogger.error(e);
|
1126
1143
|
}
|
1127
1144
|
} else {
|
1145
|
+
workerLogger.debug('failed to decrypt, emitting error', this.logContext);
|
1128
1146
|
this.emit(CryptorEvent.Error, new CryptorError("encryption key missing for encoding", CryptorErrorReason.MissingKey));
|
1129
1147
|
}
|
1130
1148
|
});
|
@@ -1140,10 +1158,12 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
1140
1158
|
if (!this.isEnabled() ||
|
1141
1159
|
// skip for decryption for empty dtx frames
|
1142
1160
|
encodedFrame.data.byteLength === 0) {
|
1161
|
+
workerLogger.debug('skipping empty frame', this.logContext);
|
1143
1162
|
this.sifGuard.recordUserFrame();
|
1144
1163
|
return controller.enqueue(encodedFrame);
|
1145
1164
|
}
|
1146
1165
|
if (isFrameServerInjected(encodedFrame.data, this.sifTrailer)) {
|
1166
|
+
workerLogger.debug('enqueue SIF', this.logContext);
|
1147
1167
|
this.sifGuard.recordSif();
|
1148
1168
|
if (this.sifGuard.isSifAllowed()) {
|
1149
1169
|
encodedFrame.data = encodedFrame.data.slice(0, encodedFrame.data.byteLength - this.sifTrailer.byteLength);
|
@@ -1162,6 +1182,7 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
1162
1182
|
const decodedFrame = yield this.decryptFrame(encodedFrame, keyIndex);
|
1163
1183
|
this.keys.decryptionSuccess();
|
1164
1184
|
if (decodedFrame) {
|
1185
|
+
workerLogger.debug('enqueue decrypted frame', this.logContext);
|
1165
1186
|
return controller.enqueue(decodedFrame);
|
1166
1187
|
}
|
1167
1188
|
} catch (error) {
|
@@ -1199,6 +1220,7 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
1199
1220
|
throw new TypeError("no encryption key found for decryption of ".concat(this.participantIdentity));
|
1200
1221
|
}
|
1201
1222
|
let frameInfo = this.getUnencryptedBytes(encodedFrame);
|
1223
|
+
workerLogger.debug('frameInfo for decoded frame', Object.assign(Object.assign({}, frameInfo), this.logContext));
|
1202
1224
|
// Construct frame trailer. Similar to the frame header described in
|
1203
1225
|
// https://tools.ietf.org/html/draft-omara-sframe-00#section-4.2
|
1204
1226
|
// but we put it at the end.
|
@@ -1361,6 +1383,9 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
1361
1383
|
// @ts-expect-error payloadType is not yet part of the typescript definition and currently not supported in Safari
|
1362
1384
|
const payloadType = frame.getMetadata().payloadType;
|
1363
1385
|
const codec = payloadType ? this.rtpMap.get(payloadType) : undefined;
|
1386
|
+
workerLogger.debug('reading codec from frame', Object.assign({
|
1387
|
+
codec
|
1388
|
+
}, this.logContext));
|
1364
1389
|
return codec;
|
1365
1390
|
}
|
1366
1391
|
}
|
@@ -1548,18 +1573,21 @@ class ParticipantKeyHandler extends eventsExports.EventEmitter {
|
|
1548
1573
|
}
|
1549
1574
|
/**
|
1550
1575
|
* takes in a key material with `deriveBits` and `deriveKey` set as key usages
|
1551
|
-
* and derives encryption keys from the material and sets it on the key ring
|
1576
|
+
* and derives encryption keys from the material and sets it on the key ring buffers
|
1552
1577
|
* together with the material
|
1553
1578
|
* also updates the currentKeyIndex
|
1554
1579
|
*/
|
1555
|
-
setKeyFromMaterial(material) {
|
1556
|
-
let keyIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
1580
|
+
setKeyFromMaterial(material, keyIndex) {
|
1557
1581
|
let emitRatchetEvent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
1558
1582
|
return __awaiter(this, void 0, void 0, function* () {
|
1559
|
-
const newIndex = keyIndex >= 0 ? keyIndex % this.cryptoKeyRing.length : -1;
|
1560
|
-
workerLogger.debug("setting new key with index ".concat(newIndex));
|
1561
1583
|
const keySet = yield deriveKeys(material, this.keyProviderOptions.ratchetSalt);
|
1562
|
-
|
1584
|
+
const newIndex = keyIndex >= 0 ? keyIndex % this.cryptoKeyRing.length : this.currentKeyIndex;
|
1585
|
+
workerLogger.debug("setting new key with index ".concat(keyIndex), {
|
1586
|
+
usage: material.usages,
|
1587
|
+
algorithm: material.algorithm,
|
1588
|
+
ratchetSalt: this.keyProviderOptions.ratchetSalt
|
1589
|
+
});
|
1590
|
+
this.setKeySet(keySet, newIndex, emitRatchetEvent);
|
1563
1591
|
if (newIndex >= 0) this.currentKeyIndex = newIndex;
|
1564
1592
|
});
|
1565
1593
|
}
|
@@ -1594,7 +1622,6 @@ const participantKeys = new Map();
|
|
1594
1622
|
let sharedKeyHandler;
|
1595
1623
|
let isEncryptionEnabled = false;
|
1596
1624
|
let useSharedKey = false;
|
1597
|
-
let sharedKey;
|
1598
1625
|
let sifTrailer;
|
1599
1626
|
let keyProviderOptions = KEY_PROVIDER_DEFAULTS;
|
1600
1627
|
workerLogger.setDefaultLevel('info');
|
@@ -1633,10 +1660,9 @@ onmessage = ev => {
|
|
1633
1660
|
break;
|
1634
1661
|
case 'setKey':
|
1635
1662
|
if (useSharedKey) {
|
1636
|
-
workerLogger.warn('set shared key');
|
1637
1663
|
setSharedKey(data.key, data.keyIndex);
|
1638
1664
|
} else if (data.participantIdentity) {
|
1639
|
-
workerLogger.
|
1665
|
+
workerLogger.info("set participant sender key ".concat(data.participantIdentity, " index ").concat(data.keyIndex));
|
1640
1666
|
getParticipantKeyHandler(data.participantIdentity).setKey(data.key, data.keyIndex);
|
1641
1667
|
} else {
|
1642
1668
|
workerLogger.error('no participant Id was provided and shared key usage is disabled');
|
@@ -1680,7 +1706,7 @@ function handleRatchetRequest(data) {
|
|
1680
1706
|
});
|
1681
1707
|
}
|
1682
1708
|
function getTrackCryptor(participantIdentity, trackId) {
|
1683
|
-
let cryptor = participantCryptors.find(c => c.
|
1709
|
+
let cryptor = participantCryptors.find(c => c.getTrackId() === trackId);
|
1684
1710
|
if (!cryptor) {
|
1685
1711
|
workerLogger.info('creating new cryptor for', {
|
1686
1712
|
participantIdentity
|
@@ -1709,9 +1735,6 @@ function getParticipantKeyHandler(participantIdentity) {
|
|
1709
1735
|
let keys = participantKeys.get(participantIdentity);
|
1710
1736
|
if (!keys) {
|
1711
1737
|
keys = new ParticipantKeyHandler(participantIdentity, keyProviderOptions);
|
1712
|
-
if (sharedKey) {
|
1713
|
-
keys.setKey(sharedKey);
|
1714
|
-
}
|
1715
1738
|
keys.on(KeyHandlerEvent.KeyRatcheted, emitRatchetedKeys);
|
1716
1739
|
participantKeys.set(participantIdentity, keys);
|
1717
1740
|
}
|
@@ -1719,20 +1742,32 @@ function getParticipantKeyHandler(participantIdentity) {
|
|
1719
1742
|
}
|
1720
1743
|
function getSharedKeyHandler() {
|
1721
1744
|
if (!sharedKeyHandler) {
|
1745
|
+
workerLogger.debug('creating new shared key handler');
|
1722
1746
|
sharedKeyHandler = new ParticipantKeyHandler('shared-key', keyProviderOptions);
|
1723
1747
|
}
|
1724
1748
|
return sharedKeyHandler;
|
1725
1749
|
}
|
1726
1750
|
function unsetCryptorParticipant(trackId, participantIdentity) {
|
1727
|
-
|
1728
|
-
|
1751
|
+
const cryptor = participantCryptors.find(c => c.getParticipantIdentity() === participantIdentity && c.getTrackId() === trackId);
|
1752
|
+
if (!cryptor) {
|
1753
|
+
workerLogger.warn('Could not unset participant on cryptor', {
|
1754
|
+
trackId,
|
1755
|
+
participantIdentity
|
1756
|
+
});
|
1757
|
+
} else {
|
1758
|
+
cryptor.unsetParticipant();
|
1759
|
+
}
|
1729
1760
|
}
|
1730
1761
|
function setEncryptionEnabled(enable, participantIdentity) {
|
1762
|
+
workerLogger.debug("setting encryption enabled for all tracks of ".concat(participantIdentity), {
|
1763
|
+
enable
|
1764
|
+
});
|
1731
1765
|
encryptionEnabledMap.set(participantIdentity, enable);
|
1732
1766
|
}
|
1733
1767
|
function setSharedKey(key, index) {
|
1734
|
-
workerLogger.
|
1735
|
-
|
1768
|
+
workerLogger.info('set shared key', {
|
1769
|
+
index
|
1770
|
+
});
|
1736
1771
|
getSharedKeyHandler().setKey(key, index);
|
1737
1772
|
}
|
1738
1773
|
function setupCryptorErrorEvents(cryptor) {
|