livekit-client 2.0.1 → 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 +53 -18
- package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
- package/dist/livekit-client.esm.mjs +94 -57
- 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/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/track/LocalAudioTrack.d.ts +8 -7
- package/dist/src/room/track/LocalAudioTrack.d.ts.map +1 -1
- package/dist/src/room/track/LocalTrack.d.ts +11 -9
- package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
- package/dist/src/room/track/LocalTrackPublication.d.ts +2 -2
- package/dist/src/room/track/LocalVideoTrack.d.ts +3 -3
- package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -1
- package/dist/src/room/track/RemoteAudioTrack.d.ts +2 -1
- package/dist/src/room/track/RemoteAudioTrack.d.ts.map +1 -1
- package/dist/src/room/track/RemoteTrack.d.ts +2 -2
- package/dist/src/room/track/RemoteTrack.d.ts.map +1 -1
- package/dist/src/room/track/RemoteVideoTrack.d.ts +2 -1
- package/dist/src/room/track/RemoteVideoTrack.d.ts.map +1 -1
- package/dist/src/room/track/Track.d.ts +5 -3
- package/dist/src/room/track/Track.d.ts.map +1 -1
- package/dist/src/room/track/processor/types.d.ts +4 -0
- package/dist/src/room/track/processor/types.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/LocalAudioTrack.d.ts +8 -7
- package/dist/ts4.2/src/room/track/LocalTrack.d.ts +11 -9
- package/dist/ts4.2/src/room/track/LocalTrackPublication.d.ts +2 -2
- package/dist/ts4.2/src/room/track/LocalVideoTrack.d.ts +3 -3
- package/dist/ts4.2/src/room/track/RemoteAudioTrack.d.ts +2 -1
- package/dist/ts4.2/src/room/track/RemoteTrack.d.ts +2 -2
- package/dist/ts4.2/src/room/track/RemoteVideoTrack.d.ts +2 -1
- package/dist/ts4.2/src/room/track/Track.d.ts +5 -3
- package/dist/ts4.2/src/room/track/processor/types.d.ts +4 -0
- package/package.json +1 -1
- package/src/api/SignalClient.ts +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 +17 -14
- package/src/room/Room.ts +21 -4
- package/src/room/events.ts +4 -0
- package/src/room/participant/LocalParticipant.ts +0 -1
- package/src/room/track/LocalAudioTrack.ts +9 -11
- package/src/room/track/LocalTrack.ts +78 -56
- package/src/room/track/LocalVideoTrack.ts +3 -3
- package/src/room/track/RemoteAudioTrack.ts +1 -1
- package/src/room/track/RemoteTrack.ts +4 -2
- package/src/room/track/RemoteVideoTrack.ts +1 -1
- package/src/room/track/Track.ts +7 -3
- package/src/room/track/processor/types.ts +4 -0
@@ -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())}))}"function"==typeof SuppressedError&&SuppressedError;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 l=typeof window!==t?window.log:void 0;return u.noConflict=function(){return typeof window!==t&&window.log===u&&(window.log=l),u},u.getLoggers=function(){return y},u.default=u,u},(t=o).exports?t.exports=r():n.log=r();var s,a,c=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={})),function(e){e.Default="livekit",e.Room="livekit-room",e.Participant="livekit-participant",e.Track="livekit-track",e.Publication="livekit-track-publication",e.Engine="livekit-engine",e.Signal="livekit-signal",e.PCManager="livekit-pc-manager",e.PCTransport="livekit-pc-transport",e.E2EE="lk-e2ee"}(a||(a={})),c.getLogger("livekit").setDefaultLevel(s.info);const d=c.getLogger("lk-e2ee"),u="AES-GCM",y={key:10,delta:3,audio:1,empty:0},l={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 p,f,v,g,m,w;!function(e){e.PermissionDenied="PermissionDenied",e.NotFound="NotFound",e.DeviceInUse="DeviceInUse",e.Other="Other"}(p||(p={})),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}}(p||(p={})),function(e){e[e.InvalidKey=0]="InvalidKey",e[e.MissingKey=1]="MissingKey",e[e.InternalError=2]="InternalError"}(f||(f={}));class I extends h{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:f.InternalError;super(40,e),this.reason=t}}!function(e){e.SetKey="setKey",e.RatchetRequest="ratchetRequest",e.KeyRatcheted="keyRatcheted"}(v||(v={})),function(e){e.KeyRatcheted="keyRatcheted"}(g||(g={})),function(e){e.ParticipantEncryptionStatusChanged="participantEncryptionStatusChanged",e.EncryptionError="encryptionError"}(m||(m={})),function(e){e.Error="cryptorError"}(w||(w={}));var S,L={exports:{}},b="object"==typeof Reflect?Reflect:null,E=b&&"function"==typeof b.apply?b.apply:function(e,t,n){return Function.prototype.apply.call(e,t,n)};S=b&&"function"==typeof b.ownKeys?b.ownKeys:Object.getOwnPropertySymbols?function(e){return Object.getOwnPropertyNames(e).concat(Object.getOwnPropertySymbols(e))}:function(e){return Object.getOwnPropertyNames(e)};var k=Number.isNaN||function(e){return e!=e};function K(){K.init.call(this)}L.exports=K,L.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))}O(e,t,o,{once:!0}),"error"!==t&&function(e,t,n){"function"==typeof e.on&&O(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 C=10;function _(e){if("function"!=typeof e)throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof e)}function A(e){return void 0===e._maxListeners?K.defaultMaxListeners:e._maxListeners}function T(e,t,n,r){var i,o,s,a;if(_(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=A(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 P(){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=P.bind(r);return i.listener=n,r.wrapFn=i,i}function x(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 U(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 O(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 C},set:function(e){if("number"!=typeof e||e<0||k(e))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+e+".");C=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||k(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 A(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)E(a,this,t);else{var c=a.length,d=F(a,c);for(n=0;n<c;++n)E(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 _(t),this.on(e,R(this,e,t)),this},K.prototype.prependOnceListener=function(e,t){return _(t),this.prependListener(e,R(this,e,t)),this},K.prototype.removeListener=function(e,t){var n,r,i,o,s;if(_(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 x(this,e,!0)},K.prototype.rawListeners=function(e){return x(this,e,!1)},K.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):U.call(e,t)},K.prototype.listenerCount=U,K.prototype.eventNames=function(){return this._eventsCount>0?S(this._events):[]};var M=L.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:u,length:128},!1,["encrypt","decrypt"]);return{material:t,encryptionKey:r}}))}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&&(d.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=>{d.warn(e),this.emit(w.Error,e instanceof I?e:new I(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 c=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:u,iv:e,additionalData:new Uint8Array(t.data,0,c.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(c.byteLength+o.byteLength);return s.set(c),s.set(o,c.byteLength),t.data=s.buffer,n.enqueue(t)}catch(e){d.error(e)}}else this.emit(w.Error,new I("encryption key missing for encoding",f.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 d.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 I&&e.reason===f.InvalidKey?this.keys.hasValidKey&&(this.emit(w.Error,e),this.keys.decryptionFailure()):d.warn("decoding frame failed",{error:e})}else!this.keys.getKeySet(e)&&this.keys.hasValidKey&&(d.warn("skipping decryption due to missing key at index ".concat(e)),this.emit(w.Error,new I("missing key at index ".concat(e," for participant ").concat(this.participantIdentity),f.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],d=new Uint8Array(t.data,t.data.byteLength-c-r.byteLength,c),y=n.byteLength,l=t.data.byteLength-(n.byteLength+c+r.byteLength),h=yield crypto.subtle.decrypt({name:u,iv:d,additionalData:new Uint8Array(t.data,0,n.byteLength)},null!==(o=i.encryptionKey)&&void 0!==o?o:e.encryptionKey,new Uint8Array(t.data,y,l)),p=new ArrayBuffer(n.byteLength+h.byteLength),f=new Uint8Array(p);return f.set(new Uint8Array(t.data,0,n.byteLength)),f.set(new Uint8Array(h),n.byteLength),t.data=p,t}catch(o){if(this.keyProviderOptions.ratchetWindowSize>0){if(i.ratchetCount<this.keyProviderOptions.ratchetWindowSize){let o;if(d.debug("ratcheting key attempt ".concat(i.ratchetCount," of ").concat(this.keyProviderOptions.ratchetWindowSize,", for kind ").concat(t instanceof RTCEncodedAudioFrame?"audio":"video")),(null!=r?r: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&&(null!=r?r:e)===this.keys.getKeySet(n)&&(this.keys.setKeySet(o,n,!0),this.keys.setCurrentKeyIndex(n)),s}throw d.warn("maximum ratchet attempts exceeded"),new I("valid key missing for participant ".concat(this.participantIdentity),f.InvalidKey)}throw new I("Decryption failed: ".concat(o.message),f.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=y[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(X(i[e])))),n.isH264){for(const t of e){switch(X(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=y[e.type],n}return n.unencryptedBytes=y.audio,n}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&H}const H=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&&(d.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:u},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(g.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*(){const e=n>=0?n%this.cryptoKeyRing.length:-1;d.debug("setting new key with index ".concat(e));const i=yield N(t,this.keyProviderOptions.ratchetSalt);this.setKeySet(i,e>=0?e:this.currentKeyIndex,r),e>=0&&(this.currentKeyIndex=e)}))}setKeySet(e,t){let n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];this.cryptoKeyRing[t%this.cryptoKeyRing.length]=e,n&&this.emit(g.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=[],Y=new Map;let Q,J,Z,$=!1,ee=l;function te(e,t){let n=W.find((e=>e.getTrackId()===t));if(n)e!==n.getParticipantIdentity()&&n.setParticipant(e,ne(e));else{if(d.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(w.Error,(e=>{const t={kind:"error",data:{error:new Error("".concat(f[e.reason],": ").concat(e.message))}};postMessage(t)}))}(n),W.push(n)}return n}function ne(e){if($)return re();let t=Y.get(e);return t||(t=new z(e,ee),J&&t.setKey(J),t.on(g.KeyRatcheted,ie),Y.set(e,t)),t}function re(){return Q||(Q=new z("shared-key",ee)),Q}function ie(e,t,n){postMessage({kind:"ratchetKey",data:{participantIdentity:t,keyIndex:n,material:e}})}d.setDefaultLevel("info"),onmessage=t=>{const{kind:n,data:r}=t.data;switch(n){case"init":d.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),d.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":$?(d.warn("set shared key"),a=r.key,c=r.keyIndex,d.debug("setting shared key"),J=a,re().setKey(a,c)):r.participantIdentity?(d.warn("set participant sender key ".concat(r.participantIdentity," index ").concat(r.keyIndex)),ne(r.participantIdentity).setKey(r.key,r.keyIndex)):d.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 d.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,c,u,y},self.RTCTransformEvent&&(d.debug("setup transform event"),self.onrtctransform=e=>{const t=e.transformer;d.debug("transformer",t),t.handled=!0;const{kind:n,participantIdentity:r,trackId:i,codec:o}=t.options,s=te(r,i);d.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())}))}"function"==typeof SuppressedError&&SuppressedError;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 l=typeof window!==t?window.log:void 0;return u.noConflict=function(){return typeof window!==t&&window.log===u&&(window.log=l),u},u.getLoggers=function(){return y},u.default=u,u},(t=o).exports?t.exports=r():n.log=r();var s,a,c=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={})),function(e){e.Default="livekit",e.Room="livekit-room",e.Participant="livekit-participant",e.Track="livekit-track",e.Publication="livekit-track-publication",e.Engine="livekit-engine",e.Signal="livekit-signal",e.PCManager="livekit-pc-manager",e.PCTransport="livekit-pc-transport",e.E2EE="lk-e2ee"}(a||(a={})),c.getLogger("livekit").setDefaultLevel(s.info);const d=c.getLogger("lk-e2ee"),u="AES-GCM",y={key:10,delta:3,audio:1,empty:0},l={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 p,f,v,g,m,w;!function(e){e.PermissionDenied="PermissionDenied",e.NotFound="NotFound",e.DeviceInUse="DeviceInUse",e.Other="Other"}(p||(p={})),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}}(p||(p={})),function(e){e[e.InvalidKey=0]="InvalidKey",e[e.MissingKey=1]="MissingKey",e[e.InternalError=2]="InternalError"}(f||(f={}));class I extends h{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:f.InternalError;super(40,e),this.reason=t}}!function(e){e.SetKey="setKey",e.RatchetRequest="ratchetRequest",e.KeyRatcheted="keyRatcheted"}(v||(v={})),function(e){e.KeyRatcheted="keyRatcheted"}(g||(g={})),function(e){e.ParticipantEncryptionStatusChanged="participantEncryptionStatusChanged",e.EncryptionError="encryptionError"}(m||(m={})),function(e){e.Error="cryptorError"}(w||(w={}));var b,S={exports:{}},L="object"==typeof Reflect?Reflect:null,k=L&&"function"==typeof L.apply?L.apply:function(e,t,n){return Function.prototype.apply.call(e,t,n)};b=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 C(){C.init.call(this)}S.exports=C,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})}))},C.EventEmitter=C,C.prototype._events=void 0,C.prototype._eventsCount=0,C.prototype._maxListeners=void 0;var K=10;function _(e){if("function"!=typeof e)throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof e)}function A(e){return void 0===e._maxListeners?C.defaultMaxListeners:e._maxListeners}function T(e,t,n,r){var i,o,s,a;if(_(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=A(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 x(){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 P(e,t,n){var r={fired:!1,wrapFn:void 0,target:e,type:t,listener:n},i=x.bind(r);return i.listener=n,r.wrapFn=i,i}function R(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 O(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(C,"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}}),C.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},C.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},C.prototype.getMaxListeners=function(){return A(this)},C.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)k(a,this,t);else{var c=a.length,d=F(a,c);for(n=0;n<c;++n)k(d[n],this,t)}return!0},C.prototype.addListener=function(e,t){return T(this,e,t,!1)},C.prototype.on=C.prototype.addListener,C.prototype.prependListener=function(e,t){return T(this,e,t,!0)},C.prototype.once=function(e,t){return _(t),this.on(e,P(this,e,t)),this},C.prototype.prependOnceListener=function(e,t){return _(t),this.prependListener(e,P(this,e,t)),this},C.prototype.removeListener=function(e,t){var n,r,i,o,s;if(_(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},C.prototype.off=C.prototype.removeListener,C.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},C.prototype.listeners=function(e){return R(this,e,!0)},C.prototype.rawListeners=function(e){return R(this,e,!1)},C.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):O.call(e,t)},C.prototype.listenerCount=O,C.prototype.eventNames=function(){return this._eventsCount>0?b(this._events):[]};var 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:u,length:128},!1,["encrypt","decrypt"]);return{material:t,encryptionKey:r}}))}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 j=new Map;class q extends M.EventEmitter{encodeFunction(e,t){throw Error("not implemented for subclass")}decodeFunction(e,t){throw Error("not implemented for subclass")}}class V extends q{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}get logContext(){return{identity:this.participantIdentity,trackId:this.trackId,fallbackCodec:this.videoCodec}}setParticipant(e,t){this.participantIdentity=e,this.keys=t,this.sifGuard.reset()}unsetParticipant(){d.debug("unsetting participant",this.logContext),this.participantIdentity=void 0}isEnabled(){return this.participantIdentity?j.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&&(d.info("setting codec on cryptor to",{codec:i}),this.videoCodec=i),d.debug("Setting up frame cryptor transform",Object.assign({operation:e,passedTrackId:r,codec:i},this.logContext));const o="encode"===e?this.encodeFunction:this.decodeFunction,s=new TransformStream({transform:o.bind(this)});t.pipeThrough(s).pipeTo(n).catch((e=>{d.warn(e),this.emit(w.Error,e instanceof I?e:new I(e.message))})),this.trackId=r}setSifTrailer(e){d.debug("setting SIF trailer",Object.assign(Object.assign({},this.logContext),{trailer: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);d.debug("frameInfo for encoded frame",Object.assign(Object.assign({},a),this.logContext));const c=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:u,iv:e,additionalData:new Uint8Array(t.data,0,c.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(c.byteLength+o.byteLength);return s.set(c),s.set(o,c.byteLength),t.data=s.buffer,n.enqueue(t)}catch(e){d.error(e)}}else d.debug("failed to decrypt, emitting error",this.logContext),this.emit(w.Error,new I("encryption key missing for encoding",f.MissingKey))}))}decodeFunction(t,n){return e(this,void 0,void 0,(function*(){if(!this.isEnabled()||0===t.data.byteLength)return d.debug("skipping empty frame",this.logContext),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 d.debug("enqueue SIF",this.logContext),this.sifGuard.recordSif(),this.sifGuard.isSifAllowed()?(t.data=t.data.slice(0,t.data.byteLength-this.sifTrailer.byteLength),n.enqueue(t)):void d.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 d.debug("enqueue decrypted frame",this.logContext),n.enqueue(r)}catch(e){e instanceof I&&e.reason===f.InvalidKey?this.keys.hasValidKey&&(this.emit(w.Error,e),this.keys.decryptionFailure()):d.warn("decoding frame failed",{error:e})}else!this.keys.getKeySet(e)&&this.keys.hasValidKey&&(d.warn("skipping decryption due to missing key at index ".concat(e)),this.emit(w.Error,new I("missing key at index ".concat(e," for participant ").concat(this.participantIdentity),f.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);d.debug("frameInfo for decoded frame",Object.assign(Object.assign({},s),this.logContext));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],d=new Uint8Array(t.data,t.data.byteLength-c-r.byteLength,c),y=n.byteLength,l=t.data.byteLength-(n.byteLength+c+r.byteLength),h=yield crypto.subtle.decrypt({name:u,iv:d,additionalData:new Uint8Array(t.data,0,n.byteLength)},null!==(o=i.encryptionKey)&&void 0!==o?o:e.encryptionKey,new Uint8Array(t.data,y,l)),p=new ArrayBuffer(n.byteLength+h.byteLength),f=new Uint8Array(p);return f.set(new Uint8Array(t.data,0,n.byteLength)),f.set(new Uint8Array(h),n.byteLength),t.data=p,t}catch(o){if(this.keyProviderOptions.ratchetWindowSize>0){if(i.ratchetCount<this.keyProviderOptions.ratchetWindowSize){let o;if(d.debug("ratcheting key attempt ".concat(i.ratchetCount," of ").concat(this.keyProviderOptions.ratchetWindowSize,", for kind ").concat(t instanceof RTCEncodedAudioFrame?"audio":"video")),(null!=r?r: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&&(null!=r?r:e)===this.keys.getKeySet(n)&&(this.keys.setKeySet(o,n,!0),this.keys.setCurrentKeyIndex(n)),s}throw d.warn("maximum ratchet attempts exceeded"),new I("valid key missing for participant ".concat(this.participantIdentity),f.InvalidKey)}throw new I("Decryption failed: ".concat(o.message),f.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=y[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(X(i[e])))),n.isH264){for(const t of e){switch(X(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=y[e.type],n}return n.unencryptedBytes=y.audio,n}getVideoCodec(e){if(0===this.rtpMap.size)return;const t=e.getMetadata().payloadType,n=t?this.rtpMap.get(t):void 0;return d.debug("reading codec from frame",Object.assign({codec:n},this.logContext)),n}}function X(e){return e&H}const H=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&&(d.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:u},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(g.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,n){let r=arguments.length>2&&void 0!==arguments[2]&&arguments[2];return e(this,void 0,void 0,(function*(){const e=yield N(t,this.keyProviderOptions.ratchetSalt),i=n>=0?n%this.cryptoKeyRing.length:this.currentKeyIndex;d.debug("setting new key with index ".concat(n),{usage:t.usages,algorithm:t.algorithm,ratchetSalt:this.keyProviderOptions.ratchetSalt}),this.setKeySet(e,i,r),i>=0&&(this.currentKeyIndex=i)}))}setKeySet(e,t){let n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];this.cryptoKeyRing[t%this.cryptoKeyRing.length]=e,n&&this.emit(g.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=[],Y=new Map;let Q,J,Z=!1,$=l;function ee(e,t){let n=W.find((e=>e.getTrackId()===t));if(n)e!==n.getParticipantIdentity()&&n.setParticipant(e,te(e));else{if(d.info("creating new cryptor for",{participantIdentity:e}),!$)throw Error("Missing keyProvider options");n=new V({participantIdentity:e,keys:te(e),keyProviderOptions:$,sifTrailer:J}),function(e){e.on(w.Error,(e=>{const t={kind:"error",data:{error:new Error("".concat(f[e.reason],": ").concat(e.message))}};postMessage(t)}))}(n),W.push(n)}return n}function te(e){if(Z)return ne();let t=Y.get(e);return t||(t=new z(e,$),t.on(g.KeyRatcheted,re),Y.set(e,t)),t}function ne(){return Q||(d.debug("creating new shared key handler"),Q=new z("shared-key",$)),Q}function re(e,t,n){postMessage({kind:"ratchetKey",data:{participantIdentity:t,keyIndex:n,material:e}})}d.setDefaultLevel("info"),onmessage=t=>{const{kind:n,data:r}=t.data;switch(n){case"init":d.info("worker initialized"),$=r.keyProviderOptions,Z=!!r.keyProviderOptions.sharedKey;postMessage({kind:"initAck",data:{enabled:false}});break;case"enable":a=r.enabled,c=r.participantIdentity,d.debug("setting encryption enabled for all tracks of ".concat(c),{enable:a}),j.set(c,a),d.info("updated e2ee enabled status"),postMessage(t.data);break;case"decode":ee(r.participantIdentity,r.trackId).setupTransform(n,r.readableStream,r.writableStream,r.trackId,r.codec);break;case"encode":ee(r.participantIdentity,r.trackId).setupTransform(n,r.readableStream,r.writableStream,r.trackId,r.codec);break;case"setKey":Z?(o=r.key,s=r.keyIndex,d.info("set shared key",{index:s}),ne().setKey(o,s)):r.participantIdentity?(d.info("set participant sender key ".concat(r.participantIdentity," index ").concat(r.keyIndex)),te(r.participantIdentity).setKey(r.key,r.keyIndex)):d.error("no participant Id was provided and shared key usage is disabled");break;case"removeTransform":!function(e,t){const n=W.find((n=>n.getParticipantIdentity()===t&&n.getTrackId()===e));n?n.unsetParticipant():d.warn("Could not unset participant on cryptor",{trackId:e,participantIdentity:t})}(r.trackId,r.participantIdentity);break;case"updateCodec":ee(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(Z){const e=ne();yield e.ratchetKey(t.keyIndex),e.resetKeyStatus()}else if(t.participantIdentity){const e=te(t.participantIdentity);yield e.ratchetKey(t.keyIndex),e.resetKeyStatus()}else d.error("no participant Id was provided for ratchet request and shared key usage is disabled")}))}(r);break;case"setSifTrailer":i=r.trailer,J=i,W.forEach((e=>{e.setSifTrailer(i)}))}var i,o,s,a,c},self.RTCTransformEvent&&(d.debug("setup transform event"),self.onrtctransform=e=>{const t=e.transformer;d.debug("transformer",t),t.handled=!0;const{kind:n,participantIdentity:r,trackId:i,codec:o}=t.options,s=ee(r,i);d.debug("transform",{codec:o}),s.setupTransform(n,t.readable,t.writable,i,o)})}));
|
2
2
|
//# sourceMappingURL=livekit-client.e2ee.worker.js.map
|