livekit-client 1.13.3 → 1.13.4
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/README.md +2 -2
- 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 +86 -16
- package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
- package/dist/livekit-client.esm.mjs +87 -8
- 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/utils.d.ts +3 -0
- package/dist/src/e2ee/utils.d.ts.map +1 -1
- package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/track/LocalTrack.d.ts +7 -0
- package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
- package/dist/src/room/track/RemoteTrack.d.ts +7 -0
- package/dist/src/room/track/RemoteTrack.d.ts.map +1 -1
- package/dist/ts4.2/src/e2ee/utils.d.ts +3 -0
- package/dist/ts4.2/src/room/track/LocalTrack.d.ts +7 -0
- package/dist/ts4.2/src/room/track/RemoteTrack.d.ts +7 -0
- package/package.json +1 -1
- package/src/e2ee/utils.ts +52 -0
- package/src/e2ee/worker/FrameCryptor.ts +45 -27
- package/src/room/RTCEngine.ts +3 -2
- package/src/room/Room.ts +3 -3
- package/src/room/participant/LocalParticipant.ts +2 -2
- package/src/room/track/LocalTrack.ts +14 -0
- package/src/room/track/RemoteTrack.ts +14 -0
package/README.md
CHANGED
@@ -121,9 +121,9 @@ function handleTrackUnsubscribed(
|
|
121
121
|
track.detach();
|
122
122
|
}
|
123
123
|
|
124
|
-
function handleLocalTrackUnpublished(
|
124
|
+
function handleLocalTrackUnpublished(publication: LocalTrackPublication, participant: LocalParticipant) {
|
125
125
|
// when local tracks are ended, update UI to remove them from rendering
|
126
|
-
track.detach();
|
126
|
+
publication.track.detach();
|
127
127
|
}
|
128
128
|
|
129
129
|
function handleActiveSpeakerChange(speakers: Participant[]) {
|
@@ -1,2 +1,2 @@
|
|
1
|
-
!function(e){"function"==typeof define&&define.amd?define(e):e()}((function(){"use strict";function e(e,t,n,r){return new(n||(n=Promise))((function(i,o){function s(e){try{c(r.next(e))}catch(e){o(e)}}function a(e){try{c(r.throw(e))}catch(e){o(e)}}function c(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(s,a)}c((r=r.apply(e,t||[])).next())}))}var t,n,r,i="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},o={exports:{}};n=i,r=function(){var e=function(){},t="undefined",n=typeof window!==t&&typeof window.navigator!==t&&/Trident\/|MSIE /.test(window.navigator.userAgent),r=["trace","debug","info","warn","error"];function i(e,t){var n=e[t];if("function"==typeof n.bind)return n.bind(e);try{return Function.prototype.bind.call(n,e)}catch(t){return function(){return Function.prototype.apply.apply(n,[e,arguments])}}}function o(){console.log&&(console.log.apply?console.log.apply(console,arguments):Function.prototype.apply.apply(console.log,[console,arguments])),console.trace&&console.trace()}function s(t,n){for(var i=0;i<r.length;i++){var o=r[i];this[o]=i<t?e:this.methodFactory(o,t,n)}this.log=this.debug}function a(e,n,r){return function(){typeof console!==t&&(s.call(this,n,r),this[e].apply(this,arguments))}}function c(r,s,c){return function(r){return"debug"===r&&(r="log"),typeof console!==t&&("trace"===r&&n?o:void 0!==console[r]?i(console,r):void 0!==console.log?i(console,"log"):e)}(r)||a.apply(this,arguments)}function d(e,n,i){var o,a=this;n=null==n?"WARN":n;var d="loglevel";function u(){var e;if(typeof window!==t&&d){try{e=window.localStorage[d]}catch(e){}if(typeof e===t)try{var n=window.document.cookie,r=n.indexOf(encodeURIComponent(d)+"=");-1!==r&&(e=/^([^;]+)/.exec(n.slice(r))[1])}catch(e){}return void 0===a.levels[e]&&(e=void 0),e}}"string"==typeof e?d+=":"+e:"symbol"==typeof e&&(d=void 0),a.name=e,a.levels={TRACE:0,DEBUG:1,INFO:2,WARN:3,ERROR:4,SILENT:5},a.methodFactory=i||c,a.getLevel=function(){return o},a.setLevel=function(n,i){if("string"==typeof n&&void 0!==a.levels[n.toUpperCase()]&&(n=a.levels[n.toUpperCase()]),!("number"==typeof n&&n>=0&&n<=a.levels.SILENT))throw"log.setLevel() called with invalid level: "+n;if(o=n,!1!==i&&function(e){var n=(r[e]||"silent").toUpperCase();if(typeof window!==t&&d){try{return void(window.localStorage[d]=n)}catch(e){}try{window.document.cookie=encodeURIComponent(d)+"="+n+";"}catch(e){}}}(n),s.call(a,n,e),typeof console===t&&n<a.levels.SILENT)return"No console available for logging"},a.setDefaultLevel=function(e){n=e,u()||a.setLevel(e,!1)},a.resetLevel=function(){a.setLevel(n,!1),function(){if(typeof window!==t&&d){try{return void window.localStorage.removeItem(d)}catch(e){}try{window.document.cookie=encodeURIComponent(d)+"=; expires=Thu, 01 Jan 1970 00:00:00 UTC"}catch(e){}}}()},a.enableAll=function(e){a.setLevel(a.levels.TRACE,e)},a.disableAll=function(e){a.setLevel(a.levels.SILENT,e)};var y=u();null==y&&(y=n),a.setLevel(y,!1)}var u=new d,y={};u.getLogger=function(e){if("symbol"!=typeof e&&"string"!=typeof e||""===e)throw new TypeError("You must supply a name when creating a logger.");var t=y[e];return t||(t=y[e]=new d(e,u.getLevel(),u.methodFactory)),t};var h=typeof window!==t?window.log:void 0;return u.noConflict=function(){return typeof window!==t&&window.log===u&&(window.log=h),u},u.getLoggers=function(){return y},u.default=u,u},(t=o).exports?t.exports=r():n.log=r();var s,a=o.exports;!function(e){e[e.trace=0]="trace",e[e.debug=1]="debug",e[e.info=2]="info",e[e.warn=3]="warn",e[e.error=4]="error",e[e.silent=5]="silent"}(s||(s={}));a.getLogger("livekit").setDefaultLevel(s.info);const c=a.getLogger("lk-e2ee"),d="AES-GCM",u={key:10,delta:3,audio:1,empty:0},y={sharedKey:!1,ratchetSalt:"LKFrameEncryptionKey",ratchetWindowSize:8,failureTolerance:10};class h extends Error{constructor(e,t){super(t||"an error has occured"),this.code=e}}var l,p,f,v,g,m;!function(e){e.PermissionDenied="PermissionDenied",e.NotFound="NotFound",e.DeviceInUse="DeviceInUse",e.Other="Other"}(l||(l={})),function(e){e.getFailure=function(t){if(t&&"name"in t)return"NotFoundError"===t.name||"DevicesNotFoundError"===t.name?e.NotFound:"NotAllowedError"===t.name||"PermissionDeniedError"===t.name?e.PermissionDenied:"NotReadableError"===t.name||"TrackStartError"===t.name?e.DeviceInUse:e.Other}}(l||(l={})),function(e){e[e.InvalidKey=0]="InvalidKey",e[e.MissingKey=1]="MissingKey",e[e.InternalError=2]="InternalError"}(p||(p={}));class w extends h{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:p.InternalError;super(40,e),this.reason=t}}!function(e){e.SetKey="setKey",e.RatchetRequest="ratchetRequest",e.KeyRatcheted="keyRatcheted"}(f||(f={})),function(e){e.KeyRatcheted="keyRatcheted"}(v||(v={})),function(e){e.ParticipantEncryptionStatusChanged="participantEncryptionStatusChanged",e.EncryptionError="encryptionError"}(g||(g={})),function(e){e.Error="cryptorError"}(m||(m={}));var I,S={exports:{}},L="object"==typeof Reflect?Reflect:null,b=L&&"function"==typeof L.apply?L.apply:function(e,t,n){return Function.prototype.apply.call(e,t,n)};I=L&&"function"==typeof L.ownKeys?L.ownKeys:Object.getOwnPropertySymbols?function(e){return Object.getOwnPropertyNames(e).concat(Object.getOwnPropertySymbols(e))}:function(e){return Object.getOwnPropertyNames(e)};var E=Number.isNaN||function(e){return e!=e};function k(){k.init.call(this)}S.exports=k,S.exports.once=function(e,t){return new Promise((function(n,r){function i(n){e.removeListener(t,o),r(n)}function o(){"function"==typeof e.removeListener&&e.removeListener("error",i),n([].slice.call(arguments))}U(e,t,o,{once:!0}),"error"!==t&&function(e,t,n){"function"==typeof e.on&&U(e,"error",t,n)}(e,i,{once:!0})}))},k.EventEmitter=k,k.prototype._events=void 0,k.prototype._eventsCount=0,k.prototype._maxListeners=void 0;var K=10;function C(e){if("function"!=typeof e)throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof e)}function _(e){return void 0===e._maxListeners?k.defaultMaxListeners:e._maxListeners}function T(e,t,n,r){var i,o,s,a;if(C(n),void 0===(o=e._events)?(o=e._events=Object.create(null),e._eventsCount=0):(void 0!==o.newListener&&(e.emit("newListener",t,n.listener?n.listener:n),o=e._events),s=o[t]),void 0===s)s=o[t]=n,++e._eventsCount;else if("function"==typeof s?s=o[t]=r?[n,s]:[s,n]:r?s.unshift(n):s.push(n),(i=_(e))>0&&s.length>i&&!s.warned){s.warned=!0;var c=new Error("Possible EventEmitter memory leak detected. "+s.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");c.name="MaxListenersExceededWarning",c.emitter=e,c.type=t,c.count=s.length,a=c,console&&console.warn&&console.warn(a)}return e}function A(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function R(e,t,n){var r={fired:!1,wrapFn:void 0,target:e,type:t,listener:n},i=A.bind(r);return i.listener=n,r.wrapFn=i,i}function P(e,t,n){var r=e._events;if(void 0===r)return[];var i=r[t];return void 0===i?[]:"function"==typeof i?n?[i.listener||i]:[i]:n?function(e){for(var t=new Array(e.length),n=0;n<t.length;++n)t[n]=e[n].listener||e[n];return t}(i):F(i,i.length)}function x(e){var t=this._events;if(void 0!==t){var n=t[e];if("function"==typeof n)return 1;if(void 0!==n)return n.length}return 0}function F(e,t){for(var n=new Array(t),r=0;r<t;++r)n[r]=e[r];return n}function U(e,t,n,r){if("function"==typeof e.on)r.once?e.once(t,n):e.on(t,n);else{if("function"!=typeof e.addEventListener)throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type '+typeof e);e.addEventListener(t,(function i(o){r.once&&e.removeEventListener(t,i),n(o)}))}}Object.defineProperty(k,"defaultMaxListeners",{enumerable:!0,get:function(){return K},set:function(e){if("number"!=typeof e||e<0||E(e))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+e+".");K=e}}),k.init=function(){void 0!==this._events&&this._events!==Object.getPrototypeOf(this)._events||(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0},k.prototype.setMaxListeners=function(e){if("number"!=typeof e||e<0||E(e))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+e+".");return this._maxListeners=e,this},k.prototype.getMaxListeners=function(){return _(this)},k.prototype.emit=function(e){for(var t=[],n=1;n<arguments.length;n++)t.push(arguments[n]);var r="error"===e,i=this._events;if(void 0!==i)r=r&&void 0===i.error;else if(!r)return!1;if(r){var o;if(t.length>0&&(o=t[0]),o instanceof Error)throw o;var s=new Error("Unhandled error."+(o?" ("+o.message+")":""));throw s.context=o,s}var a=i[e];if(void 0===a)return!1;if("function"==typeof a)b(a,this,t);else{var c=a.length,d=F(a,c);for(n=0;n<c;++n)b(d[n],this,t)}return!0},k.prototype.addListener=function(e,t){return T(this,e,t,!1)},k.prototype.on=k.prototype.addListener,k.prototype.prependListener=function(e,t){return T(this,e,t,!0)},k.prototype.once=function(e,t){return C(t),this.on(e,R(this,e,t)),this},k.prototype.prependOnceListener=function(e,t){return C(t),this.prependListener(e,R(this,e,t)),this},k.prototype.removeListener=function(e,t){var n,r,i,o,s;if(C(t),void 0===(r=this._events))return this;if(void 0===(n=r[e]))return this;if(n===t||n.listener===t)0==--this._eventsCount?this._events=Object.create(null):(delete r[e],r.removeListener&&this.emit("removeListener",e,n.listener||t));else if("function"!=typeof n){for(i=-1,o=n.length-1;o>=0;o--)if(n[o]===t||n[o].listener===t){s=n[o].listener,i=o;break}if(i<0)return this;0===i?n.shift():function(e,t){for(;t+1<e.length;t++)e[t]=e[t+1];e.pop()}(n,i),1===n.length&&(r[e]=n[0]),void 0!==r.removeListener&&this.emit("removeListener",e,s||t)}return this},k.prototype.off=k.prototype.removeListener,k.prototype.removeAllListeners=function(e){var t,n,r;if(void 0===(n=this._events))return this;if(void 0===n.removeListener)return 0===arguments.length?(this._events=Object.create(null),this._eventsCount=0):void 0!==n[e]&&(0==--this._eventsCount?this._events=Object.create(null):delete n[e]),this;if(0===arguments.length){var i,o=Object.keys(n);for(r=0;r<o.length;++r)"removeListener"!==(i=o[r])&&this.removeAllListeners(i);return this.removeAllListeners("removeListener"),this._events=Object.create(null),this._eventsCount=0,this}if("function"==typeof(t=n[e]))this.removeListener(e,t);else if(void 0!==t)for(r=t.length-1;r>=0;r--)this.removeListener(e,t[r]);return this},k.prototype.listeners=function(e){return P(this,e,!0)},k.prototype.rawListeners=function(e){return P(this,e,!1)},k.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):x.call(e,t)},k.prototype.listenerCount=x,k.prototype.eventNames=function(){return this._eventsCount>0?I(this._events):[]};var O,M=S.exports;function D(e,t){const n=(new TextEncoder).encode(t);switch(e){case"HKDF":return{name:"HKDF",salt:n,hash:"SHA-256",info:new ArrayBuffer(128)};case"PBKDF2":return{name:"PBKDF2",salt:n,hash:"SHA-256",iterations:1e5};default:throw new Error("algorithm ".concat(e," is currently unsupported"))}}function N(t,n){return e(this,void 0,void 0,(function*(){const e=D(t.algorithm.name,n),r=yield crypto.subtle.deriveKey(e,t,{name:d,length:128},!1,["encrypt","decrypt"]);return{material:t,encryptionKey:r}}))}!function(e){e.telephone={maxBitrate:12e3},e.speech={maxBitrate:2e4},e.music={maxBitrate:32e3},e.musicStereo={maxBitrate:48e3},e.musicHighQuality={maxBitrate:64e3},e.musicHighQualityStereo={maxBitrate:96e3}}(O||(O={}));class B{constructor(){this.consecutiveSifCount=0,this.lastSifReceivedAt=0,this.userFramesSinceSif=0}recordSif(){var e;this.consecutiveSifCount+=1,null!==(e=this.sifSequenceStartedAt)&&void 0!==e||(this.sifSequenceStartedAt=Date.now()),this.lastSifReceivedAt=Date.now()}recordUserFrame(){void 0!==this.sifSequenceStartedAt&&(this.userFramesSinceSif+=1,(this.userFramesSinceSif>this.consecutiveSifCount||Date.now()-this.lastSifReceivedAt>2e3)&&this.reset())}isSifAllowed(){return this.consecutiveSifCount<100&&(void 0===this.sifSequenceStartedAt||Date.now()-this.sifSequenceStartedAt<2e3)}reset(){this.userFramesSinceSif=0,this.consecutiveSifCount=0,this.sifSequenceStartedAt=void 0}}const q=new Map;class V extends M.EventEmitter{encodeFunction(e,t){throw Error("not implemented for subclass")}decodeFunction(e,t){throw Error("not implemented for subclass")}}class j extends V{constructor(e){var t;super(),this.sendCounts=new Map,this.keys=e.keys,this.participantIdentity=e.participantIdentity,this.rtpMap=new Map,this.keyProviderOptions=e.keyProviderOptions,this.sifTrailer=null!==(t=e.sifTrailer)&&void 0!==t?t:Uint8Array.from([]),this.sifGuard=new B}setParticipant(e,t){this.participantIdentity=e,this.keys=t,this.sifGuard.reset()}unsetParticipant(){this.participantIdentity=void 0}isEnabled(){return this.participantIdentity?q.get(this.participantIdentity):void 0}getParticipantIdentity(){return this.participantIdentity}getTrackId(){return this.trackId}setVideoCodec(e){this.videoCodec=e}setRtpMap(e){this.rtpMap=e}setupTransform(e,t,n,r,i){i&&(c.info("setting codec on cryptor to",{codec:i}),this.videoCodec=i);const o="encode"===e?this.encodeFunction:this.decodeFunction,s=new TransformStream({transform:o.bind(this)});t.pipeThrough(s).pipeTo(n).catch((e=>{c.warn(e),this.emit(m.Error,e instanceof w?e:new w(e.message))})),this.trackId=r}setSifTrailer(e){this.sifTrailer=e}encodeFunction(t,n){var r;return e(this,void 0,void 0,(function*(){if(!this.isEnabled()||0===t.data.byteLength)return n.enqueue(t);const e=this.keys.getKeySet();if(!e)throw new TypeError("key set not found for ".concat(this.participantIdentity," at index ").concat(this.keys.getCurrentKeyIndex()));const{encryptionKey:i}=e,o=this.keys.getCurrentKeyIndex();if(i){const e=this.makeIV(null!==(r=t.getMetadata().synchronizationSource)&&void 0!==r?r:-1,t.timestamp),s=new Uint8Array(t.data,0,this.getUnencryptedBytes(t)),a=new Uint8Array(2);a[0]=12,a[1]=o;try{const r=yield crypto.subtle.encrypt({name:d,iv:e,additionalData:new Uint8Array(t.data,0,s.byteLength)},i,new Uint8Array(t.data,this.getUnencryptedBytes(t))),o=new ArrayBuffer(s.byteLength+r.byteLength+e.byteLength+a.byteLength),c=new Uint8Array(o);return c.set(s),c.set(new Uint8Array(r),s.byteLength),c.set(new Uint8Array(e),s.byteLength+r.byteLength),c.set(a,s.byteLength+r.byteLength+e.byteLength),t.data=o,n.enqueue(t)}catch(e){c.error(e)}}else this.emit(m.Error,new w("encryption key missing for encoding",p.MissingKey))}))}decodeFunction(t,n){return e(this,void 0,void 0,(function*(){if(!this.isEnabled()||0===t.data.byteLength)return this.sifGuard.recordUserFrame(),n.enqueue(t);if(function(e,t){if(0===t.byteLength)return!1;const n=new Uint8Array(e.slice(e.byteLength-t.byteLength));return t.every(((e,t)=>e===n[t]))}(t.data,this.sifTrailer))return this.sifGuard.recordSif(),this.sifGuard.isSifAllowed()?(t.data=t.data.slice(0,t.data.byteLength-this.sifTrailer.byteLength),n.enqueue(t)):void c.warn("SIF limit reached, dropping frame");this.sifGuard.recordUserFrame();const e=new Uint8Array(t.data)[t.data.byteLength-1];if(this.keys.getKeySet(e)&&this.keys.hasValidKey)try{const r=yield this.decryptFrame(t,e);if(this.keys.decryptionSuccess(),r)return n.enqueue(r)}catch(e){e instanceof w&&e.reason===p.InvalidKey?this.keys.hasValidKey&&(this.emit(m.Error,e),this.keys.decryptionFailure()):c.warn("decoding frame failed",{error:e})}else!this.keys.getKeySet(e)&&this.keys.hasValidKey&&(c.warn("skipping decryption due to missing key at index"),this.emit(m.Error,new w("missing key at index for participant ".concat(this.participantIdentity),p.MissingKey)))}))}decryptFrame(t,n){let r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{ratchetCount:0};var o;return e(this,void 0,void 0,(function*(){const e=this.keys.getKeySet(n);if(!i.encryptionKey&&!e)throw new TypeError("no encryption key found for decryption of ".concat(this.participantIdentity));try{const n=new Uint8Array(t.data,0,this.getUnencryptedBytes(t)),r=new Uint8Array(t.data,t.data.byteLength-2,2),s=r[0],a=new Uint8Array(t.data,t.data.byteLength-s-r.byteLength,s),c=n.byteLength,u=t.data.byteLength-(n.byteLength+s+r.byteLength),y=yield crypto.subtle.decrypt({name:d,iv:a,additionalData:new Uint8Array(t.data,0,n.byteLength)},null!==(o=i.encryptionKey)&&void 0!==o?o:e.encryptionKey,new Uint8Array(t.data,c,u)),h=new ArrayBuffer(n.byteLength+y.byteLength),l=new Uint8Array(h);return l.set(new Uint8Array(t.data,0,n.byteLength)),l.set(new Uint8Array(y),n.byteLength),t.data=h,t}catch(o){if(this.keyProviderOptions.ratchetWindowSize>0){if(i.ratchetCount<this.keyProviderOptions.ratchetWindowSize){let o;if(c.debug("ratcheting key attempt ".concat(i.ratchetCount," of ").concat(this.keyProviderOptions.ratchetWindowSize,", for kind ").concat(t instanceof RTCEncodedAudioFrame?"audio":"video")),e===this.keys.getKeySet(n)){const e=yield this.keys.ratchetKey(n,!1);o=yield N(e,this.keyProviderOptions.ratchetSalt)}const s=yield this.decryptFrame(t,n,r||e,{ratchetCount:i.ratchetCount+1,encryptionKey:null==o?void 0:o.encryptionKey});return s&&o&&(this.keys.setKeySet(o,n,!0),this.keys.setCurrentKeyIndex(n)),s}throw r&&(c.debug("resetting to initial material"),this.keys.setKeyFromMaterial(r.material,n)),c.warn("maximum ratchet attempts exceeded"),new w("valid key missing for participant ".concat(this.participantIdentity),p.InvalidKey)}throw new w("Decryption failed: ".concat(o.message),p.InvalidKey)}}))}makeIV(e,t){var n;const r=new ArrayBuffer(12),i=new DataView(r);this.sendCounts.has(e)||this.sendCounts.set(e,Math.floor(65535*Math.random()));const o=null!==(n=this.sendCounts.get(e))&&void 0!==n?n:0;return i.setUint32(0,e),i.setUint32(4,t),i.setUint32(8,t-o%65535),this.sendCounts.set(e,o+1),r}getUnencryptedBytes(e){var t;if(function(e){return"type"in e}(e)){let n=null!==(t=this.getVideoCodec(e))&&void 0!==t?t:this.videoCodec;if("av1"===n||"vp9"===n)throw new Error("".concat(n," is not yet supported for end to end encryption"));if("vp8"===n)return u[e.type];const r=new Uint8Array(e.data);try{const e=function(e){const t=[];let n=0,r=0,i=e.length-2;for(;r<i;){for(;r<i&&(0!==e[r]||0!==e[r+1]||1!==e[r+2]);)r++;r>=i&&(r=e.length);let o=r;for(;o>n&&0===e[o-1];)o--;if(0===n){if(o!==n)throw TypeError("byte stream contains leading data")}else t.push(n);n=r+=3}return t}(r);if("h264"===n||e.some((e=>[z.SLICE_IDR,z.SLICE_NON_IDR].includes(X(r[e]))))){for(const t of e){switch(X(r[t])){case z.SLICE_IDR:case z.SLICE_NON_IDR:return t+2}}throw new TypeError("Could not find NALU")}}catch(e){}return u[e.type]}return u.audio}getVideoCodec(e){if(0===this.rtpMap.size)return;const t=e.getMetadata().payloadType;return t?this.rtpMap.get(t):void 0}}function X(e){return e&G}const G=31;var z;!function(e){e[e.SLICE_NON_IDR=1]="SLICE_NON_IDR",e[e.SLICE_PARTITION_A=2]="SLICE_PARTITION_A",e[e.SLICE_PARTITION_B=3]="SLICE_PARTITION_B",e[e.SLICE_PARTITION_C=4]="SLICE_PARTITION_C",e[e.SLICE_IDR=5]="SLICE_IDR",e[e.SEI=6]="SEI",e[e.SPS=7]="SPS",e[e.PPS=8]="PPS",e[e.AUD=9]="AUD",e[e.END_SEQ=10]="END_SEQ",e[e.END_STREAM=11]="END_STREAM",e[e.FILLER_DATA=12]="FILLER_DATA",e[e.SPS_EXT=13]="SPS_EXT",e[e.PREFIX_NALU=14]="PREFIX_NALU",e[e.SUBSET_SPS=15]="SUBSET_SPS",e[e.DPS=16]="DPS",e[e.SLICE_AUX=19]="SLICE_AUX",e[e.SLICE_EXT=20]="SLICE_EXT",e[e.SLICE_LAYER_EXT=21]="SLICE_LAYER_EXT"}(z||(z={}));class W extends M.EventEmitter{get hasValidKey(){return this._hasValidKey}constructor(e,t){super(),this.decryptionFailureCount=0,this._hasValidKey=!0,this.currentKeyIndex=0,this.cryptoKeyRing=new Array(16).fill(void 0),this.keyProviderOptions=t,this.ratchetPromiseMap=new Map,this.participantIdentity=e,this.resetKeyStatus()}decryptionFailure(){this.keyProviderOptions.failureTolerance<0||(this.decryptionFailureCount+=1,this.decryptionFailureCount>this.keyProviderOptions.failureTolerance&&(c.warn("key for ".concat(this.participantIdentity," is being marked as invalid")),this._hasValidKey=!1))}decryptionSuccess(){this.resetKeyStatus()}resetKeyStatus(){this.decryptionFailureCount=0,this._hasValidKey=!0}ratchetKey(t){let n=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];const r=null!=t?t:this.getCurrentKeyIndex(),i=this.ratchetPromiseMap.get(r);if(void 0!==i)return i;const o=new Promise(((t,i)=>e(this,void 0,void 0,(function*(){try{const i=this.getKeySet(r);if(!i)throw new TypeError("Cannot ratchet key without a valid keyset of participant ".concat(this.participantIdentity));const o=i.material,s=yield function(t){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{name:d},r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"encrypt";return e(this,void 0,void 0,(function*(){return crypto.subtle.importKey("raw",t,n,!1,"derive"===r?["deriveBits","deriveKey"]:["encrypt","decrypt"])}))}(yield function(t,n){return e(this,void 0,void 0,(function*(){const e=D(t.algorithm.name,n);return crypto.subtle.deriveBits(e,t,256)}))}(o,this.keyProviderOptions.ratchetSalt),o.algorithm.name,"derive");n&&(this.setKeyFromMaterial(s,r,!0),this.emit(v.KeyRatcheted,s,this.participantIdentity,r)),t(s)}catch(e){i(e)}finally{this.ratchetPromiseMap.delete(r)}}))));return this.ratchetPromiseMap.set(r,o),o}setKey(t){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;return e(this,void 0,void 0,(function*(){yield this.setKeyFromMaterial(t,n),this.resetKeyStatus()}))}setKeyFromMaterial(t){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,r=arguments.length>2&&void 0!==arguments[2]&&arguments[2];return e(this,void 0,void 0,(function*(){c.debug("setting new key"),n>=0&&(this.currentKeyIndex=n%this.cryptoKeyRing.length);const e=yield N(t,this.keyProviderOptions.ratchetSalt);this.setKeySet(e,this.currentKeyIndex,r)}))}setKeySet(e,t){let n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];this.cryptoKeyRing[t%this.cryptoKeyRing.length]=e,n&&this.emit(v.KeyRatcheted,e.material,this.participantIdentity,t)}setCurrentKeyIndex(t){return e(this,void 0,void 0,(function*(){this.currentKeyIndex=t%this.cryptoKeyRing.length,this.resetKeyStatus()}))}getCurrentKeyIndex(){return this.currentKeyIndex}getKeySet(e){return this.cryptoKeyRing[null!=e?e:this.currentKeyIndex]}}const H=[],Q=new Map;let Y,J,Z,$=!1,ee=y;function te(e,t){let n=H.find((e=>e.getTrackId()===t));if(n)e!==n.getParticipantIdentity()&&n.setParticipant(e,ne(e));else{if(c.info("creating new cryptor for",{participantIdentity:e}),!ee)throw Error("Missing keyProvider options");n=new j({participantIdentity:e,keys:ne(e),keyProviderOptions:ee,sifTrailer:Z}),function(e){e.on(m.Error,(e=>{const t={kind:"error",data:{error:new Error("".concat(p[e.reason],": ").concat(e.message))}};postMessage(t)}))}(n),H.push(n)}return n}function ne(e){if($)return re();let t=Q.get(e);return t||(t=new W(e,ee),J&&t.setKey(J),t.on(v.KeyRatcheted,ie),Q.set(e,t)),t}function re(){return Y||(Y=new W("shared-key",ee)),Y}function ie(e,t,n){postMessage({kind:"ratchetKey",data:{participantIdentity:t,keyIndex:n,material:e}})}c.setDefaultLevel("info"),onmessage=t=>{const{kind:n,data:r}=t.data;switch(n){case"init":c.info("worker initialized"),ee=r.keyProviderOptions,$=!!r.keyProviderOptions.sharedKey;postMessage({kind:"initAck",data:{enabled:false}});break;case"enable":u=r.enabled,y=r.participantIdentity,q.set(y,u),c.info("updated e2ee enabled status"),postMessage(t.data);break;case"decode":te(r.participantIdentity,r.trackId).setupTransform(n,r.readableStream,r.writableStream,r.trackId,r.codec);break;case"encode":te(r.participantIdentity,r.trackId).setupTransform(n,r.readableStream,r.writableStream,r.trackId,r.codec);break;case"setKey":$?(c.warn("set shared key"),a=r.key,d=r.keyIndex,c.debug("setting shared key"),J=a,re().setKey(a,d)):r.participantIdentity?(c.warn("set participant sender key ".concat(r.participantIdentity)),ne(r.participantIdentity).setKey(r.key,r.keyIndex)):c.error("no participant Id was provided and shared key usage is disabled");break;case"removeTransform":o=r.trackId,null===(s=H.find((e=>e.getTrackId()===o)))||void 0===s||s.unsetParticipant();break;case"updateCodec":te(r.participantIdentity,r.trackId).setVideoCodec(r.codec);break;case"setRTPMap":H.forEach((e=>{e.getParticipantIdentity()===r.participantIdentity&&e.setRtpMap(r.map)}));break;case"ratchetRequest":!function(t){e(this,void 0,void 0,(function*(){if($){const e=re();yield e.ratchetKey(t.keyIndex),e.resetKeyStatus()}else if(t.participantIdentity){const e=ne(t.participantIdentity);yield e.ratchetKey(t.keyIndex),e.resetKeyStatus()}else c.error("no participant Id was provided for ratchet request and shared key usage is disabled")}))}(r);break;case"setSifTrailer":i=r.trailer,Z=i,H.forEach((e=>{e.setSifTrailer(i)}))}var i,o,s,a,d,u,y},self.RTCTransformEvent&&(c.debug("setup transform event"),self.onrtctransform=e=>{const t=e.transformer;c.debug("transformer",t),t.handled=!0;const{kind:n,participantIdentity:r,trackId:i,codec:o}=t.options,s=te(r,i);c.debug("transform",{codec:o}),s.setupTransform(n,t.readable,t.writable,i,o)})}));
|
1
|
+
!function(e){"function"==typeof define&&define.amd?define(e):e()}((function(){"use strict";function e(e,t,n,r){return new(n||(n=Promise))((function(i,o){function s(e){try{c(r.next(e))}catch(e){o(e)}}function a(e){try{c(r.throw(e))}catch(e){o(e)}}function c(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(s,a)}c((r=r.apply(e,t||[])).next())}))}var t,n,r,i="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},o={exports:{}};n=i,r=function(){var e=function(){},t="undefined",n=typeof window!==t&&typeof window.navigator!==t&&/Trident\/|MSIE /.test(window.navigator.userAgent),r=["trace","debug","info","warn","error"];function i(e,t){var n=e[t];if("function"==typeof n.bind)return n.bind(e);try{return Function.prototype.bind.call(n,e)}catch(t){return function(){return Function.prototype.apply.apply(n,[e,arguments])}}}function o(){console.log&&(console.log.apply?console.log.apply(console,arguments):Function.prototype.apply.apply(console.log,[console,arguments])),console.trace&&console.trace()}function s(t,n){for(var i=0;i<r.length;i++){var o=r[i];this[o]=i<t?e:this.methodFactory(o,t,n)}this.log=this.debug}function a(e,n,r){return function(){typeof console!==t&&(s.call(this,n,r),this[e].apply(this,arguments))}}function c(r,s,c){return function(r){return"debug"===r&&(r="log"),typeof console!==t&&("trace"===r&&n?o:void 0!==console[r]?i(console,r):void 0!==console.log?i(console,"log"):e)}(r)||a.apply(this,arguments)}function d(e,n,i){var o,a=this;n=null==n?"WARN":n;var d="loglevel";function u(){var e;if(typeof window!==t&&d){try{e=window.localStorage[d]}catch(e){}if(typeof e===t)try{var n=window.document.cookie,r=n.indexOf(encodeURIComponent(d)+"=");-1!==r&&(e=/^([^;]+)/.exec(n.slice(r))[1])}catch(e){}return void 0===a.levels[e]&&(e=void 0),e}}"string"==typeof e?d+=":"+e:"symbol"==typeof e&&(d=void 0),a.name=e,a.levels={TRACE:0,DEBUG:1,INFO:2,WARN:3,ERROR:4,SILENT:5},a.methodFactory=i||c,a.getLevel=function(){return o},a.setLevel=function(n,i){if("string"==typeof n&&void 0!==a.levels[n.toUpperCase()]&&(n=a.levels[n.toUpperCase()]),!("number"==typeof n&&n>=0&&n<=a.levels.SILENT))throw"log.setLevel() called with invalid level: "+n;if(o=n,!1!==i&&function(e){var n=(r[e]||"silent").toUpperCase();if(typeof window!==t&&d){try{return void(window.localStorage[d]=n)}catch(e){}try{window.document.cookie=encodeURIComponent(d)+"="+n+";"}catch(e){}}}(n),s.call(a,n,e),typeof console===t&&n<a.levels.SILENT)return"No console available for logging"},a.setDefaultLevel=function(e){n=e,u()||a.setLevel(e,!1)},a.resetLevel=function(){a.setLevel(n,!1),function(){if(typeof window!==t&&d){try{return void window.localStorage.removeItem(d)}catch(e){}try{window.document.cookie=encodeURIComponent(d)+"=; expires=Thu, 01 Jan 1970 00:00:00 UTC"}catch(e){}}}()},a.enableAll=function(e){a.setLevel(a.levels.TRACE,e)},a.disableAll=function(e){a.setLevel(a.levels.SILENT,e)};var y=u();null==y&&(y=n),a.setLevel(y,!1)}var u=new d,y={};u.getLogger=function(e){if("symbol"!=typeof e&&"string"!=typeof e||""===e)throw new TypeError("You must supply a name when creating a logger.");var t=y[e];return t||(t=y[e]=new d(e,u.getLevel(),u.methodFactory)),t};var h=typeof window!==t?window.log:void 0;return u.noConflict=function(){return typeof window!==t&&window.log===u&&(window.log=h),u},u.getLoggers=function(){return y},u.default=u,u},(t=o).exports?t.exports=r():n.log=r();var s,a=o.exports;!function(e){e[e.trace=0]="trace",e[e.debug=1]="debug",e[e.info=2]="info",e[e.warn=3]="warn",e[e.error=4]="error",e[e.silent=5]="silent"}(s||(s={}));a.getLogger("livekit").setDefaultLevel(s.info);const c=a.getLogger("lk-e2ee"),d="AES-GCM",u={key:10,delta:3,audio:1,empty:0},y={sharedKey:!1,ratchetSalt:"LKFrameEncryptionKey",ratchetWindowSize:8,failureTolerance:10};class h extends Error{constructor(e,t){super(t||"an error has occured"),this.code=e}}var l,p,f,v,g,m;!function(e){e.PermissionDenied="PermissionDenied",e.NotFound="NotFound",e.DeviceInUse="DeviceInUse",e.Other="Other"}(l||(l={})),function(e){e.getFailure=function(t){if(t&&"name"in t)return"NotFoundError"===t.name||"DevicesNotFoundError"===t.name?e.NotFound:"NotAllowedError"===t.name||"PermissionDeniedError"===t.name?e.PermissionDenied:"NotReadableError"===t.name||"TrackStartError"===t.name?e.DeviceInUse:e.Other}}(l||(l={})),function(e){e[e.InvalidKey=0]="InvalidKey",e[e.MissingKey=1]="MissingKey",e[e.InternalError=2]="InternalError"}(p||(p={}));class w extends h{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:p.InternalError;super(40,e),this.reason=t}}!function(e){e.SetKey="setKey",e.RatchetRequest="ratchetRequest",e.KeyRatcheted="keyRatcheted"}(f||(f={})),function(e){e.KeyRatcheted="keyRatcheted"}(v||(v={})),function(e){e.ParticipantEncryptionStatusChanged="participantEncryptionStatusChanged",e.EncryptionError="encryptionError"}(g||(g={})),function(e){e.Error="cryptorError"}(m||(m={}));var I,S={exports:{}},L="object"==typeof Reflect?Reflect:null,b=L&&"function"==typeof L.apply?L.apply:function(e,t,n){return Function.prototype.apply.call(e,t,n)};I=L&&"function"==typeof L.ownKeys?L.ownKeys:Object.getOwnPropertySymbols?function(e){return Object.getOwnPropertyNames(e).concat(Object.getOwnPropertySymbols(e))}:function(e){return Object.getOwnPropertyNames(e)};var E=Number.isNaN||function(e){return e!=e};function k(){k.init.call(this)}S.exports=k,S.exports.once=function(e,t){return new Promise((function(n,r){function i(n){e.removeListener(t,o),r(n)}function o(){"function"==typeof e.removeListener&&e.removeListener("error",i),n([].slice.call(arguments))}U(e,t,o,{once:!0}),"error"!==t&&function(e,t,n){"function"==typeof e.on&&U(e,"error",t,n)}(e,i,{once:!0})}))},k.EventEmitter=k,k.prototype._events=void 0,k.prototype._eventsCount=0,k.prototype._maxListeners=void 0;var K=10;function C(e){if("function"!=typeof e)throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof e)}function _(e){return void 0===e._maxListeners?k.defaultMaxListeners:e._maxListeners}function A(e,t,n,r){var i,o,s,a;if(C(n),void 0===(o=e._events)?(o=e._events=Object.create(null),e._eventsCount=0):(void 0!==o.newListener&&(e.emit("newListener",t,n.listener?n.listener:n),o=e._events),s=o[t]),void 0===s)s=o[t]=n,++e._eventsCount;else if("function"==typeof s?s=o[t]=r?[n,s]:[s,n]:r?s.unshift(n):s.push(n),(i=_(e))>0&&s.length>i&&!s.warned){s.warned=!0;var c=new Error("Possible EventEmitter memory leak detected. "+s.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");c.name="MaxListenersExceededWarning",c.emitter=e,c.type=t,c.count=s.length,a=c,console&&console.warn&&console.warn(a)}return e}function T(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function R(e,t,n){var r={fired:!1,wrapFn:void 0,target:e,type:t,listener:n},i=T.bind(r);return i.listener=n,r.wrapFn=i,i}function P(e,t,n){var r=e._events;if(void 0===r)return[];var i=r[t];return void 0===i?[]:"function"==typeof i?n?[i.listener||i]:[i]:n?function(e){for(var t=new Array(e.length),n=0;n<t.length;++n)t[n]=e[n].listener||e[n];return t}(i):F(i,i.length)}function x(e){var t=this._events;if(void 0!==t){var n=t[e];if("function"==typeof n)return 1;if(void 0!==n)return n.length}return 0}function F(e,t){for(var n=new Array(t),r=0;r<t;++r)n[r]=e[r];return n}function U(e,t,n,r){if("function"==typeof e.on)r.once?e.once(t,n):e.on(t,n);else{if("function"!=typeof e.addEventListener)throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type '+typeof e);e.addEventListener(t,(function i(o){r.once&&e.removeEventListener(t,i),n(o)}))}}Object.defineProperty(k,"defaultMaxListeners",{enumerable:!0,get:function(){return K},set:function(e){if("number"!=typeof e||e<0||E(e))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+e+".");K=e}}),k.init=function(){void 0!==this._events&&this._events!==Object.getPrototypeOf(this)._events||(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0},k.prototype.setMaxListeners=function(e){if("number"!=typeof e||e<0||E(e))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+e+".");return this._maxListeners=e,this},k.prototype.getMaxListeners=function(){return _(this)},k.prototype.emit=function(e){for(var t=[],n=1;n<arguments.length;n++)t.push(arguments[n]);var r="error"===e,i=this._events;if(void 0!==i)r=r&&void 0===i.error;else if(!r)return!1;if(r){var o;if(t.length>0&&(o=t[0]),o instanceof Error)throw o;var s=new Error("Unhandled error."+(o?" ("+o.message+")":""));throw s.context=o,s}var a=i[e];if(void 0===a)return!1;if("function"==typeof a)b(a,this,t);else{var c=a.length,d=F(a,c);for(n=0;n<c;++n)b(d[n],this,t)}return!0},k.prototype.addListener=function(e,t){return A(this,e,t,!1)},k.prototype.on=k.prototype.addListener,k.prototype.prependListener=function(e,t){return A(this,e,t,!0)},k.prototype.once=function(e,t){return C(t),this.on(e,R(this,e,t)),this},k.prototype.prependOnceListener=function(e,t){return C(t),this.prependListener(e,R(this,e,t)),this},k.prototype.removeListener=function(e,t){var n,r,i,o,s;if(C(t),void 0===(r=this._events))return this;if(void 0===(n=r[e]))return this;if(n===t||n.listener===t)0==--this._eventsCount?this._events=Object.create(null):(delete r[e],r.removeListener&&this.emit("removeListener",e,n.listener||t));else if("function"!=typeof n){for(i=-1,o=n.length-1;o>=0;o--)if(n[o]===t||n[o].listener===t){s=n[o].listener,i=o;break}if(i<0)return this;0===i?n.shift():function(e,t){for(;t+1<e.length;t++)e[t]=e[t+1];e.pop()}(n,i),1===n.length&&(r[e]=n[0]),void 0!==r.removeListener&&this.emit("removeListener",e,s||t)}return this},k.prototype.off=k.prototype.removeListener,k.prototype.removeAllListeners=function(e){var t,n,r;if(void 0===(n=this._events))return this;if(void 0===n.removeListener)return 0===arguments.length?(this._events=Object.create(null),this._eventsCount=0):void 0!==n[e]&&(0==--this._eventsCount?this._events=Object.create(null):delete n[e]),this;if(0===arguments.length){var i,o=Object.keys(n);for(r=0;r<o.length;++r)"removeListener"!==(i=o[r])&&this.removeAllListeners(i);return this.removeAllListeners("removeListener"),this._events=Object.create(null),this._eventsCount=0,this}if("function"==typeof(t=n[e]))this.removeListener(e,t);else if(void 0!==t)for(r=t.length-1;r>=0;r--)this.removeListener(e,t[r]);return this},k.prototype.listeners=function(e){return P(this,e,!0)},k.prototype.rawListeners=function(e){return P(this,e,!1)},k.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):x.call(e,t)},k.prototype.listenerCount=x,k.prototype.eventNames=function(){return this._eventsCount>0?I(this._events):[]};var O,M=S.exports;function D(e,t){const n=(new TextEncoder).encode(t);switch(e){case"HKDF":return{name:"HKDF",salt:n,hash:"SHA-256",info:new ArrayBuffer(128)};case"PBKDF2":return{name:"PBKDF2",salt:n,hash:"SHA-256",iterations:1e5};default:throw new Error("algorithm ".concat(e," is currently unsupported"))}}function N(t,n){return e(this,void 0,void 0,(function*(){const e=D(t.algorithm.name,n),r=yield crypto.subtle.deriveKey(e,t,{name:d,length:128},!1,["encrypt","decrypt"]);return{material:t,encryptionKey:r}}))}!function(e){e.telephone={maxBitrate:12e3},e.speech={maxBitrate:2e4},e.music={maxBitrate:32e3},e.musicStereo={maxBitrate:48e3},e.musicHighQuality={maxBitrate:64e3},e.musicHighQualityStereo={maxBitrate:96e3}}(O||(O={}));class B{constructor(){this.consecutiveSifCount=0,this.lastSifReceivedAt=0,this.userFramesSinceSif=0}recordSif(){var e;this.consecutiveSifCount+=1,null!==(e=this.sifSequenceStartedAt)&&void 0!==e||(this.sifSequenceStartedAt=Date.now()),this.lastSifReceivedAt=Date.now()}recordUserFrame(){void 0!==this.sifSequenceStartedAt&&(this.userFramesSinceSif+=1,(this.userFramesSinceSif>this.consecutiveSifCount||Date.now()-this.lastSifReceivedAt>2e3)&&this.reset())}isSifAllowed(){return this.consecutiveSifCount<100&&(void 0===this.sifSequenceStartedAt||Date.now()-this.sifSequenceStartedAt<2e3)}reset(){this.userFramesSinceSif=0,this.consecutiveSifCount=0,this.sifSequenceStartedAt=void 0}}const q=new Map;class V extends M.EventEmitter{encodeFunction(e,t){throw Error("not implemented for subclass")}decodeFunction(e,t){throw Error("not implemented for subclass")}}class j extends V{constructor(e){var t;super(),this.sendCounts=new Map,this.keys=e.keys,this.participantIdentity=e.participantIdentity,this.rtpMap=new Map,this.keyProviderOptions=e.keyProviderOptions,this.sifTrailer=null!==(t=e.sifTrailer)&&void 0!==t?t:Uint8Array.from([]),this.sifGuard=new B}setParticipant(e,t){this.participantIdentity=e,this.keys=t,this.sifGuard.reset()}unsetParticipant(){this.participantIdentity=void 0}isEnabled(){return this.participantIdentity?q.get(this.participantIdentity):void 0}getParticipantIdentity(){return this.participantIdentity}getTrackId(){return this.trackId}setVideoCodec(e){this.videoCodec=e}setRtpMap(e){this.rtpMap=e}setupTransform(e,t,n,r,i){i&&(c.info("setting codec on cryptor to",{codec:i}),this.videoCodec=i);const o="encode"===e?this.encodeFunction:this.decodeFunction,s=new TransformStream({transform:o.bind(this)});t.pipeThrough(s).pipeTo(n).catch((e=>{c.warn(e),this.emit(m.Error,e instanceof w?e:new w(e.message))})),this.trackId=r}setSifTrailer(e){this.sifTrailer=e}encodeFunction(t,n){var r;return e(this,void 0,void 0,(function*(){if(!this.isEnabled()||0===t.data.byteLength)return n.enqueue(t);const e=this.keys.getKeySet();if(!e)throw new TypeError("key set not found for ".concat(this.participantIdentity," at index ").concat(this.keys.getCurrentKeyIndex()));const{encryptionKey:i}=e,o=this.keys.getCurrentKeyIndex();if(i){const e=this.makeIV(null!==(r=t.getMetadata().synchronizationSource)&&void 0!==r?r:-1,t.timestamp);let a=this.getUnencryptedBytes(t);const u=new Uint8Array(t.data,0,a.unencryptedBytes),y=new Uint8Array(2);y[0]=12,y[1]=o;try{const r=yield crypto.subtle.encrypt({name:d,iv:e,additionalData:new Uint8Array(t.data,0,u.byteLength)},i,new Uint8Array(t.data,a.unencryptedBytes));let o=new Uint8Array(r.byteLength+e.byteLength+y.byteLength);o.set(new Uint8Array(r)),o.set(new Uint8Array(e),r.byteLength),o.set(y,r.byteLength+e.byteLength),a.isH264&&(o=function(e){const t=[];for(var n=0,r=0;r<e.length;++r){var i=e[r];i<=3&&n>=2&&(t.push(3),n=0),t.push(i),0==i?++n:n=0}return new Uint8Array(t)}(o));var s=new Uint8Array(u.byteLength+o.byteLength);return s.set(u),s.set(o,u.byteLength),t.data=s.buffer,n.enqueue(t)}catch(e){c.error(e)}}else this.emit(m.Error,new w("encryption key missing for encoding",p.MissingKey))}))}decodeFunction(t,n){return e(this,void 0,void 0,(function*(){if(!this.isEnabled()||0===t.data.byteLength)return this.sifGuard.recordUserFrame(),n.enqueue(t);if(function(e,t){if(0===t.byteLength)return!1;const n=new Uint8Array(e.slice(e.byteLength-t.byteLength));return t.every(((e,t)=>e===n[t]))}(t.data,this.sifTrailer))return this.sifGuard.recordSif(),this.sifGuard.isSifAllowed()?(t.data=t.data.slice(0,t.data.byteLength-this.sifTrailer.byteLength),n.enqueue(t)):void c.warn("SIF limit reached, dropping frame");this.sifGuard.recordUserFrame();const e=new Uint8Array(t.data)[t.data.byteLength-1];if(this.keys.getKeySet(e)&&this.keys.hasValidKey)try{const r=yield this.decryptFrame(t,e);if(this.keys.decryptionSuccess(),r)return n.enqueue(r)}catch(e){e instanceof w&&e.reason===p.InvalidKey?this.keys.hasValidKey&&(this.emit(m.Error,e),this.keys.decryptionFailure()):c.warn("decoding frame failed",{error:e})}else!this.keys.getKeySet(e)&&this.keys.hasValidKey&&(c.warn("skipping decryption due to missing key at index"),this.emit(m.Error,new w("missing key at index for participant ".concat(this.participantIdentity),p.MissingKey)))}))}decryptFrame(t,n){let r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{ratchetCount:0};var o;return e(this,void 0,void 0,(function*(){const e=this.keys.getKeySet(n);if(!i.encryptionKey&&!e)throw new TypeError("no encryption key found for decryption of ".concat(this.participantIdentity));let s=this.getUnencryptedBytes(t);try{const n=new Uint8Array(t.data,0,s.unencryptedBytes);var a=new Uint8Array(t.data,n.length,t.data.byteLength-n.length);if(s.isH264&&function(e){for(var t=0;t<e.length-3;t++)if(0==e[t]&&0==e[t+1]&&3==e[t+2])return!0;return!1}(a)){a=function(e){const t=[];for(var n=e.length,r=0;r<e.length;)n-r>=3&&!e[r]&&!e[r+1]&&3==e[r+2]?(t.push(e[r++]),t.push(e[r++]),r++):t.push(e[r++]);return new Uint8Array(t)}(a);const e=new Uint8Array(n.byteLength+a.byteLength);e.set(n),e.set(a,n.byteLength),t.data=e.buffer}const r=new Uint8Array(t.data,t.data.byteLength-2,2),c=r[0],u=new Uint8Array(t.data,t.data.byteLength-c-r.byteLength,c),y=n.byteLength,h=t.data.byteLength-(n.byteLength+c+r.byteLength),l=yield crypto.subtle.decrypt({name:d,iv:u,additionalData:new Uint8Array(t.data,0,n.byteLength)},null!==(o=i.encryptionKey)&&void 0!==o?o:e.encryptionKey,new Uint8Array(t.data,y,h)),p=new ArrayBuffer(n.byteLength+l.byteLength),f=new Uint8Array(p);return f.set(new Uint8Array(t.data,0,n.byteLength)),f.set(new Uint8Array(l),n.byteLength),t.data=p,t}catch(o){if(this.keyProviderOptions.ratchetWindowSize>0){if(i.ratchetCount<this.keyProviderOptions.ratchetWindowSize){let o;if(c.debug("ratcheting key attempt ".concat(i.ratchetCount," of ").concat(this.keyProviderOptions.ratchetWindowSize,", for kind ").concat(t instanceof RTCEncodedAudioFrame?"audio":"video")),e===this.keys.getKeySet(n)){const e=yield this.keys.ratchetKey(n,!1);o=yield N(e,this.keyProviderOptions.ratchetSalt)}const s=yield this.decryptFrame(t,n,r||e,{ratchetCount:i.ratchetCount+1,encryptionKey:null==o?void 0:o.encryptionKey});return s&&o&&(this.keys.setKeySet(o,n,!0),this.keys.setCurrentKeyIndex(n)),s}throw r&&(c.debug("resetting to initial material"),this.keys.setKeyFromMaterial(r.material,n)),c.warn("maximum ratchet attempts exceeded"),new w("valid key missing for participant ".concat(this.participantIdentity),p.InvalidKey)}throw new w("Decryption failed: ".concat(o.message),p.InvalidKey)}}))}makeIV(e,t){var n;const r=new ArrayBuffer(12),i=new DataView(r);this.sendCounts.has(e)||this.sendCounts.set(e,Math.floor(65535*Math.random()));const o=null!==(n=this.sendCounts.get(e))&&void 0!==n?n:0;return i.setUint32(0,e),i.setUint32(4,t),i.setUint32(8,t-o%65535),this.sendCounts.set(e,o+1),r}getUnencryptedBytes(e){var t,n={unencryptedBytes:0,isH264:!1};if(function(e){return"type"in e}(e)){let r=null!==(t=this.getVideoCodec(e))&&void 0!==t?t:this.videoCodec;if("av1"===r||"vp9"===r)throw new Error("".concat(r," is not yet supported for end to end encryption"));if("vp8"===r)return n.unencryptedBytes=u[e.type],n;const i=new Uint8Array(e.data);try{const e=function(e){const t=[];let n=0,r=0,i=e.length-2;for(;r<i;){for(;r<i&&(0!==e[r]||0!==e[r+1]||1!==e[r+2]);)r++;r>=i&&(r=e.length);let o=r;for(;o>n&&0===e[o-1];)o--;if(0===n){if(o!==n)throw TypeError("byte stream contains leading data")}else t.push(n);n=r+=3}return t}(i);if(n.isH264="h264"===r||e.some((e=>[G.SLICE_IDR,G.SLICE_NON_IDR].includes(H(i[e])))),n.isH264){for(const t of e){switch(H(i[t])){case G.SLICE_IDR:case G.SLICE_NON_IDR:return n.unencryptedBytes=t+2,n}}throw new TypeError("Could not find NALU")}}catch(e){}return n.unencryptedBytes=u[e.type],n}return n.unencryptedBytes=u.audio,n}getVideoCodec(e){if(0===this.rtpMap.size)return;const t=e.getMetadata().payloadType;return t?this.rtpMap.get(t):void 0}}function H(e){return e&X}const X=31;var G;!function(e){e[e.SLICE_NON_IDR=1]="SLICE_NON_IDR",e[e.SLICE_PARTITION_A=2]="SLICE_PARTITION_A",e[e.SLICE_PARTITION_B=3]="SLICE_PARTITION_B",e[e.SLICE_PARTITION_C=4]="SLICE_PARTITION_C",e[e.SLICE_IDR=5]="SLICE_IDR",e[e.SEI=6]="SEI",e[e.SPS=7]="SPS",e[e.PPS=8]="PPS",e[e.AUD=9]="AUD",e[e.END_SEQ=10]="END_SEQ",e[e.END_STREAM=11]="END_STREAM",e[e.FILLER_DATA=12]="FILLER_DATA",e[e.SPS_EXT=13]="SPS_EXT",e[e.PREFIX_NALU=14]="PREFIX_NALU",e[e.SUBSET_SPS=15]="SUBSET_SPS",e[e.DPS=16]="DPS",e[e.SLICE_AUX=19]="SLICE_AUX",e[e.SLICE_EXT=20]="SLICE_EXT",e[e.SLICE_LAYER_EXT=21]="SLICE_LAYER_EXT"}(G||(G={}));class z extends M.EventEmitter{get hasValidKey(){return this._hasValidKey}constructor(e,t){super(),this.decryptionFailureCount=0,this._hasValidKey=!0,this.currentKeyIndex=0,this.cryptoKeyRing=new Array(16).fill(void 0),this.keyProviderOptions=t,this.ratchetPromiseMap=new Map,this.participantIdentity=e,this.resetKeyStatus()}decryptionFailure(){this.keyProviderOptions.failureTolerance<0||(this.decryptionFailureCount+=1,this.decryptionFailureCount>this.keyProviderOptions.failureTolerance&&(c.warn("key for ".concat(this.participantIdentity," is being marked as invalid")),this._hasValidKey=!1))}decryptionSuccess(){this.resetKeyStatus()}resetKeyStatus(){this.decryptionFailureCount=0,this._hasValidKey=!0}ratchetKey(t){let n=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];const r=null!=t?t:this.getCurrentKeyIndex(),i=this.ratchetPromiseMap.get(r);if(void 0!==i)return i;const o=new Promise(((t,i)=>e(this,void 0,void 0,(function*(){try{const i=this.getKeySet(r);if(!i)throw new TypeError("Cannot ratchet key without a valid keyset of participant ".concat(this.participantIdentity));const o=i.material,s=yield function(t){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{name:d},r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"encrypt";return e(this,void 0,void 0,(function*(){return crypto.subtle.importKey("raw",t,n,!1,"derive"===r?["deriveBits","deriveKey"]:["encrypt","decrypt"])}))}(yield function(t,n){return e(this,void 0,void 0,(function*(){const e=D(t.algorithm.name,n);return crypto.subtle.deriveBits(e,t,256)}))}(o,this.keyProviderOptions.ratchetSalt),o.algorithm.name,"derive");n&&(this.setKeyFromMaterial(s,r,!0),this.emit(v.KeyRatcheted,s,this.participantIdentity,r)),t(s)}catch(e){i(e)}finally{this.ratchetPromiseMap.delete(r)}}))));return this.ratchetPromiseMap.set(r,o),o}setKey(t){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;return e(this,void 0,void 0,(function*(){yield this.setKeyFromMaterial(t,n),this.resetKeyStatus()}))}setKeyFromMaterial(t){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,r=arguments.length>2&&void 0!==arguments[2]&&arguments[2];return e(this,void 0,void 0,(function*(){c.debug("setting new key"),n>=0&&(this.currentKeyIndex=n%this.cryptoKeyRing.length);const e=yield N(t,this.keyProviderOptions.ratchetSalt);this.setKeySet(e,this.currentKeyIndex,r)}))}setKeySet(e,t){let n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];this.cryptoKeyRing[t%this.cryptoKeyRing.length]=e,n&&this.emit(v.KeyRatcheted,e.material,this.participantIdentity,t)}setCurrentKeyIndex(t){return e(this,void 0,void 0,(function*(){this.currentKeyIndex=t%this.cryptoKeyRing.length,this.resetKeyStatus()}))}getCurrentKeyIndex(){return this.currentKeyIndex}getKeySet(e){return this.cryptoKeyRing[null!=e?e:this.currentKeyIndex]}}const W=[],Q=new Map;let Y,J,Z,$=!1,ee=y;function te(e,t){let n=W.find((e=>e.getTrackId()===t));if(n)e!==n.getParticipantIdentity()&&n.setParticipant(e,ne(e));else{if(c.info("creating new cryptor for",{participantIdentity:e}),!ee)throw Error("Missing keyProvider options");n=new j({participantIdentity:e,keys:ne(e),keyProviderOptions:ee,sifTrailer:Z}),function(e){e.on(m.Error,(e=>{const t={kind:"error",data:{error:new Error("".concat(p[e.reason],": ").concat(e.message))}};postMessage(t)}))}(n),W.push(n)}return n}function ne(e){if($)return re();let t=Q.get(e);return t||(t=new z(e,ee),J&&t.setKey(J),t.on(v.KeyRatcheted,ie),Q.set(e,t)),t}function re(){return Y||(Y=new z("shared-key",ee)),Y}function ie(e,t,n){postMessage({kind:"ratchetKey",data:{participantIdentity:t,keyIndex:n,material:e}})}c.setDefaultLevel("info"),onmessage=t=>{const{kind:n,data:r}=t.data;switch(n){case"init":c.info("worker initialized"),ee=r.keyProviderOptions,$=!!r.keyProviderOptions.sharedKey;postMessage({kind:"initAck",data:{enabled:false}});break;case"enable":u=r.enabled,y=r.participantIdentity,q.set(y,u),c.info("updated e2ee enabled status"),postMessage(t.data);break;case"decode":te(r.participantIdentity,r.trackId).setupTransform(n,r.readableStream,r.writableStream,r.trackId,r.codec);break;case"encode":te(r.participantIdentity,r.trackId).setupTransform(n,r.readableStream,r.writableStream,r.trackId,r.codec);break;case"setKey":$?(c.warn("set shared key"),a=r.key,d=r.keyIndex,c.debug("setting shared key"),J=a,re().setKey(a,d)):r.participantIdentity?(c.warn("set participant sender key ".concat(r.participantIdentity)),ne(r.participantIdentity).setKey(r.key,r.keyIndex)):c.error("no participant Id was provided and shared key usage is disabled");break;case"removeTransform":o=r.trackId,null===(s=W.find((e=>e.getTrackId()===o)))||void 0===s||s.unsetParticipant();break;case"updateCodec":te(r.participantIdentity,r.trackId).setVideoCodec(r.codec);break;case"setRTPMap":W.forEach((e=>{e.getParticipantIdentity()===r.participantIdentity&&e.setRtpMap(r.map)}));break;case"ratchetRequest":!function(t){e(this,void 0,void 0,(function*(){if($){const e=re();yield e.ratchetKey(t.keyIndex),e.resetKeyStatus()}else if(t.participantIdentity){const e=ne(t.participantIdentity);yield e.ratchetKey(t.keyIndex),e.resetKeyStatus()}else c.error("no participant Id was provided for ratchet request and shared key usage is disabled")}))}(r);break;case"setSifTrailer":i=r.trailer,Z=i,W.forEach((e=>{e.setSifTrailer(i)}))}var i,o,s,a,d,u,y},self.RTCTransformEvent&&(c.debug("setup transform event"),self.onrtctransform=e=>{const t=e.transformer;c.debug("transformer",t),t.handled=!0;const{kind:n,participantIdentity:r,trackId:i,codec:o}=t.options,s=te(r,i);c.debug("transform",{codec:o}),s.setupTransform(n,t.readable,t.writable,i,o)})}));
|
2
2
|
//# sourceMappingURL=livekit-client.e2ee.worker.js.map
|