@transmitsecurity/platform-web-sdk 2.3.0 → 2.3.1
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/CHANGELOG.md +18 -1
- package/dist/common.cjs +1 -1
- package/dist/common.js +1 -1
- package/dist/drs.cjs +1 -1
- package/dist/drs.d.ts +7 -1
- package/dist/drs.js +1 -1
- package/dist/ido.cjs +1 -1
- package/dist/ido.d.ts +92 -1
- package/dist/ido.js +1 -1
- package/dist/idv.cjs +1 -1
- package/dist/idv.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/ts-platform-websdk.js +1 -1
- package/dist/web-sdk-drs+idv+webauthn+ido.js +1 -1
- package/dist/web-sdk.d.ts +101 -3
- package/dist/webauthn.cjs +1 -1
- package/dist/webauthn.js +1 -1
- package/package.json +2 -2
package/dist/web-sdk.d.ts
CHANGED
|
@@ -58,6 +58,7 @@ interface initConfigParams {
|
|
|
58
58
|
};
|
|
59
59
|
ido?: {
|
|
60
60
|
serverPath?: string;
|
|
61
|
+
collectRiskData?: boolean;
|
|
61
62
|
[key: string]: any;
|
|
62
63
|
};
|
|
63
64
|
[key: string]: any;
|
|
@@ -632,11 +633,17 @@ declare class TSAccountProtection {
|
|
|
632
633
|
/** @ignore */
|
|
633
634
|
getActions(): Promise<string[]>;
|
|
634
635
|
getSessionToken(): Promise<any>;
|
|
636
|
+
/**
|
|
637
|
+
* Returns the lightweight (citadel) device payload to be forwarded to citadel via the caller's backend.
|
|
638
|
+
* The response from citadel includes a `deviceId` that must be passed back via {@link setDeviceId}
|
|
639
|
+
* — the server may issue a new one or rotate it, and the SDK only persists it when told to.
|
|
640
|
+
*/
|
|
635
641
|
getPayload(): Promise<LightweightPayload>;
|
|
636
642
|
clearQueue(): void;
|
|
637
643
|
/**
|
|
638
644
|
* Sets the deviceId for lightweight mode (citadel).
|
|
639
|
-
* Should be called after
|
|
645
|
+
* Should be called after every response from citadel — the server may rotate the deviceId
|
|
646
|
+
* (e.g. after schema validation), so always propagate the returned value back into the SDK.
|
|
640
647
|
* @param deviceId - The JWT deviceId returned from citadel backend
|
|
641
648
|
*/
|
|
642
649
|
setDeviceId(deviceId: string): void;
|
|
@@ -2155,7 +2162,98 @@ declare enum IdoJourneyActionType {
|
|
|
2155
2162
|
* On failure, the `IdoServiceResponse` {@link IdoServiceResponse.errorData} field will contain
|
|
2156
2163
|
* relevant error codes that can be used to handle various failure scenarios.
|
|
2157
2164
|
*/
|
|
2158
|
-
MobileApproveAuthentication = "transmit_platform_mobile_approve_authentication"
|
|
2165
|
+
MobileApproveAuthentication = "transmit_platform_mobile_approve_authentication",
|
|
2166
|
+
/**
|
|
2167
|
+
* @description `journeyStepId` for a selfie acquisition action.
|
|
2168
|
+
* This action instructs the client to acquire a selfie image from the user, typically as part of an identity verification or face authentication process.
|
|
2169
|
+
*
|
|
2170
|
+
* Data received in the {@link IdoServiceResponse} object:
|
|
2171
|
+
* ```json
|
|
2172
|
+
* {
|
|
2173
|
+
* "data": {
|
|
2174
|
+
* "start_token": "<START_TOKEN>", // Optional: used to start an identity verification session if required
|
|
2175
|
+
* "acquisition_id": "<ACQUISITION_ID>" // Required: ID needed to start selfie capture
|
|
2176
|
+
* }
|
|
2177
|
+
* }
|
|
2178
|
+
* ```
|
|
2179
|
+
*
|
|
2180
|
+
* To perform the selfie acquisition:
|
|
2181
|
+
* 1. If a `start_token` is present, initialize the IDV SDK session:
|
|
2182
|
+
* ```javascript
|
|
2183
|
+
* if (response.data.start_token !== undefined) {
|
|
2184
|
+
* await idv.start(response.data.start_token);
|
|
2185
|
+
* }
|
|
2186
|
+
* ```
|
|
2187
|
+
* 2. Run the selfie acquisition by calling the IDV SDK's `captureSelfie()` method:
|
|
2188
|
+
* ```javascript
|
|
2189
|
+
* await idv.captureSelfie({ acquisitionId: response.data.acquisition_id });
|
|
2190
|
+
* ```
|
|
2191
|
+
*
|
|
2192
|
+
* After acquiring the selfie, the client response does not need to include any data:
|
|
2193
|
+
* ```javascript
|
|
2194
|
+
* ido.submitClientResponse(ClientResponseOptionType.ClientInput);
|
|
2195
|
+
* ```
|
|
2196
|
+
*
|
|
2197
|
+
* If an error occurs while capturing the selfie, the client should handle error states and inform the user
|
|
2198
|
+
* and/or retry as appropriate according to application requirements.
|
|
2199
|
+
*
|
|
2200
|
+
* For deeper understanding and more implementation details, refer to the IDV SDK documentation:
|
|
2201
|
+
* {@link https://developer.transmitsecurity.com/sdk-ref/idvsdk/overview IDV SDK Reference}
|
|
2202
|
+
*/
|
|
2203
|
+
SelfieAcquisition = "transmit_platform_selfie_acquisition",
|
|
2204
|
+
/**
|
|
2205
|
+
* @description `journeyStepId` for a document acquisition action.
|
|
2206
|
+
* This action instructs the client to acquire a document image from the user, typically as part of an identity verification or face authentication process.
|
|
2207
|
+
*
|
|
2208
|
+
* Data received in the {@link IdoServiceResponse} object:
|
|
2209
|
+
* ```json
|
|
2210
|
+
* {
|
|
2211
|
+
* "data": {
|
|
2212
|
+
* "start_token": "<START_TOKEN>", // Optional: used to start an identity verification session if required
|
|
2213
|
+
* "acquisition_id": "<ACQUISITION_ID>" // Required: ID needed to start document capture
|
|
2214
|
+
* }
|
|
2215
|
+
* }
|
|
2216
|
+
* ```
|
|
2217
|
+
*
|
|
2218
|
+
* To perform the document acquisition:
|
|
2219
|
+
* 1. If a `start_token` is present, initialize the IDV SDK session:
|
|
2220
|
+
* ```javascript
|
|
2221
|
+
* if (response.data.start_token !== undefined) {
|
|
2222
|
+
* await idv.start(response.data.start_token);
|
|
2223
|
+
* }
|
|
2224
|
+
* ```
|
|
2225
|
+
* 2. Run the document acquisition by calling the IDV SDK's `captureDocument()` method:
|
|
2226
|
+
* ```javascript
|
|
2227
|
+
* await idv.captureDocument({ acquisitionId: response.data.acquisition_id });
|
|
2228
|
+
* ```
|
|
2229
|
+
*
|
|
2230
|
+
* After acquiring the document, the client response does not need to include any data:
|
|
2231
|
+
* ```javascript
|
|
2232
|
+
* ido.submitClientResponse(ClientResponseOptionType.ClientInput);
|
|
2233
|
+
* ```
|
|
2234
|
+
*
|
|
2235
|
+
* If an error occurs while capturing the document, the client should handle error states and inform the user
|
|
2236
|
+
* and/or retry as appropriate according to application requirements.
|
|
2237
|
+
*
|
|
2238
|
+
* For deeper understanding and more implementation details, refer to the IDV SDK documentation:
|
|
2239
|
+
* {@link https://developer.transmitsecurity.com/sdk-ref/idvsdk/overview IDV SDK Reference}
|
|
2240
|
+
*/
|
|
2241
|
+
DocumentAcquisition = "transmit_platform_document_acquisition",
|
|
2242
|
+
/**
|
|
2243
|
+
* @description `journeyStepId` for IDV recommendation action.
|
|
2244
|
+
*
|
|
2245
|
+
* When this action is received, it indicates that identity verification (IDV) processing is being performed asynchronously on the backend.
|
|
2246
|
+
* The client is responsible for implementing a polling mechanism: keep calling
|
|
2247
|
+
* `ido.submitClientResponse(ClientResponseOptionType.ClientInput)` in a loop until the server responds with a new action or returns an error.
|
|
2248
|
+
*
|
|
2249
|
+
* Note: No data is provided by the server in the {@link IdoServiceResponse} object for this action at any time.
|
|
2250
|
+
*
|
|
2251
|
+
* It is recommended to show a blocking UI element (such as a loader or progress indicator) while polling,
|
|
2252
|
+
* to inform the user that processing is ongoing.
|
|
2253
|
+
*
|
|
2254
|
+
* This process can take a couple of seconds. The recommended polling interval is every 1 second.
|
|
2255
|
+
*/
|
|
2256
|
+
WaitForIdvRecommendations = "transmit_platform_idv_recommendation"
|
|
2159
2257
|
}
|
|
2160
2258
|
/**
|
|
2161
2259
|
* @interface
|
|
@@ -2388,6 +2486,6 @@ declare class TSWebSDK {
|
|
|
2388
2486
|
}
|
|
2389
2487
|
declare const _default: TSWebSDK;
|
|
2390
2488
|
|
|
2391
|
-
declare const PACKAGE_VERSION = "2.3.
|
|
2489
|
+
declare const PACKAGE_VERSION = "2.3.1";
|
|
2392
2490
|
|
|
2393
2491
|
export { ActionEventOptions, ActionResponse, AuthenticationAutofillActivateHandlers, AutofillHandlers, CrossDeviceController, ErrorCode$1 as ErrorCode, PACKAGE_VERSION, SDK_VERSIONS, SdkError, WebauthnApis, WebauthnAuthenticationFlows, WebauthnCrossDeviceFlows, WebauthnCrossDeviceRegistrationOptions, WebauthnRegistrationOptions, authenticate, index_d$3 as common, crossDevice, _default as default, webSdkModule_d as drs, getDefaultPaths, index_d as ido, index_d$2 as idv, initConfigParams, initialize, isAutofillSupported, isPlatformAuthenticatorSupported, register, index_d$1 as webauthn };
|
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));var t=require("./common.cjs"),e=require("./common.cjs");function i(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 a(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 r(t){for(var e=1;e<arguments.length;e++){var r=null!=arguments[e]?arguments[e]:{};e%2?a(Object(r),!0).forEach((function(e){i(t,e,r[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(r,e))}))}return t}class n{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 o,c;!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"}(o||(o={}));class l extends Error{constructor(t,e){super(t),this.errorCode=o.NotInitialized,this.data=e}}class u extends l{constructor(t,e){super(null!=t?t:"WebAuthnSdk is not initialized",e),this.errorCode=o.NotInitialized}}class d extends l{constructor(t,e){super(null!=t?t:"Authentication failed with an error",e),this.errorCode=o.AuthenticationFailed}}class h extends l{constructor(t,e){super(null!=t?t:"Authentication was canceled by the user or got timeout",e),this.errorCode=o.AuthenticationCanceled}}class p extends l{constructor(t,e){super(null!=t?t:"Registration failed with an error",e),this.errorCode=o.RegistrationFailed}}class v extends l{constructor(t,e){super(null!=t?t:"Registration was canceled by the user or got timeout",e),this.errorCode=o.RegistrationCanceled}}class g extends l{constructor(t){super(null!=t?t:"Autofill flow was aborted"),this.errorCode=o.AutofillAuthenticationAborted}}class f extends l{constructor(t){super(null!=t?t:"Operation was aborted by timeout"),this.errorCode=o.AutofillAuthenticationAborted}}class w extends l{constructor(t){super(null!=t?t:"Passkey with this username is already registered with the relying party."),this.errorCode=o.AlreadyRegistered}}class m extends l{constructor(t,e){super(null!=t?t:"Authentication process is already active",e),this.errorCode=o.AuthenticationProcessAlreadyActive}}class y extends l{constructor(t,e){super(null!=t?t:"Invalid approval data",e),this.errorCode=o.InvalidApprovalData}}class b extends l{constructor(t,e){super(null!=t?t:"Failed to init cross device authentication",e),this.errorCode=o.FailedToInitCrossDeviceSession}}class C extends l{constructor(t,e){super(null!=t?t:"Failed to get cross device status",e),this.errorCode=o.FailedToGetCrossDeviceStatus}}function A(t){return t.errorCode&&Object.values(o).includes(t.errorCode)}!function(t){t[t.persistent=0]="persistent",t[t.session=1]="session"}(c||(c={}));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===c.session?sessionStorage:localStorage}}D.allowedKeys={clientId:c.session},D.configurationKeys=["clientId"];class _{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 u("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(r(r({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 d("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(r(r(r(r(r({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 d("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(r(r({client_id:this.getValidatedClientId()},t.username&&{username:t.username}),t.approvalData&&{approval_data:t.approvalData}))});if(!(null==e?void 0:e.ok))throw new b(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 d("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 p("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 p("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 u("Missing clientId");return e}}var S,T,k,I;_.newApiDomains=["api.idsec-dev.com","api.idsec-stg.com"],function(t){t.InputAutofill="input-autofill",t.Modal="modal"}(S||(S={})),exports.WebauthnCrossDeviceStatus=void 0,(T=exports.WebauthnCrossDeviceStatus||(exports.WebauthnCrossDeviceStatus={})).Pending="pending",T.Scanned="scanned",T.Success="success",T.Error="error",T.Timeout="timeout",T.Aborted="aborted",function(t){t.toAuthenticationError=t=>A(t)?t:"NotAllowedError"===t.name?new h:"OperationError"===t.name?new m(t.message):"SecurityError"===t.name?new d(t.message):t===o.AuthenticationAbortedTimeout?new f:"AbortError"===t.name||t===o.AutofillAuthenticationAborted?new g:new d("Something went wrong during authentication",{error:t}),t.toRegistrationError=t=>A(t)?t:"NotAllowedError"===t.name?new v:"SecurityError"===t.name?new p(t.message):"InvalidStateError"===t.name?new w:t===o.RegistrationAbortedTimeout?new f:new p("Something went wrong during registration",{error:t})}(k||(k={})),function(t){t.processCredentialRequestOptions=t=>r(r({},t),{},{challenge:n.base64ToArrayBuffer(t.challenge),allowCredentials:t.allowCredentials.map((t=>r(r({},t),{},{id:n.base64ToArrayBuffer(t.id)})))}),t.processCredentialCreationOptions=(t,e)=>{var i;const a=JSON.parse(JSON.stringify(t));return a.challenge=n.base64ToArrayBuffer(t.challenge),a.user.id=n.base64ToArrayBuffer(t.user.id),(null==e?void 0:e.limitSingleCredentialToDevice)&&(a.excludeCredentials=null===(i=t.excludeCredentials)||void 0===i?void 0:i.map((t=>r(r({},t),{},{id:n.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:n.arrayBufferToBase64(t.rawId),response:{authenticatorData:n.arrayBufferToBase64(i.authenticatorData),clientDataJSON:n.arrayBufferToBase64(i.clientDataJSON),signature:n.arrayBufferToBase64(i.signature),userHandle:n.arrayBufferToBase64(i.userHandle)},authenticatorAttachment:e,type:t.type}},t.encodeRegistrationResult=t=>{const{authenticatorAttachment:e}=t,i=t.response;return{id:t.id,rawId:n.arrayBufferToBase64(t.rawId),response:{attestationObject:n.arrayBufferToBase64(i.attestationObject),clientDataJSON:n.arrayBufferToBase64(i.clientDataJSON)},authenticatorAttachment:e,type:t.type}}}(I||(I={}));class P{async modal(t){try{const e=await this.performAuthentication(r(r({},t),{},{mediationType:S.Modal}));return n.jsonToBase64(e)}catch(t){throw k.toAuthenticationError(t)}}activateAutofill(t){const{handlers:e,username:i}=t,{onSuccess:a,onError:r,onReady:s}=e;this.performAuthentication({username:i,mediationType:S.InputAutofill,onReady:s}).then((t=>{a(n.jsonToBase64(t))})).catch((t=>{const e=k.toAuthenticationError(t);if(!r)throw e;r(e)}))}abortAutofill(){this.abortController&&this.abortController.abort(o.AutofillAuthenticationAborted)}abortAuthentication(){this.abortController&&this.abortController.abort(o.AuthenticationAbortedTimeout)}async performAuthentication(t){var e,i;const a="crossDeviceTicketId"in t?await _.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await _.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=I.processCredentialRequestOptions(r),s=this.getMediatedCredentialRequest(n,t.mediationType);t.mediationType===S.InputAutofill&&(null===(i=t.onReady)||void 0===i||i.call(t));const o=await navigator.credentials.get(s).catch((t=>{throw k.toAuthenticationError(t)}));return{webauthnSessionId:a.webauthn_session_id,publicKeyCredential:I.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===S.InputAutofill?i.mediation="conditional":t.timeout&&setTimeout((()=>{this.abortAuthentication()}),t.timeout),i}}class O{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 R=/^[A-Za-z0-9\-_.: ]*$/;function j(t){if(t&&(!function(t){return Object.keys(t).length<=10}(t)||!function(t){const e=t=>"string"==typeof t,i=t=>R.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 y("Provided approval data should have 10 properties max. Also, it should contain only \n alphanumeric characters, numbers, and the special characters: '-', '_', '.'")}class x{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 _.initCrossDeviceAuthentication(r({},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;j(i);const a=(await _.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 _.attachDeviceToCrossDeviceSession({ticketId:t});return r({status:e.status,startedAt:e.started_at},e.approval_data&&{approvalData:e.approval_data})}async pollCrossDeviceSession(t,e){return this.poller=new O((async()=>{var i,a;const r=await _.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 C("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 K{async register(t){var e,i,a;this.abortController=new AbortController;const s=r({allowCrossPlatformAuthenticators:!("crossDeviceTicketId"in t),registerAsDiscoverable:!0},t.options);try{const r="crossDeviceTicketId"in t?await _.startCrossDeviceRegistration({ticketId:t.crossDeviceTicketId}):await _.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===(a=t.options)||void 0===a?void 0:a.limitSingleCredentialToDevice}),o=I.processCredentialCreationOptions(r.credential_creation_options,s);setTimeout((()=>{this.abortRegistration()}),o.timeout);const c=await this.registerCredential(o),l={webauthnSessionId:r.webauthn_session_id,publicKeyCredential:c,userAgent:navigator.userAgent};return n.jsonToBase64(l)}catch(t){throw k.toRegistrationError(t)}}abortRegistration(){this.abortController&&this.abortController.abort(o.RegistrationAbortedTimeout)}async registerCredential(t){const e=await navigator.credentials.create({publicKey:t,signal:this.abortController&&this.abortController.signal}).catch((t=>{throw k.toRegistrationError(t)}));return I.encodeRegistrationResult(e)}}class B{async modal(t){try{const e=await this.performApproval(t);return n.jsonToBase64(e)}catch(t){throw k.toAuthenticationError(t)}}async performApproval(t){"approvalData"in t&&j(t.approvalData);const e="crossDeviceTicketId"in t?await _.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await _.startAuthentication({username:t.username,approvalData:t.approvalData}),i=e.credential_request_options,a=I.processCredentialRequestOptions(i),r=await navigator.credentials.get({publicKey:a}).catch((t=>{throw k.toAuthenticationError(t)}));return{webauthnSessionId:e.webauthn_session_id,publicKeyCredential:I.encodeAuthenticationResult(r),userAgent:navigator.userAgent}}}class E{constructor(){this._initialized=!1,this._authenticationHandler=new P,this._registrationHandler=new K,this._approvalHandler=new B,this._crossDeviceHandler=new x(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=E.StaticPublicKeyCredential)||void 0===t?void 0:t.isUserVerifyingPlatformAuthenticatorAvailable())}catch(t){return!1}},this.isAutofillSupported=async()=>{var t,e;return!(!(null===(t=E.StaticPublicKeyCredential)||void 0===t?void 0:t.isConditionalMediationAvailable)||!await(null===(e=E.StaticPublicKeyCredential)||void 0===e?void 0:e.isConditionalMediationAvailable()))}}async init(t){const{clientId:e,options:i}=t;try{if(!e)throw new u("Invalid clientId",{clientId:e});if(i.webauthnApiPaths){const t=_.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 u("Invalid custom paths",{customApiPaths:i.webauthnApiPaths})}_.init(e,i),this._initialized=!0}catch(t){throw A(t)?t:new u("Failed to initialize SDK")}}getDefaultPaths(){return this.initCheck(),_.getDefaultPaths()}getApiPaths(){return this.initCheck(),_.getApiPaths()}initCheck(){if(!this._initialized)throw new u}}E.StaticPublicKeyCredential=window.PublicKeyCredential;const N=new t("webauthn"),H=new E;N.events.on(N.events.MODULE_INITIALIZED,(()=>{var t;const e=N.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;H.init({clientId:i,options:r({},a)})}));const W={modal:async t=>(H.initCheck(),H.authenticate.modal(t)),autofill:{activate:t=>{H.initCheck(),H.authenticate.autofill.activate(t)},abort:()=>{H.initCheck(),H.authenticate.autofill.abort()}}},q={modal:async t=>(H.initCheck(),H.approve.modal(t))};async function F(t){return H.initCheck(),H.register(t)}const{crossDevice:M}=H,{isPlatformAuthenticatorSupported:z}=H,{isAutofillSupported:J}=H,{getDefaultPaths:$}=H;window.localWebAuthnSDK=H;var U=Object.freeze({__proto__:null,get WebauthnCrossDeviceStatus(){return exports.WebauthnCrossDeviceStatus},approve:q,authenticate:W,crossDevice:M,getDefaultPaths:$,isAutofillSupported:J,isPlatformAuthenticatorSupported:z,register:F});const V={initialize:e.initialize,...U};Object.defineProperty(exports,"initialize",{enumerable:!0,get:function(){return e.initialize}}),exports.PACKAGE_VERSION="2.3.0",exports.approve=q,exports.authenticate=W,exports.crossDevice=M,exports.getDefaultPaths=$,exports.isAutofillSupported=J,exports.isPlatformAuthenticatorSupported=z,exports.register=F,exports.webauthn=V;
|
|
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,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 a(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 r(t){for(var e=1;e<arguments.length;e++){var r=null!=arguments[e]?arguments[e]:{};e%2?a(Object(r),!0).forEach((function(e){i(t,e,r[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(r,e))}))}return t}class n{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 o,c;!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"}(o||(o={}));class l extends Error{constructor(t,e){super(t),this.errorCode=o.NotInitialized,this.data=e}}class u extends l{constructor(t,e){super(null!=t?t:"WebAuthnSdk is not initialized",e),this.errorCode=o.NotInitialized}}class d extends l{constructor(t,e){super(null!=t?t:"Authentication failed with an error",e),this.errorCode=o.AuthenticationFailed}}class h extends l{constructor(t,e){super(null!=t?t:"Authentication was canceled by the user or got timeout",e),this.errorCode=o.AuthenticationCanceled}}class p extends l{constructor(t,e){super(null!=t?t:"Registration failed with an error",e),this.errorCode=o.RegistrationFailed}}class v extends l{constructor(t,e){super(null!=t?t:"Registration was canceled by the user or got timeout",e),this.errorCode=o.RegistrationCanceled}}class g extends l{constructor(t){super(null!=t?t:"Autofill flow was aborted"),this.errorCode=o.AutofillAuthenticationAborted}}class f extends l{constructor(t){super(null!=t?t:"Operation was aborted by timeout"),this.errorCode=o.AutofillAuthenticationAborted}}class m extends l{constructor(t){super(null!=t?t:"Passkey with this username is already registered with the relying party."),this.errorCode=o.AlreadyRegistered}}class w extends l{constructor(t,e){super(null!=t?t:"Authentication process is already active",e),this.errorCode=o.AuthenticationProcessAlreadyActive}}class y extends l{constructor(t,e){super(null!=t?t:"Invalid approval data",e),this.errorCode=o.InvalidApprovalData}}class b extends l{constructor(t,e){super(null!=t?t:"Failed to init cross device authentication",e),this.errorCode=o.FailedToInitCrossDeviceSession}}class C extends l{constructor(t,e){super(null!=t?t:"Failed to get cross device status",e),this.errorCode=o.FailedToGetCrossDeviceStatus}}function A(t){return t.errorCode&&Object.values(o).includes(t.errorCode)}!function(t){t[t.persistent=0]="persistent",t[t.session=1]="session"}(c||(c={}));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===c.session?sessionStorage:localStorage}}D.allowedKeys={clientId:c.session},D.configurationKeys=["clientId"];class _{static isNewApiDomain(t){return t&&(this.newApiDomains.includes(t)||t.startsWith("api.")&&t.endsWith(".transmitsecurity.io")||t.startsWith("api.")&&t.endsWith(".idsec-dev.com"))}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 u("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(r(r({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 d("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(r(r(r(r(r({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 d("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(r(r({client_id:this.getValidatedClientId()},t.username&&{username:t.username}),t.approvalData&&{approval_data:t.approvalData}))});if(!(null==e?void 0:e.ok))throw new b(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 d("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 p("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 p("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 u("Missing clientId");return e}}var S,T,k,I;_.newApiDomains=["api.idsec-dev.com","api.idsec-stg.com"],function(t){t.InputAutofill="input-autofill",t.Modal="modal"}(S||(S={})),exports.WebauthnCrossDeviceStatus=void 0,(T=exports.WebauthnCrossDeviceStatus||(exports.WebauthnCrossDeviceStatus={})).Pending="pending",T.Scanned="scanned",T.Success="success",T.Error="error",T.Timeout="timeout",T.Aborted="aborted",function(t){t.toAuthenticationError=t=>A(t)?t:"NotAllowedError"===t.name?new h:"OperationError"===t.name?new w(t.message):"SecurityError"===t.name?new d(t.message):t===o.AuthenticationAbortedTimeout?new f:"AbortError"===t.name||t===o.AutofillAuthenticationAborted?new g:new d("Something went wrong during authentication",{error:t}),t.toRegistrationError=t=>A(t)?t:"NotAllowedError"===t.name?new v:"SecurityError"===t.name?new p(t.message):"InvalidStateError"===t.name?new m:t===o.RegistrationAbortedTimeout?new f:new p("Something went wrong during registration",{error:t})}(k||(k={})),function(t){t.processCredentialRequestOptions=t=>r(r({},t),{},{challenge:n.base64ToArrayBuffer(t.challenge),allowCredentials:t.allowCredentials.map((t=>r(r({},t),{},{id:n.base64ToArrayBuffer(t.id)})))}),t.processCredentialCreationOptions=(t,e)=>{var i;const a=JSON.parse(JSON.stringify(t));return a.challenge=n.base64ToArrayBuffer(t.challenge),a.user.id=n.base64ToArrayBuffer(t.user.id),(null==e?void 0:e.limitSingleCredentialToDevice)&&(a.excludeCredentials=null===(i=t.excludeCredentials)||void 0===i?void 0:i.map((t=>r(r({},t),{},{id:n.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:n.arrayBufferToBase64(t.rawId),response:{authenticatorData:n.arrayBufferToBase64(i.authenticatorData),clientDataJSON:n.arrayBufferToBase64(i.clientDataJSON),signature:n.arrayBufferToBase64(i.signature),userHandle:n.arrayBufferToBase64(i.userHandle)},authenticatorAttachment:e,type:t.type}},t.encodeRegistrationResult=t=>{const{authenticatorAttachment:e}=t,i=t.response;return{id:t.id,rawId:n.arrayBufferToBase64(t.rawId),response:{attestationObject:n.arrayBufferToBase64(i.attestationObject),clientDataJSON:n.arrayBufferToBase64(i.clientDataJSON)},authenticatorAttachment:e,type:t.type}}}(I||(I={}));class P{async modal(t){try{const e=await this.performAuthentication(r(r({},t),{},{mediationType:S.Modal}));return n.jsonToBase64(e)}catch(t){throw k.toAuthenticationError(t)}}activateAutofill(t){const{handlers:e,username:i}=t,{onSuccess:a,onError:r,onReady:s}=e;this.performAuthentication({username:i,mediationType:S.InputAutofill,onReady:s}).then((t=>{a(n.jsonToBase64(t))})).catch((t=>{const e=k.toAuthenticationError(t);if(!r)throw e;r(e)}))}abortAutofill(){this.abortController&&this.abortController.abort(o.AutofillAuthenticationAborted)}abortAuthentication(){this.abortController&&this.abortController.abort(o.AuthenticationAbortedTimeout)}async performAuthentication(t){var e,i;const a="crossDeviceTicketId"in t?await _.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await _.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=I.processCredentialRequestOptions(r),s=this.getMediatedCredentialRequest(n,t.mediationType);t.mediationType===S.InputAutofill&&(null===(i=t.onReady)||void 0===i||i.call(t));const o=await navigator.credentials.get(s).catch((t=>{throw k.toAuthenticationError(t)}));return{webauthnSessionId:a.webauthn_session_id,publicKeyCredential:I.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===S.InputAutofill?i.mediation="conditional":t.timeout&&setTimeout((()=>{this.abortAuthentication()}),t.timeout),i}}class O{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 R=/^[A-Za-z0-9\-_.: ]*$/;function j(t){if(t&&(!function(t){return Object.keys(t).length<=10}(t)||!function(t){const e=t=>"string"==typeof t,i=t=>R.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 y("Provided approval data should have 10 properties max. Also, it should contain only \n alphanumeric characters, numbers, and the special characters: '-', '_', '.'")}class x{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 _.initCrossDeviceAuthentication(r({},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;j(i);const a=(await _.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 _.attachDeviceToCrossDeviceSession({ticketId:t});return r({status:e.status,startedAt:e.started_at},e.approval_data&&{approvalData:e.approval_data})}async pollCrossDeviceSession(t,e){return this.poller=new O((async()=>{var i,a;const r=await _.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 C("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 K{async register(t){var e,i,a;this.abortController=new AbortController;const s=r({allowCrossPlatformAuthenticators:!("crossDeviceTicketId"in t),registerAsDiscoverable:!0},t.options);try{const r="crossDeviceTicketId"in t?await _.startCrossDeviceRegistration({ticketId:t.crossDeviceTicketId}):await _.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===(a=t.options)||void 0===a?void 0:a.limitSingleCredentialToDevice}),o=I.processCredentialCreationOptions(r.credential_creation_options,s);setTimeout((()=>{this.abortRegistration()}),o.timeout);const c=await this.registerCredential(o),l={webauthnSessionId:r.webauthn_session_id,publicKeyCredential:c,userAgent:navigator.userAgent};return n.jsonToBase64(l)}catch(t){throw k.toRegistrationError(t)}}abortRegistration(){this.abortController&&this.abortController.abort(o.RegistrationAbortedTimeout)}async registerCredential(t){const e=await navigator.credentials.create({publicKey:t,signal:this.abortController&&this.abortController.signal}).catch((t=>{throw k.toRegistrationError(t)}));return I.encodeRegistrationResult(e)}}class B{async modal(t){try{const e=await this.performApproval(t);return n.jsonToBase64(e)}catch(t){throw k.toAuthenticationError(t)}}async performApproval(t){"approvalData"in t&&j(t.approvalData);const e="crossDeviceTicketId"in t?await _.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await _.startAuthentication({username:t.username,approvalData:t.approvalData}),i=e.credential_request_options,a=I.processCredentialRequestOptions(i),r=await navigator.credentials.get({publicKey:a}).catch((t=>{throw k.toAuthenticationError(t)}));return{webauthnSessionId:e.webauthn_session_id,publicKeyCredential:I.encodeAuthenticationResult(r),userAgent:navigator.userAgent}}}class E{constructor(){this._initialized=!1,this._authenticationHandler=new P,this._registrationHandler=new K,this._approvalHandler=new B,this._crossDeviceHandler=new x(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=E.StaticPublicKeyCredential)||void 0===t?void 0:t.isUserVerifyingPlatformAuthenticatorAvailable())}catch(t){return!1}},this.isAutofillSupported=async()=>{var t,e;return!(!(null===(t=E.StaticPublicKeyCredential)||void 0===t?void 0:t.isConditionalMediationAvailable)||!await(null===(e=E.StaticPublicKeyCredential)||void 0===e?void 0:e.isConditionalMediationAvailable()))}}async init(t){const{clientId:e,options:i}=t;try{if(!e)throw new u("Invalid clientId",{clientId:e});if(i.webauthnApiPaths){const t=_.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 u("Invalid custom paths",{customApiPaths:i.webauthnApiPaths})}_.init(e,i),this._initialized=!0}catch(t){throw A(t)?t:new u("Failed to initialize SDK")}}getDefaultPaths(){return this.initCheck(),_.getDefaultPaths()}getApiPaths(){return this.initCheck(),_.getApiPaths()}initCheck(){if(!this._initialized)throw new u}}E.StaticPublicKeyCredential=window.PublicKeyCredential;const N=new t("webauthn"),H=new E;N.events.on(N.events.MODULE_INITIALIZED,(()=>{var t;const e=N.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;H.init({clientId:i,options:r({},a)})}));const W={modal:async t=>(H.initCheck(),H.authenticate.modal(t)),autofill:{activate:t=>{H.initCheck(),H.authenticate.autofill.activate(t)},abort:()=>{H.initCheck(),H.authenticate.autofill.abort()}}},q={modal:async t=>(H.initCheck(),H.approve.modal(t))};async function F(t){return H.initCheck(),H.register(t)}const{crossDevice:M}=H,{isPlatformAuthenticatorSupported:z}=H,{isAutofillSupported:J}=H,{getDefaultPaths:$}=H;window.localWebAuthnSDK=H;var U=Object.freeze({__proto__:null,get WebauthnCrossDeviceStatus(){return exports.WebauthnCrossDeviceStatus},approve:q,authenticate:W,crossDevice:M,getDefaultPaths:$,isAutofillSupported:J,isPlatformAuthenticatorSupported:z,register:F});const V={initialize:e.initialize,...U};Object.defineProperty(exports,"initialize",{enumerable:!0,get:function(){return e.initialize}}),exports.PACKAGE_VERSION="2.3.1",exports.approve=q,exports.authenticate=W,exports.crossDevice=M,exports.getDefaultPaths=$,exports.isAutofillSupported=J,exports.isPlatformAuthenticatorSupported=z,exports.register=F,exports.webauthn=V;
|
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));import t from"./common.js";import{initialize as e}from"./common.js";export{initialize}from"./common.js";function i(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 a(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 n(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?a(Object(n),!0).forEach((function(e){i(t,e,n[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))}))}return t}class r{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 s,c;!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"}(s||(s={}));class l extends Error{constructor(t,e){super(t),this.errorCode=s.NotInitialized,this.data=e}}class u extends l{constructor(t,e){super(null!=t?t:"WebAuthnSdk is not initialized",e),this.errorCode=s.NotInitialized}}class d extends l{constructor(t,e){super(null!=t?t:"Authentication failed with an error",e),this.errorCode=s.AuthenticationFailed}}class h extends l{constructor(t,e){super(null!=t?t:"Authentication was canceled by the user or got timeout",e),this.errorCode=s.AuthenticationCanceled}}class p extends l{constructor(t,e){super(null!=t?t:"Registration failed with an error",e),this.errorCode=s.RegistrationFailed}}class v extends l{constructor(t,e){super(null!=t?t:"Registration was canceled by the user or got timeout",e),this.errorCode=s.RegistrationCanceled}}class g extends l{constructor(t){super(null!=t?t:"Autofill flow was aborted"),this.errorCode=s.AutofillAuthenticationAborted}}class m extends l{constructor(t){super(null!=t?t:"Operation was aborted by timeout"),this.errorCode=s.AutofillAuthenticationAborted}}class f extends l{constructor(t){super(null!=t?t:"Passkey with this username is already registered with the relying party."),this.errorCode=s.AlreadyRegistered}}class w extends l{constructor(t,e){super(null!=t?t:"Authentication process is already active",e),this.errorCode=s.AuthenticationProcessAlreadyActive}}class y extends l{constructor(t,e){super(null!=t?t:"Invalid approval data",e),this.errorCode=s.InvalidApprovalData}}class b extends l{constructor(t,e){super(null!=t?t:"Failed to init cross device authentication",e),this.errorCode=s.FailedToInitCrossDeviceSession}}class A extends l{constructor(t,e){super(null!=t?t:"Failed to get cross device status",e),this.errorCode=s.FailedToGetCrossDeviceStatus}}function C(t){return t.errorCode&&Object.values(s).includes(t.errorCode)}!function(t){t[t.persistent=0]="persistent",t[t.session=1]="session"}(c||(c={}));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===c.session?sessionStorage:localStorage}}_.allowedKeys={clientId:c.session},_.configurationKeys=["clientId"];class D{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 u("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(n(n({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 d("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(n(n(n(n(n({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 d("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(n(n({client_id:this.getValidatedClientId()},t.username&&{username:t.username}),t.approvalData&&{approval_data:t.approvalData}))});if(!(null==e?void 0:e.ok))throw new b(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 d("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 p("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 p("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 u("Missing clientId");return e}}var S,T,k,I;D.newApiDomains=["api.idsec-dev.com","api.idsec-stg.com"],function(t){t.InputAutofill="input-autofill",t.Modal="modal"}(S||(S={})),function(t){t.Pending="pending",t.Scanned="scanned",t.Success="success",t.Error="error",t.Timeout="timeout",t.Aborted="aborted"}(T||(T={})),function(t){t.toAuthenticationError=t=>C(t)?t:"NotAllowedError"===t.name?new h:"OperationError"===t.name?new w(t.message):"SecurityError"===t.name?new d(t.message):t===s.AuthenticationAbortedTimeout?new m:"AbortError"===t.name||t===s.AutofillAuthenticationAborted?new g:new d("Something went wrong during authentication",{error:t}),t.toRegistrationError=t=>C(t)?t:"NotAllowedError"===t.name?new v:"SecurityError"===t.name?new p(t.message):"InvalidStateError"===t.name?new f:t===s.RegistrationAbortedTimeout?new m:new p("Something went wrong during registration",{error:t})}(k||(k={})),function(t){t.processCredentialRequestOptions=t=>n(n({},t),{},{challenge:r.base64ToArrayBuffer(t.challenge),allowCredentials:t.allowCredentials.map((t=>n(n({},t),{},{id:r.base64ToArrayBuffer(t.id)})))}),t.processCredentialCreationOptions=(t,e)=>{var i;const a=JSON.parse(JSON.stringify(t));return a.challenge=r.base64ToArrayBuffer(t.challenge),a.user.id=r.base64ToArrayBuffer(t.user.id),(null==e?void 0:e.limitSingleCredentialToDevice)&&(a.excludeCredentials=null===(i=t.excludeCredentials)||void 0===i?void 0:i.map((t=>n(n({},t),{},{id:r.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:r.arrayBufferToBase64(t.rawId),response:{authenticatorData:r.arrayBufferToBase64(i.authenticatorData),clientDataJSON:r.arrayBufferToBase64(i.clientDataJSON),signature:r.arrayBufferToBase64(i.signature),userHandle:r.arrayBufferToBase64(i.userHandle)},authenticatorAttachment:e,type:t.type}},t.encodeRegistrationResult=t=>{const{authenticatorAttachment:e}=t,i=t.response;return{id:t.id,rawId:r.arrayBufferToBase64(t.rawId),response:{attestationObject:r.arrayBufferToBase64(i.attestationObject),clientDataJSON:r.arrayBufferToBase64(i.clientDataJSON)},authenticatorAttachment:e,type:t.type}}}(I||(I={}));class P{async modal(t){try{const e=await this.performAuthentication(n(n({},t),{},{mediationType:S.Modal}));return r.jsonToBase64(e)}catch(t){throw k.toAuthenticationError(t)}}activateAutofill(t){const{handlers:e,username:i}=t,{onSuccess:a,onError:n,onReady:o}=e;this.performAuthentication({username:i,mediationType:S.InputAutofill,onReady:o}).then((t=>{a(r.jsonToBase64(t))})).catch((t=>{const e=k.toAuthenticationError(t);if(!n)throw e;n(e)}))}abortAutofill(){this.abortController&&this.abortController.abort(s.AutofillAuthenticationAborted)}abortAuthentication(){this.abortController&&this.abortController.abort(s.AuthenticationAbortedTimeout)}async performAuthentication(t){var e,i;const a="crossDeviceTicketId"in t?await D.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await D.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=I.processCredentialRequestOptions(n),o=this.getMediatedCredentialRequest(r,t.mediationType);t.mediationType===S.InputAutofill&&(null===(i=t.onReady)||void 0===i||i.call(t));const s=await navigator.credentials.get(o).catch((t=>{throw k.toAuthenticationError(t)}));return{webauthnSessionId:a.webauthn_session_id,publicKeyCredential:I.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===S.InputAutofill?i.mediation="conditional":t.timeout&&setTimeout((()=>{this.abortAuthentication()}),t.timeout),i}}class O{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 R=/^[A-Za-z0-9\-_.: ]*$/;function j(t){if(t&&(!function(t){return Object.keys(t).length<=10}(t)||!function(t){const e=t=>"string"==typeof t,i=t=>R.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 y("Provided approval data should have 10 properties max. Also, it should contain only \n alphanumeric characters, numbers, and the special characters: '-', '_', '.'")}class B{constructor(t,e,i){this.authenticationHandler=t,this.registrationHandler=e,this.approvalHandler=i,this.init={registration:async t=>(this.ticketStatus=T.Pending,this.pollCrossDeviceSession(t.crossDeviceTicketId,t.handlers)),authentication:async t=>{const{username:e}=t,i=(await D.initCrossDeviceAuthentication(n({},e&&{username:e}))).cross_device_ticket_id;return this.ticketStatus=T.Pending,this.pollCrossDeviceSession(i,t.handlers)},approval:async t=>{const{username:e,approvalData:i}=t;j(i);const a=(await D.initCrossDeviceAuthentication({username:e,approvalData:i})).cross_device_ticket_id;return this.ticketStatus=T.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 D.attachDeviceToCrossDeviceSession({ticketId:t});return n({status:e.status,startedAt:e.started_at},e.approval_data&&{approvalData:e.approval_data})}async pollCrossDeviceSession(t,e){return this.poller=new O((async()=>{var i,a;const n=await D.getCrossDeviceTicketStatus({ticketId:t}),r=n.status;if(r!==this.ticketStatus)switch(this.ticketStatus=r,r){case T.Scanned:await e.onDeviceAttach();break;case T.Error:case T.Timeout:case T.Aborted:await e.onFailure(n),null===(i=this.poller)||void 0===i||i.stop();break;case T.Success:if("onCredentialRegister"in e)await e.onCredentialRegister();else{if(!n.session_id)throw new A("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:T.Timeout})}),3e5),{crossDeviceTicketId:t,stop:()=>{var t;null===(t=this.poller)||void 0===t||t.stop()}}}}class K{async register(t){var e,i,a;this.abortController=new AbortController;const o=n({allowCrossPlatformAuthenticators:!("crossDeviceTicketId"in t),registerAsDiscoverable:!0},t.options);try{const n="crossDeviceTicketId"in t?await D.startCrossDeviceRegistration({ticketId:t.crossDeviceTicketId}):await D.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===(a=t.options)||void 0===a?void 0:a.limitSingleCredentialToDevice}),s=I.processCredentialCreationOptions(n.credential_creation_options,o);setTimeout((()=>{this.abortRegistration()}),s.timeout);const c=await this.registerCredential(s),l={webauthnSessionId:n.webauthn_session_id,publicKeyCredential:c,userAgent:navigator.userAgent};return r.jsonToBase64(l)}catch(t){throw k.toRegistrationError(t)}}abortRegistration(){this.abortController&&this.abortController.abort(s.RegistrationAbortedTimeout)}async registerCredential(t){const e=await navigator.credentials.create({publicKey:t,signal:this.abortController&&this.abortController.signal}).catch((t=>{throw k.toRegistrationError(t)}));return I.encodeRegistrationResult(e)}}class E{async modal(t){try{const e=await this.performApproval(t);return r.jsonToBase64(e)}catch(t){throw k.toAuthenticationError(t)}}async performApproval(t){"approvalData"in t&&j(t.approvalData);const e="crossDeviceTicketId"in t?await D.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await D.startAuthentication({username:t.username,approvalData:t.approvalData}),i=e.credential_request_options,a=I.processCredentialRequestOptions(i),n=await navigator.credentials.get({publicKey:a}).catch((t=>{throw k.toAuthenticationError(t)}));return{webauthnSessionId:e.webauthn_session_id,publicKeyCredential:I.encodeAuthenticationResult(n),userAgent:navigator.userAgent}}}class H{constructor(){this._initialized=!1,this._authenticationHandler=new P,this._registrationHandler=new K,this._approvalHandler=new E,this._crossDeviceHandler=new B(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=H.StaticPublicKeyCredential)||void 0===t?void 0:t.isUserVerifyingPlatformAuthenticatorAvailable())}catch(t){return!1}},this.isAutofillSupported=async()=>{var t,e;return!(!(null===(t=H.StaticPublicKeyCredential)||void 0===t?void 0:t.isConditionalMediationAvailable)||!await(null===(e=H.StaticPublicKeyCredential)||void 0===e?void 0:e.isConditionalMediationAvailable()))}}async init(t){const{clientId:e,options:i}=t;try{if(!e)throw new u("Invalid clientId",{clientId:e});if(i.webauthnApiPaths){const t=D.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 u("Invalid custom paths",{customApiPaths:i.webauthnApiPaths})}D.init(e,i),this._initialized=!0}catch(t){throw C(t)?t:new u("Failed to initialize SDK")}}getDefaultPaths(){return this.initCheck(),D.getDefaultPaths()}getApiPaths(){return this.initCheck(),D.getApiPaths()}initCheck(){if(!this._initialized)throw new u}}H.StaticPublicKeyCredential=window.PublicKeyCredential;const N=new t("webauthn"),F=new H;N.events.on(N.events.MODULE_INITIALIZED,(()=>{var t;const e=N.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;F.init({clientId:i,options:n({},a)})}));const x={modal:async t=>(F.initCheck(),F.authenticate.modal(t)),autofill:{activate:t=>{F.initCheck(),F.authenticate.autofill.activate(t)},abort:()=>{F.initCheck(),F.authenticate.autofill.abort()}}},q={modal:async t=>(F.initCheck(),F.approve.modal(t))};async function M(t){return F.initCheck(),F.register(t)}const{crossDevice:J}=F,{isPlatformAuthenticatorSupported:z}=F,{isAutofillSupported:$}=F,{getDefaultPaths:U}=F;window.localWebAuthnSDK=F;const W="2.3.0",V={initialize:e,...Object.freeze({__proto__:null,get WebauthnCrossDeviceStatus(){return T},approve:q,authenticate:x,crossDevice:J,getDefaultPaths:U,isAutofillSupported:$,isPlatformAuthenticatorSupported:z,register:M})};export{W as PACKAGE_VERSION,T as WebauthnCrossDeviceStatus,q as approve,x as authenticate,J as crossDevice,U as getDefaultPaths,$ as isAutofillSupported,z as isPlatformAuthenticatorSupported,M as register,V 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,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 a(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 n(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?a(Object(n),!0).forEach((function(e){i(t,e,n[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))}))}return t}class r{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 o,c;!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"}(o||(o={}));class l extends Error{constructor(t,e){super(t),this.errorCode=o.NotInitialized,this.data=e}}class d extends l{constructor(t,e){super(null!=t?t:"WebAuthnSdk is not initialized",e),this.errorCode=o.NotInitialized}}class u extends l{constructor(t,e){super(null!=t?t:"Authentication failed with an error",e),this.errorCode=o.AuthenticationFailed}}class h extends l{constructor(t,e){super(null!=t?t:"Authentication was canceled by the user or got timeout",e),this.errorCode=o.AuthenticationCanceled}}class p extends l{constructor(t,e){super(null!=t?t:"Registration failed with an error",e),this.errorCode=o.RegistrationFailed}}class v extends l{constructor(t,e){super(null!=t?t:"Registration was canceled by the user or got timeout",e),this.errorCode=o.RegistrationCanceled}}class g extends l{constructor(t){super(null!=t?t:"Autofill flow was aborted"),this.errorCode=o.AutofillAuthenticationAborted}}class m extends l{constructor(t){super(null!=t?t:"Operation was aborted by timeout"),this.errorCode=o.AutofillAuthenticationAborted}}class f extends l{constructor(t){super(null!=t?t:"Passkey with this username is already registered with the relying party."),this.errorCode=o.AlreadyRegistered}}class w extends l{constructor(t,e){super(null!=t?t:"Authentication process is already active",e),this.errorCode=o.AuthenticationProcessAlreadyActive}}class y extends l{constructor(t,e){super(null!=t?t:"Invalid approval data",e),this.errorCode=o.InvalidApprovalData}}class b extends l{constructor(t,e){super(null!=t?t:"Failed to init cross device authentication",e),this.errorCode=o.FailedToInitCrossDeviceSession}}class A extends l{constructor(t,e){super(null!=t?t:"Failed to get cross device status",e),this.errorCode=o.FailedToGetCrossDeviceStatus}}function C(t){return t.errorCode&&Object.values(o).includes(t.errorCode)}!function(t){t[t.persistent=0]="persistent",t[t.session=1]="session"}(c||(c={}));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===c.session?sessionStorage:localStorage}}_.allowedKeys={clientId:c.session},_.configurationKeys=["clientId"];class D{static isNewApiDomain(t){return t&&(this.newApiDomains.includes(t)||t.startsWith("api.")&&t.endsWith(".transmitsecurity.io")||t.startsWith("api.")&&t.endsWith(".idsec-dev.com"))}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){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(n(n({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 u("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(n(n(n(n(n({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 u("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(n(n({client_id:this.getValidatedClientId()},t.username&&{username:t.username}),t.approvalData&&{approval_data:t.approvalData}))});if(!(null==e?void 0:e.ok))throw new b(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 u("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 p("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 p("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 S,T,k,I;D.newApiDomains=["api.idsec-dev.com","api.idsec-stg.com"],function(t){t.InputAutofill="input-autofill",t.Modal="modal"}(S||(S={})),function(t){t.Pending="pending",t.Scanned="scanned",t.Success="success",t.Error="error",t.Timeout="timeout",t.Aborted="aborted"}(T||(T={})),function(t){t.toAuthenticationError=t=>C(t)?t:"NotAllowedError"===t.name?new h:"OperationError"===t.name?new w(t.message):"SecurityError"===t.name?new u(t.message):t===o.AuthenticationAbortedTimeout?new m:"AbortError"===t.name||t===o.AutofillAuthenticationAborted?new g:new u("Something went wrong during authentication",{error:t}),t.toRegistrationError=t=>C(t)?t:"NotAllowedError"===t.name?new v:"SecurityError"===t.name?new p(t.message):"InvalidStateError"===t.name?new f:t===o.RegistrationAbortedTimeout?new m:new p("Something went wrong during registration",{error:t})}(k||(k={})),function(t){t.processCredentialRequestOptions=t=>n(n({},t),{},{challenge:r.base64ToArrayBuffer(t.challenge),allowCredentials:t.allowCredentials.map((t=>n(n({},t),{},{id:r.base64ToArrayBuffer(t.id)})))}),t.processCredentialCreationOptions=(t,e)=>{var i;const a=JSON.parse(JSON.stringify(t));return a.challenge=r.base64ToArrayBuffer(t.challenge),a.user.id=r.base64ToArrayBuffer(t.user.id),(null==e?void 0:e.limitSingleCredentialToDevice)&&(a.excludeCredentials=null===(i=t.excludeCredentials)||void 0===i?void 0:i.map((t=>n(n({},t),{},{id:r.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:r.arrayBufferToBase64(t.rawId),response:{authenticatorData:r.arrayBufferToBase64(i.authenticatorData),clientDataJSON:r.arrayBufferToBase64(i.clientDataJSON),signature:r.arrayBufferToBase64(i.signature),userHandle:r.arrayBufferToBase64(i.userHandle)},authenticatorAttachment:e,type:t.type}},t.encodeRegistrationResult=t=>{const{authenticatorAttachment:e}=t,i=t.response;return{id:t.id,rawId:r.arrayBufferToBase64(t.rawId),response:{attestationObject:r.arrayBufferToBase64(i.attestationObject),clientDataJSON:r.arrayBufferToBase64(i.clientDataJSON)},authenticatorAttachment:e,type:t.type}}}(I||(I={}));class P{async modal(t){try{const e=await this.performAuthentication(n(n({},t),{},{mediationType:S.Modal}));return r.jsonToBase64(e)}catch(t){throw k.toAuthenticationError(t)}}activateAutofill(t){const{handlers:e,username:i}=t,{onSuccess:a,onError:n,onReady:s}=e;this.performAuthentication({username:i,mediationType:S.InputAutofill,onReady:s}).then((t=>{a(r.jsonToBase64(t))})).catch((t=>{const e=k.toAuthenticationError(t);if(!n)throw e;n(e)}))}abortAutofill(){this.abortController&&this.abortController.abort(o.AutofillAuthenticationAborted)}abortAuthentication(){this.abortController&&this.abortController.abort(o.AuthenticationAbortedTimeout)}async performAuthentication(t){var e,i;const a="crossDeviceTicketId"in t?await D.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await D.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=I.processCredentialRequestOptions(n),s=this.getMediatedCredentialRequest(r,t.mediationType);t.mediationType===S.InputAutofill&&(null===(i=t.onReady)||void 0===i||i.call(t));const o=await navigator.credentials.get(s).catch((t=>{throw k.toAuthenticationError(t)}));return{webauthnSessionId:a.webauthn_session_id,publicKeyCredential:I.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===S.InputAutofill?i.mediation="conditional":t.timeout&&setTimeout((()=>{this.abortAuthentication()}),t.timeout),i}}class O{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 R=/^[A-Za-z0-9\-_.: ]*$/;function j(t){if(t&&(!function(t){return Object.keys(t).length<=10}(t)||!function(t){const e=t=>"string"==typeof t,i=t=>R.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 y("Provided approval data should have 10 properties max. Also, it should contain only \n alphanumeric characters, numbers, and the special characters: '-', '_', '.'")}class B{constructor(t,e,i){this.authenticationHandler=t,this.registrationHandler=e,this.approvalHandler=i,this.init={registration:async t=>(this.ticketStatus=T.Pending,this.pollCrossDeviceSession(t.crossDeviceTicketId,t.handlers)),authentication:async t=>{const{username:e}=t,i=(await D.initCrossDeviceAuthentication(n({},e&&{username:e}))).cross_device_ticket_id;return this.ticketStatus=T.Pending,this.pollCrossDeviceSession(i,t.handlers)},approval:async t=>{const{username:e,approvalData:i}=t;j(i);const a=(await D.initCrossDeviceAuthentication({username:e,approvalData:i})).cross_device_ticket_id;return this.ticketStatus=T.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 D.attachDeviceToCrossDeviceSession({ticketId:t});return n({status:e.status,startedAt:e.started_at},e.approval_data&&{approvalData:e.approval_data})}async pollCrossDeviceSession(t,e){return this.poller=new O((async()=>{var i,a;const n=await D.getCrossDeviceTicketStatus({ticketId:t}),r=n.status;if(r!==this.ticketStatus)switch(this.ticketStatus=r,r){case T.Scanned:await e.onDeviceAttach();break;case T.Error:case T.Timeout:case T.Aborted:await e.onFailure(n),null===(i=this.poller)||void 0===i||i.stop();break;case T.Success:if("onCredentialRegister"in e)await e.onCredentialRegister();else{if(!n.session_id)throw new A("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:T.Timeout})}),3e5),{crossDeviceTicketId:t,stop:()=>{var t;null===(t=this.poller)||void 0===t||t.stop()}}}}class K{async register(t){var e,i,a;this.abortController=new AbortController;const s=n({allowCrossPlatformAuthenticators:!("crossDeviceTicketId"in t),registerAsDiscoverable:!0},t.options);try{const n="crossDeviceTicketId"in t?await D.startCrossDeviceRegistration({ticketId:t.crossDeviceTicketId}):await D.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===(a=t.options)||void 0===a?void 0:a.limitSingleCredentialToDevice}),o=I.processCredentialCreationOptions(n.credential_creation_options,s);setTimeout((()=>{this.abortRegistration()}),o.timeout);const c=await this.registerCredential(o),l={webauthnSessionId:n.webauthn_session_id,publicKeyCredential:c,userAgent:navigator.userAgent};return r.jsonToBase64(l)}catch(t){throw k.toRegistrationError(t)}}abortRegistration(){this.abortController&&this.abortController.abort(o.RegistrationAbortedTimeout)}async registerCredential(t){const e=await navigator.credentials.create({publicKey:t,signal:this.abortController&&this.abortController.signal}).catch((t=>{throw k.toRegistrationError(t)}));return I.encodeRegistrationResult(e)}}class E{async modal(t){try{const e=await this.performApproval(t);return r.jsonToBase64(e)}catch(t){throw k.toAuthenticationError(t)}}async performApproval(t){"approvalData"in t&&j(t.approvalData);const e="crossDeviceTicketId"in t?await D.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await D.startAuthentication({username:t.username,approvalData:t.approvalData}),i=e.credential_request_options,a=I.processCredentialRequestOptions(i),n=await navigator.credentials.get({publicKey:a}).catch((t=>{throw k.toAuthenticationError(t)}));return{webauthnSessionId:e.webauthn_session_id,publicKeyCredential:I.encodeAuthenticationResult(n),userAgent:navigator.userAgent}}}class H{constructor(){this._initialized=!1,this._authenticationHandler=new P,this._registrationHandler=new K,this._approvalHandler=new E,this._crossDeviceHandler=new B(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=H.StaticPublicKeyCredential)||void 0===t?void 0:t.isUserVerifyingPlatformAuthenticatorAvailable())}catch(t){return!1}},this.isAutofillSupported=async()=>{var t,e;return!(!(null===(t=H.StaticPublicKeyCredential)||void 0===t?void 0:t.isConditionalMediationAvailable)||!await(null===(e=H.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=D.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})}D.init(e,i),this._initialized=!0}catch(t){throw C(t)?t:new d("Failed to initialize SDK")}}getDefaultPaths(){return this.initCheck(),D.getDefaultPaths()}getApiPaths(){return this.initCheck(),D.getApiPaths()}initCheck(){if(!this._initialized)throw new d}}H.StaticPublicKeyCredential=window.PublicKeyCredential;const N=new t("webauthn"),F=new H;N.events.on(N.events.MODULE_INITIALIZED,(()=>{var t;const e=N.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;F.init({clientId:i,options:n({},a)})}));const x={modal:async t=>(F.initCheck(),F.authenticate.modal(t)),autofill:{activate:t=>{F.initCheck(),F.authenticate.autofill.activate(t)},abort:()=>{F.initCheck(),F.authenticate.autofill.abort()}}},q={modal:async t=>(F.initCheck(),F.approve.modal(t))};async function M(t){return F.initCheck(),F.register(t)}const{crossDevice:J}=F,{isPlatformAuthenticatorSupported:z}=F,{isAutofillSupported:$}=F,{getDefaultPaths:W}=F;window.localWebAuthnSDK=F;const U="2.3.1",V={initialize:e,...Object.freeze({__proto__:null,get WebauthnCrossDeviceStatus(){return T},approve:q,authenticate:x,crossDevice:J,getDefaultPaths:W,isAutofillSupported:$,isPlatformAuthenticatorSupported:z,register:M})};export{U as PACKAGE_VERSION,T as WebauthnCrossDeviceStatus,q as approve,x as authenticate,J as crossDevice,W as getDefaultPaths,$ as isAutofillSupported,z as isPlatformAuthenticatorSupported,M as register,V as webauthn};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@transmitsecurity/platform-web-sdk",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -94,5 +94,5 @@
|
|
|
94
94
|
"identity"
|
|
95
95
|
],
|
|
96
96
|
"description": "Transmit Security Web SDK - Browser-only authentication and identity verification",
|
|
97
|
-
"packageManager": "yarn@1.22.22+
|
|
97
|
+
"packageManager": "yarn@1.22.22+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610"
|
|
98
98
|
}
|