@transmitsecurity/platform-web-sdk 1.18.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/webauthn.cjs CHANGED
@@ -1 +1 @@
1
- "undefined"==typeof globalThis&&("undefined"!=typeof window?(window.globalThis=window,window.global=window):"undefined"!=typeof self&&(self.globalThis=self,self.global=self));const t=Symbol("MODULE_INITIALIZED"),e=new Map;function i(t,i){var a,n;null===(a=e.get(t))||void 0===a||a.forEach((n=t=>t(i),function(){try{return n(...arguments)}catch(t){console.log(t)}}))}let a=null;function n(t){a=t}var s=Object.freeze({__proto__:null,getInitConfig:function(){return a},get initConfig(){return a},setInitConfig:n});function r(e){n(e),i(t,void 0)}var o=Object.freeze({__proto__:null,initialize:r});function c(t,e,i){return(e=function(t){var e=function(t,e){if("object"!=typeof t||!t)return t;var i=t[Symbol.toPrimitive];if(void 0!==i){var a=i.call(t,e||"default");if("object"!=typeof a)return a;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(t,"string");return"symbol"==typeof e?e:e+""}(e))in t?Object.defineProperty(t,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):t[e]=i,t}function l(t,e){var i=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);e&&(a=a.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),i.push.apply(i,a)}return i}function u(t){for(var e=1;e<arguments.length;e++){var i=null!=arguments[e]?arguments[e]:{};e%2?l(Object(i),!0).forEach((function(e){c(t,e,i[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(i)):l(Object(i)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(i,e))}))}return t}function d(t,e){return Object.entries(e).reduce(((e,i)=>{let[a,n]=i;return u(u({},e),{},{[a]:h.isPrototypeOf(n)?new n(t.slug):"function"==typeof n?n.bind(t):"object"==typeof n&&!Array.isArray(n)&&n?d(t,n):n})}),{})}class h{constructor(t){this.slug=t}static create(t){return class extends h{constructor(e){super(e),Object.assign(this,d(this,t(this)))}}}}var y=Object.freeze({__proto__:null,Agent:h}),p=Object.freeze({__proto__:null,MODULE_INITIALIZED:t,emit:i,off:function(t,i){const a=e.get(t);if(!a)return;const n=a.indexOf(i);-1!==n&&a.splice(n,1)},on:function(t,i){var a;e.has(t)?null===(a=e.get(t))||void 0===a||a.push(i):e.set(t,[i])}});function g(t,e){const i=!t||"object"!=typeof t||Array.isArray(t)?{}:t;return[e.reduce(((t,e)=>{if(e in t){const i=t[e];if(null!==i&&"object"==typeof i&&!Array.isArray(i))return i}const i={};return t[e]=i,i}),i),i]}const v="tsec",f="general";function w(t){return t?f:a.clientId}function m(t){return function(t){if(!t)return{};try{return JSON.parse(t)}catch(t){return{}}}((t?sessionStorage:localStorage).getItem(v))}function b(t,e){const i=t?sessionStorage:localStorage,a=e(m(t));i.setItem(v,JSON.stringify(a))}var D=Object.freeze({__proto__:null,COMMON_STORAGE_KEY:v,GENERAL_ID_KEY:f,getValue:function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const i=w(!!e.isGeneral),a=m(!!e.sessionOnly),[n]=g(a,[this.slug.toString(),i]);return n[t]},hasValue:function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const i=w(!!e.isGeneral);return function(t,e){let i=t;return e.every((t=>!(!i||"object"!=typeof i||Array.isArray(i)||!(t in i)||(i=i[t],0))),t)}(m(!!e.sessionOnly),[this.slug.toString(),i,t])},removeValue:function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const i=w(!!e.isGeneral);b(!!e.sessionOnly,(e=>{const[a,n]=g(e,[this.slug.toString(),i]);return delete a[t],n}))},setValue:function(t,e){let i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const a=w(!!i.isGeneral);b(!!i.sessionOnly,(i=>{const[n,s]=g(i,[this.slug.toString(),a]);return n[t]=e,s}))}});const S="RSA-PSS",A=async(t,e)=>await window.crypto.subtle.generateKey({name:t,modulusLength:2048,publicExponent:new Uint8Array([1,0,1]),hash:"SHA-256"},!1,e),C=async()=>await A("RSA-OAEP",["encrypt","decrypt"]),_=async()=>await A(S,["sign"]),K=async(t,e)=>{const i=(new TextEncoder).encode(e);return await window.crypto.subtle.sign({name:S,saltLength:32},t,i)};class k{constructor(t,e,i){this.slug=t,this.dbName=e,this.dbVersion=i}queryObjectStore(t,e){let i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const{attemptToRecoverDB:a=!0}=i,n=window.indexedDB||window.mozIndexedDB||window.webkitIndexedDB||window.msIndexedDB||window.shimIndexedDB,s=`${this.slug}:${this.dbName}`,r=n.open(s,this.dbVersion||1);r.onupgradeneeded=()=>{var e;const i=r.result;(null===(e=null==i?void 0:i.objectStoreNames)||void 0===e?void 0:e.contains)&&!i.objectStoreNames.contains(t)&&i.createObjectStore(t,{keyPath:"key"})},r.onsuccess=()=>{const o=r.result;let c;try{c=o.transaction(t,(null==i?void 0:i.operation)||"readwrite")}catch(r){if(a&&r instanceof DOMException&&"NotFoundError"===r.name){o.close();return void(n.deleteDatabase(s).onsuccess=()=>{this.queryObjectStore(t,e,u(u({},i),{},{attemptToRecoverDB:!1}))})}throw r}const l=c.objectStore(t);e(l,o),c.oncomplete||(c.oncomplete=()=>{o.close()})}}put(t,e,i){return new Promise(((a,n)=>{this.queryObjectStore(t,(t=>{const s=t.put({key:e,value:i});s.onsuccess=()=>{a(s.result)},s.onerror=t=>{n("Failed adding item to objectStore, err: "+t)}}))}))}add(t,e,i){return new Promise(((a,n)=>{this.queryObjectStore(t,(t=>{const s=t.add({key:e,value:i});s.onsuccess=()=>{a(s.result)},s.onerror=t=>{const e=t.target.error;n(e)}}))}))}get(t,e){return new Promise(((i,a)=>{this.queryObjectStore(t,(t=>{const n=t.get(e);n.onsuccess=()=>{var t;n.result?i(null===(t=n.result)||void 0===t?void 0:t.value):i(void 0)},n.onerror=t=>{a("Failed adding item to objectStore, err: "+t)}}))}))}getAll(t,e){return new Promise(((i,a)=>{this.queryObjectStore(t,(t=>{const n=t.getAll(null,e);n.onsuccess=()=>{if(n.result){const t=n.result;(null==t?void 0:t.length)?i(t.map((t=>null==t?void 0:t.value))):i(t)}else i([])},n.onerror=t=>{a("Failed getting items, err: "+t)}}))}))}delete(t,e){return new Promise(((i,a)=>{this.queryObjectStore(t,(t=>{const n=t.delete(e);n.onsuccess=()=>{i()},n.onerror=t=>{a(`Failed deleting key: '${e}' from objectStore, err: `+t)}}))}))}clear(t){return new Promise(((e,i)=>{this.queryObjectStore(t,(t=>{const a=t.clear();a.onsuccess=()=>{e()},a.onerror=t=>{i("Failed clearing objectStore, err: "+t)}}))}))}executeTransaction(t,e){return new Promise(((i,a)=>{this.queryObjectStore(t,((t,n)=>{const s=t.transaction;s.onerror=()=>{a(`Transaction failed: ${s.error}`)},s.onabort=()=>{a("Transaction aborted")},s.oncomplete=()=>{n.close(),i()};for(const i of e){let e;if("delete"===i.type)e=t.delete(i.key);else{if("put"!==i.type)return s.abort(),void a("Unknown operation type");e=t.put({key:i.key,value:i.value})}e.onerror=()=>{s.abort(),a(`Operation failed: ${e.error}`)}}}))}))}}const R="init",P="completed",T="RSA2048",I=[R,P];class O{constructor(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"sign",i=arguments.length>2?arguments[2]:void 0;var a,n,s,r,o;this.agent=t,this.keysType=e,this.options=i,this._extractingKeysPromise=null;const c=!(null===(a=this.options)||void 0===a?void 0:a.productScope),l=null===(n=this.options)||void 0===n?void 0:n.fallbackClientId;this.keysDatabaseName=c||!(null===(s=this.options)||void 0===s?void 0:s.indexedDBName)?"ts_crypto_binding":this.options.indexedDBName,this.dbVersion=c?1:(null===(r=this.options)||void 0===r?void 0:r.dbVersion)||1,this.keysStoreName=c||!(null===(o=this.options)||void 0===o?void 0:o.keysStoreName)?"identifiers_store":this.options.keysStoreName;const u=c?"platform":t.slug,d=this.getClientConfiguration(l,u);this.indexedDBClient=new k(d.main,this.keysDatabaseName,this.dbVersion),this.indexedDBClientFallback=new k(d.fallback,this.keysDatabaseName,this.dbVersion)}getClientConfiguration(t,e){return t?{main:e,fallback:`${e}:${t}`}:{main:e,fallback:`${e}:${a.clientId}`}}getKeysRecordKey(){return`${this.keysType}_keys`}getRotatedKeysRecordKey(){return`rotated_${this.keysType}_keys`}getRotatedKeysRecordKeyPending(){return`rotated_pending_${this.keysType}_keys`}arrayBufferToBase64(t){return window.btoa(String.fromCharCode(...new Uint8Array(t)))}async getPKRepresentations(t){const e=await crypto.subtle.exportKey("spki",t);return{arrayBufferKey:e,base64Key:this.arrayBufferToBase64(e)}}async generateKeyPair(){return"sign"==this.keysType?await _():await C()}async calcKeyIdentifier(t){const e=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(e)).map((t=>t.toString(16).padStart(2,"0"))).join("")}async extractKeysData(){if(this._extractingKeysPromise)return this._extractingKeysPromise;this._extractingKeysPromise=(async()=>{var t,e;const i=(null===(e=null===(t=this.options)||void 0===t?void 0:t.keyRotation)||void 0===e?void 0:e.isEnabled)?await this.getRotatedKeysData():await this.getKeysData(),{base64Key:a}=await this.getPKRepresentations(i.publicKey);return this.publicKeyBase64=a,this.keyIdentifier=i.keyIdentifier,i})();try{return await this._extractingKeysPromise}finally{this._extractingKeysPromise=null}}async generateKeyPairData(t){const e=await this.generateKeyPair(),{arrayBufferKey:i}=await this.getPKRepresentations(e.publicKey),a=t||await this.calcKeyIdentifier(i);return u(u({},e),{},{keyIdentifier:a,createdDate:Date.now()})}shouldKeyBeRotated(t){var e;const i=null===(e=this.options)||void 0===e?void 0:e.keyRotation;if(!(null==i?void 0:i.isEnabled)||!i.expiryDays||void 0===i.startedAt)return!1;const a=24*i.expiryDays*60*60*1e3,n=t.createdDate&&t.createdDate>=i.startedAt?t.createdDate:i.startedAt;return Date.now()-n>a-2592e6}async extractMainKeysData(){return await this.indexedDBClient.get(this.keysStoreName,this.getKeysRecordKey())}async extractFallbackMainKeysData(){return await this.indexedDBClientFallback.get(this.keysStoreName,this.getKeysRecordKey())}async extractRotatedKeysData(){return await this.indexedDBClient.get(this.keysStoreName,this.getRotatedKeysRecordKey())}async extractPendingRotatedKeysData(){return await this.indexedDBClient.get(this.keysStoreName,this.getRotatedKeysRecordKeyPending())}async saveKeyData(t,e){try{return await this.indexedDBClient.add(this.keysStoreName,t,e),e}catch(e){if(e instanceof DOMException&&"ConstraintError"===e.name){const e=await this.indexedDBClient.get(this.keysStoreName,t);if(e)return e}throw e}}async getKeysData(){const t=this.getKeysRecordKey();let e=await this.extractMainKeysData();if(e)return e;if(e=await this.extractFallbackMainKeysData(),e)return this.saveKeyData(t,e);const i=await this.generateKeyPairData();return this.saveKeyData(t,i)}async getOrCreateRotatedKeys(){let t=await this.extractRotatedKeysData();if(!t){const e=this.getRotatedKeysRecordKey(),i=await this.getKeysData(),a=u(u({},i),{},{createdDate:i.createdDate||Date.now()});t=await this.saveKeyData(e,a)}return t}async getRotatedKeysData(){const t=await this.getOrCreateRotatedKeys();if(this.shouldKeyBeRotated(t)){if(!await this.extractPendingRotatedKeysData()){const e=this.getRotatedKeysRecordKeyPending(),i=await this.generateKeyPairData(t.keyIdentifier);await this.saveKeyData(e,i)}}return t}async getPublicData(){return this.publicKeyBase64&&this.keyIdentifier||await this.extractKeysData(),{publicKey:this.publicKeyBase64,keyIdentifier:this.keyIdentifier}}async sign(t){if("sign"==this.keysType){const{privateKey:e}=await this.extractKeysData(),i=await K(e,t);return this.arrayBufferToBase64(i)}throw new Error("keysType must be 'sign' in order to use sign keys")}async clearKeys(){const t=this.getKeysRecordKey();await this.indexedDBClient.delete(this.keysStoreName,t)}getBaseRotationPayload(){return{keyIdentifier:this.keyIdentifier,slot:this.getRotatedKeysRecordKey(),publicKey:this.publicKeyBase64,publicKeyType:T,tenantId:this.options.keyRotation.tenantId}}async getRotationData(){var t,e;if(!(null===(e=null===(t=this.options)||void 0===t?void 0:t.keyRotation)||void 0===e?void 0:e.isEnabled))return;this.publicKeyBase64&&this.keyIdentifier||await this.extractKeysData();const i=await this.extractPendingRotatedKeysData();if(i){const{base64Key:t}=await this.getPKRepresentations(i.publicKey),{privateKey:e}=await this.extractKeysData(),a=u(u({},this.getBaseRotationPayload()),{},{newPublicKey:t,createdDate:i.createdDate,newPublicKeyType:T}),n=JSON.stringify(a);return{data:n,signature:await this.signPayload(n,e)}}const a=await this.extractRotatedKeysData();if(a&&!1===a.confirmed){await this.extractKeysData();const t=JSON.stringify(this.getBaseRotationPayload());return{data:t,signature:await this.signPayload(t,a.privateKey)}}}async signPayload(t,e){const i=await K(e,t);return this.arrayBufferToBase64(i)}async handleRotateResponse(t){if(I.includes(t))if(t===R){const t=await this.extractPendingRotatedKeysData();if(t){const e=u(u({},t),{},{confirmed:!1});await this.indexedDBClient.executeTransaction(this.keysStoreName,[{type:"delete",key:this.getRotatedKeysRecordKey()},{type:"put",key:this.getRotatedKeysRecordKey(),value:e},{type:"delete",key:this.getRotatedKeysRecordKeyPending()}]);const{base64Key:i}=await this.getPKRepresentations(t.publicKey);this.publicKeyBase64=i,this.keyIdentifier=t.keyIdentifier}}else if(t===P){const t=await this.extractRotatedKeysData();t&&!1===t.confirmed&&await this.indexedDBClient.put(this.keysStoreName,this.getRotatedKeysRecordKey(),u(u({},t),{},{confirmed:!0}))}}}var x=Object.freeze({__proto__:null,createCryptoBinding:function(){return new O(this,arguments.length>0&&void 0!==arguments[0]?arguments[0]:"sign",arguments.length>1?arguments[1]:void 0)},generateRSAKeyPair:C,generateRSASignKeyPair:_,signAssymetric:K,verifyAssymetric:async(t,e,i)=>{const a=(new TextEncoder).encode(e);return await window.crypto.subtle.verify(S,t,i,a)}}),j=Object.freeze({__proto__:null});const B=h.create((t=>{class e extends Error{constructor(e,i){super(`${t.slug}-${e} ${i}`)}}return{TsError:e,TsInternalError:class extends e{constructor(t){super(t,"Internal error")}}}}));var E=h.create((()=>u({exceptions:B},y)));class N{constructor(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];this.agent=t,this.middlewares=e,this.logs=[]}info(t,e){this.pushLog(3,t,e)}warn(t,e){this.pushLog(4,t,e)}error(t,e){this.pushLog(5,t,e)}pushLog(t,e){let i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};this.logs.push({timestamp:Date.now(),module:this.agent.slug,severity:t,fields:i,message:e});const a=this.middlewares.map((t=>t(this)));Promise.all(a).catch((()=>{}))}}var F=Object.freeze({__proto__:null,consoleMiddleware:function(t){const e=t.logs[t.logs.length-1];console.log(`${e.severity} ${e.message}`,e.fields)},createSdkLogger:function(){return new N(this,arguments.length>0&&void 0!==arguments[0]?arguments[0]:[])}});function H(t,e){if(!(null==t?void 0:t.trim()))return"";if(function(t){try{return new URL(t),!0}catch(t){return!1}}(t))return t;const i="http://mock.com",a=new URL(i);a.search=(null==e?void 0:e.toString())||"",a.pathname=t;return a.href.replace(i,"")}const M={"Content-Type":"application/json","X-TS-client-time":(new Date).toUTCString(),"X-TS-ua":navigator.userAgent};function $(t,e,i){var a;const n=(s=e||{},encodeURI(JSON.stringify(s)).split(/%..|./).length-1);var s;return{method:t,headers:u(u(u({},{"X-TS-body-size":String(n)}),M),i||{}),body:null!==(a=e&&JSON.stringify(e||{}))&&void 0!==a?a:void 0}}function q(t,e,i,a,n){const s=H(t,a),r=$(e,i,n);return fetch(s,r)}async function z(t,e,i,a,n){let s;if(s=await q(t,e,i,a,n),!s.ok)throw new Error("Request failed");return s}var J=Object.freeze({__proto__:null,httpDelete:async function(t,e){const i=await z(t,"DELETE",void 0,void 0,e);return u(u({data:await i.json()},i),{},{headers:i.headers})},httpGet:async function(t,e,i){const a=await z(t,"GET",void 0,e,i);return u(u({data:await a.json()},a),{},{headers:a.headers})},httpPost:async function(t,e,i,a){const n=await z(t,"POST",e,i,a);return u(u({data:await n.json()},n),{},{headers:n.headers})},httpPut:async function(t,e,i,a){const n=await z(t,"PUT",e,i,a);return u(u({data:await n.json()},n),{},{headers:n.headers})},init:$}),W=h.create((()=>({events:p,moduleMetadata:s,mainEntry:o,utils:E,storage:D,crypto:x,indexedDB:j,logger:F,http:J})));class L{static arrayBufferToBase64(t){return btoa(String.fromCharCode(...new Uint8Array(t)))}static base64ToArrayBuffer(t){return Uint8Array.from(atob(t),(t=>t.charCodeAt(0)))}static stringToBase64(t){return btoa(t)}static jsonToBase64(t){const e=JSON.stringify(t);return btoa(e)}static base64ToJson(t){const e=atob(t);return JSON.parse(e)}}const U={log:console.log,error:console.error};var V,G;!function(t){t.NotInitialized="not_initialized",t.AuthenticationFailed="authentication_failed",t.AuthenticationAbortedTimeout="authentication_aborted_timeout",t.AuthenticationCanceled="webauthn_authentication_canceled",t.RegistrationFailed="registration_failed",t.AlreadyRegistered="username_already_registered",t.RegistrationAbortedTimeout="registration_aborted_timeout",t.RegistrationCanceled="webauthn_registration_canceled",t.AutofillAuthenticationAborted="autofill_authentication_aborted",t.AuthenticationProcessAlreadyActive="authentication_process_already_active",t.InvalidApprovalData="invalid_approval_data",t.FailedToInitCrossDeviceSession="cross_device_init_failed",t.FailedToGetCrossDeviceStatus="cross_device_status_failed",t.Unknown="unknown"}(V||(V={}));class Z extends Error{constructor(t,e){super(t),this.errorCode=V.NotInitialized,this.data=e}}class X extends Z{constructor(t,e){super(null!=t?t:"WebAuthnSdk is not initialized",e),this.errorCode=V.NotInitialized}}class Y extends Z{constructor(t,e){super(null!=t?t:"Authentication failed with an error",e),this.errorCode=V.AuthenticationFailed}}class Q extends Z{constructor(t,e){super(null!=t?t:"Authentication was canceled by the user or got timeout",e),this.errorCode=V.AuthenticationCanceled}}class tt extends Z{constructor(t,e){super(null!=t?t:"Registration failed with an error",e),this.errorCode=V.RegistrationFailed}}class et extends Z{constructor(t,e){super(null!=t?t:"Registration was canceled by the user or got timeout",e),this.errorCode=V.RegistrationCanceled}}class it extends Z{constructor(t){super(null!=t?t:"Autofill flow was aborted"),this.errorCode=V.AutofillAuthenticationAborted}}class at extends Z{constructor(t){super(null!=t?t:"Operation was aborted by timeout"),this.errorCode=V.AutofillAuthenticationAborted}}class nt extends Z{constructor(t){super(null!=t?t:"Passkey with this username is already registered with the relying party."),this.errorCode=V.AlreadyRegistered}}class st extends Z{constructor(t,e){super(null!=t?t:"Authentication process is already active",e),this.errorCode=V.AuthenticationProcessAlreadyActive}}class rt extends Z{constructor(t,e){super(null!=t?t:"Invalid approval data",e),this.errorCode=V.InvalidApprovalData}}class ot extends Z{constructor(t,e){super(null!=t?t:"Failed to init cross device authentication",e),this.errorCode=V.FailedToInitCrossDeviceSession}}class ct extends Z{constructor(t,e){super(null!=t?t:"Failed to get cross device status",e),this.errorCode=V.FailedToGetCrossDeviceStatus}}function lt(t){return t.errorCode&&Object.values(V).includes(t.errorCode)}!function(t){t[t.persistent=0]="persistent",t[t.session=1]="session"}(G||(G={}));class ut{static get(t){return ut.getStorageMedium(ut.allowedKeys[t]).getItem(ut.getStorageKey(t))||void 0}static set(t,e){return ut.getStorageMedium(ut.allowedKeys[t]).setItem(ut.getStorageKey(t),e)}static remove(t){ut.getStorageMedium(ut.allowedKeys[t]).removeItem(ut.getStorageKey(t))}static clear(t){for(const[e,i]of Object.entries(ut.allowedKeys)){const a=e;t&&this.configurationKeys.includes(a)||ut.getStorageMedium(i).removeItem(ut.getStorageKey(a))}}static getStorageKey(t){return`WebAuthnSdk:${t}`}static getStorageMedium(t){return t===G.session?sessionStorage:localStorage}}ut.allowedKeys={clientId:G.session},ut.configurationKeys=["clientId"];class dt{static isNewApiDomain(t){return t&&(this.newApiDomains.includes(t)||t.startsWith("api.")&&t.endsWith(".transmitsecurity.io"))}static dnsPrefetch(t){const e=document.createElement("link");e.rel="dns-prefetch",e.href=t,document.head.appendChild(e)}static preconnect(t,e){const i=document.createElement("link");i.rel="preconnect",i.href=t,e&&(i.crossOrigin="anonymous"),document.head.appendChild(i)}static warmupConnection(t){this.dnsPrefetch(t),this.preconnect(t,!1),this.preconnect(t,!0)}static init(t,e){var i,a;try{this._serverPath=new URL(e.serverPath),this.isNewApiDomain(null===(i=this._serverPath)||void 0===i?void 0:i.hostname)&&this.warmupConnection(this._serverPath.origin),this._apiPaths=null!==(a=e.webauthnApiPaths)&&void 0!==a?a:this.getDefaultPaths(),this._clientId=t,ut.set("clientId",t)}catch(t){throw new X("Invalid options.serverPath",{error:t})}}static getDefaultPaths(){var t;const e=this.isNewApiDomain(null===(t=this._serverPath)||void 0===t?void 0:t.hostname)?"/cis":"";return{startAuthentication:`${e}/v1/auth/webauthn/authenticate/start`,startRegistration:`${e}/v1/auth/webauthn/register/start`,initCrossDeviceAuthentication:`${e}/v1/auth/webauthn/cross-device/authenticate/init`,startCrossDeviceAuthentication:`${e}/v1/auth/webauthn/cross-device/authenticate/start`,startCrossDeviceRegistration:`${e}/v1/auth/webauthn/cross-device/register/start`,getCrossDeviceTicketStatus:`${e}/v1/auth/webauthn/cross-device/status`,attachDeviceToCrossDeviceSession:`${e}/v1/auth/webauthn/cross-device/attach-device`}}static getApiPaths(){return this._apiPaths}static async sendRequest(t,e,i){U.log(`[WebAuthn SDK] Calling ${e.method} ${t}...`);const a=new URL(this._serverPath);return a.pathname=t,i&&(a.search=i),fetch(a.toString(),e)}static async startRegistration(t){const e=await this.sendRequest(this._apiPaths.startRegistration,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(u(u({client_id:this.getValidatedClientId(),username:t.username,display_name:t.displayName},t.timeout&&{timeout:t.timeout}),t.limitSingleCredentialToDevice&&{limit_single_credential_to_device:t.limitSingleCredentialToDevice}))});if(!(null==e?void 0:e.ok))throw new Y("Failed to start registration",null==e?void 0:e.body);return await e.json()}static async startAuthentication(t){const e=await this.sendRequest(this._apiPaths.startAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(u(u(u({client_id:this.getValidatedClientId()},t.username&&{username:t.username}),t.approvalData&&{approval_data:t.approvalData}),t.timeout&&{timeout:t.timeout}))});if(!(null==e?void 0:e.ok))throw new Y("Failed to start authentication",null==e?void 0:e.body);return await e.json()}static async initCrossDeviceAuthentication(t){const e=await this.sendRequest(this._apiPaths.initCrossDeviceAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(u(u({client_id:this.getValidatedClientId()},t.username&&{username:t.username}),t.approvalData&&{approval_data:t.approvalData}))});if(!(null==e?void 0:e.ok))throw new ot(void 0,null==e?void 0:e.body);return await e.json()}static async getCrossDeviceTicketStatus(t){const e=await this.sendRequest(this._apiPaths.getCrossDeviceTicketStatus,{method:"GET"},`cross_device_ticket_id=${t.ticketId}`);if(!(null==e?void 0:e.ok))throw new ct(void 0,null==e?void 0:e.body);return await e.json()}static async startCrossDeviceAuthentication(t){const e=await this.sendRequest(this._apiPaths.startCrossDeviceAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new Y("Failed to start cross device authentication",null==e?void 0:e.body);return await e.json()}static async startCrossDeviceRegistration(t){const e=await this.sendRequest(this._apiPaths.startCrossDeviceRegistration,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new tt("Failed to start cross device registration",null==e?void 0:e.body);return await e.json()}static async attachDeviceToCrossDeviceSession(t){const e=await this.sendRequest(this._apiPaths.attachDeviceToCrossDeviceSession,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new tt("Failed to attach device to cross device session",null==e?void 0:e.body);return await e.json()}static getValidatedClientId(){var t;const e=null!==(t=this._clientId)&&void 0!==t?t:ut.get("clientId");if(!e)throw new X("Missing clientId");return e}}var ht,yt,pt,gt;dt.newApiDomains=["api.idsec-dev.com","api.idsec-stg.com"],function(t){t.InputAutofill="input-autofill",t.Modal="modal"}(ht||(ht={})),exports.WebauthnCrossDeviceStatus=void 0,(yt=exports.WebauthnCrossDeviceStatus||(exports.WebauthnCrossDeviceStatus={})).Pending="pending",yt.Scanned="scanned",yt.Success="success",yt.Error="error",yt.Timeout="timeout",yt.Aborted="aborted",function(t){t.toAuthenticationError=t=>lt(t)?t:"NotAllowedError"===t.name?new Q:"OperationError"===t.name?new st(t.message):"SecurityError"===t.name?new Y(t.message):t===V.AuthenticationAbortedTimeout?new at:"AbortError"===t.name||t===V.AutofillAuthenticationAborted?new it:new Y("Something went wrong during authentication",{error:t}),t.toRegistrationError=t=>lt(t)?t:"NotAllowedError"===t.name?new et:"SecurityError"===t.name?new tt(t.message):"InvalidStateError"===t.name?new nt:t===V.RegistrationAbortedTimeout?new at:new tt("Something went wrong during registration",{error:t})}(pt||(pt={})),function(t){t.processCredentialRequestOptions=t=>u(u({},t),{},{challenge:L.base64ToArrayBuffer(t.challenge),allowCredentials:t.allowCredentials.map((t=>u(u({},t),{},{id:L.base64ToArrayBuffer(t.id)})))}),t.processCredentialCreationOptions=(t,e)=>{var i;const a=JSON.parse(JSON.stringify(t));return a.challenge=L.base64ToArrayBuffer(t.challenge),a.user.id=L.base64ToArrayBuffer(t.user.id),(null==e?void 0:e.limitSingleCredentialToDevice)&&(a.excludeCredentials=null===(i=t.excludeCredentials)||void 0===i?void 0:i.map((t=>u(u({},t),{},{id:L.base64ToArrayBuffer(t.id)})))),(null==e?void 0:e.registerAsDiscoverable)?(a.authenticatorSelection.residentKey="preferred",a.authenticatorSelection.requireResidentKey=!0):(a.authenticatorSelection.residentKey="discouraged",a.authenticatorSelection.requireResidentKey=!1),a.authenticatorSelection.authenticatorAttachment=(null==e?void 0:e.allowCrossPlatformAuthenticators)?void 0:"platform",a},t.encodeAuthenticationResult=t=>{const{authenticatorAttachment:e}=t,i=t.response;return{id:t.id,rawId:L.arrayBufferToBase64(t.rawId),response:{authenticatorData:L.arrayBufferToBase64(i.authenticatorData),clientDataJSON:L.arrayBufferToBase64(i.clientDataJSON),signature:L.arrayBufferToBase64(i.signature),userHandle:L.arrayBufferToBase64(i.userHandle)},authenticatorAttachment:e,type:t.type}},t.encodeRegistrationResult=t=>{const{authenticatorAttachment:e}=t,i=t.response;return{id:t.id,rawId:L.arrayBufferToBase64(t.rawId),response:{attestationObject:L.arrayBufferToBase64(i.attestationObject),clientDataJSON:L.arrayBufferToBase64(i.clientDataJSON)},authenticatorAttachment:e,type:t.type}}}(gt||(gt={}));class vt{async modal(t){try{const e=await this.performAuthentication(u(u({},t),{},{mediationType:ht.Modal}));return L.jsonToBase64(e)}catch(t){throw pt.toAuthenticationError(t)}}activateAutofill(t,e){const{onSuccess:i,onError:a,onReady:n}=t;this.performAuthentication({username:e,mediationType:ht.InputAutofill,onReady:n}).then((t=>{i(L.jsonToBase64(t))})).catch((t=>{const e=pt.toAuthenticationError(t);if(!a)throw e;a(e)}))}abortAutofill(){this.abortController&&this.abortController.abort(V.AutofillAuthenticationAborted)}abortAuthentication(){this.abortController&&this.abortController.abort(V.AuthenticationAbortedTimeout)}async performAuthentication(t){var e,i;const a="crossDeviceTicketId"in t?await dt.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await dt.startAuthentication({username:t.username,timeout:null===(e=t.options)||void 0===e?void 0:e.timeout}),n=a.credential_request_options,s=gt.processCredentialRequestOptions(n),r=this.getMediatedCredentialRequest(s,t.mediationType);t.mediationType===ht.InputAutofill&&(null===(i=t.onReady)||void 0===i||i.call(t));const o=await navigator.credentials.get(r).catch((t=>{throw pt.toAuthenticationError(t)}));return{webauthnSessionId:a.webauthn_session_id,publicKeyCredential:gt.encodeAuthenticationResult(o),userAgent:navigator.userAgent}}getMediatedCredentialRequest(t,e){const i={publicKey:t};return this.abortController=new AbortController,i.signal=this.abortController&&this.abortController.signal,e===ht.InputAutofill?i.mediation="conditional":t.timeout&&setTimeout((()=>{this.abortAuthentication()}),t.timeout),i}}class ft{constructor(t,e){this.handler=t,this.intervalInMs=e}begin(){var t;this.intervalId=window.setInterval((t=this.handler,async function(){t.isRunning||(t.isRunning=!0,await t(...arguments),t.isRunning=!1)}),this.intervalInMs)}stop(){clearInterval(this.intervalId)}}const wt=/^[A-Za-z0-9\-_.: ]*$/;function mt(t){if(t&&(!function(t){return Object.keys(t).length<=10}(t)||!function(t){const e=t=>"string"==typeof t,i=t=>wt.test(t);return Object.keys(t).every((a=>e(a)&&e(t[a])&&i(a)&&i(t[a])))}(t)))throw U.error("Failed validating approval data"),new rt("Provided approval data should have 10 properties max. Also, it should contain only \n alphanumeric characters, numbers, and the special characters: '-', '_', '.'")}class bt{constructor(t,e,i){this.authenticationHandler=t,this.registrationHandler=e,this.approvalHandler=i,this.init={registration:async t=>(this.ticketStatus=exports.WebauthnCrossDeviceStatus.Pending,this.pollCrossDeviceSession(t.crossDeviceTicketId,t.handlers)),authentication:async t=>{const{username:e}=t,i=(await dt.initCrossDeviceAuthentication(u({},e&&{username:e}))).cross_device_ticket_id;return this.ticketStatus=exports.WebauthnCrossDeviceStatus.Pending,this.pollCrossDeviceSession(i,t.handlers)},approval:async t=>{const{username:e,approvalData:i}=t;mt(i);const a=(await dt.initCrossDeviceAuthentication({username:e,approvalData:i})).cross_device_ticket_id;return this.ticketStatus=exports.WebauthnCrossDeviceStatus.Pending,this.pollCrossDeviceSession(a,t.handlers)}},this.authenticate={modal:async t=>this.authenticationHandler.modal({crossDeviceTicketId:t})},this.approve={modal:async t=>this.approvalHandler.modal({crossDeviceTicketId:t})}}async register(t,e){return this.registrationHandler.register({crossDeviceTicketId:t},e)}async attachDevice(t){const e=await dt.attachDeviceToCrossDeviceSession({ticketId:t});return u({status:e.status,startedAt:e.started_at},e.approval_data&&{approvalData:e.approval_data})}async pollCrossDeviceSession(t,e){return this.poller=new ft((async()=>{var i,a;const n=await dt.getCrossDeviceTicketStatus({ticketId:t}),s=n.status;if(s!==this.ticketStatus)switch(this.ticketStatus=s,s){case exports.WebauthnCrossDeviceStatus.Scanned:await e.onDeviceAttach();break;case exports.WebauthnCrossDeviceStatus.Error:case exports.WebauthnCrossDeviceStatus.Timeout:case exports.WebauthnCrossDeviceStatus.Aborted:await e.onFailure(n),null===(i=this.poller)||void 0===i||i.stop();break;case exports.WebauthnCrossDeviceStatus.Success:if("onCredentialRegister"in e)await e.onCredentialRegister();else{if(!n.session_id)throw new ct("Cross device session is complete without returning session_id",n);await e.onCredentialAuthenticate(n.session_id)}null===(a=this.poller)||void 0===a||a.stop()}}),1e3),this.poller.begin(),setTimeout((()=>{var t;null===(t=this.poller)||void 0===t||t.stop(),e.onFailure({status:exports.WebauthnCrossDeviceStatus.Timeout})}),3e5),{crossDeviceTicketId:t,stop:()=>{var t;null===(t=this.poller)||void 0===t||t.stop()}}}}class Dt{async register(t,e){this.abortController=new AbortController;const i=u({allowCrossPlatformAuthenticators:!("crossDeviceTicketId"in t),registerAsDiscoverable:!0},e);try{const a="crossDeviceTicketId"in t?await dt.startCrossDeviceRegistration({ticketId:t.crossDeviceTicketId}):await dt.startRegistration({username:t.username,displayName:(null==e?void 0:e.displayName)||t.username,timeout:null==e?void 0:e.timeout,limitSingleCredentialToDevice:null==e?void 0:e.limitSingleCredentialToDevice}),n=gt.processCredentialCreationOptions(a.credential_creation_options,i);setTimeout((()=>{this.abortRegistration()}),n.timeout);const s=await this.registerCredential(n),r={webauthnSessionId:a.webauthn_session_id,publicKeyCredential:s,userAgent:navigator.userAgent};return L.jsonToBase64(r)}catch(t){throw pt.toRegistrationError(t)}}abortRegistration(){this.abortController&&this.abortController.abort(V.RegistrationAbortedTimeout)}async registerCredential(t){const e=await navigator.credentials.create({publicKey:t,signal:this.abortController&&this.abortController.signal}).catch((t=>{throw pt.toRegistrationError(t)}));return gt.encodeRegistrationResult(e)}}class St{async modal(t){try{const e=await this.performApproval(t);return L.jsonToBase64(e)}catch(t){throw pt.toAuthenticationError(t)}}async performApproval(t){"approvalData"in t&&mt(t.approvalData);const e="crossDeviceTicketId"in t?await dt.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await dt.startAuthentication({username:t.username,approvalData:t.approvalData}),i=e.credential_request_options,a=gt.processCredentialRequestOptions(i),n=await navigator.credentials.get({publicKey:a}).catch((t=>{throw pt.toAuthenticationError(t)}));return{webauthnSessionId:e.webauthn_session_id,publicKeyCredential:gt.encodeAuthenticationResult(n),userAgent:navigator.userAgent}}}class At{constructor(){this._initialized=!1,this._authenticationHandler=new vt,this._registrationHandler=new Dt,this._approvalHandler=new St,this._crossDeviceHandler=new bt(this._authenticationHandler,this._registrationHandler,this._approvalHandler),this.authenticate={modal:async(t,e)=>(this.initCheck(),this._authenticationHandler.modal({username:t,options:e})),autofill:{activate:(t,e)=>(this.initCheck(),this._authenticationHandler.activateAutofill(t,e)),abort:()=>this._authenticationHandler.abortAutofill()}},this.approve={modal:async(t,e)=>(this.initCheck(),this._approvalHandler.modal({username:t,approvalData:e}))},this.register=async(t,e)=>(this.initCheck(),this._registrationHandler.register({username:t},e)),this.crossDevice={init:{registration:async t=>(this.initCheck(),this._crossDeviceHandler.init.registration(t)),authentication:async t=>(this.initCheck(),this._crossDeviceHandler.init.authentication(t)),approval:async t=>(this.initCheck(),this._crossDeviceHandler.init.approval(t))},authenticate:{modal:async t=>(this.initCheck(),this._crossDeviceHandler.authenticate.modal(t))},approve:{modal:async t=>(this.initCheck(),this._crossDeviceHandler.approve.modal(t))},register:async(t,e)=>(this.initCheck(),this._crossDeviceHandler.register(t,e)),attachDevice:async t=>(this.initCheck(),this._crossDeviceHandler.attachDevice(t))},this.isPlatformAuthenticatorSupported=async()=>{var t;try{return await(null===(t=At.StaticPublicKeyCredential)||void 0===t?void 0:t.isUserVerifyingPlatformAuthenticatorAvailable())}catch(t){return!1}},this.isAutofillSupported=async()=>{var t,e;return!(!(null===(t=At.StaticPublicKeyCredential)||void 0===t?void 0:t.isConditionalMediationAvailable)||!await(null===(e=At.StaticPublicKeyCredential)||void 0===e?void 0:e.isConditionalMediationAvailable()))}}async init(t,e){try{if(!t)throw new X("Invalid clientId",{clientId:t});if(e.webauthnApiPaths){const t=dt.getDefaultPaths();if(function(t,e){const i=new Set(t),a=new Set(e);return[...t.filter((t=>!a.has(t))),...e.filter((t=>!i.has(t)))]}(Object.keys(e.webauthnApiPaths),Object.keys(t)).length)throw new X("Invalid custom paths",{customApiPaths:e.webauthnApiPaths})}dt.init(t,e),this._initialized=!0}catch(t){throw lt(t)?t:new X("Failed to initialize SDK")}}getDefaultPaths(){return this.initCheck(),dt.getDefaultPaths()}getApiPaths(){return this.initCheck(),dt.getApiPaths()}initCheck(){if(!this._initialized)throw new X}}At.StaticPublicKeyCredential=window.PublicKeyCredential;const Ct=new W("webauthn"),_t=new At;Ct.events.on(Ct.events.MODULE_INITIALIZED,(()=>{var t;const e=Ct.moduleMetadata.getInitConfig();if(!(null===(t=null==e?void 0:e.webauthn)||void 0===t?void 0:t.serverPath))return;const{clientId:i,webauthn:a}=e;_t.init(i,u({},a))}));const Kt={modal:async(t,e)=>(_t.initCheck(),_t.authenticate.modal(t,e)),autofill:{activate:(t,e)=>{_t.initCheck(),_t.authenticate.autofill.activate(t,e)},abort:()=>{_t.initCheck(),_t.authenticate.autofill.abort()}}},kt={modal:async(t,e)=>(_t.initCheck(),_t.approve.modal(t,e))};async function Rt(t,e){return _t.initCheck(),_t.register(t,e)}const{crossDevice:Pt}=_t,{isPlatformAuthenticatorSupported:Tt}=_t,{isAutofillSupported:It}=_t,{getDefaultPaths:Ot}=_t;window.localWebAuthnSDK=_t;const xt={initialize:r,...Object.freeze({__proto__:null,get WebauthnCrossDeviceStatus(){return exports.WebauthnCrossDeviceStatus},approve:kt,authenticate:Kt,crossDevice:Pt,getDefaultPaths:Ot,isAutofillSupported:It,isPlatformAuthenticatorSupported:Tt,register:Rt})};exports.PACKAGE_VERSION="1.18.2",exports.approve=kt,exports.authenticate=Kt,exports.crossDevice=Pt,exports.getDefaultPaths=Ot,exports.initialize=r,exports.isAutofillSupported=It,exports.isPlatformAuthenticatorSupported=Tt,exports.register=Rt,exports.webauthn=xt;
1
+ "undefined"==typeof globalThis&&("undefined"!=typeof window?(window.globalThis=window,window.global=window):"undefined"!=typeof self&&(self.globalThis=self,self.global=self));var t=require("./common.cjs"),e=require("./common.cjs");function i(t,e){var i=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);e&&(a=a.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),i.push.apply(i,a)}return i}function a(t){for(var e=1;e<arguments.length;e++){var a=null!=arguments[e]?arguments[e]:{};e%2?i(Object(a),!0).forEach((function(e){n(t,e,a[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(a,e))}))}return t}function r(t){var e=function(t,e){if("object"!=typeof t||!t)return t;var i=t[Symbol.toPrimitive];if(void 0!==i){var a=i.call(t,e||"default");if("object"!=typeof a)return a;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(t,"string");return"symbol"==typeof e?e:String(e)}function n(t,e,i){return(e=r(e))in t?Object.defineProperty(t,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):t[e]=i,t}class s{static arrayBufferToBase64(t){return btoa(String.fromCharCode(...new Uint8Array(t)))}static base64ToArrayBuffer(t){return Uint8Array.from(atob(t),(t=>t.charCodeAt(0)))}static stringToBase64(t){return btoa(t)}static jsonToBase64(t){const e=JSON.stringify(t);return btoa(e)}static base64ToJson(t){const e=atob(t);return JSON.parse(e)}}const o={log:console.log,error:console.error};var c,l;!function(t){t.NotInitialized="not_initialized",t.AuthenticationFailed="authentication_failed",t.AuthenticationAbortedTimeout="authentication_aborted_timeout",t.AuthenticationCanceled="webauthn_authentication_canceled",t.RegistrationFailed="registration_failed",t.AlreadyRegistered="username_already_registered",t.RegistrationAbortedTimeout="registration_aborted_timeout",t.RegistrationCanceled="webauthn_registration_canceled",t.AutofillAuthenticationAborted="autofill_authentication_aborted",t.AuthenticationProcessAlreadyActive="authentication_process_already_active",t.InvalidApprovalData="invalid_approval_data",t.FailedToInitCrossDeviceSession="cross_device_init_failed",t.FailedToGetCrossDeviceStatus="cross_device_status_failed",t.Unknown="unknown"}(c||(c={}));class u extends Error{constructor(t,e){super(t),this.errorCode=c.NotInitialized,this.data=e}}class d extends u{constructor(t,e){super(null!=t?t:"WebAuthnSdk is not initialized",e),this.errorCode=c.NotInitialized}}class h extends u{constructor(t,e){super(null!=t?t:"Authentication failed with an error",e),this.errorCode=c.AuthenticationFailed}}class p extends u{constructor(t,e){super(null!=t?t:"Authentication was canceled by the user or got timeout",e),this.errorCode=c.AuthenticationCanceled}}class v extends u{constructor(t,e){super(null!=t?t:"Registration failed with an error",e),this.errorCode=c.RegistrationFailed}}class g extends u{constructor(t,e){super(null!=t?t:"Registration was canceled by the user or got timeout",e),this.errorCode=c.RegistrationCanceled}}class f extends u{constructor(t){super(null!=t?t:"Autofill flow was aborted"),this.errorCode=c.AutofillAuthenticationAborted}}class w extends u{constructor(t){super(null!=t?t:"Operation was aborted by timeout"),this.errorCode=c.AutofillAuthenticationAborted}}class m extends u{constructor(t){super(null!=t?t:"Passkey with this username is already registered with the relying party."),this.errorCode=c.AlreadyRegistered}}class y extends u{constructor(t,e){super(null!=t?t:"Authentication process is already active",e),this.errorCode=c.AuthenticationProcessAlreadyActive}}class b extends u{constructor(t,e){super(null!=t?t:"Invalid approval data",e),this.errorCode=c.InvalidApprovalData}}class C extends u{constructor(t,e){super(null!=t?t:"Failed to init cross device authentication",e),this.errorCode=c.FailedToInitCrossDeviceSession}}class A extends u{constructor(t,e){super(null!=t?t:"Failed to get cross device status",e),this.errorCode=c.FailedToGetCrossDeviceStatus}}function D(t){return t.errorCode&&Object.values(c).includes(t.errorCode)}!function(t){t[t.persistent=0]="persistent",t[t.session=1]="session"}(l||(l={}));class _{static get(t){return _.getStorageMedium(_.allowedKeys[t]).getItem(_.getStorageKey(t))||void 0}static set(t,e){return _.getStorageMedium(_.allowedKeys[t]).setItem(_.getStorageKey(t),e)}static remove(t){_.getStorageMedium(_.allowedKeys[t]).removeItem(_.getStorageKey(t))}static clear(t){for(const[e,i]of Object.entries(_.allowedKeys)){const a=e;t&&this.configurationKeys.includes(a)||_.getStorageMedium(i).removeItem(_.getStorageKey(a))}}static getStorageKey(t){return`WebAuthnSdk:${t}`}static getStorageMedium(t){return t===l.session?sessionStorage:localStorage}}_.allowedKeys={clientId:l.session},_.configurationKeys=["clientId"];class S{static isNewApiDomain(t){return t&&(this.newApiDomains.includes(t)||t.startsWith("api.")&&t.endsWith(".transmitsecurity.io"))}static dnsPrefetch(t){const e=document.createElement("link");e.rel="dns-prefetch",e.href=t,document.head.appendChild(e)}static preconnect(t,e){const i=document.createElement("link");i.rel="preconnect",i.href=t,e&&(i.crossOrigin="anonymous"),document.head.appendChild(i)}static warmupConnection(t){this.dnsPrefetch(t),this.preconnect(t,!1),this.preconnect(t,!0)}static init(t,e){var i,a;try{this._serverPath=new URL(e.serverPath),this.isNewApiDomain(null===(i=this._serverPath)||void 0===i?void 0:i.hostname)&&this.warmupConnection(this._serverPath.origin),this._apiPaths=null!==(a=e.webauthnApiPaths)&&void 0!==a?a:this.getDefaultPaths(),this._clientId=t,_.set("clientId",t)}catch(t){throw new d("Invalid options.serverPath",{error:t})}}static getDefaultPaths(){var t;const e=this.isNewApiDomain(null===(t=this._serverPath)||void 0===t?void 0:t.hostname)?"/cis":"";return{startAuthentication:`${e}/v1/auth/webauthn/authenticate/start`,startRegistration:`${e}/v1/auth/webauthn/register/start`,initCrossDeviceAuthentication:`${e}/v1/auth/webauthn/cross-device/authenticate/init`,startCrossDeviceAuthentication:`${e}/v1/auth/webauthn/cross-device/authenticate/start`,startCrossDeviceRegistration:`${e}/v1/auth/webauthn/cross-device/register/start`,getCrossDeviceTicketStatus:`${e}/v1/auth/webauthn/cross-device/status`,attachDeviceToCrossDeviceSession:`${e}/v1/auth/webauthn/cross-device/attach-device`}}static getApiPaths(){return this._apiPaths}static async sendRequest(t,e,i){o.log(`[WebAuthn SDK] Calling ${e.method} ${t}...`);const a=new URL(this._serverPath);return a.pathname=t,i&&(a.search=i),fetch(a.toString(),e)}static async startRegistration(t){const e=await this.sendRequest(this._apiPaths.startRegistration,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a(a({client_id:this.getValidatedClientId(),username:t.username,display_name:t.displayName},t.timeout&&{timeout:t.timeout}),t.limitSingleCredentialToDevice&&{limit_single_credential_to_device:t.limitSingleCredentialToDevice}))});if(!(null==e?void 0:e.ok))throw new h("Failed to start registration",null==e?void 0:e.body);return await e.json()}static async startAuthentication(t){const e=await this.sendRequest(this._apiPaths.startAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a(a(a(a(a({client_id:this.getValidatedClientId()},t.username&&{username:t.username}),t.identifier&&{identifier:t.identifier}),t.identifierType&&{identifier_type:t.identifierType}),t.approvalData&&{approval_data:t.approvalData}),t.timeout&&{timeout:t.timeout}))});if(!(null==e?void 0:e.ok))throw new h("Failed to start authentication",null==e?void 0:e.body);return await e.json()}static async initCrossDeviceAuthentication(t){const e=await this.sendRequest(this._apiPaths.initCrossDeviceAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a(a({client_id:this.getValidatedClientId()},t.username&&{username:t.username}),t.approvalData&&{approval_data:t.approvalData}))});if(!(null==e?void 0:e.ok))throw new C(void 0,null==e?void 0:e.body);return await e.json()}static async getCrossDeviceTicketStatus(t){const e=await this.sendRequest(this._apiPaths.getCrossDeviceTicketStatus,{method:"GET"},`cross_device_ticket_id=${t.ticketId}`);if(!(null==e?void 0:e.ok))throw new A(void 0,null==e?void 0:e.body);return await e.json()}static async startCrossDeviceAuthentication(t){const e=await this.sendRequest(this._apiPaths.startCrossDeviceAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new h("Failed to start cross device authentication",null==e?void 0:e.body);return await e.json()}static async startCrossDeviceRegistration(t){const e=await this.sendRequest(this._apiPaths.startCrossDeviceRegistration,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new v("Failed to start cross device registration",null==e?void 0:e.body);return await e.json()}static async attachDeviceToCrossDeviceSession(t){const e=await this.sendRequest(this._apiPaths.attachDeviceToCrossDeviceSession,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new v("Failed to attach device to cross device session",null==e?void 0:e.body);return await e.json()}static getValidatedClientId(){var t;const e=null!==(t=this._clientId)&&void 0!==t?t:_.get("clientId");if(!e)throw new d("Missing clientId");return e}}var T,k,I,P;S.newApiDomains=["api.idsec-dev.com","api.idsec-stg.com"],function(t){t.InputAutofill="input-autofill",t.Modal="modal"}(T||(T={})),exports.WebauthnCrossDeviceStatus=void 0,(k=exports.WebauthnCrossDeviceStatus||(exports.WebauthnCrossDeviceStatus={})).Pending="pending",k.Scanned="scanned",k.Success="success",k.Error="error",k.Timeout="timeout",k.Aborted="aborted",function(t){t.toAuthenticationError=t=>D(t)?t:"NotAllowedError"===t.name?new p:"OperationError"===t.name?new y(t.message):"SecurityError"===t.name?new h(t.message):t===c.AuthenticationAbortedTimeout?new w:"AbortError"===t.name||t===c.AutofillAuthenticationAborted?new f:new h("Something went wrong during authentication",{error:t}),t.toRegistrationError=t=>D(t)?t:"NotAllowedError"===t.name?new g:"SecurityError"===t.name?new v(t.message):"InvalidStateError"===t.name?new m:t===c.RegistrationAbortedTimeout?new w:new v("Something went wrong during registration",{error:t})}(I||(I={})),function(t){t.processCredentialRequestOptions=t=>a(a({},t),{},{challenge:s.base64ToArrayBuffer(t.challenge),allowCredentials:t.allowCredentials.map((t=>a(a({},t),{},{id:s.base64ToArrayBuffer(t.id)})))}),t.processCredentialCreationOptions=(t,e)=>{var i;const r=JSON.parse(JSON.stringify(t));return r.challenge=s.base64ToArrayBuffer(t.challenge),r.user.id=s.base64ToArrayBuffer(t.user.id),(null==e?void 0:e.limitSingleCredentialToDevice)&&(r.excludeCredentials=null===(i=t.excludeCredentials)||void 0===i?void 0:i.map((t=>a(a({},t),{},{id:s.base64ToArrayBuffer(t.id)})))),(null==e?void 0:e.registerAsDiscoverable)?(r.authenticatorSelection.residentKey="preferred",r.authenticatorSelection.requireResidentKey=!0):(r.authenticatorSelection.residentKey="discouraged",r.authenticatorSelection.requireResidentKey=!1),r.authenticatorSelection.authenticatorAttachment=(null==e?void 0:e.allowCrossPlatformAuthenticators)?void 0:"platform",r},t.encodeAuthenticationResult=t=>{const{authenticatorAttachment:e}=t,i=t.response;return{id:t.id,rawId:s.arrayBufferToBase64(t.rawId),response:{authenticatorData:s.arrayBufferToBase64(i.authenticatorData),clientDataJSON:s.arrayBufferToBase64(i.clientDataJSON),signature:s.arrayBufferToBase64(i.signature),userHandle:s.arrayBufferToBase64(i.userHandle)},authenticatorAttachment:e,type:t.type}},t.encodeRegistrationResult=t=>{const{authenticatorAttachment:e}=t,i=t.response;return{id:t.id,rawId:s.arrayBufferToBase64(t.rawId),response:{attestationObject:s.arrayBufferToBase64(i.attestationObject),clientDataJSON:s.arrayBufferToBase64(i.clientDataJSON)},authenticatorAttachment:e,type:t.type}}}(P||(P={}));class O{async modal(t){try{const e=await this.performAuthentication(a(a({},t),{},{mediationType:T.Modal}));return s.jsonToBase64(e)}catch(t){throw I.toAuthenticationError(t)}}activateAutofill(t){const{handlers:e,username:i}=t,{onSuccess:a,onError:r,onReady:n}=e;this.performAuthentication({username:i,mediationType:T.InputAutofill,onReady:n}).then((t=>{a(s.jsonToBase64(t))})).catch((t=>{const e=I.toAuthenticationError(t);if(!r)throw e;r(e)}))}abortAutofill(){this.abortController&&this.abortController.abort(c.AutofillAuthenticationAborted)}abortAuthentication(){this.abortController&&this.abortController.abort(c.AuthenticationAbortedTimeout)}async performAuthentication(t){var e,i;const a="crossDeviceTicketId"in t?await S.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await S.startAuthentication({username:t.username,identifier:t.identifier,identifierType:t.identifierType,timeout:null===(e=t.options)||void 0===e?void 0:e.timeout}),r=a.credential_request_options,n=P.processCredentialRequestOptions(r),s=this.getMediatedCredentialRequest(n,t.mediationType);t.mediationType===T.InputAutofill&&(null===(i=t.onReady)||void 0===i||i.call(t));const o=await navigator.credentials.get(s).catch((t=>{throw I.toAuthenticationError(t)}));return{webauthnSessionId:a.webauthn_session_id,publicKeyCredential:P.encodeAuthenticationResult(o),userAgent:navigator.userAgent}}getMediatedCredentialRequest(t,e){const i={publicKey:t};return this.abortController=new AbortController,i.signal=this.abortController&&this.abortController.signal,e===T.InputAutofill?i.mediation="conditional":t.timeout&&setTimeout((()=>{this.abortAuthentication()}),t.timeout),i}}class R{constructor(t,e){this.handler=t,this.intervalInMs=e}begin(){var t;this.intervalId=window.setInterval((t=this.handler,async function(){t.isRunning||(t.isRunning=!0,await t(...arguments),t.isRunning=!1)}),this.intervalInMs)}stop(){clearInterval(this.intervalId)}}const j=/^[A-Za-z0-9\-_.: ]*$/;function x(t){if(t&&(!function(t){return Object.keys(t).length<=10}(t)||!function(t){const e=t=>"string"==typeof t,i=t=>j.test(t);return Object.keys(t).every((a=>e(a)&&e(t[a])&&i(a)&&i(t[a])))}(t)))throw o.error("Failed validating approval data"),new b("Provided approval data should have 10 properties max. Also, it should contain only \n alphanumeric characters, numbers, and the special characters: '-', '_', '.'")}class K{constructor(t,e,i){this.authenticationHandler=t,this.registrationHandler=e,this.approvalHandler=i,this.init={registration:async t=>(this.ticketStatus=exports.WebauthnCrossDeviceStatus.Pending,this.pollCrossDeviceSession(t.crossDeviceTicketId,t.handlers)),authentication:async t=>{const{username:e}=t,i=(await S.initCrossDeviceAuthentication(a({},e&&{username:e}))).cross_device_ticket_id;return this.ticketStatus=exports.WebauthnCrossDeviceStatus.Pending,this.pollCrossDeviceSession(i,t.handlers)},approval:async t=>{const{username:e,approvalData:i}=t;x(i);const a=(await S.initCrossDeviceAuthentication({username:e,approvalData:i})).cross_device_ticket_id;return this.ticketStatus=exports.WebauthnCrossDeviceStatus.Pending,this.pollCrossDeviceSession(a,t.handlers)}},this.authenticate={modal:async t=>this.authenticationHandler.modal({crossDeviceTicketId:t})},this.approve={modal:async t=>this.approvalHandler.modal({crossDeviceTicketId:t})}}async register(t){return this.registrationHandler.register(t)}async attachDevice(t){const e=await S.attachDeviceToCrossDeviceSession({ticketId:t});return a({status:e.status,startedAt:e.started_at},e.approval_data&&{approvalData:e.approval_data})}async pollCrossDeviceSession(t,e){return this.poller=new R((async()=>{var i,a;const r=await S.getCrossDeviceTicketStatus({ticketId:t}),n=r.status;if(n!==this.ticketStatus)switch(this.ticketStatus=n,n){case exports.WebauthnCrossDeviceStatus.Scanned:await e.onDeviceAttach();break;case exports.WebauthnCrossDeviceStatus.Error:case exports.WebauthnCrossDeviceStatus.Timeout:case exports.WebauthnCrossDeviceStatus.Aborted:await e.onFailure(r),null===(i=this.poller)||void 0===i||i.stop();break;case exports.WebauthnCrossDeviceStatus.Success:if("onCredentialRegister"in e)await e.onCredentialRegister();else{if(!r.session_id)throw new A("Cross device session is complete without returning session_id",r);await e.onCredentialAuthenticate(r.session_id)}null===(a=this.poller)||void 0===a||a.stop()}}),1e3),this.poller.begin(),setTimeout((()=>{var t;null===(t=this.poller)||void 0===t||t.stop(),e.onFailure({status:exports.WebauthnCrossDeviceStatus.Timeout})}),3e5),{crossDeviceTicketId:t,stop:()=>{var t;null===(t=this.poller)||void 0===t||t.stop()}}}}class B{async register(t){var e,i,r;this.abortController=new AbortController;const n=a({allowCrossPlatformAuthenticators:!("crossDeviceTicketId"in t),registerAsDiscoverable:!0},t.options);try{const a="crossDeviceTicketId"in t?await S.startCrossDeviceRegistration({ticketId:t.crossDeviceTicketId}):await S.startRegistration({username:t.username,displayName:(null===(e=t.options)||void 0===e?void 0:e.displayName)||t.username,timeout:null===(i=t.options)||void 0===i?void 0:i.timeout,limitSingleCredentialToDevice:null===(r=t.options)||void 0===r?void 0:r.limitSingleCredentialToDevice}),o=P.processCredentialCreationOptions(a.credential_creation_options,n);setTimeout((()=>{this.abortRegistration()}),o.timeout);const c=await this.registerCredential(o),l={webauthnSessionId:a.webauthn_session_id,publicKeyCredential:c,userAgent:navigator.userAgent};return s.jsonToBase64(l)}catch(t){throw I.toRegistrationError(t)}}abortRegistration(){this.abortController&&this.abortController.abort(c.RegistrationAbortedTimeout)}async registerCredential(t){const e=await navigator.credentials.create({publicKey:t,signal:this.abortController&&this.abortController.signal}).catch((t=>{throw I.toRegistrationError(t)}));return P.encodeRegistrationResult(e)}}class E{async modal(t){try{const e=await this.performApproval(t);return s.jsonToBase64(e)}catch(t){throw I.toAuthenticationError(t)}}async performApproval(t){"approvalData"in t&&x(t.approvalData);const e="crossDeviceTicketId"in t?await S.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await S.startAuthentication({username:t.username,approvalData:t.approvalData}),i=e.credential_request_options,a=P.processCredentialRequestOptions(i),r=await navigator.credentials.get({publicKey:a}).catch((t=>{throw I.toAuthenticationError(t)}));return{webauthnSessionId:e.webauthn_session_id,publicKeyCredential:P.encodeAuthenticationResult(r),userAgent:navigator.userAgent}}}class N{constructor(){this._initialized=!1,this._authenticationHandler=new O,this._registrationHandler=new B,this._approvalHandler=new E,this._crossDeviceHandler=new K(this._authenticationHandler,this._registrationHandler,this._approvalHandler),this.authenticate={modal:async t=>(this.initCheck(),this._authenticationHandler.modal(t)),autofill:{activate:t=>(this.initCheck(),this._authenticationHandler.activateAutofill(t)),abort:()=>this._authenticationHandler.abortAutofill()}},this.approve={modal:async t=>(this.initCheck(),this._approvalHandler.modal(t))},this.register=async t=>(this.initCheck(),this._registrationHandler.register(t)),this.crossDevice={init:{registration:async t=>(this.initCheck(),this._crossDeviceHandler.init.registration(t)),authentication:async t=>(this.initCheck(),this._crossDeviceHandler.init.authentication(t)),approval:async t=>(this.initCheck(),this._crossDeviceHandler.init.approval(t))},authenticate:{modal:async t=>(this.initCheck(),this._crossDeviceHandler.authenticate.modal(t))},approve:{modal:async t=>(this.initCheck(),this._crossDeviceHandler.approve.modal(t))},register:async t=>(this.initCheck(),this._crossDeviceHandler.register(t)),attachDevice:async t=>(this.initCheck(),this._crossDeviceHandler.attachDevice(t))},this.isPlatformAuthenticatorSupported=async()=>{var t;try{return await(null===(t=N.StaticPublicKeyCredential)||void 0===t?void 0:t.isUserVerifyingPlatformAuthenticatorAvailable())}catch(t){return!1}},this.isAutofillSupported=async()=>{var t,e;return!(!(null===(t=N.StaticPublicKeyCredential)||void 0===t?void 0:t.isConditionalMediationAvailable)||!await(null===(e=N.StaticPublicKeyCredential)||void 0===e?void 0:e.isConditionalMediationAvailable()))}}async init(t){const{clientId:e,options:i}=t;try{if(!e)throw new d("Invalid clientId",{clientId:e});if(i.webauthnApiPaths){const t=S.getDefaultPaths();if(function(t,e){const i=new Set(t),a=new Set(e);return[...t.filter((t=>!a.has(t))),...e.filter((t=>!i.has(t)))]}(Object.keys(i.webauthnApiPaths),Object.keys(t)).length)throw new d("Invalid custom paths",{customApiPaths:i.webauthnApiPaths})}S.init(e,i),this._initialized=!0}catch(t){throw D(t)?t:new d("Failed to initialize SDK")}}getDefaultPaths(){return this.initCheck(),S.getDefaultPaths()}getApiPaths(){return this.initCheck(),S.getApiPaths()}initCheck(){if(!this._initialized)throw new d}}N.StaticPublicKeyCredential=window.PublicKeyCredential;const H=new t("webauthn"),W=new N;H.events.on(H.events.MODULE_INITIALIZED,(()=>{var t;const e=H.moduleMetadata.getInitConfig();if(!(null===(t=null==e?void 0:e.webauthn)||void 0===t?void 0:t.serverPath))return;const{clientId:i,webauthn:r}=e;W.init({clientId:i,options:a({},r)})}));const q={modal:async t=>(W.initCheck(),W.authenticate.modal(t)),autofill:{activate:t=>{W.initCheck(),W.authenticate.autofill.activate(t)},abort:()=>{W.initCheck(),W.authenticate.autofill.abort()}}},F={modal:async t=>(W.initCheck(),W.approve.modal(t))};async function M(t){return W.initCheck(),W.register(t)}const{crossDevice:z}=W,{isPlatformAuthenticatorSupported:J}=W,{isAutofillSupported:$}=W,{getDefaultPaths:U}=W;window.localWebAuthnSDK=W;var V=Object.freeze({__proto__:null,get WebauthnCrossDeviceStatus(){return exports.WebauthnCrossDeviceStatus},approve:F,authenticate:q,crossDevice:z,getDefaultPaths:U,isAutofillSupported:$,isPlatformAuthenticatorSupported:J,register:M});const G={initialize:e.initialize,...V};Object.defineProperty(exports,"initialize",{enumerable:!0,get:function(){return e.initialize}}),exports.PACKAGE_VERSION="2.0.0",exports.approve=F,exports.authenticate=q,exports.crossDevice=z,exports.getDefaultPaths=U,exports.isAutofillSupported=$,exports.isPlatformAuthenticatorSupported=J,exports.register=M,exports.webauthn=G;
@@ -236,7 +236,10 @@ interface WebauthnCrossDeviceFlows {
236
236
  * @throws {@link ErrorCode.RegistrationFailed}
237
237
  * @throws {@link ErrorCode.RegistrationCanceled}
238
238
  */
239
- register: (crossDeviceTicketId: string, options?: WebauthnCrossDeviceRegistrationOptions) => Promise<string>;
239
+ register: (params: {
240
+ crossDeviceTicketId: string;
241
+ options?: WebauthnCrossDeviceRegistrationOptions;
242
+ }) => Promise<string>;
240
243
  /**
241
244
  * Indicates when a session is accepted on another device in cross-device flows.
242
245
  *
@@ -348,14 +351,17 @@ interface AutofillHandlers {
348
351
  * Invokes a WebAuthn authentication, including prompting the user to select from a list of registered credentials using autofill, and then prompting the user for biometrics. In order to prompt this credentials list, the autocomplete="username webauthn" attribute **must** be defined on the username input box of the authentication page.<br/>
349
352
  * If authentication is completed successfully, the `onSuccess` callback will be triggered with the credential result, which is an object encoded as a base64 string. This encoded result should then be passed to the [backend authentication endpoint](/openapi/user/backend-webauthn/#operation/authenticateWebauthnCredential) to retrieve user tokens.<br/>
350
353
  * If it fails, the `onError` callback will be triggered with an SdkError.
354
+ * @param params.handlers - Handlers that will be invoked once the authentication is completed (success or failure)
355
+ * @param params.username - Name of user account, as used in the WebAuthn registration. If not provided, the authentication will start without the context of a user and it will be inferred by the chosen passkey
351
356
  * @throws {@link ErrorCode.NotInitialized}
352
357
  * @throws {@link ErrorCode.AuthenticationFailed}
353
358
  * @throws {@link ErrorCode.AuthenticationCanceled}
354
359
  * @throws {@link ErrorCode.AutofillAuthenticationAborted}
355
- * @param handlers Handlers that will be invoked once the authentication is completed (success or failure)
356
- * @param username Name of user account, as used in the WebAuthn registration. If not provided, the authentication will start without the context of a user and it will be inferred by the chosen passkey
357
360
  */
358
- activate(handlers: AuthenticationAutofillActivateHandlers, username?: string): void;
361
+ activate(params: {
362
+ handlers: AuthenticationAutofillActivateHandlers;
363
+ username?: string;
364
+ }): void;
359
365
  /**
360
366
  * Aborts a WebAuthn authentication. This method should be called after the passkey autofill is dismissed in order to be able to query existing passkeys once again. This will end the browser's `navigator.credentials.get()` operation.
361
367
  */
@@ -371,20 +377,29 @@ interface WebauthnAuthenticationOptions {
371
377
 
372
378
  interface WebauthnAuthenticationFlows {
373
379
  /**
374
- * Invokes a WebAuthn authentication, including prompting the user to select from a list of registered credentials, and then prompting the user for biometrics. The credentials list is displayed using the native browser modal.<br/>
375
- * If username isn't provided, it will promote a modal with a list of all discoverable credentials on the device. If username is provided, this call must be invoked for a registered username. If the target username is not registered or in case of any other failure, an SdkError will be thrown.<br/>
376
- * If authentication is completed successfully, this call will return a promise that resolves to the credential result, which is an object encoded as a base64 string. This encoded result should then be passed to the [backend authentication endpoint](/openapi/user/backend-webauthn/#operation/authenticateWebauthnCredential) to retrieve user tokens.<br/>
377
-
378
- * @param username Name of user account, as used in the WebAuthn registration. If not provided, the authentication will start without the context of a user and it will be inferred by the chosen passkey
379
- * @param options {@link WebauthnAuthenticationOptions} Options for the authentication process
380
- * @throws {@link ErrorCode.NotInitialized}
381
- * @throws {@link ErrorCode.AuthenticationFailed}
382
- * @throws {@link ErrorCode.AuthenticationCanceled}
383
- * @throws {@link ErrorCode.InvalidApprovalData}
384
- * @throws {@link ErrorCode.AuthenticationProcessAlreadyActive}
385
- * @returns Base64-encoded object, which contains the credential result. This encoded result will be used to fetch user tokens via the [backend authentication endpoint](/openapi/user/backend-webauthn/#operation/authenticateWebauthnCredential).
386
- */
387
- modal(username?: string, options?: WebauthnAuthenticationOptions): Promise<string>;
380
+ * Invokes a WebAuthn authentication, including prompting the user to select from a list of registered credentials, and then prompting the user for biometrics. The credentials list is displayed using the native browser modal.<br/>
381
+ * If username isn't provided, it will promote a modal with a list of all discoverable credentials on the device. If username is provided, this call must be invoked for a registered username. If the target username is not registered or in case of any other failure, an SdkError will be thrown.<br/>
382
+ * If authentication is completed successfully, this call will return a promise that resolves to the credential result, which is an object encoded as a base64 string. This encoded result should then be passed to the [backend authentication endpoint](/openapi/user/backend-webauthn/#operation/authenticateWebauthnCredential) to retrieve user tokens.<br/>
383
+ *
384
+ * @param params.username - Name of user account, as used in the WebAuthn registration. If not provided, the authentication will start without the context of a user and it will be inferred by the chosen passkey
385
+ * @param params.options - Options for the authentication process
386
+ * @param params.identifier - Identifier value (email, phone number, user ID, or custom identifier). Mutually exclusive with username.
387
+ * @param params.identifierType - Type of identifier (email, phone_number, user_id, username, or custom identifier type). Required when using identifier.
388
+ * @throws {@link ErrorCode.NotInitialized}
389
+ * @throws {@link ErrorCode.AuthenticationFailed}
390
+ * @throws {@link ErrorCode.AuthenticationCanceled}
391
+ * @throws {@link ErrorCode.InvalidApprovalData}
392
+ * @throws {@link ErrorCode.AuthenticationProcessAlreadyActive}
393
+ * @returns Base64-encoded object, which contains the credential result. This encoded result will be used to fetch user tokens via the [backend authentication endpoint](/openapi/user/backend-webauthn/#operation/authenticateWebauthnCredential).
394
+ */
395
+ modal(params: {
396
+ username?: string;
397
+ options?: WebauthnAuthenticationOptions;
398
+ } | {
399
+ identifier?: string;
400
+ identifierType?: string;
401
+ options?: WebauthnAuthenticationOptions;
402
+ }): Promise<string>;
388
403
  /**
389
404
  * Property used to implement credential selection via autofill UI.
390
405
  */
@@ -396,8 +411,8 @@ interface WebauthnApprovalFlows {
396
411
  * Invokes a WebAuthn approval, including prompting the user to select from a list of registered credentials, and then prompting the user for biometrics. The credentials list is displayed using the native browser modal.<br/>
397
412
  * This call must be invoked for a registered username. If the target username is not registered or in case of any other failure, an SdkError will be thrown.<br/>
398
413
  * If approval is completed successfully, this call will return a promise that resolves to the credential result, which is an object encoded as a base64 string. This encoded result should then be passed to the [backend authentication endpoint](/openapi/user/backend-webauthn/#operation/authenticateWebauthnCredential) to retrieve user tokens.<br/>
399
- * @param username Name of user account, as used in the WebAuthn registration.
400
- * @param approvalData Data that represents the approval to be signed with a passkey
414
+ * @param params.username Name of user account, as used in the WebAuthn registration.
415
+ * @param params.approvalData Data that represents the approval to be signed with a passkey
401
416
  * @throws {@link ErrorCode.NotInitialized}
402
417
  * @throws {@link ErrorCode.InvalidApprovalData}
403
418
  * @throws {@link ErrorCode.AuthenticationFailed}
@@ -405,7 +420,10 @@ interface WebauthnApprovalFlows {
405
420
  * @throws {@link ErrorCode.AuthenticationProcessAlreadyActive}
406
421
  * @returns Base64-encoded object, which contains the credential result. This encoded result will be used to fetch user tokens via the [backend authentication endpoint](/openapi/user/backend-webauthn/#operation/authenticateWebauthnCredential).
407
422
  */
408
- modal(username: string | undefined, approvalData: Record<string, string>): Promise<string>;
423
+ modal(params: {
424
+ username: string | undefined;
425
+ approvalData: Record<string, string>;
426
+ }): Promise<string>;
409
427
  }
410
428
 
411
429
  declare module '@transmit-security/web-sdk-common/dist/module-metadata/module-metadata' {
@@ -424,13 +442,16 @@ declare const approve: WebauthnApprovalFlows;
424
442
  *
425
443
  * If registration fails, an SdkError will be thrown.
426
444
  *
427
- * @param username WebAuthn username to register
428
- * @param options Additional configuration for registration flow
445
+ * @param params.username - WebAuthn username to register
446
+ * @param params.options - Additional configuration for registration flow
429
447
  * @throws {@link ErrorCode.NotInitialized}
430
448
  * @throws {@link ErrorCode.RegistrationFailed}
431
449
  * @throws {@link ErrorCode.RegistrationCanceled}
432
450
  */
433
- declare function register(username: string, options?: WebauthnRegistrationOptions): Promise<string>;
451
+ declare function register(params: {
452
+ username: string;
453
+ options?: WebauthnRegistrationOptions;
454
+ }): Promise<string>;
434
455
  /**
435
456
  * Returns webauthn cross device flows
436
457
  * @type WebauthnCrossDeviceFlows
package/dist/webauthn.js CHANGED
@@ -1 +1 @@
1
- "undefined"==typeof globalThis&&("undefined"!=typeof window?(window.globalThis=window,window.global=window):"undefined"!=typeof self&&(self.globalThis=self,self.global=self));const t=Symbol("MODULE_INITIALIZED"),e=new Map;function i(t,i){var a,n;null===(a=e.get(t))||void 0===a||a.forEach((n=t=>t(i),function(){try{return n(...arguments)}catch(t){console.log(t)}}))}let a=null;function n(t){a=t}var r=Object.freeze({__proto__:null,getInitConfig:function(){return a},get initConfig(){return a},setInitConfig:n});function s(e){n(e),i(t,void 0)}var o=Object.freeze({__proto__:null,initialize:s});function c(t,e,i){return(e=function(t){var e=function(t,e){if("object"!=typeof t||!t)return t;var i=t[Symbol.toPrimitive];if(void 0!==i){var a=i.call(t,e||"default");if("object"!=typeof a)return a;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(t,"string");return"symbol"==typeof e?e:e+""}(e))in t?Object.defineProperty(t,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):t[e]=i,t}function l(t,e){var i=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);e&&(a=a.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),i.push.apply(i,a)}return i}function d(t){for(var e=1;e<arguments.length;e++){var i=null!=arguments[e]?arguments[e]:{};e%2?l(Object(i),!0).forEach((function(e){c(t,e,i[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(i)):l(Object(i)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(i,e))}))}return t}function u(t,e){return Object.entries(e).reduce(((e,i)=>{let[a,n]=i;return d(d({},e),{},{[a]:h.isPrototypeOf(n)?new n(t.slug):"function"==typeof n?n.bind(t):"object"==typeof n&&!Array.isArray(n)&&n?u(t,n):n})}),{})}class h{constructor(t){this.slug=t}static create(t){return class extends h{constructor(e){super(e),Object.assign(this,u(this,t(this)))}}}}var y=Object.freeze({__proto__:null,Agent:h}),p=Object.freeze({__proto__:null,MODULE_INITIALIZED:t,emit:i,off:function(t,i){const a=e.get(t);if(!a)return;const n=a.indexOf(i);-1!==n&&a.splice(n,1)},on:function(t,i){var a;e.has(t)?null===(a=e.get(t))||void 0===a||a.push(i):e.set(t,[i])}});function g(t,e){const i=!t||"object"!=typeof t||Array.isArray(t)?{}:t;return[e.reduce(((t,e)=>{if(e in t){const i=t[e];if(null!==i&&"object"==typeof i&&!Array.isArray(i))return i}const i={};return t[e]=i,i}),i),i]}const v="tsec",f="general";function w(t){return t?f:a.clientId}function m(t){return function(t){if(!t)return{};try{return JSON.parse(t)}catch(t){return{}}}((t?sessionStorage:localStorage).getItem(v))}function b(t,e){const i=t?sessionStorage:localStorage,a=e(m(t));i.setItem(v,JSON.stringify(a))}var D=Object.freeze({__proto__:null,COMMON_STORAGE_KEY:v,GENERAL_ID_KEY:f,getValue:function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const i=w(!!e.isGeneral),a=m(!!e.sessionOnly),[n]=g(a,[this.slug.toString(),i]);return n[t]},hasValue:function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const i=w(!!e.isGeneral);return function(t,e){let i=t;return e.every((t=>!(!i||"object"!=typeof i||Array.isArray(i)||!(t in i)||(i=i[t],0))),t)}(m(!!e.sessionOnly),[this.slug.toString(),i,t])},removeValue:function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const i=w(!!e.isGeneral);b(!!e.sessionOnly,(e=>{const[a,n]=g(e,[this.slug.toString(),i]);return delete a[t],n}))},setValue:function(t,e){let i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const a=w(!!i.isGeneral);b(!!i.sessionOnly,(i=>{const[n,r]=g(i,[this.slug.toString(),a]);return n[t]=e,r}))}});const A="RSA-PSS",_=async(t,e)=>await window.crypto.subtle.generateKey({name:t,modulusLength:2048,publicExponent:new Uint8Array([1,0,1]),hash:"SHA-256"},!1,e),S=async()=>await _("RSA-OAEP",["encrypt","decrypt"]),C=async()=>await _(A,["sign"]),k=async(t,e)=>{const i=(new TextEncoder).encode(e);return await window.crypto.subtle.sign({name:A,saltLength:32},t,i)};class K{constructor(t,e,i){this.slug=t,this.dbName=e,this.dbVersion=i}queryObjectStore(t,e){let i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const{attemptToRecoverDB:a=!0}=i,n=window.indexedDB||window.mozIndexedDB||window.webkitIndexedDB||window.msIndexedDB||window.shimIndexedDB,r=`${this.slug}:${this.dbName}`,s=n.open(r,this.dbVersion||1);s.onupgradeneeded=()=>{var e;const i=s.result;(null===(e=null==i?void 0:i.objectStoreNames)||void 0===e?void 0:e.contains)&&!i.objectStoreNames.contains(t)&&i.createObjectStore(t,{keyPath:"key"})},s.onsuccess=()=>{const o=s.result;let c;try{c=o.transaction(t,(null==i?void 0:i.operation)||"readwrite")}catch(s){if(a&&s instanceof DOMException&&"NotFoundError"===s.name){o.close();return void(n.deleteDatabase(r).onsuccess=()=>{this.queryObjectStore(t,e,d(d({},i),{},{attemptToRecoverDB:!1}))})}throw s}const l=c.objectStore(t);e(l,o),c.oncomplete||(c.oncomplete=()=>{o.close()})}}put(t,e,i){return new Promise(((a,n)=>{this.queryObjectStore(t,(t=>{const r=t.put({key:e,value:i});r.onsuccess=()=>{a(r.result)},r.onerror=t=>{n("Failed adding item to objectStore, err: "+t)}}))}))}add(t,e,i){return new Promise(((a,n)=>{this.queryObjectStore(t,(t=>{const r=t.add({key:e,value:i});r.onsuccess=()=>{a(r.result)},r.onerror=t=>{const e=t.target.error;n(e)}}))}))}get(t,e){return new Promise(((i,a)=>{this.queryObjectStore(t,(t=>{const n=t.get(e);n.onsuccess=()=>{var t;n.result?i(null===(t=n.result)||void 0===t?void 0:t.value):i(void 0)},n.onerror=t=>{a("Failed adding item to objectStore, err: "+t)}}))}))}getAll(t,e){return new Promise(((i,a)=>{this.queryObjectStore(t,(t=>{const n=t.getAll(null,e);n.onsuccess=()=>{if(n.result){const t=n.result;(null==t?void 0:t.length)?i(t.map((t=>null==t?void 0:t.value))):i(t)}else i([])},n.onerror=t=>{a("Failed getting items, err: "+t)}}))}))}delete(t,e){return new Promise(((i,a)=>{this.queryObjectStore(t,(t=>{const n=t.delete(e);n.onsuccess=()=>{i()},n.onerror=t=>{a(`Failed deleting key: '${e}' from objectStore, err: `+t)}}))}))}clear(t){return new Promise(((e,i)=>{this.queryObjectStore(t,(t=>{const a=t.clear();a.onsuccess=()=>{e()},a.onerror=t=>{i("Failed clearing objectStore, err: "+t)}}))}))}executeTransaction(t,e){return new Promise(((i,a)=>{this.queryObjectStore(t,((t,n)=>{const r=t.transaction;r.onerror=()=>{a(`Transaction failed: ${r.error}`)},r.onabort=()=>{a("Transaction aborted")},r.oncomplete=()=>{n.close(),i()};for(const i of e){let e;if("delete"===i.type)e=t.delete(i.key);else{if("put"!==i.type)return r.abort(),void a("Unknown operation type");e=t.put({key:i.key,value:i.value})}e.onerror=()=>{r.abort(),a(`Operation failed: ${e.error}`)}}}))}))}}const R="init",P="completed",T="RSA2048",I=[R,P];class O{constructor(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"sign",i=arguments.length>2?arguments[2]:void 0;var a,n,r,s,o;this.agent=t,this.keysType=e,this.options=i,this._extractingKeysPromise=null;const c=!(null===(a=this.options)||void 0===a?void 0:a.productScope),l=null===(n=this.options)||void 0===n?void 0:n.fallbackClientId;this.keysDatabaseName=c||!(null===(r=this.options)||void 0===r?void 0:r.indexedDBName)?"ts_crypto_binding":this.options.indexedDBName,this.dbVersion=c?1:(null===(s=this.options)||void 0===s?void 0:s.dbVersion)||1,this.keysStoreName=c||!(null===(o=this.options)||void 0===o?void 0:o.keysStoreName)?"identifiers_store":this.options.keysStoreName;const d=c?"platform":t.slug,u=this.getClientConfiguration(l,d);this.indexedDBClient=new K(u.main,this.keysDatabaseName,this.dbVersion),this.indexedDBClientFallback=new K(u.fallback,this.keysDatabaseName,this.dbVersion)}getClientConfiguration(t,e){return t?{main:e,fallback:`${e}:${t}`}:{main:e,fallback:`${e}:${a.clientId}`}}getKeysRecordKey(){return`${this.keysType}_keys`}getRotatedKeysRecordKey(){return`rotated_${this.keysType}_keys`}getRotatedKeysRecordKeyPending(){return`rotated_pending_${this.keysType}_keys`}arrayBufferToBase64(t){return window.btoa(String.fromCharCode(...new Uint8Array(t)))}async getPKRepresentations(t){const e=await crypto.subtle.exportKey("spki",t);return{arrayBufferKey:e,base64Key:this.arrayBufferToBase64(e)}}async generateKeyPair(){return"sign"==this.keysType?await C():await S()}async calcKeyIdentifier(t){const e=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(e)).map((t=>t.toString(16).padStart(2,"0"))).join("")}async extractKeysData(){if(this._extractingKeysPromise)return this._extractingKeysPromise;this._extractingKeysPromise=(async()=>{var t,e;const i=(null===(e=null===(t=this.options)||void 0===t?void 0:t.keyRotation)||void 0===e?void 0:e.isEnabled)?await this.getRotatedKeysData():await this.getKeysData(),{base64Key:a}=await this.getPKRepresentations(i.publicKey);return this.publicKeyBase64=a,this.keyIdentifier=i.keyIdentifier,i})();try{return await this._extractingKeysPromise}finally{this._extractingKeysPromise=null}}async generateKeyPairData(t){const e=await this.generateKeyPair(),{arrayBufferKey:i}=await this.getPKRepresentations(e.publicKey),a=t||await this.calcKeyIdentifier(i);return d(d({},e),{},{keyIdentifier:a,createdDate:Date.now()})}shouldKeyBeRotated(t){var e;const i=null===(e=this.options)||void 0===e?void 0:e.keyRotation;if(!(null==i?void 0:i.isEnabled)||!i.expiryDays||void 0===i.startedAt)return!1;const a=24*i.expiryDays*60*60*1e3,n=t.createdDate&&t.createdDate>=i.startedAt?t.createdDate:i.startedAt;return Date.now()-n>a-2592e6}async extractMainKeysData(){return await this.indexedDBClient.get(this.keysStoreName,this.getKeysRecordKey())}async extractFallbackMainKeysData(){return await this.indexedDBClientFallback.get(this.keysStoreName,this.getKeysRecordKey())}async extractRotatedKeysData(){return await this.indexedDBClient.get(this.keysStoreName,this.getRotatedKeysRecordKey())}async extractPendingRotatedKeysData(){return await this.indexedDBClient.get(this.keysStoreName,this.getRotatedKeysRecordKeyPending())}async saveKeyData(t,e){try{return await this.indexedDBClient.add(this.keysStoreName,t,e),e}catch(e){if(e instanceof DOMException&&"ConstraintError"===e.name){const e=await this.indexedDBClient.get(this.keysStoreName,t);if(e)return e}throw e}}async getKeysData(){const t=this.getKeysRecordKey();let e=await this.extractMainKeysData();if(e)return e;if(e=await this.extractFallbackMainKeysData(),e)return this.saveKeyData(t,e);const i=await this.generateKeyPairData();return this.saveKeyData(t,i)}async getOrCreateRotatedKeys(){let t=await this.extractRotatedKeysData();if(!t){const e=this.getRotatedKeysRecordKey(),i=await this.getKeysData(),a=d(d({},i),{},{createdDate:i.createdDate||Date.now()});t=await this.saveKeyData(e,a)}return t}async getRotatedKeysData(){const t=await this.getOrCreateRotatedKeys();if(this.shouldKeyBeRotated(t)){if(!await this.extractPendingRotatedKeysData()){const e=this.getRotatedKeysRecordKeyPending(),i=await this.generateKeyPairData(t.keyIdentifier);await this.saveKeyData(e,i)}}return t}async getPublicData(){return this.publicKeyBase64&&this.keyIdentifier||await this.extractKeysData(),{publicKey:this.publicKeyBase64,keyIdentifier:this.keyIdentifier}}async sign(t){if("sign"==this.keysType){const{privateKey:e}=await this.extractKeysData(),i=await k(e,t);return this.arrayBufferToBase64(i)}throw new Error("keysType must be 'sign' in order to use sign keys")}async clearKeys(){const t=this.getKeysRecordKey();await this.indexedDBClient.delete(this.keysStoreName,t)}getBaseRotationPayload(){return{keyIdentifier:this.keyIdentifier,slot:this.getRotatedKeysRecordKey(),publicKey:this.publicKeyBase64,publicKeyType:T,tenantId:this.options.keyRotation.tenantId}}async getRotationData(){var t,e;if(!(null===(e=null===(t=this.options)||void 0===t?void 0:t.keyRotation)||void 0===e?void 0:e.isEnabled))return;this.publicKeyBase64&&this.keyIdentifier||await this.extractKeysData();const i=await this.extractPendingRotatedKeysData();if(i){const{base64Key:t}=await this.getPKRepresentations(i.publicKey),{privateKey:e}=await this.extractKeysData(),a=d(d({},this.getBaseRotationPayload()),{},{newPublicKey:t,createdDate:i.createdDate,newPublicKeyType:T}),n=JSON.stringify(a);return{data:n,signature:await this.signPayload(n,e)}}const a=await this.extractRotatedKeysData();if(a&&!1===a.confirmed){await this.extractKeysData();const t=JSON.stringify(this.getBaseRotationPayload());return{data:t,signature:await this.signPayload(t,a.privateKey)}}}async signPayload(t,e){const i=await k(e,t);return this.arrayBufferToBase64(i)}async handleRotateResponse(t){if(I.includes(t))if(t===R){const t=await this.extractPendingRotatedKeysData();if(t){const e=d(d({},t),{},{confirmed:!1});await this.indexedDBClient.executeTransaction(this.keysStoreName,[{type:"delete",key:this.getRotatedKeysRecordKey()},{type:"put",key:this.getRotatedKeysRecordKey(),value:e},{type:"delete",key:this.getRotatedKeysRecordKeyPending()}]);const{base64Key:i}=await this.getPKRepresentations(t.publicKey);this.publicKeyBase64=i,this.keyIdentifier=t.keyIdentifier}}else if(t===P){const t=await this.extractRotatedKeysData();t&&!1===t.confirmed&&await this.indexedDBClient.put(this.keysStoreName,this.getRotatedKeysRecordKey(),d(d({},t),{},{confirmed:!0}))}}}var j=Object.freeze({__proto__:null,createCryptoBinding:function(){return new O(this,arguments.length>0&&void 0!==arguments[0]?arguments[0]:"sign",arguments.length>1?arguments[1]:void 0)},generateRSAKeyPair:S,generateRSASignKeyPair:C,signAssymetric:k,verifyAssymetric:async(t,e,i)=>{const a=(new TextEncoder).encode(e);return await window.crypto.subtle.verify(A,t,i,a)}}),x=Object.freeze({__proto__:null});const B=h.create((t=>{class e extends Error{constructor(e,i){super(`${t.slug}-${e} ${i}`)}}return{TsError:e,TsInternalError:class extends e{constructor(t){super(t,"Internal error")}}}}));var E=h.create((()=>d({exceptions:B},y)));class N{constructor(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];this.agent=t,this.middlewares=e,this.logs=[]}info(t,e){this.pushLog(3,t,e)}warn(t,e){this.pushLog(4,t,e)}error(t,e){this.pushLog(5,t,e)}pushLog(t,e){let i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};this.logs.push({timestamp:Date.now(),module:this.agent.slug,severity:t,fields:i,message:e});const a=this.middlewares.map((t=>t(this)));Promise.all(a).catch((()=>{}))}}var F=Object.freeze({__proto__:null,consoleMiddleware:function(t){const e=t.logs[t.logs.length-1];console.log(`${e.severity} ${e.message}`,e.fields)},createSdkLogger:function(){return new N(this,arguments.length>0&&void 0!==arguments[0]?arguments[0]:[])}});function H(t,e){if(!(null==t?void 0:t.trim()))return"";if(function(t){try{return new URL(t),!0}catch(t){return!1}}(t))return t;const i="http://mock.com",a=new URL(i);a.search=(null==e?void 0:e.toString())||"",a.pathname=t;return a.href.replace(i,"")}const M={"Content-Type":"application/json","X-TS-client-time":(new Date).toUTCString(),"X-TS-ua":navigator.userAgent};function $(t,e,i){var a;const n=(r=e||{},encodeURI(JSON.stringify(r)).split(/%..|./).length-1);var r;return{method:t,headers:d(d(d({},{"X-TS-body-size":String(n)}),M),i||{}),body:null!==(a=e&&JSON.stringify(e||{}))&&void 0!==a?a:void 0}}function q(t,e,i,a,n){const r=H(t,a),s=$(e,i,n);return fetch(r,s)}async function z(t,e,i,a,n){let r;if(r=await q(t,e,i,a,n),!r.ok)throw new Error("Request failed");return r}var J=Object.freeze({__proto__:null,httpDelete:async function(t,e){const i=await z(t,"DELETE",void 0,void 0,e);return d(d({data:await i.json()},i),{},{headers:i.headers})},httpGet:async function(t,e,i){const a=await z(t,"GET",void 0,e,i);return d(d({data:await a.json()},a),{},{headers:a.headers})},httpPost:async function(t,e,i,a){const n=await z(t,"POST",e,i,a);return d(d({data:await n.json()},n),{},{headers:n.headers})},httpPut:async function(t,e,i,a){const n=await z(t,"PUT",e,i,a);return d(d({data:await n.json()},n),{},{headers:n.headers})},init:$}),L=h.create((()=>({events:p,moduleMetadata:r,mainEntry:o,utils:E,storage:D,crypto:j,indexedDB:x,logger:F,http:J})));class U{static arrayBufferToBase64(t){return btoa(String.fromCharCode(...new Uint8Array(t)))}static base64ToArrayBuffer(t){return Uint8Array.from(atob(t),(t=>t.charCodeAt(0)))}static stringToBase64(t){return btoa(t)}static jsonToBase64(t){const e=JSON.stringify(t);return btoa(e)}static base64ToJson(t){const e=atob(t);return JSON.parse(e)}}const V={log:console.log,error:console.error};var G,W;!function(t){t.NotInitialized="not_initialized",t.AuthenticationFailed="authentication_failed",t.AuthenticationAbortedTimeout="authentication_aborted_timeout",t.AuthenticationCanceled="webauthn_authentication_canceled",t.RegistrationFailed="registration_failed",t.AlreadyRegistered="username_already_registered",t.RegistrationAbortedTimeout="registration_aborted_timeout",t.RegistrationCanceled="webauthn_registration_canceled",t.AutofillAuthenticationAborted="autofill_authentication_aborted",t.AuthenticationProcessAlreadyActive="authentication_process_already_active",t.InvalidApprovalData="invalid_approval_data",t.FailedToInitCrossDeviceSession="cross_device_init_failed",t.FailedToGetCrossDeviceStatus="cross_device_status_failed",t.Unknown="unknown"}(G||(G={}));class Z extends Error{constructor(t,e){super(t),this.errorCode=G.NotInitialized,this.data=e}}class X extends Z{constructor(t,e){super(null!=t?t:"WebAuthnSdk is not initialized",e),this.errorCode=G.NotInitialized}}class Y extends Z{constructor(t,e){super(null!=t?t:"Authentication failed with an error",e),this.errorCode=G.AuthenticationFailed}}class Q extends Z{constructor(t,e){super(null!=t?t:"Authentication was canceled by the user or got timeout",e),this.errorCode=G.AuthenticationCanceled}}class tt extends Z{constructor(t,e){super(null!=t?t:"Registration failed with an error",e),this.errorCode=G.RegistrationFailed}}class et extends Z{constructor(t,e){super(null!=t?t:"Registration was canceled by the user or got timeout",e),this.errorCode=G.RegistrationCanceled}}class it extends Z{constructor(t){super(null!=t?t:"Autofill flow was aborted"),this.errorCode=G.AutofillAuthenticationAborted}}class at extends Z{constructor(t){super(null!=t?t:"Operation was aborted by timeout"),this.errorCode=G.AutofillAuthenticationAborted}}class nt extends Z{constructor(t){super(null!=t?t:"Passkey with this username is already registered with the relying party."),this.errorCode=G.AlreadyRegistered}}class rt extends Z{constructor(t,e){super(null!=t?t:"Authentication process is already active",e),this.errorCode=G.AuthenticationProcessAlreadyActive}}class st extends Z{constructor(t,e){super(null!=t?t:"Invalid approval data",e),this.errorCode=G.InvalidApprovalData}}class ot extends Z{constructor(t,e){super(null!=t?t:"Failed to init cross device authentication",e),this.errorCode=G.FailedToInitCrossDeviceSession}}class ct extends Z{constructor(t,e){super(null!=t?t:"Failed to get cross device status",e),this.errorCode=G.FailedToGetCrossDeviceStatus}}function lt(t){return t.errorCode&&Object.values(G).includes(t.errorCode)}!function(t){t[t.persistent=0]="persistent",t[t.session=1]="session"}(W||(W={}));class dt{static get(t){return dt.getStorageMedium(dt.allowedKeys[t]).getItem(dt.getStorageKey(t))||void 0}static set(t,e){return dt.getStorageMedium(dt.allowedKeys[t]).setItem(dt.getStorageKey(t),e)}static remove(t){dt.getStorageMedium(dt.allowedKeys[t]).removeItem(dt.getStorageKey(t))}static clear(t){for(const[e,i]of Object.entries(dt.allowedKeys)){const a=e;t&&this.configurationKeys.includes(a)||dt.getStorageMedium(i).removeItem(dt.getStorageKey(a))}}static getStorageKey(t){return`WebAuthnSdk:${t}`}static getStorageMedium(t){return t===W.session?sessionStorage:localStorage}}dt.allowedKeys={clientId:W.session},dt.configurationKeys=["clientId"];class ut{static isNewApiDomain(t){return t&&(this.newApiDomains.includes(t)||t.startsWith("api.")&&t.endsWith(".transmitsecurity.io"))}static dnsPrefetch(t){const e=document.createElement("link");e.rel="dns-prefetch",e.href=t,document.head.appendChild(e)}static preconnect(t,e){const i=document.createElement("link");i.rel="preconnect",i.href=t,e&&(i.crossOrigin="anonymous"),document.head.appendChild(i)}static warmupConnection(t){this.dnsPrefetch(t),this.preconnect(t,!1),this.preconnect(t,!0)}static init(t,e){var i,a;try{this._serverPath=new URL(e.serverPath),this.isNewApiDomain(null===(i=this._serverPath)||void 0===i?void 0:i.hostname)&&this.warmupConnection(this._serverPath.origin),this._apiPaths=null!==(a=e.webauthnApiPaths)&&void 0!==a?a:this.getDefaultPaths(),this._clientId=t,dt.set("clientId",t)}catch(t){throw new X("Invalid options.serverPath",{error:t})}}static getDefaultPaths(){var t;const e=this.isNewApiDomain(null===(t=this._serverPath)||void 0===t?void 0:t.hostname)?"/cis":"";return{startAuthentication:`${e}/v1/auth/webauthn/authenticate/start`,startRegistration:`${e}/v1/auth/webauthn/register/start`,initCrossDeviceAuthentication:`${e}/v1/auth/webauthn/cross-device/authenticate/init`,startCrossDeviceAuthentication:`${e}/v1/auth/webauthn/cross-device/authenticate/start`,startCrossDeviceRegistration:`${e}/v1/auth/webauthn/cross-device/register/start`,getCrossDeviceTicketStatus:`${e}/v1/auth/webauthn/cross-device/status`,attachDeviceToCrossDeviceSession:`${e}/v1/auth/webauthn/cross-device/attach-device`}}static getApiPaths(){return this._apiPaths}static async sendRequest(t,e,i){V.log(`[WebAuthn SDK] Calling ${e.method} ${t}...`);const a=new URL(this._serverPath);return a.pathname=t,i&&(a.search=i),fetch(a.toString(),e)}static async startRegistration(t){const e=await this.sendRequest(this._apiPaths.startRegistration,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(d(d({client_id:this.getValidatedClientId(),username:t.username,display_name:t.displayName},t.timeout&&{timeout:t.timeout}),t.limitSingleCredentialToDevice&&{limit_single_credential_to_device:t.limitSingleCredentialToDevice}))});if(!(null==e?void 0:e.ok))throw new Y("Failed to start registration",null==e?void 0:e.body);return await e.json()}static async startAuthentication(t){const e=await this.sendRequest(this._apiPaths.startAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(d(d(d({client_id:this.getValidatedClientId()},t.username&&{username:t.username}),t.approvalData&&{approval_data:t.approvalData}),t.timeout&&{timeout:t.timeout}))});if(!(null==e?void 0:e.ok))throw new Y("Failed to start authentication",null==e?void 0:e.body);return await e.json()}static async initCrossDeviceAuthentication(t){const e=await this.sendRequest(this._apiPaths.initCrossDeviceAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(d(d({client_id:this.getValidatedClientId()},t.username&&{username:t.username}),t.approvalData&&{approval_data:t.approvalData}))});if(!(null==e?void 0:e.ok))throw new ot(void 0,null==e?void 0:e.body);return await e.json()}static async getCrossDeviceTicketStatus(t){const e=await this.sendRequest(this._apiPaths.getCrossDeviceTicketStatus,{method:"GET"},`cross_device_ticket_id=${t.ticketId}`);if(!(null==e?void 0:e.ok))throw new ct(void 0,null==e?void 0:e.body);return await e.json()}static async startCrossDeviceAuthentication(t){const e=await this.sendRequest(this._apiPaths.startCrossDeviceAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new Y("Failed to start cross device authentication",null==e?void 0:e.body);return await e.json()}static async startCrossDeviceRegistration(t){const e=await this.sendRequest(this._apiPaths.startCrossDeviceRegistration,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new tt("Failed to start cross device registration",null==e?void 0:e.body);return await e.json()}static async attachDeviceToCrossDeviceSession(t){const e=await this.sendRequest(this._apiPaths.attachDeviceToCrossDeviceSession,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new tt("Failed to attach device to cross device session",null==e?void 0:e.body);return await e.json()}static getValidatedClientId(){var t;const e=null!==(t=this._clientId)&&void 0!==t?t:dt.get("clientId");if(!e)throw new X("Missing clientId");return e}}var ht,yt,pt,gt;ut.newApiDomains=["api.idsec-dev.com","api.idsec-stg.com"],function(t){t.InputAutofill="input-autofill",t.Modal="modal"}(ht||(ht={})),function(t){t.Pending="pending",t.Scanned="scanned",t.Success="success",t.Error="error",t.Timeout="timeout",t.Aborted="aborted"}(yt||(yt={})),function(t){t.toAuthenticationError=t=>lt(t)?t:"NotAllowedError"===t.name?new Q:"OperationError"===t.name?new rt(t.message):"SecurityError"===t.name?new Y(t.message):t===G.AuthenticationAbortedTimeout?new at:"AbortError"===t.name||t===G.AutofillAuthenticationAborted?new it:new Y("Something went wrong during authentication",{error:t}),t.toRegistrationError=t=>lt(t)?t:"NotAllowedError"===t.name?new et:"SecurityError"===t.name?new tt(t.message):"InvalidStateError"===t.name?new nt:t===G.RegistrationAbortedTimeout?new at:new tt("Something went wrong during registration",{error:t})}(pt||(pt={})),function(t){t.processCredentialRequestOptions=t=>d(d({},t),{},{challenge:U.base64ToArrayBuffer(t.challenge),allowCredentials:t.allowCredentials.map((t=>d(d({},t),{},{id:U.base64ToArrayBuffer(t.id)})))}),t.processCredentialCreationOptions=(t,e)=>{var i;const a=JSON.parse(JSON.stringify(t));return a.challenge=U.base64ToArrayBuffer(t.challenge),a.user.id=U.base64ToArrayBuffer(t.user.id),(null==e?void 0:e.limitSingleCredentialToDevice)&&(a.excludeCredentials=null===(i=t.excludeCredentials)||void 0===i?void 0:i.map((t=>d(d({},t),{},{id:U.base64ToArrayBuffer(t.id)})))),(null==e?void 0:e.registerAsDiscoverable)?(a.authenticatorSelection.residentKey="preferred",a.authenticatorSelection.requireResidentKey=!0):(a.authenticatorSelection.residentKey="discouraged",a.authenticatorSelection.requireResidentKey=!1),a.authenticatorSelection.authenticatorAttachment=(null==e?void 0:e.allowCrossPlatformAuthenticators)?void 0:"platform",a},t.encodeAuthenticationResult=t=>{const{authenticatorAttachment:e}=t,i=t.response;return{id:t.id,rawId:U.arrayBufferToBase64(t.rawId),response:{authenticatorData:U.arrayBufferToBase64(i.authenticatorData),clientDataJSON:U.arrayBufferToBase64(i.clientDataJSON),signature:U.arrayBufferToBase64(i.signature),userHandle:U.arrayBufferToBase64(i.userHandle)},authenticatorAttachment:e,type:t.type}},t.encodeRegistrationResult=t=>{const{authenticatorAttachment:e}=t,i=t.response;return{id:t.id,rawId:U.arrayBufferToBase64(t.rawId),response:{attestationObject:U.arrayBufferToBase64(i.attestationObject),clientDataJSON:U.arrayBufferToBase64(i.clientDataJSON)},authenticatorAttachment:e,type:t.type}}}(gt||(gt={}));class vt{async modal(t){try{const e=await this.performAuthentication(d(d({},t),{},{mediationType:ht.Modal}));return U.jsonToBase64(e)}catch(t){throw pt.toAuthenticationError(t)}}activateAutofill(t,e){const{onSuccess:i,onError:a,onReady:n}=t;this.performAuthentication({username:e,mediationType:ht.InputAutofill,onReady:n}).then((t=>{i(U.jsonToBase64(t))})).catch((t=>{const e=pt.toAuthenticationError(t);if(!a)throw e;a(e)}))}abortAutofill(){this.abortController&&this.abortController.abort(G.AutofillAuthenticationAborted)}abortAuthentication(){this.abortController&&this.abortController.abort(G.AuthenticationAbortedTimeout)}async performAuthentication(t){var e,i;const a="crossDeviceTicketId"in t?await ut.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await ut.startAuthentication({username:t.username,timeout:null===(e=t.options)||void 0===e?void 0:e.timeout}),n=a.credential_request_options,r=gt.processCredentialRequestOptions(n),s=this.getMediatedCredentialRequest(r,t.mediationType);t.mediationType===ht.InputAutofill&&(null===(i=t.onReady)||void 0===i||i.call(t));const o=await navigator.credentials.get(s).catch((t=>{throw pt.toAuthenticationError(t)}));return{webauthnSessionId:a.webauthn_session_id,publicKeyCredential:gt.encodeAuthenticationResult(o),userAgent:navigator.userAgent}}getMediatedCredentialRequest(t,e){const i={publicKey:t};return this.abortController=new AbortController,i.signal=this.abortController&&this.abortController.signal,e===ht.InputAutofill?i.mediation="conditional":t.timeout&&setTimeout((()=>{this.abortAuthentication()}),t.timeout),i}}class ft{constructor(t,e){this.handler=t,this.intervalInMs=e}begin(){var t;this.intervalId=window.setInterval((t=this.handler,async function(){t.isRunning||(t.isRunning=!0,await t(...arguments),t.isRunning=!1)}),this.intervalInMs)}stop(){clearInterval(this.intervalId)}}const wt=/^[A-Za-z0-9\-_.: ]*$/;function mt(t){if(t&&(!function(t){return Object.keys(t).length<=10}(t)||!function(t){const e=t=>"string"==typeof t,i=t=>wt.test(t);return Object.keys(t).every((a=>e(a)&&e(t[a])&&i(a)&&i(t[a])))}(t)))throw V.error("Failed validating approval data"),new st("Provided approval data should have 10 properties max. Also, it should contain only \n alphanumeric characters, numbers, and the special characters: '-', '_', '.'")}class bt{constructor(t,e,i){this.authenticationHandler=t,this.registrationHandler=e,this.approvalHandler=i,this.init={registration:async t=>(this.ticketStatus=yt.Pending,this.pollCrossDeviceSession(t.crossDeviceTicketId,t.handlers)),authentication:async t=>{const{username:e}=t,i=(await ut.initCrossDeviceAuthentication(d({},e&&{username:e}))).cross_device_ticket_id;return this.ticketStatus=yt.Pending,this.pollCrossDeviceSession(i,t.handlers)},approval:async t=>{const{username:e,approvalData:i}=t;mt(i);const a=(await ut.initCrossDeviceAuthentication({username:e,approvalData:i})).cross_device_ticket_id;return this.ticketStatus=yt.Pending,this.pollCrossDeviceSession(a,t.handlers)}},this.authenticate={modal:async t=>this.authenticationHandler.modal({crossDeviceTicketId:t})},this.approve={modal:async t=>this.approvalHandler.modal({crossDeviceTicketId:t})}}async register(t,e){return this.registrationHandler.register({crossDeviceTicketId:t},e)}async attachDevice(t){const e=await ut.attachDeviceToCrossDeviceSession({ticketId:t});return d({status:e.status,startedAt:e.started_at},e.approval_data&&{approvalData:e.approval_data})}async pollCrossDeviceSession(t,e){return this.poller=new ft((async()=>{var i,a;const n=await ut.getCrossDeviceTicketStatus({ticketId:t}),r=n.status;if(r!==this.ticketStatus)switch(this.ticketStatus=r,r){case yt.Scanned:await e.onDeviceAttach();break;case yt.Error:case yt.Timeout:case yt.Aborted:await e.onFailure(n),null===(i=this.poller)||void 0===i||i.stop();break;case yt.Success:if("onCredentialRegister"in e)await e.onCredentialRegister();else{if(!n.session_id)throw new ct("Cross device session is complete without returning session_id",n);await e.onCredentialAuthenticate(n.session_id)}null===(a=this.poller)||void 0===a||a.stop()}}),1e3),this.poller.begin(),setTimeout((()=>{var t;null===(t=this.poller)||void 0===t||t.stop(),e.onFailure({status:yt.Timeout})}),3e5),{crossDeviceTicketId:t,stop:()=>{var t;null===(t=this.poller)||void 0===t||t.stop()}}}}class Dt{async register(t,e){this.abortController=new AbortController;const i=d({allowCrossPlatformAuthenticators:!("crossDeviceTicketId"in t),registerAsDiscoverable:!0},e);try{const a="crossDeviceTicketId"in t?await ut.startCrossDeviceRegistration({ticketId:t.crossDeviceTicketId}):await ut.startRegistration({username:t.username,displayName:(null==e?void 0:e.displayName)||t.username,timeout:null==e?void 0:e.timeout,limitSingleCredentialToDevice:null==e?void 0:e.limitSingleCredentialToDevice}),n=gt.processCredentialCreationOptions(a.credential_creation_options,i);setTimeout((()=>{this.abortRegistration()}),n.timeout);const r=await this.registerCredential(n),s={webauthnSessionId:a.webauthn_session_id,publicKeyCredential:r,userAgent:navigator.userAgent};return U.jsonToBase64(s)}catch(t){throw pt.toRegistrationError(t)}}abortRegistration(){this.abortController&&this.abortController.abort(G.RegistrationAbortedTimeout)}async registerCredential(t){const e=await navigator.credentials.create({publicKey:t,signal:this.abortController&&this.abortController.signal}).catch((t=>{throw pt.toRegistrationError(t)}));return gt.encodeRegistrationResult(e)}}class At{async modal(t){try{const e=await this.performApproval(t);return U.jsonToBase64(e)}catch(t){throw pt.toAuthenticationError(t)}}async performApproval(t){"approvalData"in t&&mt(t.approvalData);const e="crossDeviceTicketId"in t?await ut.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await ut.startAuthentication({username:t.username,approvalData:t.approvalData}),i=e.credential_request_options,a=gt.processCredentialRequestOptions(i),n=await navigator.credentials.get({publicKey:a}).catch((t=>{throw pt.toAuthenticationError(t)}));return{webauthnSessionId:e.webauthn_session_id,publicKeyCredential:gt.encodeAuthenticationResult(n),userAgent:navigator.userAgent}}}class _t{constructor(){this._initialized=!1,this._authenticationHandler=new vt,this._registrationHandler=new Dt,this._approvalHandler=new At,this._crossDeviceHandler=new bt(this._authenticationHandler,this._registrationHandler,this._approvalHandler),this.authenticate={modal:async(t,e)=>(this.initCheck(),this._authenticationHandler.modal({username:t,options:e})),autofill:{activate:(t,e)=>(this.initCheck(),this._authenticationHandler.activateAutofill(t,e)),abort:()=>this._authenticationHandler.abortAutofill()}},this.approve={modal:async(t,e)=>(this.initCheck(),this._approvalHandler.modal({username:t,approvalData:e}))},this.register=async(t,e)=>(this.initCheck(),this._registrationHandler.register({username:t},e)),this.crossDevice={init:{registration:async t=>(this.initCheck(),this._crossDeviceHandler.init.registration(t)),authentication:async t=>(this.initCheck(),this._crossDeviceHandler.init.authentication(t)),approval:async t=>(this.initCheck(),this._crossDeviceHandler.init.approval(t))},authenticate:{modal:async t=>(this.initCheck(),this._crossDeviceHandler.authenticate.modal(t))},approve:{modal:async t=>(this.initCheck(),this._crossDeviceHandler.approve.modal(t))},register:async(t,e)=>(this.initCheck(),this._crossDeviceHandler.register(t,e)),attachDevice:async t=>(this.initCheck(),this._crossDeviceHandler.attachDevice(t))},this.isPlatformAuthenticatorSupported=async()=>{var t;try{return await(null===(t=_t.StaticPublicKeyCredential)||void 0===t?void 0:t.isUserVerifyingPlatformAuthenticatorAvailable())}catch(t){return!1}},this.isAutofillSupported=async()=>{var t,e;return!(!(null===(t=_t.StaticPublicKeyCredential)||void 0===t?void 0:t.isConditionalMediationAvailable)||!await(null===(e=_t.StaticPublicKeyCredential)||void 0===e?void 0:e.isConditionalMediationAvailable()))}}async init(t,e){try{if(!t)throw new X("Invalid clientId",{clientId:t});if(e.webauthnApiPaths){const t=ut.getDefaultPaths();if(function(t,e){const i=new Set(t),a=new Set(e);return[...t.filter((t=>!a.has(t))),...e.filter((t=>!i.has(t)))]}(Object.keys(e.webauthnApiPaths),Object.keys(t)).length)throw new X("Invalid custom paths",{customApiPaths:e.webauthnApiPaths})}ut.init(t,e),this._initialized=!0}catch(t){throw lt(t)?t:new X("Failed to initialize SDK")}}getDefaultPaths(){return this.initCheck(),ut.getDefaultPaths()}getApiPaths(){return this.initCheck(),ut.getApiPaths()}initCheck(){if(!this._initialized)throw new X}}_t.StaticPublicKeyCredential=window.PublicKeyCredential;const St=new L("webauthn"),Ct=new _t;St.events.on(St.events.MODULE_INITIALIZED,(()=>{var t;const e=St.moduleMetadata.getInitConfig();if(!(null===(t=null==e?void 0:e.webauthn)||void 0===t?void 0:t.serverPath))return;const{clientId:i,webauthn:a}=e;Ct.init(i,d({},a))}));const kt={modal:async(t,e)=>(Ct.initCheck(),Ct.authenticate.modal(t,e)),autofill:{activate:(t,e)=>{Ct.initCheck(),Ct.authenticate.autofill.activate(t,e)},abort:()=>{Ct.initCheck(),Ct.authenticate.autofill.abort()}}},Kt={modal:async(t,e)=>(Ct.initCheck(),Ct.approve.modal(t,e))};async function Rt(t,e){return Ct.initCheck(),Ct.register(t,e)}const{crossDevice:Pt}=Ct,{isPlatformAuthenticatorSupported:Tt}=Ct,{isAutofillSupported:It}=Ct,{getDefaultPaths:Ot}=Ct;window.localWebAuthnSDK=Ct;const jt="1.18.2",xt={initialize:s,...Object.freeze({__proto__:null,get WebauthnCrossDeviceStatus(){return yt},approve:Kt,authenticate:kt,crossDevice:Pt,getDefaultPaths:Ot,isAutofillSupported:It,isPlatformAuthenticatorSupported:Tt,register:Rt})};export{jt as PACKAGE_VERSION,yt as WebauthnCrossDeviceStatus,Kt as approve,kt as authenticate,Pt as crossDevice,Ot as getDefaultPaths,s as initialize,It as isAutofillSupported,Tt as isPlatformAuthenticatorSupported,Rt as register,xt as webauthn};
1
+ "undefined"==typeof globalThis&&("undefined"!=typeof window?(window.globalThis=window,window.global=window):"undefined"!=typeof self&&(self.globalThis=self,self.global=self));import t from"./common.js";import{initialize as e}from"./common.js";export{initialize}from"./common.js";function i(t,e){var i=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);e&&(a=a.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),i.push.apply(i,a)}return i}function a(t){for(var e=1;e<arguments.length;e++){var a=null!=arguments[e]?arguments[e]:{};e%2?i(Object(a),!0).forEach((function(e){r(t,e,a[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(a,e))}))}return t}function n(t){var e=function(t,e){if("object"!=typeof t||!t)return t;var i=t[Symbol.toPrimitive];if(void 0!==i){var a=i.call(t,e||"default");if("object"!=typeof a)return a;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(t,"string");return"symbol"==typeof e?e:String(e)}function r(t,e,i){return(e=n(e))in t?Object.defineProperty(t,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):t[e]=i,t}class o{static arrayBufferToBase64(t){return btoa(String.fromCharCode(...new Uint8Array(t)))}static base64ToArrayBuffer(t){return Uint8Array.from(atob(t),(t=>t.charCodeAt(0)))}static stringToBase64(t){return btoa(t)}static jsonToBase64(t){const e=JSON.stringify(t);return btoa(e)}static base64ToJson(t){const e=atob(t);return JSON.parse(e)}}const s={log:console.log,error:console.error};var c,l;!function(t){t.NotInitialized="not_initialized",t.AuthenticationFailed="authentication_failed",t.AuthenticationAbortedTimeout="authentication_aborted_timeout",t.AuthenticationCanceled="webauthn_authentication_canceled",t.RegistrationFailed="registration_failed",t.AlreadyRegistered="username_already_registered",t.RegistrationAbortedTimeout="registration_aborted_timeout",t.RegistrationCanceled="webauthn_registration_canceled",t.AutofillAuthenticationAborted="autofill_authentication_aborted",t.AuthenticationProcessAlreadyActive="authentication_process_already_active",t.InvalidApprovalData="invalid_approval_data",t.FailedToInitCrossDeviceSession="cross_device_init_failed",t.FailedToGetCrossDeviceStatus="cross_device_status_failed",t.Unknown="unknown"}(c||(c={}));class u extends Error{constructor(t,e){super(t),this.errorCode=c.NotInitialized,this.data=e}}class d extends u{constructor(t,e){super(null!=t?t:"WebAuthnSdk is not initialized",e),this.errorCode=c.NotInitialized}}class h extends u{constructor(t,e){super(null!=t?t:"Authentication failed with an error",e),this.errorCode=c.AuthenticationFailed}}class p extends u{constructor(t,e){super(null!=t?t:"Authentication was canceled by the user or got timeout",e),this.errorCode=c.AuthenticationCanceled}}class v extends u{constructor(t,e){super(null!=t?t:"Registration failed with an error",e),this.errorCode=c.RegistrationFailed}}class g extends u{constructor(t,e){super(null!=t?t:"Registration was canceled by the user or got timeout",e),this.errorCode=c.RegistrationCanceled}}class m extends u{constructor(t){super(null!=t?t:"Autofill flow was aborted"),this.errorCode=c.AutofillAuthenticationAborted}}class f extends u{constructor(t){super(null!=t?t:"Operation was aborted by timeout"),this.errorCode=c.AutofillAuthenticationAborted}}class w extends u{constructor(t){super(null!=t?t:"Passkey with this username is already registered with the relying party."),this.errorCode=c.AlreadyRegistered}}class y extends u{constructor(t,e){super(null!=t?t:"Authentication process is already active",e),this.errorCode=c.AuthenticationProcessAlreadyActive}}class b extends u{constructor(t,e){super(null!=t?t:"Invalid approval data",e),this.errorCode=c.InvalidApprovalData}}class A extends u{constructor(t,e){super(null!=t?t:"Failed to init cross device authentication",e),this.errorCode=c.FailedToInitCrossDeviceSession}}class C extends u{constructor(t,e){super(null!=t?t:"Failed to get cross device status",e),this.errorCode=c.FailedToGetCrossDeviceStatus}}function _(t){return t.errorCode&&Object.values(c).includes(t.errorCode)}!function(t){t[t.persistent=0]="persistent",t[t.session=1]="session"}(l||(l={}));class D{static get(t){return D.getStorageMedium(D.allowedKeys[t]).getItem(D.getStorageKey(t))||void 0}static set(t,e){return D.getStorageMedium(D.allowedKeys[t]).setItem(D.getStorageKey(t),e)}static remove(t){D.getStorageMedium(D.allowedKeys[t]).removeItem(D.getStorageKey(t))}static clear(t){for(const[e,i]of Object.entries(D.allowedKeys)){const a=e;t&&this.configurationKeys.includes(a)||D.getStorageMedium(i).removeItem(D.getStorageKey(a))}}static getStorageKey(t){return`WebAuthnSdk:${t}`}static getStorageMedium(t){return t===l.session?sessionStorage:localStorage}}D.allowedKeys={clientId:l.session},D.configurationKeys=["clientId"];class S{static isNewApiDomain(t){return t&&(this.newApiDomains.includes(t)||t.startsWith("api.")&&t.endsWith(".transmitsecurity.io"))}static dnsPrefetch(t){const e=document.createElement("link");e.rel="dns-prefetch",e.href=t,document.head.appendChild(e)}static preconnect(t,e){const i=document.createElement("link");i.rel="preconnect",i.href=t,e&&(i.crossOrigin="anonymous"),document.head.appendChild(i)}static warmupConnection(t){this.dnsPrefetch(t),this.preconnect(t,!1),this.preconnect(t,!0)}static init(t,e){var i,a;try{this._serverPath=new URL(e.serverPath),this.isNewApiDomain(null===(i=this._serverPath)||void 0===i?void 0:i.hostname)&&this.warmupConnection(this._serverPath.origin),this._apiPaths=null!==(a=e.webauthnApiPaths)&&void 0!==a?a:this.getDefaultPaths(),this._clientId=t,D.set("clientId",t)}catch(t){throw new d("Invalid options.serverPath",{error:t})}}static getDefaultPaths(){var t;const e=this.isNewApiDomain(null===(t=this._serverPath)||void 0===t?void 0:t.hostname)?"/cis":"";return{startAuthentication:`${e}/v1/auth/webauthn/authenticate/start`,startRegistration:`${e}/v1/auth/webauthn/register/start`,initCrossDeviceAuthentication:`${e}/v1/auth/webauthn/cross-device/authenticate/init`,startCrossDeviceAuthentication:`${e}/v1/auth/webauthn/cross-device/authenticate/start`,startCrossDeviceRegistration:`${e}/v1/auth/webauthn/cross-device/register/start`,getCrossDeviceTicketStatus:`${e}/v1/auth/webauthn/cross-device/status`,attachDeviceToCrossDeviceSession:`${e}/v1/auth/webauthn/cross-device/attach-device`}}static getApiPaths(){return this._apiPaths}static async sendRequest(t,e,i){s.log(`[WebAuthn SDK] Calling ${e.method} ${t}...`);const a=new URL(this._serverPath);return a.pathname=t,i&&(a.search=i),fetch(a.toString(),e)}static async startRegistration(t){const e=await this.sendRequest(this._apiPaths.startRegistration,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a(a({client_id:this.getValidatedClientId(),username:t.username,display_name:t.displayName},t.timeout&&{timeout:t.timeout}),t.limitSingleCredentialToDevice&&{limit_single_credential_to_device:t.limitSingleCredentialToDevice}))});if(!(null==e?void 0:e.ok))throw new h("Failed to start registration",null==e?void 0:e.body);return await e.json()}static async startAuthentication(t){const e=await this.sendRequest(this._apiPaths.startAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a(a(a(a(a({client_id:this.getValidatedClientId()},t.username&&{username:t.username}),t.identifier&&{identifier:t.identifier}),t.identifierType&&{identifier_type:t.identifierType}),t.approvalData&&{approval_data:t.approvalData}),t.timeout&&{timeout:t.timeout}))});if(!(null==e?void 0:e.ok))throw new h("Failed to start authentication",null==e?void 0:e.body);return await e.json()}static async initCrossDeviceAuthentication(t){const e=await this.sendRequest(this._apiPaths.initCrossDeviceAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a(a({client_id:this.getValidatedClientId()},t.username&&{username:t.username}),t.approvalData&&{approval_data:t.approvalData}))});if(!(null==e?void 0:e.ok))throw new A(void 0,null==e?void 0:e.body);return await e.json()}static async getCrossDeviceTicketStatus(t){const e=await this.sendRequest(this._apiPaths.getCrossDeviceTicketStatus,{method:"GET"},`cross_device_ticket_id=${t.ticketId}`);if(!(null==e?void 0:e.ok))throw new C(void 0,null==e?void 0:e.body);return await e.json()}static async startCrossDeviceAuthentication(t){const e=await this.sendRequest(this._apiPaths.startCrossDeviceAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new h("Failed to start cross device authentication",null==e?void 0:e.body);return await e.json()}static async startCrossDeviceRegistration(t){const e=await this.sendRequest(this._apiPaths.startCrossDeviceRegistration,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new v("Failed to start cross device registration",null==e?void 0:e.body);return await e.json()}static async attachDeviceToCrossDeviceSession(t){const e=await this.sendRequest(this._apiPaths.attachDeviceToCrossDeviceSession,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new v("Failed to attach device to cross device session",null==e?void 0:e.body);return await e.json()}static getValidatedClientId(){var t;const e=null!==(t=this._clientId)&&void 0!==t?t:D.get("clientId");if(!e)throw new d("Missing clientId");return e}}var T,k,I,P;S.newApiDomains=["api.idsec-dev.com","api.idsec-stg.com"],function(t){t.InputAutofill="input-autofill",t.Modal="modal"}(T||(T={})),function(t){t.Pending="pending",t.Scanned="scanned",t.Success="success",t.Error="error",t.Timeout="timeout",t.Aborted="aborted"}(k||(k={})),function(t){t.toAuthenticationError=t=>_(t)?t:"NotAllowedError"===t.name?new p:"OperationError"===t.name?new y(t.message):"SecurityError"===t.name?new h(t.message):t===c.AuthenticationAbortedTimeout?new f:"AbortError"===t.name||t===c.AutofillAuthenticationAborted?new m:new h("Something went wrong during authentication",{error:t}),t.toRegistrationError=t=>_(t)?t:"NotAllowedError"===t.name?new g:"SecurityError"===t.name?new v(t.message):"InvalidStateError"===t.name?new w:t===c.RegistrationAbortedTimeout?new f:new v("Something went wrong during registration",{error:t})}(I||(I={})),function(t){t.processCredentialRequestOptions=t=>a(a({},t),{},{challenge:o.base64ToArrayBuffer(t.challenge),allowCredentials:t.allowCredentials.map((t=>a(a({},t),{},{id:o.base64ToArrayBuffer(t.id)})))}),t.processCredentialCreationOptions=(t,e)=>{var i;const n=JSON.parse(JSON.stringify(t));return n.challenge=o.base64ToArrayBuffer(t.challenge),n.user.id=o.base64ToArrayBuffer(t.user.id),(null==e?void 0:e.limitSingleCredentialToDevice)&&(n.excludeCredentials=null===(i=t.excludeCredentials)||void 0===i?void 0:i.map((t=>a(a({},t),{},{id:o.base64ToArrayBuffer(t.id)})))),(null==e?void 0:e.registerAsDiscoverable)?(n.authenticatorSelection.residentKey="preferred",n.authenticatorSelection.requireResidentKey=!0):(n.authenticatorSelection.residentKey="discouraged",n.authenticatorSelection.requireResidentKey=!1),n.authenticatorSelection.authenticatorAttachment=(null==e?void 0:e.allowCrossPlatformAuthenticators)?void 0:"platform",n},t.encodeAuthenticationResult=t=>{const{authenticatorAttachment:e}=t,i=t.response;return{id:t.id,rawId:o.arrayBufferToBase64(t.rawId),response:{authenticatorData:o.arrayBufferToBase64(i.authenticatorData),clientDataJSON:o.arrayBufferToBase64(i.clientDataJSON),signature:o.arrayBufferToBase64(i.signature),userHandle:o.arrayBufferToBase64(i.userHandle)},authenticatorAttachment:e,type:t.type}},t.encodeRegistrationResult=t=>{const{authenticatorAttachment:e}=t,i=t.response;return{id:t.id,rawId:o.arrayBufferToBase64(t.rawId),response:{attestationObject:o.arrayBufferToBase64(i.attestationObject),clientDataJSON:o.arrayBufferToBase64(i.clientDataJSON)},authenticatorAttachment:e,type:t.type}}}(P||(P={}));class O{async modal(t){try{const e=await this.performAuthentication(a(a({},t),{},{mediationType:T.Modal}));return o.jsonToBase64(e)}catch(t){throw I.toAuthenticationError(t)}}activateAutofill(t){const{handlers:e,username:i}=t,{onSuccess:a,onError:n,onReady:r}=e;this.performAuthentication({username:i,mediationType:T.InputAutofill,onReady:r}).then((t=>{a(o.jsonToBase64(t))})).catch((t=>{const e=I.toAuthenticationError(t);if(!n)throw e;n(e)}))}abortAutofill(){this.abortController&&this.abortController.abort(c.AutofillAuthenticationAborted)}abortAuthentication(){this.abortController&&this.abortController.abort(c.AuthenticationAbortedTimeout)}async performAuthentication(t){var e,i;const a="crossDeviceTicketId"in t?await S.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await S.startAuthentication({username:t.username,identifier:t.identifier,identifierType:t.identifierType,timeout:null===(e=t.options)||void 0===e?void 0:e.timeout}),n=a.credential_request_options,r=P.processCredentialRequestOptions(n),o=this.getMediatedCredentialRequest(r,t.mediationType);t.mediationType===T.InputAutofill&&(null===(i=t.onReady)||void 0===i||i.call(t));const s=await navigator.credentials.get(o).catch((t=>{throw I.toAuthenticationError(t)}));return{webauthnSessionId:a.webauthn_session_id,publicKeyCredential:P.encodeAuthenticationResult(s),userAgent:navigator.userAgent}}getMediatedCredentialRequest(t,e){const i={publicKey:t};return this.abortController=new AbortController,i.signal=this.abortController&&this.abortController.signal,e===T.InputAutofill?i.mediation="conditional":t.timeout&&setTimeout((()=>{this.abortAuthentication()}),t.timeout),i}}class R{constructor(t,e){this.handler=t,this.intervalInMs=e}begin(){var t;this.intervalId=window.setInterval((t=this.handler,async function(){t.isRunning||(t.isRunning=!0,await t(...arguments),t.isRunning=!1)}),this.intervalInMs)}stop(){clearInterval(this.intervalId)}}const j=/^[A-Za-z0-9\-_.: ]*$/;function B(t){if(t&&(!function(t){return Object.keys(t).length<=10}(t)||!function(t){const e=t=>"string"==typeof t,i=t=>j.test(t);return Object.keys(t).every((a=>e(a)&&e(t[a])&&i(a)&&i(t[a])))}(t)))throw s.error("Failed validating approval data"),new b("Provided approval data should have 10 properties max. Also, it should contain only \n alphanumeric characters, numbers, and the special characters: '-', '_', '.'")}class K{constructor(t,e,i){this.authenticationHandler=t,this.registrationHandler=e,this.approvalHandler=i,this.init={registration:async t=>(this.ticketStatus=k.Pending,this.pollCrossDeviceSession(t.crossDeviceTicketId,t.handlers)),authentication:async t=>{const{username:e}=t,i=(await S.initCrossDeviceAuthentication(a({},e&&{username:e}))).cross_device_ticket_id;return this.ticketStatus=k.Pending,this.pollCrossDeviceSession(i,t.handlers)},approval:async t=>{const{username:e,approvalData:i}=t;B(i);const a=(await S.initCrossDeviceAuthentication({username:e,approvalData:i})).cross_device_ticket_id;return this.ticketStatus=k.Pending,this.pollCrossDeviceSession(a,t.handlers)}},this.authenticate={modal:async t=>this.authenticationHandler.modal({crossDeviceTicketId:t})},this.approve={modal:async t=>this.approvalHandler.modal({crossDeviceTicketId:t})}}async register(t){return this.registrationHandler.register(t)}async attachDevice(t){const e=await S.attachDeviceToCrossDeviceSession({ticketId:t});return a({status:e.status,startedAt:e.started_at},e.approval_data&&{approvalData:e.approval_data})}async pollCrossDeviceSession(t,e){return this.poller=new R((async()=>{var i,a;const n=await S.getCrossDeviceTicketStatus({ticketId:t}),r=n.status;if(r!==this.ticketStatus)switch(this.ticketStatus=r,r){case k.Scanned:await e.onDeviceAttach();break;case k.Error:case k.Timeout:case k.Aborted:await e.onFailure(n),null===(i=this.poller)||void 0===i||i.stop();break;case k.Success:if("onCredentialRegister"in e)await e.onCredentialRegister();else{if(!n.session_id)throw new C("Cross device session is complete without returning session_id",n);await e.onCredentialAuthenticate(n.session_id)}null===(a=this.poller)||void 0===a||a.stop()}}),1e3),this.poller.begin(),setTimeout((()=>{var t;null===(t=this.poller)||void 0===t||t.stop(),e.onFailure({status:k.Timeout})}),3e5),{crossDeviceTicketId:t,stop:()=>{var t;null===(t=this.poller)||void 0===t||t.stop()}}}}class E{async register(t){var e,i,n;this.abortController=new AbortController;const r=a({allowCrossPlatformAuthenticators:!("crossDeviceTicketId"in t),registerAsDiscoverable:!0},t.options);try{const a="crossDeviceTicketId"in t?await S.startCrossDeviceRegistration({ticketId:t.crossDeviceTicketId}):await S.startRegistration({username:t.username,displayName:(null===(e=t.options)||void 0===e?void 0:e.displayName)||t.username,timeout:null===(i=t.options)||void 0===i?void 0:i.timeout,limitSingleCredentialToDevice:null===(n=t.options)||void 0===n?void 0:n.limitSingleCredentialToDevice}),s=P.processCredentialCreationOptions(a.credential_creation_options,r);setTimeout((()=>{this.abortRegistration()}),s.timeout);const c=await this.registerCredential(s),l={webauthnSessionId:a.webauthn_session_id,publicKeyCredential:c,userAgent:navigator.userAgent};return o.jsonToBase64(l)}catch(t){throw I.toRegistrationError(t)}}abortRegistration(){this.abortController&&this.abortController.abort(c.RegistrationAbortedTimeout)}async registerCredential(t){const e=await navigator.credentials.create({publicKey:t,signal:this.abortController&&this.abortController.signal}).catch((t=>{throw I.toRegistrationError(t)}));return P.encodeRegistrationResult(e)}}class H{async modal(t){try{const e=await this.performApproval(t);return o.jsonToBase64(e)}catch(t){throw I.toAuthenticationError(t)}}async performApproval(t){"approvalData"in t&&B(t.approvalData);const e="crossDeviceTicketId"in t?await S.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await S.startAuthentication({username:t.username,approvalData:t.approvalData}),i=e.credential_request_options,a=P.processCredentialRequestOptions(i),n=await navigator.credentials.get({publicKey:a}).catch((t=>{throw I.toAuthenticationError(t)}));return{webauthnSessionId:e.webauthn_session_id,publicKeyCredential:P.encodeAuthenticationResult(n),userAgent:navigator.userAgent}}}class N{constructor(){this._initialized=!1,this._authenticationHandler=new O,this._registrationHandler=new E,this._approvalHandler=new H,this._crossDeviceHandler=new K(this._authenticationHandler,this._registrationHandler,this._approvalHandler),this.authenticate={modal:async t=>(this.initCheck(),this._authenticationHandler.modal(t)),autofill:{activate:t=>(this.initCheck(),this._authenticationHandler.activateAutofill(t)),abort:()=>this._authenticationHandler.abortAutofill()}},this.approve={modal:async t=>(this.initCheck(),this._approvalHandler.modal(t))},this.register=async t=>(this.initCheck(),this._registrationHandler.register(t)),this.crossDevice={init:{registration:async t=>(this.initCheck(),this._crossDeviceHandler.init.registration(t)),authentication:async t=>(this.initCheck(),this._crossDeviceHandler.init.authentication(t)),approval:async t=>(this.initCheck(),this._crossDeviceHandler.init.approval(t))},authenticate:{modal:async t=>(this.initCheck(),this._crossDeviceHandler.authenticate.modal(t))},approve:{modal:async t=>(this.initCheck(),this._crossDeviceHandler.approve.modal(t))},register:async t=>(this.initCheck(),this._crossDeviceHandler.register(t)),attachDevice:async t=>(this.initCheck(),this._crossDeviceHandler.attachDevice(t))},this.isPlatformAuthenticatorSupported=async()=>{var t;try{return await(null===(t=N.StaticPublicKeyCredential)||void 0===t?void 0:t.isUserVerifyingPlatformAuthenticatorAvailable())}catch(t){return!1}},this.isAutofillSupported=async()=>{var t,e;return!(!(null===(t=N.StaticPublicKeyCredential)||void 0===t?void 0:t.isConditionalMediationAvailable)||!await(null===(e=N.StaticPublicKeyCredential)||void 0===e?void 0:e.isConditionalMediationAvailable()))}}async init(t){const{clientId:e,options:i}=t;try{if(!e)throw new d("Invalid clientId",{clientId:e});if(i.webauthnApiPaths){const t=S.getDefaultPaths();if(function(t,e){const i=new Set(t),a=new Set(e);return[...t.filter((t=>!a.has(t))),...e.filter((t=>!i.has(t)))]}(Object.keys(i.webauthnApiPaths),Object.keys(t)).length)throw new d("Invalid custom paths",{customApiPaths:i.webauthnApiPaths})}S.init(e,i),this._initialized=!0}catch(t){throw _(t)?t:new d("Failed to initialize SDK")}}getDefaultPaths(){return this.initCheck(),S.getDefaultPaths()}getApiPaths(){return this.initCheck(),S.getApiPaths()}initCheck(){if(!this._initialized)throw new d}}N.StaticPublicKeyCredential=window.PublicKeyCredential;const F=new t("webauthn"),x=new N;F.events.on(F.events.MODULE_INITIALIZED,(()=>{var t;const e=F.moduleMetadata.getInitConfig();if(!(null===(t=null==e?void 0:e.webauthn)||void 0===t?void 0:t.serverPath))return;const{clientId:i,webauthn:n}=e;x.init({clientId:i,options:a({},n)})}));const q={modal:async t=>(x.initCheck(),x.authenticate.modal(t)),autofill:{activate:t=>{x.initCheck(),x.authenticate.autofill.activate(t)},abort:()=>{x.initCheck(),x.authenticate.autofill.abort()}}},M={modal:async t=>(x.initCheck(),x.approve.modal(t))};async function J(t){return x.initCheck(),x.register(t)}const{crossDevice:z}=x,{isPlatformAuthenticatorSupported:$}=x,{isAutofillSupported:U}=x,{getDefaultPaths:W}=x;window.localWebAuthnSDK=x;const V="2.0.0",L={initialize:e,...Object.freeze({__proto__:null,get WebauthnCrossDeviceStatus(){return k},approve:M,authenticate:q,crossDevice:z,getDefaultPaths:W,isAutofillSupported:U,isPlatformAuthenticatorSupported:$,register:J})};export{V as PACKAGE_VERSION,k as WebauthnCrossDeviceStatus,M as approve,q as authenticate,z as crossDevice,W as getDefaultPaths,U as isAutofillSupported,$ as isPlatformAuthenticatorSupported,J as register,L as webauthn};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transmitsecurity/platform-web-sdk",
3
- "version": "1.18.2",
3
+ "version": "2.0.0",
4
4
  "license": "MIT",
5
5
  "private": false,
6
6
  "type": "module",
@@ -64,23 +64,35 @@
64
64
  },
65
65
  "scripts": {
66
66
  "prebuild": "yarn tsc -p ./src",
67
- "build": "web-sdk-bundler \"`cat bundler-config.json`\"",
68
- "prepare": "yarn build",
67
+ "prebuild:cdn": "yarn tsc -p ./src/tsconfig.cdn.json",
68
+ "prebuild:npm": "yarn tsc -p ./src/tsconfig.npm.json",
69
+ "build:cdn": "yarn prebuild:cdn && web-sdk-bundler \"`cat bundler-config.cdn.json`\"",
70
+ "build:npm": "yarn prebuild:npm && web-sdk-bundler \"`cat bundler-config.npm.json`\"",
71
+ "build": "yarn prebuild && yarn build:cdn && yarn build:npm",
72
+ "prepublishOnly": "yarn build:npm",
73
+ "test": "jest",
74
+ "test:idv": "npm run test:idv:unit && npm run test:idv:browser",
75
+ "test:idv:unit": "jest idv-smoke",
76
+ "test:idv:browser": "playwright test tests/idv-browser.test.ts",
69
77
  "distribute": "platform_sdk_cdn=platform-websdk.idsec-dev.com yarn distribute:env",
70
78
  "promote-latest:env": "./scripts/make-semver-aliases.sh",
71
79
  "distribute:env": "./scripts/upload-dist.sh",
72
80
  "publish:npm": "npm publish --access public"
73
81
  },
74
- "dependencies": {},
75
82
  "devDependencies": {
83
+ "@playwright/test": "^1.57.0",
76
84
  "@rollup/plugin-json": "6.1.0",
77
- "@transmit-security/authentication-sdk": "4.12.0",
78
- "@transmit-security/ido-web-sdk": "0.0.75",
79
- "@transmit-security/riskid_sdk": "1.54.1",
80
- "@transmit-security/ts-identity-verification": "1.4.13",
81
- "@transmit-security/web-sdk-bundler": "0.1.15",
82
- "@transmit-security/web-sdk-common": "1.4.0",
85
+ "@transmit-security/authentication-sdk": "5.0.0",
86
+ "@transmit-security/ido-web-sdk": "1.0.1",
87
+ "@transmit-security/riskid_sdk": "2.0.1",
88
+ "@transmit-security/ts-identity-verification": "1.4.21",
89
+ "@transmit-security/web-sdk-bundler": "0.2.0",
90
+ "@transmit-security/web-sdk-common": "2.0.1",
91
+ "@types/jest": "^29.5.0",
83
92
  "@types/node": "20.3.3",
93
+ "jest": "^29.5.0",
94
+ "jest-environment-jsdom": "^29.5.0",
95
+ "ts-jest": "^29.1.0",
84
96
  "vite": "^5.0.0"
85
97
  },
86
98
  "engines": {
@@ -96,4 +108,4 @@
96
108
  ],
97
109
  "description": "Transmit Security Web SDK - Browser-only authentication and identity verification",
98
110
  "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
99
- }
111
+ }