@transmitsecurity/platform-web-sdk 2.0.0 → 2.0.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/dist/web-sdk.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  type AgentCreate<T> = T extends new (...any: any) => Agent ? InstanceType<T> : T extends Function ? OmitThisParameter<T> : T extends {} ? BoundMethods<T> : T;
2
3
  type BoundMethods<T> = {
3
4
  [key in keyof T]: OmitThisParameter<AgentCreate<T[key]>>;
@@ -41,6 +42,25 @@ declare namespace events {
41
42
 
42
43
  interface initConfigParams {
43
44
  clientId: string;
45
+ drs?: {
46
+ enabled?: boolean;
47
+ serverPath?: string;
48
+ enableSessionToken?: boolean;
49
+ [key: string]: any;
50
+ };
51
+ webauthn?: {
52
+ serverPath?: string;
53
+ [key: string]: any;
54
+ };
55
+ idv?: {
56
+ serverPath?: string;
57
+ [key: string]: any;
58
+ };
59
+ ido?: {
60
+ serverPath?: string;
61
+ [key: string]: any;
62
+ };
63
+ [key: string]: any;
44
64
  }
45
65
  declare let initConfig: initConfigParams | null;
46
66
  declare function getInitConfig(): initConfigParams | null;
@@ -61,11 +81,9 @@ declare namespace moduleMetadata {
61
81
 
62
82
  declare function initialize(params: initConfigParams): void;
63
83
 
64
- type mainEntry_initConfigParams = initConfigParams;
65
84
  declare const mainEntry_initialize: typeof initialize;
66
85
  declare namespace mainEntry {
67
86
  export {
68
- mainEntry_initConfigParams as initConfigParams,
69
87
  mainEntry_initialize as initialize,
70
88
  };
71
89
  }
@@ -115,7 +133,7 @@ declare const COMPLETED_ROTATION_RESPONSE = "completed";
115
133
  type CryptoBindingPublicData = {
116
134
  publicKey: string;
117
135
  keyIdentifier: string;
118
- currentKeyId: string;
136
+ publicKeyId: string;
119
137
  };
120
138
  type CryptoBindingRotationPayload = {
121
139
  data: string;
@@ -160,7 +178,7 @@ declare class CryptoBinding {
160
178
  private dbVersion;
161
179
  private publicKeyBase64;
162
180
  private keyIdentifier;
163
- private currentKeyId;
181
+ private publicKeyId;
164
182
  private _extractingKeysPromise;
165
183
  constructor(agent: Agent, keysType?: 'encrypt' | 'sign', options?: CryptoBindingOptions);
166
184
  private getClientConfiguration;
@@ -399,27 +417,35 @@ type EventResponse = {
399
417
  type Recommendation = {
400
418
  type: RecommendationType;
401
419
  };
402
- type LightweightPayload = {
403
- clientId: string;
404
- deviceId: string;
405
- userId: string | null;
406
- sdkPlatform: 'mobile_web' | 'desktop_web';
407
- events: Array<Record<string, unknown>>;
408
- };
409
420
 
410
421
  interface ActionResponse {
422
+ /** The token return by the SDK when the action was reported */
411
423
  actionToken?: string;
412
424
  }
413
425
  interface InitOptions {
426
+ /** Opaque identifier of the user in your system */
414
427
  userId?: string;
415
428
  }
429
+ /**
430
+ * Initial parameters for SDK
431
+ */
416
432
  interface ConstructorOptions {
433
+ /** Print logs to console */
417
434
  verbose?: boolean;
435
+ /** Your server URL
436
+ * @required */
418
437
  serverPath: string;
438
+ /** Enable session token fetching
439
+ *
440
+ * Default value is false */
419
441
  enableSessionToken?: boolean;
442
+ /** First party server url for the identifiers migration
443
+ *
444
+ * Default value is undefined */
420
445
  firstPartyMigrationUrl?: string;
446
+ /** @internal
447
+ * Internal flag indicating this web_sdk instance has its own clientId separate from the Platform SDK root-level clientId */
421
448
  hasOwnClientId?: boolean;
422
- tier?: 'standard' | 'lightweight';
423
449
  }
424
450
  interface TransactionData {
425
451
  amount: number;
@@ -440,12 +466,27 @@ interface TransactionData {
440
466
  };
441
467
  }
442
468
  interface ActionEventOptions {
469
+ /** Any ID that could help relate the action with external context or session */
443
470
  correlationId?: string;
471
+ /** User ID of the not yet authenticated user, used to enhance risk and
472
+ * trust assessments. Once the user is authenticated,
473
+ * {@link TSAccountProtection.setAuthenticatedUser} should be called. */
444
474
  claimedUserId?: string;
475
+ /**
476
+ * The reported claimedUserId type (if provided), should not contain PII unless it is hashed.
477
+ * Supported values: email, phone_number, account_id, ssn, national_id, passport_number, drivers_license_number, other.
478
+ */
445
479
  claimedUserIdType?: string;
480
+ /**
481
+ * A transaction data-points object for transaction-monitoring
482
+ */
446
483
  transactionData?: TransactionData;
484
+ /**
485
+ * Custom attributes matching the schema previously defined in the Admin Portal
486
+ */
447
487
  customAttributes?: Record<string, string | number | boolean>;
448
488
  /**
489
+ * The fields below are supported for Enterprise-IAM sdk usage actions, added `ignore` for avoiding preseting this attribute in the docs
449
490
  * @ignore
450
491
  */
451
492
  publicKey?: string;
@@ -482,7 +523,6 @@ declare class TSAccountProtection {
482
523
  private identifiersMigrationEnabled;
483
524
  private firstPartyMigrationUrl;
484
525
  private hasOwnClientId;
485
- private tier;
486
526
  private validationManager;
487
527
  private storageManager;
488
528
  private eventsManager;
@@ -495,33 +535,58 @@ declare class TSAccountProtection {
495
535
  private logsReporter;
496
536
  private options;
497
537
  private clientId;
538
+ /**
539
+ *
540
+ Creates a new Account Protection SDK instance with your client context
541
+ @param clientId Your AccountProtection client identifier
542
+ @param options SDK configuration options
543
+ */
498
544
  constructor(clientId: string, options: ConstructorOptions);
499
545
  /** @ignore */
500
546
  constructor(serverPath: string, clientId: string);
501
547
  private generateDisabledToken;
502
548
  /**
503
549
  * @ignore
550
+ * @returns List of loaded actions that can be invoked
504
551
  */
505
552
  get actions(): string[];
506
553
  /** @ignore */
507
554
  getActions(): Promise<string[]>;
508
555
  getSessionToken(): Promise<any>;
509
- getPayload(): Promise<LightweightPayload>;
510
- clearQueue(): void;
556
+ /**
557
+ * Initializes the AccountProtection SDK, which starts automatically tracking and submitting info of the user journey
558
+ * @param options Init options
559
+ * @returns Indicates if the call succeeded
560
+ */
511
561
  init(options?: InitOptions | string): Promise<boolean>;
512
562
  private isInitialized;
513
- triggerActionEvent(actionType: string, options?: ActionEventOptions): Promise<ActionResponse>;
514
563
  /**
515
- * @ignore
564
+ * Reports a user action event to the SDK
565
+ * @param actionType Type of user action event that was predefined in the Transmit Security server
566
+ * @returns Indicates if the call succeeded
516
567
  */
517
- identifyUser(userId: string): Promise<boolean>;
568
+ triggerActionEvent(actionType: string, options?: ActionEventOptions): Promise<ActionResponse>;
518
569
  private updateUserId;
570
+ /**
571
+ * Sets the user context for all subsequent events in the browser session (or until the user is explicitly cleared)
572
+ * It should be set only after you've fully authenticated the user (including, for example, any 2FA that was required)
573
+ * @param userId Opaque identifier of the user in your system
574
+ * @param options Reserved for future use
575
+ * @returns Indicates if the call succeeded
576
+ */
519
577
  setAuthenticatedUser(userId: string, options?: {}): Promise<boolean>;
578
+ /**
579
+ * Clears the user context for all subsequent events in the browser session
580
+ * @param options Reserved for future use
581
+ * @returns Indicates if the call succeeded
582
+ */
520
583
  clearUser(options?: {}): Promise<boolean>;
521
584
  /**
522
- * @ignore
585
+ * Gets a secure session token that is signed with the device's private key
586
+ * @param actionType Optional action type to include in the token payload (default: null)
587
+ * @param expirationSeconds Optional expiration time in seconds (default: 300 seconds / 5 minutes)
588
+ * @returns A JWT-like token containing the backend session token and device information, signed with the device's private key
523
589
  */
524
- unidentifiedUser(): Promise<boolean>;
525
590
  getSecureSessionToken(actionType?: string | null, expirationSeconds?: number): Promise<string>;
526
591
  }
527
592
 
@@ -566,8 +631,6 @@ declare const getSessionToken: TSAccountProtection['getSessionToken'];
566
631
  */
567
632
  declare const getSecureSessionToken: TSAccountProtection['getSecureSessionToken'];
568
633
  /** @ignore */
569
- declare const getPayload: TSAccountProtection['getPayload'];
570
- /** @ignore */
571
634
  declare const __internal: {
572
635
  getDeviceId(): string;
573
636
  getClientId(): string;
@@ -576,11 +639,9 @@ declare const __internal: {
576
639
 
577
640
  type webSdkModule_d_ActionEventOptions = ActionEventOptions;
578
641
  type webSdkModule_d_ActionResponse = ActionResponse;
579
- type webSdkModule_d_LightweightPayload = LightweightPayload;
580
642
  declare const webSdkModule_d___internal: typeof __internal;
581
643
  declare const webSdkModule_d_clearUser: typeof clearUser;
582
644
  declare const webSdkModule_d_getActions: typeof getActions;
583
- declare const webSdkModule_d_getPayload: typeof getPayload;
584
645
  declare const webSdkModule_d_getSecureSessionToken: typeof getSecureSessionToken;
585
646
  declare const webSdkModule_d_getSessionToken: typeof getSessionToken;
586
647
  declare const webSdkModule_d_setAuthenticatedUser: typeof setAuthenticatedUser;
@@ -589,11 +650,9 @@ declare namespace webSdkModule_d {
589
650
  export {
590
651
  webSdkModule_d_ActionEventOptions as ActionEventOptions,
591
652
  webSdkModule_d_ActionResponse as ActionResponse,
592
- webSdkModule_d_LightweightPayload as LightweightPayload,
593
653
  webSdkModule_d___internal as __internal,
594
654
  webSdkModule_d_clearUser as clearUser,
595
655
  webSdkModule_d_getActions as getActions,
596
- webSdkModule_d_getPayload as getPayload,
597
656
  webSdkModule_d_getSecureSessionToken as getSecureSessionToken,
598
657
  webSdkModule_d_getSessionToken as getSessionToken,
599
658
  webSdkModule_d_setAuthenticatedUser as setAuthenticatedUser,
@@ -2216,6 +2275,6 @@ declare class TSWebSDK {
2216
2275
  }
2217
2276
  declare const _default: TSWebSDK;
2218
2277
 
2219
- declare const PACKAGE_VERSION = "2.0.0";
2278
+ declare const PACKAGE_VERSION = "2.0.1";
2220
2279
 
2221
2280
  export { ActionEventOptions, ActionResponse, AuthenticationAutofillActivateHandlers, AutofillHandlers, CrossDeviceController, ErrorCode$1 as ErrorCode, PACKAGE_VERSION, 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){var i=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);e&&(a=a.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),i.push.apply(i,a)}return i}function a(t){for(var e=1;e<arguments.length;e++){var a=null!=arguments[e]?arguments[e]:{};e%2?i(Object(a),!0).forEach((function(e){n(t,e,a[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(a,e))}))}return t}function r(t){var e=function(t,e){if("object"!=typeof t||!t)return t;var i=t[Symbol.toPrimitive];if(void 0!==i){var a=i.call(t,e||"default");if("object"!=typeof a)return a;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(t,"string");return"symbol"==typeof e?e:String(e)}function n(t,e,i){return(e=r(e))in t?Object.defineProperty(t,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):t[e]=i,t}class s{static arrayBufferToBase64(t){return btoa(String.fromCharCode(...new Uint8Array(t)))}static base64ToArrayBuffer(t){return Uint8Array.from(atob(t),(t=>t.charCodeAt(0)))}static stringToBase64(t){return btoa(t)}static jsonToBase64(t){const e=JSON.stringify(t);return btoa(e)}static base64ToJson(t){const e=atob(t);return JSON.parse(e)}}const o={log:console.log,error:console.error};var c,l;!function(t){t.NotInitialized="not_initialized",t.AuthenticationFailed="authentication_failed",t.AuthenticationAbortedTimeout="authentication_aborted_timeout",t.AuthenticationCanceled="webauthn_authentication_canceled",t.RegistrationFailed="registration_failed",t.AlreadyRegistered="username_already_registered",t.RegistrationAbortedTimeout="registration_aborted_timeout",t.RegistrationCanceled="webauthn_registration_canceled",t.AutofillAuthenticationAborted="autofill_authentication_aborted",t.AuthenticationProcessAlreadyActive="authentication_process_already_active",t.InvalidApprovalData="invalid_approval_data",t.FailedToInitCrossDeviceSession="cross_device_init_failed",t.FailedToGetCrossDeviceStatus="cross_device_status_failed",t.Unknown="unknown"}(c||(c={}));class u extends Error{constructor(t,e){super(t),this.errorCode=c.NotInitialized,this.data=e}}class d extends u{constructor(t,e){super(null!=t?t:"WebAuthnSdk is not initialized",e),this.errorCode=c.NotInitialized}}class h extends u{constructor(t,e){super(null!=t?t:"Authentication failed with an error",e),this.errorCode=c.AuthenticationFailed}}class p extends u{constructor(t,e){super(null!=t?t:"Authentication was canceled by the user or got timeout",e),this.errorCode=c.AuthenticationCanceled}}class v extends u{constructor(t,e){super(null!=t?t:"Registration failed with an error",e),this.errorCode=c.RegistrationFailed}}class g extends u{constructor(t,e){super(null!=t?t:"Registration was canceled by the user or got timeout",e),this.errorCode=c.RegistrationCanceled}}class f extends u{constructor(t){super(null!=t?t:"Autofill flow was aborted"),this.errorCode=c.AutofillAuthenticationAborted}}class w extends u{constructor(t){super(null!=t?t:"Operation was aborted by timeout"),this.errorCode=c.AutofillAuthenticationAborted}}class m extends u{constructor(t){super(null!=t?t:"Passkey with this username is already registered with the relying party."),this.errorCode=c.AlreadyRegistered}}class y extends u{constructor(t,e){super(null!=t?t:"Authentication process is already active",e),this.errorCode=c.AuthenticationProcessAlreadyActive}}class b extends u{constructor(t,e){super(null!=t?t:"Invalid approval data",e),this.errorCode=c.InvalidApprovalData}}class C extends u{constructor(t,e){super(null!=t?t:"Failed to init cross device authentication",e),this.errorCode=c.FailedToInitCrossDeviceSession}}class A extends u{constructor(t,e){super(null!=t?t:"Failed to get cross device status",e),this.errorCode=c.FailedToGetCrossDeviceStatus}}function D(t){return t.errorCode&&Object.values(c).includes(t.errorCode)}!function(t){t[t.persistent=0]="persistent",t[t.session=1]="session"}(l||(l={}));class _{static get(t){return _.getStorageMedium(_.allowedKeys[t]).getItem(_.getStorageKey(t))||void 0}static set(t,e){return _.getStorageMedium(_.allowedKeys[t]).setItem(_.getStorageKey(t),e)}static remove(t){_.getStorageMedium(_.allowedKeys[t]).removeItem(_.getStorageKey(t))}static clear(t){for(const[e,i]of Object.entries(_.allowedKeys)){const a=e;t&&this.configurationKeys.includes(a)||_.getStorageMedium(i).removeItem(_.getStorageKey(a))}}static getStorageKey(t){return`WebAuthnSdk:${t}`}static getStorageMedium(t){return t===l.session?sessionStorage:localStorage}}_.allowedKeys={clientId:l.session},_.configurationKeys=["clientId"];class S{static isNewApiDomain(t){return t&&(this.newApiDomains.includes(t)||t.startsWith("api.")&&t.endsWith(".transmitsecurity.io"))}static dnsPrefetch(t){const e=document.createElement("link");e.rel="dns-prefetch",e.href=t,document.head.appendChild(e)}static preconnect(t,e){const i=document.createElement("link");i.rel="preconnect",i.href=t,e&&(i.crossOrigin="anonymous"),document.head.appendChild(i)}static warmupConnection(t){this.dnsPrefetch(t),this.preconnect(t,!1),this.preconnect(t,!0)}static init(t,e){var i,a;try{this._serverPath=new URL(e.serverPath),this.isNewApiDomain(null===(i=this._serverPath)||void 0===i?void 0:i.hostname)&&this.warmupConnection(this._serverPath.origin),this._apiPaths=null!==(a=e.webauthnApiPaths)&&void 0!==a?a:this.getDefaultPaths(),this._clientId=t,_.set("clientId",t)}catch(t){throw new d("Invalid options.serverPath",{error:t})}}static getDefaultPaths(){var t;const e=this.isNewApiDomain(null===(t=this._serverPath)||void 0===t?void 0:t.hostname)?"/cis":"";return{startAuthentication:`${e}/v1/auth/webauthn/authenticate/start`,startRegistration:`${e}/v1/auth/webauthn/register/start`,initCrossDeviceAuthentication:`${e}/v1/auth/webauthn/cross-device/authenticate/init`,startCrossDeviceAuthentication:`${e}/v1/auth/webauthn/cross-device/authenticate/start`,startCrossDeviceRegistration:`${e}/v1/auth/webauthn/cross-device/register/start`,getCrossDeviceTicketStatus:`${e}/v1/auth/webauthn/cross-device/status`,attachDeviceToCrossDeviceSession:`${e}/v1/auth/webauthn/cross-device/attach-device`}}static getApiPaths(){return this._apiPaths}static async sendRequest(t,e,i){o.log(`[WebAuthn SDK] Calling ${e.method} ${t}...`);const a=new URL(this._serverPath);return a.pathname=t,i&&(a.search=i),fetch(a.toString(),e)}static async startRegistration(t){const e=await this.sendRequest(this._apiPaths.startRegistration,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a(a({client_id:this.getValidatedClientId(),username:t.username,display_name:t.displayName},t.timeout&&{timeout:t.timeout}),t.limitSingleCredentialToDevice&&{limit_single_credential_to_device:t.limitSingleCredentialToDevice}))});if(!(null==e?void 0:e.ok))throw new h("Failed to start registration",null==e?void 0:e.body);return await e.json()}static async startAuthentication(t){const e=await this.sendRequest(this._apiPaths.startAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a(a(a(a(a({client_id:this.getValidatedClientId()},t.username&&{username:t.username}),t.identifier&&{identifier:t.identifier}),t.identifierType&&{identifier_type:t.identifierType}),t.approvalData&&{approval_data:t.approvalData}),t.timeout&&{timeout:t.timeout}))});if(!(null==e?void 0:e.ok))throw new h("Failed to start authentication",null==e?void 0:e.body);return await e.json()}static async initCrossDeviceAuthentication(t){const e=await this.sendRequest(this._apiPaths.initCrossDeviceAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a(a({client_id:this.getValidatedClientId()},t.username&&{username:t.username}),t.approvalData&&{approval_data:t.approvalData}))});if(!(null==e?void 0:e.ok))throw new C(void 0,null==e?void 0:e.body);return await e.json()}static async getCrossDeviceTicketStatus(t){const e=await this.sendRequest(this._apiPaths.getCrossDeviceTicketStatus,{method:"GET"},`cross_device_ticket_id=${t.ticketId}`);if(!(null==e?void 0:e.ok))throw new A(void 0,null==e?void 0:e.body);return await e.json()}static async startCrossDeviceAuthentication(t){const e=await this.sendRequest(this._apiPaths.startCrossDeviceAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new h("Failed to start cross device authentication",null==e?void 0:e.body);return await e.json()}static async startCrossDeviceRegistration(t){const e=await this.sendRequest(this._apiPaths.startCrossDeviceRegistration,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new v("Failed to start cross device registration",null==e?void 0:e.body);return await e.json()}static async attachDeviceToCrossDeviceSession(t){const e=await this.sendRequest(this._apiPaths.attachDeviceToCrossDeviceSession,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new v("Failed to attach device to cross device session",null==e?void 0:e.body);return await e.json()}static getValidatedClientId(){var t;const e=null!==(t=this._clientId)&&void 0!==t?t:_.get("clientId");if(!e)throw new d("Missing clientId");return e}}var T,k,I,P;S.newApiDomains=["api.idsec-dev.com","api.idsec-stg.com"],function(t){t.InputAutofill="input-autofill",t.Modal="modal"}(T||(T={})),exports.WebauthnCrossDeviceStatus=void 0,(k=exports.WebauthnCrossDeviceStatus||(exports.WebauthnCrossDeviceStatus={})).Pending="pending",k.Scanned="scanned",k.Success="success",k.Error="error",k.Timeout="timeout",k.Aborted="aborted",function(t){t.toAuthenticationError=t=>D(t)?t:"NotAllowedError"===t.name?new p:"OperationError"===t.name?new y(t.message):"SecurityError"===t.name?new h(t.message):t===c.AuthenticationAbortedTimeout?new w:"AbortError"===t.name||t===c.AutofillAuthenticationAborted?new f:new h("Something went wrong during authentication",{error:t}),t.toRegistrationError=t=>D(t)?t:"NotAllowedError"===t.name?new g:"SecurityError"===t.name?new v(t.message):"InvalidStateError"===t.name?new m:t===c.RegistrationAbortedTimeout?new w:new v("Something went wrong during registration",{error:t})}(I||(I={})),function(t){t.processCredentialRequestOptions=t=>a(a({},t),{},{challenge:s.base64ToArrayBuffer(t.challenge),allowCredentials:t.allowCredentials.map((t=>a(a({},t),{},{id:s.base64ToArrayBuffer(t.id)})))}),t.processCredentialCreationOptions=(t,e)=>{var i;const r=JSON.parse(JSON.stringify(t));return r.challenge=s.base64ToArrayBuffer(t.challenge),r.user.id=s.base64ToArrayBuffer(t.user.id),(null==e?void 0:e.limitSingleCredentialToDevice)&&(r.excludeCredentials=null===(i=t.excludeCredentials)||void 0===i?void 0:i.map((t=>a(a({},t),{},{id:s.base64ToArrayBuffer(t.id)})))),(null==e?void 0:e.registerAsDiscoverable)?(r.authenticatorSelection.residentKey="preferred",r.authenticatorSelection.requireResidentKey=!0):(r.authenticatorSelection.residentKey="discouraged",r.authenticatorSelection.requireResidentKey=!1),r.authenticatorSelection.authenticatorAttachment=(null==e?void 0:e.allowCrossPlatformAuthenticators)?void 0:"platform",r},t.encodeAuthenticationResult=t=>{const{authenticatorAttachment:e}=t,i=t.response;return{id:t.id,rawId:s.arrayBufferToBase64(t.rawId),response:{authenticatorData:s.arrayBufferToBase64(i.authenticatorData),clientDataJSON:s.arrayBufferToBase64(i.clientDataJSON),signature:s.arrayBufferToBase64(i.signature),userHandle:s.arrayBufferToBase64(i.userHandle)},authenticatorAttachment:e,type:t.type}},t.encodeRegistrationResult=t=>{const{authenticatorAttachment:e}=t,i=t.response;return{id:t.id,rawId:s.arrayBufferToBase64(t.rawId),response:{attestationObject:s.arrayBufferToBase64(i.attestationObject),clientDataJSON:s.arrayBufferToBase64(i.clientDataJSON)},authenticatorAttachment:e,type:t.type}}}(P||(P={}));class O{async modal(t){try{const e=await this.performAuthentication(a(a({},t),{},{mediationType:T.Modal}));return s.jsonToBase64(e)}catch(t){throw I.toAuthenticationError(t)}}activateAutofill(t){const{handlers:e,username:i}=t,{onSuccess:a,onError:r,onReady:n}=e;this.performAuthentication({username:i,mediationType:T.InputAutofill,onReady:n}).then((t=>{a(s.jsonToBase64(t))})).catch((t=>{const e=I.toAuthenticationError(t);if(!r)throw e;r(e)}))}abortAutofill(){this.abortController&&this.abortController.abort(c.AutofillAuthenticationAborted)}abortAuthentication(){this.abortController&&this.abortController.abort(c.AuthenticationAbortedTimeout)}async performAuthentication(t){var e,i;const a="crossDeviceTicketId"in t?await S.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await S.startAuthentication({username:t.username,identifier:t.identifier,identifierType:t.identifierType,timeout:null===(e=t.options)||void 0===e?void 0:e.timeout}),r=a.credential_request_options,n=P.processCredentialRequestOptions(r),s=this.getMediatedCredentialRequest(n,t.mediationType);t.mediationType===T.InputAutofill&&(null===(i=t.onReady)||void 0===i||i.call(t));const o=await navigator.credentials.get(s).catch((t=>{throw I.toAuthenticationError(t)}));return{webauthnSessionId:a.webauthn_session_id,publicKeyCredential:P.encodeAuthenticationResult(o),userAgent:navigator.userAgent}}getMediatedCredentialRequest(t,e){const i={publicKey:t};return this.abortController=new AbortController,i.signal=this.abortController&&this.abortController.signal,e===T.InputAutofill?i.mediation="conditional":t.timeout&&setTimeout((()=>{this.abortAuthentication()}),t.timeout),i}}class R{constructor(t,e){this.handler=t,this.intervalInMs=e}begin(){var t;this.intervalId=window.setInterval((t=this.handler,async function(){t.isRunning||(t.isRunning=!0,await t(...arguments),t.isRunning=!1)}),this.intervalInMs)}stop(){clearInterval(this.intervalId)}}const j=/^[A-Za-z0-9\-_.: ]*$/;function x(t){if(t&&(!function(t){return Object.keys(t).length<=10}(t)||!function(t){const e=t=>"string"==typeof t,i=t=>j.test(t);return Object.keys(t).every((a=>e(a)&&e(t[a])&&i(a)&&i(t[a])))}(t)))throw o.error("Failed validating approval data"),new b("Provided approval data should have 10 properties max. Also, it should contain only \n alphanumeric characters, numbers, and the special characters: '-', '_', '.'")}class K{constructor(t,e,i){this.authenticationHandler=t,this.registrationHandler=e,this.approvalHandler=i,this.init={registration:async t=>(this.ticketStatus=exports.WebauthnCrossDeviceStatus.Pending,this.pollCrossDeviceSession(t.crossDeviceTicketId,t.handlers)),authentication:async t=>{const{username:e}=t,i=(await S.initCrossDeviceAuthentication(a({},e&&{username:e}))).cross_device_ticket_id;return this.ticketStatus=exports.WebauthnCrossDeviceStatus.Pending,this.pollCrossDeviceSession(i,t.handlers)},approval:async t=>{const{username:e,approvalData:i}=t;x(i);const a=(await S.initCrossDeviceAuthentication({username:e,approvalData:i})).cross_device_ticket_id;return this.ticketStatus=exports.WebauthnCrossDeviceStatus.Pending,this.pollCrossDeviceSession(a,t.handlers)}},this.authenticate={modal:async t=>this.authenticationHandler.modal({crossDeviceTicketId:t})},this.approve={modal:async t=>this.approvalHandler.modal({crossDeviceTicketId:t})}}async register(t){return this.registrationHandler.register(t)}async attachDevice(t){const e=await S.attachDeviceToCrossDeviceSession({ticketId:t});return a({status:e.status,startedAt:e.started_at},e.approval_data&&{approvalData:e.approval_data})}async pollCrossDeviceSession(t,e){return this.poller=new R((async()=>{var i,a;const r=await S.getCrossDeviceTicketStatus({ticketId:t}),n=r.status;if(n!==this.ticketStatus)switch(this.ticketStatus=n,n){case exports.WebauthnCrossDeviceStatus.Scanned:await e.onDeviceAttach();break;case exports.WebauthnCrossDeviceStatus.Error:case exports.WebauthnCrossDeviceStatus.Timeout:case exports.WebauthnCrossDeviceStatus.Aborted:await e.onFailure(r),null===(i=this.poller)||void 0===i||i.stop();break;case exports.WebauthnCrossDeviceStatus.Success:if("onCredentialRegister"in e)await e.onCredentialRegister();else{if(!r.session_id)throw new A("Cross device session is complete without returning session_id",r);await e.onCredentialAuthenticate(r.session_id)}null===(a=this.poller)||void 0===a||a.stop()}}),1e3),this.poller.begin(),setTimeout((()=>{var t;null===(t=this.poller)||void 0===t||t.stop(),e.onFailure({status:exports.WebauthnCrossDeviceStatus.Timeout})}),3e5),{crossDeviceTicketId:t,stop:()=>{var t;null===(t=this.poller)||void 0===t||t.stop()}}}}class B{async register(t){var e,i,r;this.abortController=new AbortController;const n=a({allowCrossPlatformAuthenticators:!("crossDeviceTicketId"in t),registerAsDiscoverable:!0},t.options);try{const a="crossDeviceTicketId"in t?await S.startCrossDeviceRegistration({ticketId:t.crossDeviceTicketId}):await S.startRegistration({username:t.username,displayName:(null===(e=t.options)||void 0===e?void 0:e.displayName)||t.username,timeout:null===(i=t.options)||void 0===i?void 0:i.timeout,limitSingleCredentialToDevice:null===(r=t.options)||void 0===r?void 0:r.limitSingleCredentialToDevice}),o=P.processCredentialCreationOptions(a.credential_creation_options,n);setTimeout((()=>{this.abortRegistration()}),o.timeout);const c=await this.registerCredential(o),l={webauthnSessionId:a.webauthn_session_id,publicKeyCredential:c,userAgent:navigator.userAgent};return s.jsonToBase64(l)}catch(t){throw I.toRegistrationError(t)}}abortRegistration(){this.abortController&&this.abortController.abort(c.RegistrationAbortedTimeout)}async registerCredential(t){const e=await navigator.credentials.create({publicKey:t,signal:this.abortController&&this.abortController.signal}).catch((t=>{throw I.toRegistrationError(t)}));return P.encodeRegistrationResult(e)}}class E{async modal(t){try{const e=await this.performApproval(t);return s.jsonToBase64(e)}catch(t){throw I.toAuthenticationError(t)}}async performApproval(t){"approvalData"in t&&x(t.approvalData);const e="crossDeviceTicketId"in t?await S.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await S.startAuthentication({username:t.username,approvalData:t.approvalData}),i=e.credential_request_options,a=P.processCredentialRequestOptions(i),r=await navigator.credentials.get({publicKey:a}).catch((t=>{throw I.toAuthenticationError(t)}));return{webauthnSessionId:e.webauthn_session_id,publicKeyCredential:P.encodeAuthenticationResult(r),userAgent:navigator.userAgent}}}class N{constructor(){this._initialized=!1,this._authenticationHandler=new O,this._registrationHandler=new B,this._approvalHandler=new E,this._crossDeviceHandler=new K(this._authenticationHandler,this._registrationHandler,this._approvalHandler),this.authenticate={modal:async t=>(this.initCheck(),this._authenticationHandler.modal(t)),autofill:{activate:t=>(this.initCheck(),this._authenticationHandler.activateAutofill(t)),abort:()=>this._authenticationHandler.abortAutofill()}},this.approve={modal:async t=>(this.initCheck(),this._approvalHandler.modal(t))},this.register=async t=>(this.initCheck(),this._registrationHandler.register(t)),this.crossDevice={init:{registration:async t=>(this.initCheck(),this._crossDeviceHandler.init.registration(t)),authentication:async t=>(this.initCheck(),this._crossDeviceHandler.init.authentication(t)),approval:async t=>(this.initCheck(),this._crossDeviceHandler.init.approval(t))},authenticate:{modal:async t=>(this.initCheck(),this._crossDeviceHandler.authenticate.modal(t))},approve:{modal:async t=>(this.initCheck(),this._crossDeviceHandler.approve.modal(t))},register:async t=>(this.initCheck(),this._crossDeviceHandler.register(t)),attachDevice:async t=>(this.initCheck(),this._crossDeviceHandler.attachDevice(t))},this.isPlatformAuthenticatorSupported=async()=>{var t;try{return await(null===(t=N.StaticPublicKeyCredential)||void 0===t?void 0:t.isUserVerifyingPlatformAuthenticatorAvailable())}catch(t){return!1}},this.isAutofillSupported=async()=>{var t,e;return!(!(null===(t=N.StaticPublicKeyCredential)||void 0===t?void 0:t.isConditionalMediationAvailable)||!await(null===(e=N.StaticPublicKeyCredential)||void 0===e?void 0:e.isConditionalMediationAvailable()))}}async init(t){const{clientId:e,options:i}=t;try{if(!e)throw new d("Invalid clientId",{clientId:e});if(i.webauthnApiPaths){const t=S.getDefaultPaths();if(function(t,e){const i=new Set(t),a=new Set(e);return[...t.filter((t=>!a.has(t))),...e.filter((t=>!i.has(t)))]}(Object.keys(i.webauthnApiPaths),Object.keys(t)).length)throw new d("Invalid custom paths",{customApiPaths:i.webauthnApiPaths})}S.init(e,i),this._initialized=!0}catch(t){throw D(t)?t:new d("Failed to initialize SDK")}}getDefaultPaths(){return this.initCheck(),S.getDefaultPaths()}getApiPaths(){return this.initCheck(),S.getApiPaths()}initCheck(){if(!this._initialized)throw new d}}N.StaticPublicKeyCredential=window.PublicKeyCredential;const H=new t("webauthn"),W=new N;H.events.on(H.events.MODULE_INITIALIZED,(()=>{var t;const e=H.moduleMetadata.getInitConfig();if(!(null===(t=null==e?void 0:e.webauthn)||void 0===t?void 0:t.serverPath))return;const{clientId:i,webauthn:r}=e;W.init({clientId:i,options:a({},r)})}));const q={modal:async t=>(W.initCheck(),W.authenticate.modal(t)),autofill:{activate:t=>{W.initCheck(),W.authenticate.autofill.activate(t)},abort:()=>{W.initCheck(),W.authenticate.autofill.abort()}}},F={modal:async t=>(W.initCheck(),W.approve.modal(t))};async function M(t){return W.initCheck(),W.register(t)}const{crossDevice:z}=W,{isPlatformAuthenticatorSupported:J}=W,{isAutofillSupported:$}=W,{getDefaultPaths:U}=W;window.localWebAuthnSDK=W;var V=Object.freeze({__proto__:null,get WebauthnCrossDeviceStatus(){return exports.WebauthnCrossDeviceStatus},approve:F,authenticate:q,crossDevice:z,getDefaultPaths:U,isAutofillSupported:$,isPlatformAuthenticatorSupported:J,register:M});const G={initialize:e.initialize,...V};Object.defineProperty(exports,"initialize",{enumerable:!0,get:function(){return e.initialize}}),exports.PACKAGE_VERSION="2.0.0",exports.approve=F,exports.authenticate=q,exports.crossDevice=z,exports.getDefaultPaths=U,exports.isAutofillSupported=$,exports.isPlatformAuthenticatorSupported=J,exports.register=M,exports.webauthn=G;
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.0.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){var i=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);e&&(a=a.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),i.push.apply(i,a)}return i}function a(t){for(var e=1;e<arguments.length;e++){var a=null!=arguments[e]?arguments[e]:{};e%2?i(Object(a),!0).forEach((function(e){r(t,e,a[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(a,e))}))}return t}function n(t){var e=function(t,e){if("object"!=typeof t||!t)return t;var i=t[Symbol.toPrimitive];if(void 0!==i){var a=i.call(t,e||"default");if("object"!=typeof a)return a;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(t,"string");return"symbol"==typeof e?e:String(e)}function r(t,e,i){return(e=n(e))in t?Object.defineProperty(t,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):t[e]=i,t}class o{static arrayBufferToBase64(t){return btoa(String.fromCharCode(...new Uint8Array(t)))}static base64ToArrayBuffer(t){return Uint8Array.from(atob(t),(t=>t.charCodeAt(0)))}static stringToBase64(t){return btoa(t)}static jsonToBase64(t){const e=JSON.stringify(t);return btoa(e)}static base64ToJson(t){const e=atob(t);return JSON.parse(e)}}const s={log:console.log,error:console.error};var c,l;!function(t){t.NotInitialized="not_initialized",t.AuthenticationFailed="authentication_failed",t.AuthenticationAbortedTimeout="authentication_aborted_timeout",t.AuthenticationCanceled="webauthn_authentication_canceled",t.RegistrationFailed="registration_failed",t.AlreadyRegistered="username_already_registered",t.RegistrationAbortedTimeout="registration_aborted_timeout",t.RegistrationCanceled="webauthn_registration_canceled",t.AutofillAuthenticationAborted="autofill_authentication_aborted",t.AuthenticationProcessAlreadyActive="authentication_process_already_active",t.InvalidApprovalData="invalid_approval_data",t.FailedToInitCrossDeviceSession="cross_device_init_failed",t.FailedToGetCrossDeviceStatus="cross_device_status_failed",t.Unknown="unknown"}(c||(c={}));class u extends Error{constructor(t,e){super(t),this.errorCode=c.NotInitialized,this.data=e}}class d extends u{constructor(t,e){super(null!=t?t:"WebAuthnSdk is not initialized",e),this.errorCode=c.NotInitialized}}class h extends u{constructor(t,e){super(null!=t?t:"Authentication failed with an error",e),this.errorCode=c.AuthenticationFailed}}class p extends u{constructor(t,e){super(null!=t?t:"Authentication was canceled by the user or got timeout",e),this.errorCode=c.AuthenticationCanceled}}class v extends u{constructor(t,e){super(null!=t?t:"Registration failed with an error",e),this.errorCode=c.RegistrationFailed}}class g extends u{constructor(t,e){super(null!=t?t:"Registration was canceled by the user or got timeout",e),this.errorCode=c.RegistrationCanceled}}class m extends u{constructor(t){super(null!=t?t:"Autofill flow was aborted"),this.errorCode=c.AutofillAuthenticationAborted}}class f extends u{constructor(t){super(null!=t?t:"Operation was aborted by timeout"),this.errorCode=c.AutofillAuthenticationAborted}}class w extends u{constructor(t){super(null!=t?t:"Passkey with this username is already registered with the relying party."),this.errorCode=c.AlreadyRegistered}}class y extends u{constructor(t,e){super(null!=t?t:"Authentication process is already active",e),this.errorCode=c.AuthenticationProcessAlreadyActive}}class b extends u{constructor(t,e){super(null!=t?t:"Invalid approval data",e),this.errorCode=c.InvalidApprovalData}}class A extends u{constructor(t,e){super(null!=t?t:"Failed to init cross device authentication",e),this.errorCode=c.FailedToInitCrossDeviceSession}}class C extends u{constructor(t,e){super(null!=t?t:"Failed to get cross device status",e),this.errorCode=c.FailedToGetCrossDeviceStatus}}function _(t){return t.errorCode&&Object.values(c).includes(t.errorCode)}!function(t){t[t.persistent=0]="persistent",t[t.session=1]="session"}(l||(l={}));class D{static get(t){return D.getStorageMedium(D.allowedKeys[t]).getItem(D.getStorageKey(t))||void 0}static set(t,e){return D.getStorageMedium(D.allowedKeys[t]).setItem(D.getStorageKey(t),e)}static remove(t){D.getStorageMedium(D.allowedKeys[t]).removeItem(D.getStorageKey(t))}static clear(t){for(const[e,i]of Object.entries(D.allowedKeys)){const a=e;t&&this.configurationKeys.includes(a)||D.getStorageMedium(i).removeItem(D.getStorageKey(a))}}static getStorageKey(t){return`WebAuthnSdk:${t}`}static getStorageMedium(t){return t===l.session?sessionStorage:localStorage}}D.allowedKeys={clientId:l.session},D.configurationKeys=["clientId"];class S{static isNewApiDomain(t){return t&&(this.newApiDomains.includes(t)||t.startsWith("api.")&&t.endsWith(".transmitsecurity.io"))}static dnsPrefetch(t){const e=document.createElement("link");e.rel="dns-prefetch",e.href=t,document.head.appendChild(e)}static preconnect(t,e){const i=document.createElement("link");i.rel="preconnect",i.href=t,e&&(i.crossOrigin="anonymous"),document.head.appendChild(i)}static warmupConnection(t){this.dnsPrefetch(t),this.preconnect(t,!1),this.preconnect(t,!0)}static init(t,e){var i,a;try{this._serverPath=new URL(e.serverPath),this.isNewApiDomain(null===(i=this._serverPath)||void 0===i?void 0:i.hostname)&&this.warmupConnection(this._serverPath.origin),this._apiPaths=null!==(a=e.webauthnApiPaths)&&void 0!==a?a:this.getDefaultPaths(),this._clientId=t,D.set("clientId",t)}catch(t){throw new d("Invalid options.serverPath",{error:t})}}static getDefaultPaths(){var t;const e=this.isNewApiDomain(null===(t=this._serverPath)||void 0===t?void 0:t.hostname)?"/cis":"";return{startAuthentication:`${e}/v1/auth/webauthn/authenticate/start`,startRegistration:`${e}/v1/auth/webauthn/register/start`,initCrossDeviceAuthentication:`${e}/v1/auth/webauthn/cross-device/authenticate/init`,startCrossDeviceAuthentication:`${e}/v1/auth/webauthn/cross-device/authenticate/start`,startCrossDeviceRegistration:`${e}/v1/auth/webauthn/cross-device/register/start`,getCrossDeviceTicketStatus:`${e}/v1/auth/webauthn/cross-device/status`,attachDeviceToCrossDeviceSession:`${e}/v1/auth/webauthn/cross-device/attach-device`}}static getApiPaths(){return this._apiPaths}static async sendRequest(t,e,i){s.log(`[WebAuthn SDK] Calling ${e.method} ${t}...`);const a=new URL(this._serverPath);return a.pathname=t,i&&(a.search=i),fetch(a.toString(),e)}static async startRegistration(t){const e=await this.sendRequest(this._apiPaths.startRegistration,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a(a({client_id:this.getValidatedClientId(),username:t.username,display_name:t.displayName},t.timeout&&{timeout:t.timeout}),t.limitSingleCredentialToDevice&&{limit_single_credential_to_device:t.limitSingleCredentialToDevice}))});if(!(null==e?void 0:e.ok))throw new h("Failed to start registration",null==e?void 0:e.body);return await e.json()}static async startAuthentication(t){const e=await this.sendRequest(this._apiPaths.startAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a(a(a(a(a({client_id:this.getValidatedClientId()},t.username&&{username:t.username}),t.identifier&&{identifier:t.identifier}),t.identifierType&&{identifier_type:t.identifierType}),t.approvalData&&{approval_data:t.approvalData}),t.timeout&&{timeout:t.timeout}))});if(!(null==e?void 0:e.ok))throw new h("Failed to start authentication",null==e?void 0:e.body);return await e.json()}static async initCrossDeviceAuthentication(t){const e=await this.sendRequest(this._apiPaths.initCrossDeviceAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a(a({client_id:this.getValidatedClientId()},t.username&&{username:t.username}),t.approvalData&&{approval_data:t.approvalData}))});if(!(null==e?void 0:e.ok))throw new A(void 0,null==e?void 0:e.body);return await e.json()}static async getCrossDeviceTicketStatus(t){const e=await this.sendRequest(this._apiPaths.getCrossDeviceTicketStatus,{method:"GET"},`cross_device_ticket_id=${t.ticketId}`);if(!(null==e?void 0:e.ok))throw new C(void 0,null==e?void 0:e.body);return await e.json()}static async startCrossDeviceAuthentication(t){const e=await this.sendRequest(this._apiPaths.startCrossDeviceAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new h("Failed to start cross device authentication",null==e?void 0:e.body);return await e.json()}static async startCrossDeviceRegistration(t){const e=await this.sendRequest(this._apiPaths.startCrossDeviceRegistration,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new v("Failed to start cross device registration",null==e?void 0:e.body);return await e.json()}static async attachDeviceToCrossDeviceSession(t){const e=await this.sendRequest(this._apiPaths.attachDeviceToCrossDeviceSession,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new v("Failed to attach device to cross device session",null==e?void 0:e.body);return await e.json()}static getValidatedClientId(){var t;const e=null!==(t=this._clientId)&&void 0!==t?t:D.get("clientId");if(!e)throw new d("Missing clientId");return e}}var T,k,I,P;S.newApiDomains=["api.idsec-dev.com","api.idsec-stg.com"],function(t){t.InputAutofill="input-autofill",t.Modal="modal"}(T||(T={})),function(t){t.Pending="pending",t.Scanned="scanned",t.Success="success",t.Error="error",t.Timeout="timeout",t.Aborted="aborted"}(k||(k={})),function(t){t.toAuthenticationError=t=>_(t)?t:"NotAllowedError"===t.name?new p:"OperationError"===t.name?new y(t.message):"SecurityError"===t.name?new h(t.message):t===c.AuthenticationAbortedTimeout?new f:"AbortError"===t.name||t===c.AutofillAuthenticationAborted?new m:new h("Something went wrong during authentication",{error:t}),t.toRegistrationError=t=>_(t)?t:"NotAllowedError"===t.name?new g:"SecurityError"===t.name?new v(t.message):"InvalidStateError"===t.name?new w:t===c.RegistrationAbortedTimeout?new f:new v("Something went wrong during registration",{error:t})}(I||(I={})),function(t){t.processCredentialRequestOptions=t=>a(a({},t),{},{challenge:o.base64ToArrayBuffer(t.challenge),allowCredentials:t.allowCredentials.map((t=>a(a({},t),{},{id:o.base64ToArrayBuffer(t.id)})))}),t.processCredentialCreationOptions=(t,e)=>{var i;const n=JSON.parse(JSON.stringify(t));return n.challenge=o.base64ToArrayBuffer(t.challenge),n.user.id=o.base64ToArrayBuffer(t.user.id),(null==e?void 0:e.limitSingleCredentialToDevice)&&(n.excludeCredentials=null===(i=t.excludeCredentials)||void 0===i?void 0:i.map((t=>a(a({},t),{},{id:o.base64ToArrayBuffer(t.id)})))),(null==e?void 0:e.registerAsDiscoverable)?(n.authenticatorSelection.residentKey="preferred",n.authenticatorSelection.requireResidentKey=!0):(n.authenticatorSelection.residentKey="discouraged",n.authenticatorSelection.requireResidentKey=!1),n.authenticatorSelection.authenticatorAttachment=(null==e?void 0:e.allowCrossPlatformAuthenticators)?void 0:"platform",n},t.encodeAuthenticationResult=t=>{const{authenticatorAttachment:e}=t,i=t.response;return{id:t.id,rawId:o.arrayBufferToBase64(t.rawId),response:{authenticatorData:o.arrayBufferToBase64(i.authenticatorData),clientDataJSON:o.arrayBufferToBase64(i.clientDataJSON),signature:o.arrayBufferToBase64(i.signature),userHandle:o.arrayBufferToBase64(i.userHandle)},authenticatorAttachment:e,type:t.type}},t.encodeRegistrationResult=t=>{const{authenticatorAttachment:e}=t,i=t.response;return{id:t.id,rawId:o.arrayBufferToBase64(t.rawId),response:{attestationObject:o.arrayBufferToBase64(i.attestationObject),clientDataJSON:o.arrayBufferToBase64(i.clientDataJSON)},authenticatorAttachment:e,type:t.type}}}(P||(P={}));class O{async modal(t){try{const e=await this.performAuthentication(a(a({},t),{},{mediationType:T.Modal}));return o.jsonToBase64(e)}catch(t){throw I.toAuthenticationError(t)}}activateAutofill(t){const{handlers:e,username:i}=t,{onSuccess:a,onError:n,onReady:r}=e;this.performAuthentication({username:i,mediationType:T.InputAutofill,onReady:r}).then((t=>{a(o.jsonToBase64(t))})).catch((t=>{const e=I.toAuthenticationError(t);if(!n)throw e;n(e)}))}abortAutofill(){this.abortController&&this.abortController.abort(c.AutofillAuthenticationAborted)}abortAuthentication(){this.abortController&&this.abortController.abort(c.AuthenticationAbortedTimeout)}async performAuthentication(t){var e,i;const a="crossDeviceTicketId"in t?await S.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await S.startAuthentication({username:t.username,identifier:t.identifier,identifierType:t.identifierType,timeout:null===(e=t.options)||void 0===e?void 0:e.timeout}),n=a.credential_request_options,r=P.processCredentialRequestOptions(n),o=this.getMediatedCredentialRequest(r,t.mediationType);t.mediationType===T.InputAutofill&&(null===(i=t.onReady)||void 0===i||i.call(t));const s=await navigator.credentials.get(o).catch((t=>{throw I.toAuthenticationError(t)}));return{webauthnSessionId:a.webauthn_session_id,publicKeyCredential:P.encodeAuthenticationResult(s),userAgent:navigator.userAgent}}getMediatedCredentialRequest(t,e){const i={publicKey:t};return this.abortController=new AbortController,i.signal=this.abortController&&this.abortController.signal,e===T.InputAutofill?i.mediation="conditional":t.timeout&&setTimeout((()=>{this.abortAuthentication()}),t.timeout),i}}class R{constructor(t,e){this.handler=t,this.intervalInMs=e}begin(){var t;this.intervalId=window.setInterval((t=this.handler,async function(){t.isRunning||(t.isRunning=!0,await t(...arguments),t.isRunning=!1)}),this.intervalInMs)}stop(){clearInterval(this.intervalId)}}const j=/^[A-Za-z0-9\-_.: ]*$/;function B(t){if(t&&(!function(t){return Object.keys(t).length<=10}(t)||!function(t){const e=t=>"string"==typeof t,i=t=>j.test(t);return Object.keys(t).every((a=>e(a)&&e(t[a])&&i(a)&&i(t[a])))}(t)))throw s.error("Failed validating approval data"),new b("Provided approval data should have 10 properties max. Also, it should contain only \n alphanumeric characters, numbers, and the special characters: '-', '_', '.'")}class K{constructor(t,e,i){this.authenticationHandler=t,this.registrationHandler=e,this.approvalHandler=i,this.init={registration:async t=>(this.ticketStatus=k.Pending,this.pollCrossDeviceSession(t.crossDeviceTicketId,t.handlers)),authentication:async t=>{const{username:e}=t,i=(await S.initCrossDeviceAuthentication(a({},e&&{username:e}))).cross_device_ticket_id;return this.ticketStatus=k.Pending,this.pollCrossDeviceSession(i,t.handlers)},approval:async t=>{const{username:e,approvalData:i}=t;B(i);const a=(await S.initCrossDeviceAuthentication({username:e,approvalData:i})).cross_device_ticket_id;return this.ticketStatus=k.Pending,this.pollCrossDeviceSession(a,t.handlers)}},this.authenticate={modal:async t=>this.authenticationHandler.modal({crossDeviceTicketId:t})},this.approve={modal:async t=>this.approvalHandler.modal({crossDeviceTicketId:t})}}async register(t){return this.registrationHandler.register(t)}async attachDevice(t){const e=await S.attachDeviceToCrossDeviceSession({ticketId:t});return a({status:e.status,startedAt:e.started_at},e.approval_data&&{approvalData:e.approval_data})}async pollCrossDeviceSession(t,e){return this.poller=new R((async()=>{var i,a;const n=await S.getCrossDeviceTicketStatus({ticketId:t}),r=n.status;if(r!==this.ticketStatus)switch(this.ticketStatus=r,r){case k.Scanned:await e.onDeviceAttach();break;case k.Error:case k.Timeout:case k.Aborted:await e.onFailure(n),null===(i=this.poller)||void 0===i||i.stop();break;case k.Success:if("onCredentialRegister"in e)await e.onCredentialRegister();else{if(!n.session_id)throw new C("Cross device session is complete without returning session_id",n);await e.onCredentialAuthenticate(n.session_id)}null===(a=this.poller)||void 0===a||a.stop()}}),1e3),this.poller.begin(),setTimeout((()=>{var t;null===(t=this.poller)||void 0===t||t.stop(),e.onFailure({status:k.Timeout})}),3e5),{crossDeviceTicketId:t,stop:()=>{var t;null===(t=this.poller)||void 0===t||t.stop()}}}}class E{async register(t){var e,i,n;this.abortController=new AbortController;const r=a({allowCrossPlatformAuthenticators:!("crossDeviceTicketId"in t),registerAsDiscoverable:!0},t.options);try{const a="crossDeviceTicketId"in t?await S.startCrossDeviceRegistration({ticketId:t.crossDeviceTicketId}):await S.startRegistration({username:t.username,displayName:(null===(e=t.options)||void 0===e?void 0:e.displayName)||t.username,timeout:null===(i=t.options)||void 0===i?void 0:i.timeout,limitSingleCredentialToDevice:null===(n=t.options)||void 0===n?void 0:n.limitSingleCredentialToDevice}),s=P.processCredentialCreationOptions(a.credential_creation_options,r);setTimeout((()=>{this.abortRegistration()}),s.timeout);const c=await this.registerCredential(s),l={webauthnSessionId:a.webauthn_session_id,publicKeyCredential:c,userAgent:navigator.userAgent};return o.jsonToBase64(l)}catch(t){throw I.toRegistrationError(t)}}abortRegistration(){this.abortController&&this.abortController.abort(c.RegistrationAbortedTimeout)}async registerCredential(t){const e=await navigator.credentials.create({publicKey:t,signal:this.abortController&&this.abortController.signal}).catch((t=>{throw I.toRegistrationError(t)}));return P.encodeRegistrationResult(e)}}class H{async modal(t){try{const e=await this.performApproval(t);return o.jsonToBase64(e)}catch(t){throw I.toAuthenticationError(t)}}async performApproval(t){"approvalData"in t&&B(t.approvalData);const e="crossDeviceTicketId"in t?await S.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await S.startAuthentication({username:t.username,approvalData:t.approvalData}),i=e.credential_request_options,a=P.processCredentialRequestOptions(i),n=await navigator.credentials.get({publicKey:a}).catch((t=>{throw I.toAuthenticationError(t)}));return{webauthnSessionId:e.webauthn_session_id,publicKeyCredential:P.encodeAuthenticationResult(n),userAgent:navigator.userAgent}}}class N{constructor(){this._initialized=!1,this._authenticationHandler=new O,this._registrationHandler=new E,this._approvalHandler=new H,this._crossDeviceHandler=new K(this._authenticationHandler,this._registrationHandler,this._approvalHandler),this.authenticate={modal:async t=>(this.initCheck(),this._authenticationHandler.modal(t)),autofill:{activate:t=>(this.initCheck(),this._authenticationHandler.activateAutofill(t)),abort:()=>this._authenticationHandler.abortAutofill()}},this.approve={modal:async t=>(this.initCheck(),this._approvalHandler.modal(t))},this.register=async t=>(this.initCheck(),this._registrationHandler.register(t)),this.crossDevice={init:{registration:async t=>(this.initCheck(),this._crossDeviceHandler.init.registration(t)),authentication:async t=>(this.initCheck(),this._crossDeviceHandler.init.authentication(t)),approval:async t=>(this.initCheck(),this._crossDeviceHandler.init.approval(t))},authenticate:{modal:async t=>(this.initCheck(),this._crossDeviceHandler.authenticate.modal(t))},approve:{modal:async t=>(this.initCheck(),this._crossDeviceHandler.approve.modal(t))},register:async t=>(this.initCheck(),this._crossDeviceHandler.register(t)),attachDevice:async t=>(this.initCheck(),this._crossDeviceHandler.attachDevice(t))},this.isPlatformAuthenticatorSupported=async()=>{var t;try{return await(null===(t=N.StaticPublicKeyCredential)||void 0===t?void 0:t.isUserVerifyingPlatformAuthenticatorAvailable())}catch(t){return!1}},this.isAutofillSupported=async()=>{var t,e;return!(!(null===(t=N.StaticPublicKeyCredential)||void 0===t?void 0:t.isConditionalMediationAvailable)||!await(null===(e=N.StaticPublicKeyCredential)||void 0===e?void 0:e.isConditionalMediationAvailable()))}}async init(t){const{clientId:e,options:i}=t;try{if(!e)throw new d("Invalid clientId",{clientId:e});if(i.webauthnApiPaths){const t=S.getDefaultPaths();if(function(t,e){const i=new Set(t),a=new Set(e);return[...t.filter((t=>!a.has(t))),...e.filter((t=>!i.has(t)))]}(Object.keys(i.webauthnApiPaths),Object.keys(t)).length)throw new d("Invalid custom paths",{customApiPaths:i.webauthnApiPaths})}S.init(e,i),this._initialized=!0}catch(t){throw _(t)?t:new d("Failed to initialize SDK")}}getDefaultPaths(){return this.initCheck(),S.getDefaultPaths()}getApiPaths(){return this.initCheck(),S.getApiPaths()}initCheck(){if(!this._initialized)throw new d}}N.StaticPublicKeyCredential=window.PublicKeyCredential;const F=new t("webauthn"),x=new N;F.events.on(F.events.MODULE_INITIALIZED,(()=>{var t;const e=F.moduleMetadata.getInitConfig();if(!(null===(t=null==e?void 0:e.webauthn)||void 0===t?void 0:t.serverPath))return;const{clientId:i,webauthn:n}=e;x.init({clientId:i,options:a({},n)})}));const q={modal:async t=>(x.initCheck(),x.authenticate.modal(t)),autofill:{activate:t=>{x.initCheck(),x.authenticate.autofill.activate(t)},abort:()=>{x.initCheck(),x.authenticate.autofill.abort()}}},M={modal:async t=>(x.initCheck(),x.approve.modal(t))};async function J(t){return x.initCheck(),x.register(t)}const{crossDevice:z}=x,{isPlatformAuthenticatorSupported:$}=x,{isAutofillSupported:U}=x,{getDefaultPaths:W}=x;window.localWebAuthnSDK=x;const V="2.0.0",L={initialize:e,...Object.freeze({__proto__:null,get WebauthnCrossDeviceStatus(){return k},approve:M,authenticate:q,crossDevice:z,getDefaultPaths:W,isAutofillSupported:U,isPlatformAuthenticatorSupported:$,register:J})};export{V as PACKAGE_VERSION,k as WebauthnCrossDeviceStatus,M as approve,q as authenticate,z as crossDevice,W as getDefaultPaths,U as isAutofillSupported,$ as isPlatformAuthenticatorSupported,J as register,L as webauthn};
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.0.1",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};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transmitsecurity/platform-web-sdk",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "license": "MIT",
5
5
  "private": false,
6
6
  "type": "module",
@@ -82,12 +82,6 @@
82
82
  "devDependencies": {
83
83
  "@playwright/test": "^1.57.0",
84
84
  "@rollup/plugin-json": "6.1.0",
85
- "@transmit-security/authentication-sdk": "5.0.0",
86
- "@transmit-security/ido-web-sdk": "1.0.1",
87
- "@transmit-security/riskid_sdk": "2.0.1",
88
- "@transmit-security/ts-identity-verification": "1.4.21",
89
- "@transmit-security/web-sdk-bundler": "0.2.0",
90
- "@transmit-security/web-sdk-common": "2.0.1",
91
85
  "@types/jest": "^29.5.0",
92
86
  "@types/node": "20.3.3",
93
87
  "jest": "^29.5.0",
@@ -108,4 +102,4 @@
108
102
  ],
109
103
  "description": "Transmit Security Web SDK - Browser-only authentication and identity verification",
110
104
  "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
111
- }
105
+ }