livekit-client 2.0.2 → 2.0.3
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 +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) {
|