@transmitsecurity/platform-web-sdk 2.3.2-beta-26093939905.0 → 2.4.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
@@ -58,6 +58,7 @@ interface initConfigParams {
58
58
  };
59
59
  ido?: {
60
60
  serverPath?: string;
61
+ collectRiskData?: boolean;
61
62
  [key: string]: any;
62
63
  };
63
64
  [key: string]: any;
@@ -440,6 +441,18 @@ type LightweightPayload = {
440
441
  type TransactionType = 'purchase' | 'bill_payment' | 'mobile_recharge' | 'money_transfer' | 'credit_transfer' | 'credit_redemption' | 'top_up' | 'withdrawal' | 'investment' | 'loan' | 'refund' | 'other';
441
442
  type TransactionMethod = 'bank_account' | 'wire' | 'card' | 'p2p' | 'wallet';
442
443
  type AvsMatchLevel = 'none' | 'postal' | 'street' | 'full' | 'unknown';
444
+ /** The outcome of an action reported via {@link TSAccountProtection.reportActionResult} */
445
+ type ActionResult = "success" | "failure" | "incomplete";
446
+ /** Type of challenge presented to the user, when a challenge was recommended for the action */
447
+ type ChallengeType = "sms_otp" | "email_otp" | "totp" | "push_otp" | "voice_otp" | "idv" | "captcha" | "password" | "passkey";
448
+ interface ActionResultOptions {
449
+ /** Identifier containing sensitive user data. Mosaic will encrypt and securely store this data. */
450
+ privateUserIdentifier?: string;
451
+ /** Type of challenge used when a challenge was recommended for this action. */
452
+ challengeType?: ChallengeType;
453
+ /** Opaque identifier of the user in your system. */
454
+ userId?: string;
455
+ }
443
456
  interface ActionResponse {
444
457
  /** The token return by the SDK when the action was reported */
445
458
  actionToken?: string;
@@ -632,11 +645,17 @@ declare class TSAccountProtection {
632
645
  /** @ignore */
633
646
  getActions(): Promise<string[]>;
634
647
  getSessionToken(): Promise<any>;
648
+ /**
649
+ * Returns the lightweight (citadel) device payload to be forwarded to citadel via the caller's backend.
650
+ * The response from citadel includes a `deviceId` that must be passed back via {@link setDeviceId}
651
+ * — the server may issue a new one or rotate it, and the SDK only persists it when told to.
652
+ */
635
653
  getPayload(): Promise<LightweightPayload>;
636
654
  clearQueue(): void;
637
655
  /**
638
656
  * Sets the deviceId for lightweight mode (citadel).
639
- * Should be called after receiving deviceId from backend on first request.
657
+ * Should be called after every response from citadel the server may rotate the deviceId
658
+ * (e.g. after schema validation), so always propagate the returned value back into the SDK.
640
659
  * @param deviceId - The JWT deviceId returned from citadel backend
641
660
  */
642
661
  setDeviceId(deviceId: string): void;
@@ -662,6 +681,16 @@ declare class TSAccountProtection {
662
681
  * @returns Indicates if the call succeeded
663
682
  */
664
683
  setAuthenticatedUser(userId: string, options?: {}): Promise<boolean>;
684
+ /**
685
+ * Reports the result of an action for which a recommendation was previously issued.
686
+ * This includes whether the user successfully completed the action and, when applicable,
687
+ * the type of challenge that was presented.
688
+ * @param actionToken The token returned when the action was triggered by {@link TSAccountProtection.triggerActionEvent}
689
+ * @param result The outcome of the action
690
+ * @param options Additional context associated with the action result
691
+ * @returns Indicates if the call succeeded
692
+ */
693
+ reportActionResult(actionToken: string, result: ActionResult, options?: ActionResultOptions): Promise<boolean>;
665
694
  /**
666
695
  * Clears the user context for all subsequent events in the browser session
667
696
  * @param options Reserved for future use
@@ -691,6 +720,16 @@ declare const triggerActionEvent: TSAccountProtection['triggerActionEvent'];
691
720
  * @returns Indicates if the call succeeded
692
721
  */
693
722
  declare const setAuthenticatedUser: TSAccountProtection['setAuthenticatedUser'];
723
+ /**
724
+ * Reports the result of an action for which a recommendation was previously issued.
725
+ * This includes whether the user successfully completed the action and, when applicable,
726
+ * the type of challenge that was presented.
727
+ * @param actionToken The token returned when the action was triggered by triggerActionEvent()
728
+ * @param result The outcome of the action ("success" | "failure" | "incomplete")
729
+ * @param options Additional context associated with the action result
730
+ * @returns Indicates if the call succeeded
731
+ */
732
+ declare const reportActionResult: TSAccountProtection['reportActionResult'];
694
733
  /**
695
734
  * Clears the user context for all subsequent events in the browser session
696
735
  * @param options Reserved for future use
@@ -725,6 +764,7 @@ declare const __internal: {
725
764
 
726
765
  type webSdkModule_d_ActionEventOptions = ActionEventOptions;
727
766
  type webSdkModule_d_ActionResponse = ActionResponse;
767
+ type webSdkModule_d_ActionResultOptions = ActionResultOptions;
728
768
  type webSdkModule_d_LightweightPayload = LightweightPayload;
729
769
  declare const webSdkModule_d___internal: typeof __internal;
730
770
  declare const webSdkModule_d_clearUser: typeof clearUser;
@@ -732,6 +772,7 @@ declare const webSdkModule_d_getActions: typeof getActions;
732
772
  declare const webSdkModule_d_getPayload: typeof getPayload;
733
773
  declare const webSdkModule_d_getSecureSessionToken: typeof getSecureSessionToken;
734
774
  declare const webSdkModule_d_getSessionToken: typeof getSessionToken;
775
+ declare const webSdkModule_d_reportActionResult: typeof reportActionResult;
735
776
  declare const webSdkModule_d_setAuthenticatedUser: typeof setAuthenticatedUser;
736
777
  declare const webSdkModule_d_setDeviceId: typeof setDeviceId;
737
778
  declare const webSdkModule_d_triggerActionEvent: typeof triggerActionEvent;
@@ -739,6 +780,7 @@ declare namespace webSdkModule_d {
739
780
  export {
740
781
  webSdkModule_d_ActionEventOptions as ActionEventOptions,
741
782
  webSdkModule_d_ActionResponse as ActionResponse,
783
+ webSdkModule_d_ActionResultOptions as ActionResultOptions,
742
784
  webSdkModule_d_LightweightPayload as LightweightPayload,
743
785
  webSdkModule_d___internal as __internal,
744
786
  webSdkModule_d_clearUser as clearUser,
@@ -746,12 +788,87 @@ declare namespace webSdkModule_d {
746
788
  webSdkModule_d_getPayload as getPayload,
747
789
  webSdkModule_d_getSecureSessionToken as getSecureSessionToken,
748
790
  webSdkModule_d_getSessionToken as getSessionToken,
791
+ webSdkModule_d_reportActionResult as reportActionResult,
749
792
  webSdkModule_d_setAuthenticatedUser as setAuthenticatedUser,
750
793
  webSdkModule_d_setDeviceId as setDeviceId,
751
794
  webSdkModule_d_triggerActionEvent as triggerActionEvent,
752
795
  };
753
796
  }
754
797
 
798
+ type AddImagesResponse = {
799
+ /**
800
+ * Feedback for the submitted image
801
+ */
802
+ feedback: AddImagesResponse.feedback;
803
+ /**
804
+ * Indicates whether all the images required for the verification check were received
805
+ */
806
+ complete: boolean;
807
+ /**
808
+ * The additional image types that need to be added
809
+ */
810
+ missing_images: Array<'document_front' | 'document_back' | 'selfie'>;
811
+ /**
812
+ * Custom feedback corresponding to the restricted criteria (as configured in the Admin Portal)
813
+ */
814
+ custom_feedback?: string;
815
+ /**
816
+ * Indicates whether the document is expected to have a barcode
817
+ */
818
+ has_barcode?: boolean;
819
+ supported_barcode_symbologies?: string[];
820
+ };
821
+ declare namespace AddImagesResponse {
822
+ /**
823
+ * Feedback for the submitted image
824
+ */
825
+ enum feedback {
826
+ OK = "ok",
827
+ OTHER = "other",
828
+ DOCUMENT_NOT_FOUND = "document_not_found",
829
+ FACE_NOT_FOUND = "face_not_found",
830
+ DOCUMENT_FACE_NOT_FOUND = "document_face_not_found",
831
+ OBSTRUCTED = "obstructed",
832
+ BLUR = "blur",
833
+ GLARE = "glare",
834
+ DOCUMENT_NOT_SUPPORTED = "document_not_supported",
835
+ DOCUMENT_NOT_MATCHING = "document_not_matching",
836
+ WRONG_DOCUMENT_SIDE = "wrong_document_side",
837
+ MULTI_FACE = "multi_face",
838
+ FACE_ROTATED = "face_rotated",
839
+ FACE_TOO_SMALL = "face_too_small",
840
+ FACE_TOO_CLOSE = "face_too_close",
841
+ CLOSED_EYES = "closed_eyes",
842
+ FACE_ANGLE_TOO_LARGE = "face_angle_too_large",
843
+ FACE_CLOSE_TO_BORDER = "face_close_to_border",
844
+ FACE_OCCLUDED = "face_occluded",
845
+ FACE_CROPPED = "face_cropped",
846
+ BARCODE_NOT_FOUND = "barcode_not_found",
847
+ GLARE_SELFIE = "glare_selfie",
848
+ BLUR_SELFIE = "blur_selfie",
849
+ RESTRICTED_CRITERIA = "restricted_criteria",
850
+ UNCLASSIFIABLE = "unclassifiable"
851
+ }
852
+ }
853
+
854
+ type Step = 'loading_screen' | 'init' | 'document_front' | 'document_back' | 'selfie' | 'processing' | 'error' | 'complete' | 'recapture';
855
+
856
+ type Errors = 'other' | 'camera-error' | 'camera-permission-dismissed' | 'camera-permission-denied' | 'trying-to-initialize-active-session' | 'unable-to-parse-data-uri' | 'failed-to-submit-image' | 'request-error' | 'session-expired';
857
+
858
+ interface CaptureItem {
859
+ sessionId: string;
860
+ type: 'document_front' | 'document_back' | 'selfie';
861
+ feedback: AddImagesResponse.feedback;
862
+ }
863
+ interface CaptureResult {
864
+ captures: CaptureItem[];
865
+ }
866
+ declare class CaptureError extends Error {
867
+ errorCode: Errors;
868
+ step: Step;
869
+ constructor(errorCode: Errors, step: Step, message?: string);
870
+ }
871
+
755
872
  /**
756
873
  * The `idv` module allows you to integrate identity verification services into your application. This allows you to
757
874
  * securely verify the identity of your customers using documents like their driver's license or passport.
@@ -764,6 +881,33 @@ declare namespace webSdkModule_d {
764
881
  * @module tsPlatform.idv
765
882
  */
766
883
 
884
+ /**
885
+ * Options for {@link captureDocument}.
886
+ * @memberof module:tsPlatform.idv
887
+ */
888
+ interface CaptureDocumentOptions {
889
+ /**
890
+ * Acquisition id obtained by calling the backend's
891
+ * `POST /verify/api/v1/verification/{sessionId}/document-acquisition` endpoint.
892
+ * The same id is used for both document_front and document_back uploads, including any retakes.
893
+ */
894
+ acquisitionId: string;
895
+ /** Optional callback invoked for each successful image capture. */
896
+ onCapture?: (result: CaptureItem) => void;
897
+ }
898
+ /**
899
+ * Options for {@link captureSelfie}.
900
+ * @memberof module:tsPlatform.idv
901
+ */
902
+ interface CaptureSelfieOptions {
903
+ /**
904
+ * Acquisition id obtained by calling the backend's
905
+ * `POST /verify/api/v1/verification/{sessionId}/selfie-acquisition` endpoint.
906
+ */
907
+ acquisitionId: string;
908
+ /** Optional callback invoked when the selfie is successfully captured. */
909
+ onCapture?: (result: CaptureItem) => void;
910
+ }
767
911
  /**
768
912
  * Starts a verification session that was created in the backend (via the [Verification API](/openapi/verify/verifications/#operation/createSession)).
769
913
  * This will start the verification process for the user and guides them through the entire identity verification flow
@@ -805,20 +949,76 @@ declare function start(startToken?: string): Promise<boolean>;
805
949
  */
806
950
  declare function recapture(): Promise<boolean>;
807
951
  /**
808
- * deprecated use {@link module:tsPlatform.idv.recapture|recapture} instead
809
- * TODO: [VER-3126](https://transmitsecurity.atlassian.net/browse/VER-3126)
952
+ * Captures document images (front and back if needed). This method is only available when flowType is 'modular'.
953
+ * Returns a Promise that resolves when the document capture sequence completes successfully.
954
+ *
955
+ * Requires an `acquisitionId` minted via the backend's
956
+ * `POST /verify/api/v1/verification/{sessionId}/document-acquisition` endpoint. The same id is sent
957
+ * with every image upload performed during the capture (front, back, retakes).
958
+ * @function captureDocument
959
+ * @param {CaptureDocumentOptions} options - Capture options including the required `acquisitionId`
960
+ * and an optional `onCapture` callback called for each image submission attempt.
961
+ * @returns {Promise<CaptureResult>} Promise that resolves with complete capture information
962
+ * @throws {Error} If `acquisitionId` is missing, flowType is not 'modular', session is not active,
963
+ * or the document step is not available
964
+ * @memberof module:tsPlatform.idv
965
+ * @example
966
+ * // Mint an acquisition id from your backend, then pass it in:
967
+ * const { acquisition_id } = await myBackend.createDocumentAcquisition(sessionId);
968
+ * const result = await tsPlatform.idv.captureDocument({ acquisitionId: acquisition_id });
969
+ * console.log('Captured:', result.captures);
970
+ *
971
+ * // With callback for intermediate results (synchronous)
972
+ * const result = await tsPlatform.idv.captureDocument({
973
+ * acquisitionId: acquisition_id,
974
+ * onCapture: (capture) => {
975
+ * console.log(`Captured ${capture.type} with feedback: ${capture.feedback}`);
976
+ * },
977
+ * });
978
+ */
979
+ declare function captureDocument(options: CaptureDocumentOptions): Promise<CaptureResult>;
980
+ /**
981
+ * Captures a selfie image. This method is only available when flowType is 'modular'.
982
+ * Returns a Promise that resolves when the selfie capture completes successfully.
983
+ *
984
+ * Requires an `acquisitionId` minted via the backend's
985
+ * `POST /verify/api/v1/verification/{sessionId}/selfie-acquisition` endpoint.
986
+ * @function captureSelfie
987
+ * @param {CaptureSelfieOptions} options - Capture options including the required `acquisitionId`
988
+ * and an optional `onCapture` callback.
989
+ * @returns {Promise<CaptureResult>} Promise that resolves with complete capture information
990
+ * @throws {Error} If `acquisitionId` is missing, flowType is not 'modular', session is not active,
991
+ * or the selfie step is not available
992
+ * @memberof module:tsPlatform.idv
993
+ * @example
994
+ * const { acquisition_id } = await myBackend.createSelfieAcquisition(sessionId);
995
+ * const result = await tsPlatform.idv.captureSelfie({ acquisitionId: acquisition_id });
996
+ * console.log('Captured:', result.captures);
810
997
  */
811
- declare function restart(): Promise<boolean>;
998
+ declare function captureSelfie(options: CaptureSelfieOptions): Promise<CaptureResult>;
812
999
  declare const version: () => string;
813
1000
 
1001
+ type index_d$2_CaptureDocumentOptions = CaptureDocumentOptions;
1002
+ type index_d$2_CaptureError = CaptureError;
1003
+ declare const index_d$2_CaptureError: typeof CaptureError;
1004
+ type index_d$2_CaptureItem = CaptureItem;
1005
+ type index_d$2_CaptureResult = CaptureResult;
1006
+ type index_d$2_CaptureSelfieOptions = CaptureSelfieOptions;
1007
+ declare const index_d$2_captureDocument: typeof captureDocument;
1008
+ declare const index_d$2_captureSelfie: typeof captureSelfie;
814
1009
  declare const index_d$2_recapture: typeof recapture;
815
- declare const index_d$2_restart: typeof restart;
816
1010
  declare const index_d$2_start: typeof start;
817
1011
  declare const index_d$2_version: typeof version;
818
1012
  declare namespace index_d$2 {
819
1013
  export {
1014
+ index_d$2_CaptureDocumentOptions as CaptureDocumentOptions,
1015
+ index_d$2_CaptureError as CaptureError,
1016
+ index_d$2_CaptureItem as CaptureItem,
1017
+ index_d$2_CaptureResult as CaptureResult,
1018
+ index_d$2_CaptureSelfieOptions as CaptureSelfieOptions,
1019
+ index_d$2_captureDocument as captureDocument,
1020
+ index_d$2_captureSelfie as captureSelfie,
820
1021
  index_d$2_recapture as recapture,
821
- index_d$2_restart as restart,
822
1022
  index_d$2_start as start,
823
1023
  index_d$2_version as version,
824
1024
  };
@@ -2479,6 +2679,6 @@ declare class TSWebSDK {
2479
2679
  }
2480
2680
  declare const _default: TSWebSDK;
2481
2681
 
2482
- declare const PACKAGE_VERSION = "2.3.2-beta-26093939905.0";
2682
+ declare const PACKAGE_VERSION = "2.4.1";
2483
2683
 
2484
2684
  export { ActionEventOptions, ActionResponse, AuthenticationAutofillActivateHandlers, AutofillHandlers, CrossDeviceController, ErrorCode$1 as ErrorCode, PACKAGE_VERSION, SDK_VERSIONS, SdkError, WebauthnApis, WebauthnAuthenticationFlows, WebauthnCrossDeviceFlows, WebauthnCrossDeviceRegistrationOptions, WebauthnRegistrationOptions, authenticate, index_d$3 as common, crossDevice, _default as default, webSdkModule_d as drs, getDefaultPaths, index_d as ido, index_d$2 as idv, initConfigParams, initialize, isAutofillSupported, isPlatformAuthenticatorSupported, register, index_d$1 as webauthn };
package/dist/webauthn.cjs CHANGED
@@ -1 +1 @@
1
- "undefined"==typeof globalThis&&("undefined"!=typeof window?(window.globalThis=window,window.global=window):"undefined"!=typeof self&&(self.globalThis=self,self.global=self));var t=require("./common.cjs"),e=require("./common.cjs");function i(t,e,i){return(e=function(t){var e=function(t,e){if("object"!=typeof t||!t)return t;var i=t[Symbol.toPrimitive];if(void 0!==i){var a=i.call(t,e||"default");if("object"!=typeof a)return a;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(t,"string");return"symbol"==typeof e?e:e+""}(e))in t?Object.defineProperty(t,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):t[e]=i,t}function a(t,e){var i=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);e&&(a=a.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),i.push.apply(i,a)}return i}function r(t){for(var e=1;e<arguments.length;e++){var r=null!=arguments[e]?arguments[e]:{};e%2?a(Object(r),!0).forEach((function(e){i(t,e,r[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(r,e))}))}return t}class n{static arrayBufferToBase64(t){return btoa(String.fromCharCode(...new Uint8Array(t)))}static base64ToArrayBuffer(t){return Uint8Array.from(atob(t),(t=>t.charCodeAt(0)))}static stringToBase64(t){return btoa(t)}static jsonToBase64(t){const e=JSON.stringify(t);return btoa(e)}static base64ToJson(t){const e=atob(t);return JSON.parse(e)}}const s={log:console.log,error:console.error};var o,c;!function(t){t.NotInitialized="not_initialized",t.AuthenticationFailed="authentication_failed",t.AuthenticationAbortedTimeout="authentication_aborted_timeout",t.AuthenticationCanceled="webauthn_authentication_canceled",t.RegistrationFailed="registration_failed",t.AlreadyRegistered="username_already_registered",t.RegistrationAbortedTimeout="registration_aborted_timeout",t.RegistrationCanceled="webauthn_registration_canceled",t.AutofillAuthenticationAborted="autofill_authentication_aborted",t.AuthenticationProcessAlreadyActive="authentication_process_already_active",t.InvalidApprovalData="invalid_approval_data",t.FailedToInitCrossDeviceSession="cross_device_init_failed",t.FailedToGetCrossDeviceStatus="cross_device_status_failed",t.Unknown="unknown"}(o||(o={}));class l extends Error{constructor(t,e){super(t),this.errorCode=o.NotInitialized,this.data=e}}class u extends l{constructor(t,e){super(null!=t?t:"WebAuthnSdk is not initialized",e),this.errorCode=o.NotInitialized}}class d extends l{constructor(t,e){super(null!=t?t:"Authentication failed with an error",e),this.errorCode=o.AuthenticationFailed}}class h extends l{constructor(t,e){super(null!=t?t:"Authentication was canceled by the user or got timeout",e),this.errorCode=o.AuthenticationCanceled}}class p extends l{constructor(t,e){super(null!=t?t:"Registration failed with an error",e),this.errorCode=o.RegistrationFailed}}class v extends l{constructor(t,e){super(null!=t?t:"Registration was canceled by the user or got timeout",e),this.errorCode=o.RegistrationCanceled}}class g extends l{constructor(t){super(null!=t?t:"Autofill flow was aborted"),this.errorCode=o.AutofillAuthenticationAborted}}class f extends l{constructor(t){super(null!=t?t:"Operation was aborted by timeout"),this.errorCode=o.AutofillAuthenticationAborted}}class m extends l{constructor(t){super(null!=t?t:"Passkey with this username is already registered with the relying party."),this.errorCode=o.AlreadyRegistered}}class w extends l{constructor(t,e){super(null!=t?t:"Authentication process is already active",e),this.errorCode=o.AuthenticationProcessAlreadyActive}}class y extends l{constructor(t,e){super(null!=t?t:"Invalid approval data",e),this.errorCode=o.InvalidApprovalData}}class b extends l{constructor(t,e){super(null!=t?t:"Failed to init cross device authentication",e),this.errorCode=o.FailedToInitCrossDeviceSession}}class C extends l{constructor(t,e){super(null!=t?t:"Failed to get cross device status",e),this.errorCode=o.FailedToGetCrossDeviceStatus}}function A(t){return t.errorCode&&Object.values(o).includes(t.errorCode)}!function(t){t[t.persistent=0]="persistent",t[t.session=1]="session"}(c||(c={}));class D{static get(t){return D.getStorageMedium(D.allowedKeys[t]).getItem(D.getStorageKey(t))||void 0}static set(t,e){return D.getStorageMedium(D.allowedKeys[t]).setItem(D.getStorageKey(t),e)}static remove(t){D.getStorageMedium(D.allowedKeys[t]).removeItem(D.getStorageKey(t))}static clear(t){for(const[e,i]of Object.entries(D.allowedKeys)){const a=e;t&&this.configurationKeys.includes(a)||D.getStorageMedium(i).removeItem(D.getStorageKey(a))}}static getStorageKey(t){return`WebAuthnSdk:${t}`}static getStorageMedium(t){return t===c.session?sessionStorage:localStorage}}D.allowedKeys={clientId:c.session},D.configurationKeys=["clientId"];class _{static isNewApiDomain(t){return t&&(this.newApiDomains.includes(t)||t.startsWith("api.")&&t.endsWith(".transmitsecurity.io")||t.startsWith("api.")&&t.endsWith(".idsec-dev.com"))}static dnsPrefetch(t){const e=document.createElement("link");e.rel="dns-prefetch",e.href=t,document.head.appendChild(e)}static preconnect(t,e){const i=document.createElement("link");i.rel="preconnect",i.href=t,e&&(i.crossOrigin="anonymous"),document.head.appendChild(i)}static warmupConnection(t){this.dnsPrefetch(t),this.preconnect(t,!1),this.preconnect(t,!0)}static init(t,e){var i,a;try{this._serverPath=new URL(e.serverPath),this.isNewApiDomain(null===(i=this._serverPath)||void 0===i?void 0:i.hostname)&&this.warmupConnection(this._serverPath.origin),this._apiPaths=null!==(a=e.webauthnApiPaths)&&void 0!==a?a:this.getDefaultPaths(),this._clientId=t,D.set("clientId",t)}catch(t){throw new u("Invalid options.serverPath",{error:t})}}static getDefaultPaths(){var t;const e=this.isNewApiDomain(null===(t=this._serverPath)||void 0===t?void 0:t.hostname)?"/cis":"";return{startAuthentication:`${e}/v1/auth/webauthn/authenticate/start`,startRegistration:`${e}/v1/auth/webauthn/register/start`,initCrossDeviceAuthentication:`${e}/v1/auth/webauthn/cross-device/authenticate/init`,startCrossDeviceAuthentication:`${e}/v1/auth/webauthn/cross-device/authenticate/start`,startCrossDeviceRegistration:`${e}/v1/auth/webauthn/cross-device/register/start`,getCrossDeviceTicketStatus:`${e}/v1/auth/webauthn/cross-device/status`,attachDeviceToCrossDeviceSession:`${e}/v1/auth/webauthn/cross-device/attach-device`}}static getApiPaths(){return this._apiPaths}static async sendRequest(t,e,i){s.log(`[WebAuthn SDK] Calling ${e.method} ${t}...`);const a=new URL(this._serverPath);return a.pathname=t,i&&(a.search=i),fetch(a.toString(),e)}static async startRegistration(t){const e=await this.sendRequest(this._apiPaths.startRegistration,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r(r({client_id:this.getValidatedClientId(),username:t.username,display_name:t.displayName},t.timeout&&{timeout:t.timeout}),t.limitSingleCredentialToDevice&&{limit_single_credential_to_device:t.limitSingleCredentialToDevice}))});if(!(null==e?void 0:e.ok))throw new d("Failed to start registration",null==e?void 0:e.body);return await e.json()}static async startAuthentication(t){const e=await this.sendRequest(this._apiPaths.startAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r(r(r(r(r({client_id:this.getValidatedClientId()},t.username&&{username:t.username}),t.identifier&&{identifier:t.identifier}),t.identifierType&&{identifier_type:t.identifierType}),t.approvalData&&{approval_data:t.approvalData}),t.timeout&&{timeout:t.timeout}))});if(!(null==e?void 0:e.ok))throw new d("Failed to start authentication",null==e?void 0:e.body);return await e.json()}static async initCrossDeviceAuthentication(t){const e=await this.sendRequest(this._apiPaths.initCrossDeviceAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r(r({client_id:this.getValidatedClientId()},t.username&&{username:t.username}),t.approvalData&&{approval_data:t.approvalData}))});if(!(null==e?void 0:e.ok))throw new b(void 0,null==e?void 0:e.body);return await e.json()}static async getCrossDeviceTicketStatus(t){const e=await this.sendRequest(this._apiPaths.getCrossDeviceTicketStatus,{method:"GET"},`cross_device_ticket_id=${t.ticketId}`);if(!(null==e?void 0:e.ok))throw new C(void 0,null==e?void 0:e.body);return await e.json()}static async startCrossDeviceAuthentication(t){const e=await this.sendRequest(this._apiPaths.startCrossDeviceAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new d("Failed to start cross device authentication",null==e?void 0:e.body);return await e.json()}static async startCrossDeviceRegistration(t){const e=await this.sendRequest(this._apiPaths.startCrossDeviceRegistration,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new p("Failed to start cross device registration",null==e?void 0:e.body);return await e.json()}static async attachDeviceToCrossDeviceSession(t){const e=await this.sendRequest(this._apiPaths.attachDeviceToCrossDeviceSession,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new p("Failed to attach device to cross device session",null==e?void 0:e.body);return await e.json()}static getValidatedClientId(){var t;const e=null!==(t=this._clientId)&&void 0!==t?t:D.get("clientId");if(!e)throw new u("Missing clientId");return e}}var S,T,k,I;_.newApiDomains=["api.idsec-dev.com","api.idsec-stg.com"],function(t){t.InputAutofill="input-autofill",t.Modal="modal"}(S||(S={})),exports.WebauthnCrossDeviceStatus=void 0,(T=exports.WebauthnCrossDeviceStatus||(exports.WebauthnCrossDeviceStatus={})).Pending="pending",T.Scanned="scanned",T.Success="success",T.Error="error",T.Timeout="timeout",T.Aborted="aborted",function(t){t.toAuthenticationError=t=>A(t)?t:"NotAllowedError"===t.name?new h:"OperationError"===t.name?new w(t.message):"SecurityError"===t.name?new d(t.message):t===o.AuthenticationAbortedTimeout?new f:"AbortError"===t.name||t===o.AutofillAuthenticationAborted?new g:new d("Something went wrong during authentication",{error:t}),t.toRegistrationError=t=>A(t)?t:"NotAllowedError"===t.name?new v:"SecurityError"===t.name?new p(t.message):"InvalidStateError"===t.name?new m:t===o.RegistrationAbortedTimeout?new f:new p("Something went wrong during registration",{error:t})}(k||(k={})),function(t){t.processCredentialRequestOptions=t=>r(r({},t),{},{challenge:n.base64ToArrayBuffer(t.challenge),allowCredentials:t.allowCredentials.map((t=>r(r({},t),{},{id:n.base64ToArrayBuffer(t.id)})))}),t.processCredentialCreationOptions=(t,e)=>{var i;const a=JSON.parse(JSON.stringify(t));return a.challenge=n.base64ToArrayBuffer(t.challenge),a.user.id=n.base64ToArrayBuffer(t.user.id),(null==e?void 0:e.limitSingleCredentialToDevice)&&(a.excludeCredentials=null===(i=t.excludeCredentials)||void 0===i?void 0:i.map((t=>r(r({},t),{},{id:n.base64ToArrayBuffer(t.id)})))),(null==e?void 0:e.registerAsDiscoverable)?(a.authenticatorSelection.residentKey="preferred",a.authenticatorSelection.requireResidentKey=!0):(a.authenticatorSelection.residentKey="discouraged",a.authenticatorSelection.requireResidentKey=!1),a.authenticatorSelection.authenticatorAttachment=(null==e?void 0:e.allowCrossPlatformAuthenticators)?void 0:"platform",a},t.encodeAuthenticationResult=t=>{const{authenticatorAttachment:e}=t,i=t.response;return{id:t.id,rawId:n.arrayBufferToBase64(t.rawId),response:{authenticatorData:n.arrayBufferToBase64(i.authenticatorData),clientDataJSON:n.arrayBufferToBase64(i.clientDataJSON),signature:n.arrayBufferToBase64(i.signature),userHandle:n.arrayBufferToBase64(i.userHandle)},authenticatorAttachment:e,type:t.type}},t.encodeRegistrationResult=t=>{const{authenticatorAttachment:e}=t,i=t.response;return{id:t.id,rawId:n.arrayBufferToBase64(t.rawId),response:{attestationObject:n.arrayBufferToBase64(i.attestationObject),clientDataJSON:n.arrayBufferToBase64(i.clientDataJSON)},authenticatorAttachment:e,type:t.type}}}(I||(I={}));class P{async modal(t){try{const e=await this.performAuthentication(r(r({},t),{},{mediationType:S.Modal}));return n.jsonToBase64(e)}catch(t){throw k.toAuthenticationError(t)}}activateAutofill(t){const{handlers:e,username:i}=t,{onSuccess:a,onError:r,onReady:s}=e;this.performAuthentication({username:i,mediationType:S.InputAutofill,onReady:s}).then((t=>{a(n.jsonToBase64(t))})).catch((t=>{const e=k.toAuthenticationError(t);if(!r)throw e;r(e)}))}abortAutofill(){this.abortController&&this.abortController.abort(o.AutofillAuthenticationAborted)}abortAuthentication(){this.abortController&&this.abortController.abort(o.AuthenticationAbortedTimeout)}async performAuthentication(t){var e,i;const a="crossDeviceTicketId"in t?await _.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await _.startAuthentication({username:t.username,identifier:t.identifier,identifierType:t.identifierType,timeout:null===(e=t.options)||void 0===e?void 0:e.timeout}),r=a.credential_request_options,n=I.processCredentialRequestOptions(r),s=this.getMediatedCredentialRequest(n,t.mediationType);t.mediationType===S.InputAutofill&&(null===(i=t.onReady)||void 0===i||i.call(t));const o=await navigator.credentials.get(s).catch((t=>{throw k.toAuthenticationError(t)}));return{webauthnSessionId:a.webauthn_session_id,publicKeyCredential:I.encodeAuthenticationResult(o),userAgent:navigator.userAgent}}getMediatedCredentialRequest(t,e){const i={publicKey:t};return this.abortController=new AbortController,i.signal=this.abortController&&this.abortController.signal,e===S.InputAutofill?i.mediation="conditional":t.timeout&&setTimeout((()=>{this.abortAuthentication()}),t.timeout),i}}class O{constructor(t,e){this.handler=t,this.intervalInMs=e}begin(){var t;this.intervalId=window.setInterval((t=this.handler,async function(){t.isRunning||(t.isRunning=!0,await t(...arguments),t.isRunning=!1)}),this.intervalInMs)}stop(){clearInterval(this.intervalId)}}const R=/^[A-Za-z0-9\-_.: ]*$/;function j(t){if(t&&(!function(t){return Object.keys(t).length<=10}(t)||!function(t){const e=t=>"string"==typeof t,i=t=>R.test(t);return Object.keys(t).every((a=>e(a)&&e(t[a])&&i(a)&&i(t[a])))}(t)))throw s.error("Failed validating approval data"),new y("Provided approval data should have 10 properties max. Also, it should contain only \n alphanumeric characters, numbers, and the special characters: '-', '_', '.'")}class x{constructor(t,e,i){this.authenticationHandler=t,this.registrationHandler=e,this.approvalHandler=i,this.init={registration:async t=>(this.ticketStatus=exports.WebauthnCrossDeviceStatus.Pending,this.pollCrossDeviceSession(t.crossDeviceTicketId,t.handlers)),authentication:async t=>{const{username:e}=t,i=(await _.initCrossDeviceAuthentication(r({},e&&{username:e}))).cross_device_ticket_id;return this.ticketStatus=exports.WebauthnCrossDeviceStatus.Pending,this.pollCrossDeviceSession(i,t.handlers)},approval:async t=>{const{username:e,approvalData:i}=t;j(i);const a=(await _.initCrossDeviceAuthentication({username:e,approvalData:i})).cross_device_ticket_id;return this.ticketStatus=exports.WebauthnCrossDeviceStatus.Pending,this.pollCrossDeviceSession(a,t.handlers)}},this.authenticate={modal:async t=>this.authenticationHandler.modal({crossDeviceTicketId:t})},this.approve={modal:async t=>this.approvalHandler.modal({crossDeviceTicketId:t})}}async register(t){return this.registrationHandler.register(t)}async attachDevice(t){const e=await _.attachDeviceToCrossDeviceSession({ticketId:t});return r({status:e.status,startedAt:e.started_at},e.approval_data&&{approvalData:e.approval_data})}async pollCrossDeviceSession(t,e){return this.poller=new O((async()=>{var i,a;const r=await _.getCrossDeviceTicketStatus({ticketId:t}),n=r.status;if(n!==this.ticketStatus)switch(this.ticketStatus=n,n){case exports.WebauthnCrossDeviceStatus.Scanned:await e.onDeviceAttach();break;case exports.WebauthnCrossDeviceStatus.Error:case exports.WebauthnCrossDeviceStatus.Timeout:case exports.WebauthnCrossDeviceStatus.Aborted:await e.onFailure(r),null===(i=this.poller)||void 0===i||i.stop();break;case exports.WebauthnCrossDeviceStatus.Success:if("onCredentialRegister"in e)await e.onCredentialRegister();else{if(!r.session_id)throw new C("Cross device session is complete without returning session_id",r);await e.onCredentialAuthenticate(r.session_id)}null===(a=this.poller)||void 0===a||a.stop()}}),1e3),this.poller.begin(),setTimeout((()=>{var t;null===(t=this.poller)||void 0===t||t.stop(),e.onFailure({status:exports.WebauthnCrossDeviceStatus.Timeout})}),3e5),{crossDeviceTicketId:t,stop:()=>{var t;null===(t=this.poller)||void 0===t||t.stop()}}}}class K{async register(t){var e,i,a;this.abortController=new AbortController;const s=r({allowCrossPlatformAuthenticators:!("crossDeviceTicketId"in t),registerAsDiscoverable:!0},t.options);try{const r="crossDeviceTicketId"in t?await _.startCrossDeviceRegistration({ticketId:t.crossDeviceTicketId}):await _.startRegistration({username:t.username,displayName:(null===(e=t.options)||void 0===e?void 0:e.displayName)||t.username,timeout:null===(i=t.options)||void 0===i?void 0:i.timeout,limitSingleCredentialToDevice:null===(a=t.options)||void 0===a?void 0:a.limitSingleCredentialToDevice}),o=I.processCredentialCreationOptions(r.credential_creation_options,s);setTimeout((()=>{this.abortRegistration()}),o.timeout);const c=await this.registerCredential(o),l={webauthnSessionId:r.webauthn_session_id,publicKeyCredential:c,userAgent:navigator.userAgent};return n.jsonToBase64(l)}catch(t){throw k.toRegistrationError(t)}}abortRegistration(){this.abortController&&this.abortController.abort(o.RegistrationAbortedTimeout)}async registerCredential(t){const e=await navigator.credentials.create({publicKey:t,signal:this.abortController&&this.abortController.signal}).catch((t=>{throw k.toRegistrationError(t)}));return I.encodeRegistrationResult(e)}}class B{async modal(t){try{const e=await this.performApproval(t);return n.jsonToBase64(e)}catch(t){throw k.toAuthenticationError(t)}}async performApproval(t){"approvalData"in t&&j(t.approvalData);const e="crossDeviceTicketId"in t?await _.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await _.startAuthentication({username:t.username,approvalData:t.approvalData}),i=e.credential_request_options,a=I.processCredentialRequestOptions(i),r=await navigator.credentials.get({publicKey:a}).catch((t=>{throw k.toAuthenticationError(t)}));return{webauthnSessionId:e.webauthn_session_id,publicKeyCredential:I.encodeAuthenticationResult(r),userAgent:navigator.userAgent}}}class E{constructor(){this._initialized=!1,this._authenticationHandler=new P,this._registrationHandler=new K,this._approvalHandler=new B,this._crossDeviceHandler=new x(this._authenticationHandler,this._registrationHandler,this._approvalHandler),this.authenticate={modal:async t=>(this.initCheck(),this._authenticationHandler.modal(t)),autofill:{activate:t=>(this.initCheck(),this._authenticationHandler.activateAutofill(t)),abort:()=>this._authenticationHandler.abortAutofill()}},this.approve={modal:async t=>(this.initCheck(),this._approvalHandler.modal(t))},this.register=async t=>(this.initCheck(),this._registrationHandler.register(t)),this.crossDevice={init:{registration:async t=>(this.initCheck(),this._crossDeviceHandler.init.registration(t)),authentication:async t=>(this.initCheck(),this._crossDeviceHandler.init.authentication(t)),approval:async t=>(this.initCheck(),this._crossDeviceHandler.init.approval(t))},authenticate:{modal:async t=>(this.initCheck(),this._crossDeviceHandler.authenticate.modal(t))},approve:{modal:async t=>(this.initCheck(),this._crossDeviceHandler.approve.modal(t))},register:async t=>(this.initCheck(),this._crossDeviceHandler.register(t)),attachDevice:async t=>(this.initCheck(),this._crossDeviceHandler.attachDevice(t))},this.isPlatformAuthenticatorSupported=async()=>{var t;try{return await(null===(t=E.StaticPublicKeyCredential)||void 0===t?void 0:t.isUserVerifyingPlatformAuthenticatorAvailable())}catch(t){return!1}},this.isAutofillSupported=async()=>{var t,e;return!(!(null===(t=E.StaticPublicKeyCredential)||void 0===t?void 0:t.isConditionalMediationAvailable)||!await(null===(e=E.StaticPublicKeyCredential)||void 0===e?void 0:e.isConditionalMediationAvailable()))}}async init(t){const{clientId:e,options:i}=t;try{if(!e)throw new u("Invalid clientId",{clientId:e});if(i.webauthnApiPaths){const t=_.getDefaultPaths();if(function(t,e){const i=new Set(t),a=new Set(e);return[...t.filter((t=>!a.has(t))),...e.filter((t=>!i.has(t)))]}(Object.keys(i.webauthnApiPaths),Object.keys(t)).length)throw new u("Invalid custom paths",{customApiPaths:i.webauthnApiPaths})}_.init(e,i),this._initialized=!0}catch(t){throw A(t)?t:new u("Failed to initialize SDK")}}getDefaultPaths(){return this.initCheck(),_.getDefaultPaths()}getApiPaths(){return this.initCheck(),_.getApiPaths()}initCheck(){if(!this._initialized)throw new u}}E.StaticPublicKeyCredential=window.PublicKeyCredential;const N=new t("webauthn"),H=new E;N.events.on(N.events.MODULE_INITIALIZED,(()=>{var t;const e=N.moduleMetadata.getInitConfig();if(!(null===(t=null==e?void 0:e.webauthn)||void 0===t?void 0:t.serverPath))return;const{clientId:i,webauthn:a}=e;H.init({clientId:i,options:r({},a)})}));const W={modal:async t=>(H.initCheck(),H.authenticate.modal(t)),autofill:{activate:t=>{H.initCheck(),H.authenticate.autofill.activate(t)},abort:()=>{H.initCheck(),H.authenticate.autofill.abort()}}},q={modal:async t=>(H.initCheck(),H.approve.modal(t))};async function F(t){return H.initCheck(),H.register(t)}const{crossDevice:M}=H,{isPlatformAuthenticatorSupported:z}=H,{isAutofillSupported:J}=H,{getDefaultPaths:$}=H;window.localWebAuthnSDK=H;var U=Object.freeze({__proto__:null,get WebauthnCrossDeviceStatus(){return exports.WebauthnCrossDeviceStatus},approve:q,authenticate:W,crossDevice:M,getDefaultPaths:$,isAutofillSupported:J,isPlatformAuthenticatorSupported:z,register:F});const V={initialize:e.initialize,...U};Object.defineProperty(exports,"initialize",{enumerable:!0,get:function(){return e.initialize}}),exports.PACKAGE_VERSION="2.3.2-beta-26093939905.0",exports.approve=q,exports.authenticate=W,exports.crossDevice=M,exports.getDefaultPaths=$,exports.isAutofillSupported=J,exports.isPlatformAuthenticatorSupported=z,exports.register=F,exports.webauthn=V;
1
+ "undefined"==typeof globalThis&&("undefined"!=typeof window?(window.globalThis=window,window.global=window):"undefined"!=typeof self&&(self.globalThis=self,self.global=self));var t=require("./common.cjs"),e=require("./common.cjs");function i(t,e,i){return(e=function(t){var e=function(t,e){if("object"!=typeof t||!t)return t;var i=t[Symbol.toPrimitive];if(void 0!==i){var a=i.call(t,e||"default");if("object"!=typeof a)return a;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(t,"string");return"symbol"==typeof e?e:e+""}(e))in t?Object.defineProperty(t,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):t[e]=i,t}function a(t,e){var i=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);e&&(a=a.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),i.push.apply(i,a)}return i}function r(t){for(var e=1;e<arguments.length;e++){var r=null!=arguments[e]?arguments[e]:{};e%2?a(Object(r),!0).forEach((function(e){i(t,e,r[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(r,e))}))}return t}class n{static arrayBufferToBase64(t){return btoa(String.fromCharCode(...new Uint8Array(t)))}static base64ToArrayBuffer(t){return Uint8Array.from(atob(t),(t=>t.charCodeAt(0)))}static stringToBase64(t){return btoa(t)}static jsonToBase64(t){const e=JSON.stringify(t);return btoa(e)}static base64ToJson(t){const e=atob(t);return JSON.parse(e)}}const s={log:console.log,error:console.error};var o,c;!function(t){t.NotInitialized="not_initialized",t.AuthenticationFailed="authentication_failed",t.AuthenticationAbortedTimeout="authentication_aborted_timeout",t.AuthenticationCanceled="webauthn_authentication_canceled",t.RegistrationFailed="registration_failed",t.AlreadyRegistered="username_already_registered",t.RegistrationAbortedTimeout="registration_aborted_timeout",t.RegistrationCanceled="webauthn_registration_canceled",t.AutofillAuthenticationAborted="autofill_authentication_aborted",t.AuthenticationProcessAlreadyActive="authentication_process_already_active",t.InvalidApprovalData="invalid_approval_data",t.FailedToInitCrossDeviceSession="cross_device_init_failed",t.FailedToGetCrossDeviceStatus="cross_device_status_failed",t.Unknown="unknown"}(o||(o={}));class l extends Error{constructor(t,e){super(t),this.errorCode=o.NotInitialized,this.data=e}}class u extends l{constructor(t,e){super(null!=t?t:"WebAuthnSdk is not initialized",e),this.errorCode=o.NotInitialized}}class d extends l{constructor(t,e){super(null!=t?t:"Authentication failed with an error",e),this.errorCode=o.AuthenticationFailed}}class h extends l{constructor(t,e){super(null!=t?t:"Authentication was canceled by the user or got timeout",e),this.errorCode=o.AuthenticationCanceled}}class p extends l{constructor(t,e){super(null!=t?t:"Registration failed with an error",e),this.errorCode=o.RegistrationFailed}}class v extends l{constructor(t,e){super(null!=t?t:"Registration was canceled by the user or got timeout",e),this.errorCode=o.RegistrationCanceled}}class g extends l{constructor(t){super(null!=t?t:"Autofill flow was aborted"),this.errorCode=o.AutofillAuthenticationAborted}}class f extends l{constructor(t){super(null!=t?t:"Operation was aborted by timeout"),this.errorCode=o.AutofillAuthenticationAborted}}class m extends l{constructor(t){super(null!=t?t:"Passkey with this username is already registered with the relying party."),this.errorCode=o.AlreadyRegistered}}class w extends l{constructor(t,e){super(null!=t?t:"Authentication process is already active",e),this.errorCode=o.AuthenticationProcessAlreadyActive}}class y extends l{constructor(t,e){super(null!=t?t:"Invalid approval data",e),this.errorCode=o.InvalidApprovalData}}class b extends l{constructor(t,e){super(null!=t?t:"Failed to init cross device authentication",e),this.errorCode=o.FailedToInitCrossDeviceSession}}class C extends l{constructor(t,e){super(null!=t?t:"Failed to get cross device status",e),this.errorCode=o.FailedToGetCrossDeviceStatus}}function A(t){return t.errorCode&&Object.values(o).includes(t.errorCode)}!function(t){t[t.persistent=0]="persistent",t[t.session=1]="session"}(c||(c={}));class D{static get(t){return D.getStorageMedium(D.allowedKeys[t]).getItem(D.getStorageKey(t))||void 0}static set(t,e){return D.getStorageMedium(D.allowedKeys[t]).setItem(D.getStorageKey(t),e)}static remove(t){D.getStorageMedium(D.allowedKeys[t]).removeItem(D.getStorageKey(t))}static clear(t){for(const[e,i]of Object.entries(D.allowedKeys)){const a=e;t&&this.configurationKeys.includes(a)||D.getStorageMedium(i).removeItem(D.getStorageKey(a))}}static getStorageKey(t){return`WebAuthnSdk:${t}`}static getStorageMedium(t){return t===c.session?sessionStorage:localStorage}}D.allowedKeys={clientId:c.session},D.configurationKeys=["clientId"];class _{static isNewApiDomain(t){return t&&(this.newApiDomains.includes(t)||t.startsWith("api.")&&t.endsWith(".transmitsecurity.io")||t.startsWith("api.")&&t.endsWith(".idsec-dev.com"))}static dnsPrefetch(t){const e=document.createElement("link");e.rel="dns-prefetch",e.href=t,document.head.appendChild(e)}static preconnect(t,e){const i=document.createElement("link");i.rel="preconnect",i.href=t,e&&(i.crossOrigin="anonymous"),document.head.appendChild(i)}static warmupConnection(t){this.dnsPrefetch(t),this.preconnect(t,!1),this.preconnect(t,!0)}static init(t,e){var i,a;try{this._serverPath=new URL(e.serverPath),this.isNewApiDomain(null===(i=this._serverPath)||void 0===i?void 0:i.hostname)&&this.warmupConnection(this._serverPath.origin),this._apiPaths=null!==(a=e.webauthnApiPaths)&&void 0!==a?a:this.getDefaultPaths(),this._clientId=t,D.set("clientId",t)}catch(t){throw new u("Invalid options.serverPath",{error:t})}}static getDefaultPaths(){var t;const e=this.isNewApiDomain(null===(t=this._serverPath)||void 0===t?void 0:t.hostname)?"/cis":"";return{startAuthentication:`${e}/v1/auth/webauthn/authenticate/start`,startRegistration:`${e}/v1/auth/webauthn/register/start`,initCrossDeviceAuthentication:`${e}/v1/auth/webauthn/cross-device/authenticate/init`,startCrossDeviceAuthentication:`${e}/v1/auth/webauthn/cross-device/authenticate/start`,startCrossDeviceRegistration:`${e}/v1/auth/webauthn/cross-device/register/start`,getCrossDeviceTicketStatus:`${e}/v1/auth/webauthn/cross-device/status`,attachDeviceToCrossDeviceSession:`${e}/v1/auth/webauthn/cross-device/attach-device`}}static getApiPaths(){return this._apiPaths}static async sendRequest(t,e,i){s.log(`[WebAuthn SDK] Calling ${e.method} ${t}...`);const a=new URL(this._serverPath);return a.pathname=t,i&&(a.search=i),fetch(a.toString(),e)}static async startRegistration(t){const e=await this.sendRequest(this._apiPaths.startRegistration,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r(r({client_id:this.getValidatedClientId(),username:t.username,display_name:t.displayName},t.timeout&&{timeout:t.timeout}),t.limitSingleCredentialToDevice&&{limit_single_credential_to_device:t.limitSingleCredentialToDevice}))});if(!(null==e?void 0:e.ok))throw new d("Failed to start registration",null==e?void 0:e.body);return await e.json()}static async startAuthentication(t){const e=await this.sendRequest(this._apiPaths.startAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r(r(r(r(r({client_id:this.getValidatedClientId()},t.username&&{username:t.username}),t.identifier&&{identifier:t.identifier}),t.identifierType&&{identifier_type:t.identifierType}),t.approvalData&&{approval_data:t.approvalData}),t.timeout&&{timeout:t.timeout}))});if(!(null==e?void 0:e.ok))throw new d("Failed to start authentication",null==e?void 0:e.body);return await e.json()}static async initCrossDeviceAuthentication(t){const e=await this.sendRequest(this._apiPaths.initCrossDeviceAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r(r({client_id:this.getValidatedClientId()},t.username&&{username:t.username}),t.approvalData&&{approval_data:t.approvalData}))});if(!(null==e?void 0:e.ok))throw new b(void 0,null==e?void 0:e.body);return await e.json()}static async getCrossDeviceTicketStatus(t){const e=await this.sendRequest(this._apiPaths.getCrossDeviceTicketStatus,{method:"GET"},`cross_device_ticket_id=${t.ticketId}`);if(!(null==e?void 0:e.ok))throw new C(void 0,null==e?void 0:e.body);return await e.json()}static async startCrossDeviceAuthentication(t){const e=await this.sendRequest(this._apiPaths.startCrossDeviceAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new d("Failed to start cross device authentication",null==e?void 0:e.body);return await e.json()}static async startCrossDeviceRegistration(t){const e=await this.sendRequest(this._apiPaths.startCrossDeviceRegistration,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new p("Failed to start cross device registration",null==e?void 0:e.body);return await e.json()}static async attachDeviceToCrossDeviceSession(t){const e=await this.sendRequest(this._apiPaths.attachDeviceToCrossDeviceSession,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new p("Failed to attach device to cross device session",null==e?void 0:e.body);return await e.json()}static getValidatedClientId(){var t;const e=null!==(t=this._clientId)&&void 0!==t?t:D.get("clientId");if(!e)throw new u("Missing clientId");return e}}var S,T,k,I;_.newApiDomains=["api.idsec-dev.com","api.idsec-stg.com"],function(t){t.InputAutofill="input-autofill",t.Modal="modal"}(S||(S={})),exports.WebauthnCrossDeviceStatus=void 0,(T=exports.WebauthnCrossDeviceStatus||(exports.WebauthnCrossDeviceStatus={})).Pending="pending",T.Scanned="scanned",T.Success="success",T.Error="error",T.Timeout="timeout",T.Aborted="aborted",function(t){t.toAuthenticationError=t=>A(t)?t:"NotAllowedError"===t.name?new h:"OperationError"===t.name?new w(t.message):"SecurityError"===t.name?new d(t.message):t===o.AuthenticationAbortedTimeout?new f:"AbortError"===t.name||t===o.AutofillAuthenticationAborted?new g:new d("Something went wrong during authentication",{error:t}),t.toRegistrationError=t=>A(t)?t:"NotAllowedError"===t.name?new v:"SecurityError"===t.name?new p(t.message):"InvalidStateError"===t.name?new m:t===o.RegistrationAbortedTimeout?new f:new p("Something went wrong during registration",{error:t})}(k||(k={})),function(t){t.processCredentialRequestOptions=t=>r(r({},t),{},{challenge:n.base64ToArrayBuffer(t.challenge),allowCredentials:t.allowCredentials.map((t=>r(r({},t),{},{id:n.base64ToArrayBuffer(t.id)})))}),t.processCredentialCreationOptions=(t,e)=>{var i;const a=JSON.parse(JSON.stringify(t));return a.challenge=n.base64ToArrayBuffer(t.challenge),a.user.id=n.base64ToArrayBuffer(t.user.id),(null==e?void 0:e.limitSingleCredentialToDevice)&&(a.excludeCredentials=null===(i=t.excludeCredentials)||void 0===i?void 0:i.map((t=>r(r({},t),{},{id:n.base64ToArrayBuffer(t.id)})))),(null==e?void 0:e.registerAsDiscoverable)?(a.authenticatorSelection.residentKey="preferred",a.authenticatorSelection.requireResidentKey=!0):(a.authenticatorSelection.residentKey="discouraged",a.authenticatorSelection.requireResidentKey=!1),a.authenticatorSelection.authenticatorAttachment=(null==e?void 0:e.allowCrossPlatformAuthenticators)?void 0:"platform",a},t.encodeAuthenticationResult=t=>{const{authenticatorAttachment:e}=t,i=t.response;return{id:t.id,rawId:n.arrayBufferToBase64(t.rawId),response:{authenticatorData:n.arrayBufferToBase64(i.authenticatorData),clientDataJSON:n.arrayBufferToBase64(i.clientDataJSON),signature:n.arrayBufferToBase64(i.signature),userHandle:n.arrayBufferToBase64(i.userHandle)},authenticatorAttachment:e,type:t.type}},t.encodeRegistrationResult=t=>{const{authenticatorAttachment:e}=t,i=t.response;return{id:t.id,rawId:n.arrayBufferToBase64(t.rawId),response:{attestationObject:n.arrayBufferToBase64(i.attestationObject),clientDataJSON:n.arrayBufferToBase64(i.clientDataJSON)},authenticatorAttachment:e,type:t.type}}}(I||(I={}));class P{async modal(t){try{const e=await this.performAuthentication(r(r({},t),{},{mediationType:S.Modal}));return n.jsonToBase64(e)}catch(t){throw k.toAuthenticationError(t)}}activateAutofill(t){const{handlers:e,username:i}=t,{onSuccess:a,onError:r,onReady:s}=e;this.performAuthentication({username:i,mediationType:S.InputAutofill,onReady:s}).then((t=>{a(n.jsonToBase64(t))})).catch((t=>{const e=k.toAuthenticationError(t);if(!r)throw e;r(e)}))}abortAutofill(){this.abortController&&this.abortController.abort(o.AutofillAuthenticationAborted)}abortAuthentication(){this.abortController&&this.abortController.abort(o.AuthenticationAbortedTimeout)}async performAuthentication(t){var e,i;const a="crossDeviceTicketId"in t?await _.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await _.startAuthentication({username:t.username,identifier:t.identifier,identifierType:t.identifierType,timeout:null===(e=t.options)||void 0===e?void 0:e.timeout}),r=a.credential_request_options,n=I.processCredentialRequestOptions(r),s=this.getMediatedCredentialRequest(n,t.mediationType);t.mediationType===S.InputAutofill&&(null===(i=t.onReady)||void 0===i||i.call(t));const o=await navigator.credentials.get(s).catch((t=>{throw k.toAuthenticationError(t)}));return{webauthnSessionId:a.webauthn_session_id,publicKeyCredential:I.encodeAuthenticationResult(o),userAgent:navigator.userAgent}}getMediatedCredentialRequest(t,e){const i={publicKey:t};return this.abortController=new AbortController,i.signal=this.abortController&&this.abortController.signal,e===S.InputAutofill?i.mediation="conditional":t.timeout&&setTimeout((()=>{this.abortAuthentication()}),t.timeout),i}}class O{constructor(t,e){this.handler=t,this.intervalInMs=e}begin(){var t;this.intervalId=window.setInterval((t=this.handler,async function(){t.isRunning||(t.isRunning=!0,await t(...arguments),t.isRunning=!1)}),this.intervalInMs)}stop(){clearInterval(this.intervalId)}}const R=/^[A-Za-z0-9\-_.: ]*$/;function j(t){if(t&&(!function(t){return Object.keys(t).length<=10}(t)||!function(t){const e=t=>"string"==typeof t,i=t=>R.test(t);return Object.keys(t).every((a=>e(a)&&e(t[a])&&i(a)&&i(t[a])))}(t)))throw s.error("Failed validating approval data"),new y("Provided approval data should have 10 properties max. Also, it should contain only \n alphanumeric characters, numbers, and the special characters: '-', '_', '.'")}class x{constructor(t,e,i){this.authenticationHandler=t,this.registrationHandler=e,this.approvalHandler=i,this.init={registration:async t=>(this.ticketStatus=exports.WebauthnCrossDeviceStatus.Pending,this.pollCrossDeviceSession(t.crossDeviceTicketId,t.handlers)),authentication:async t=>{const{username:e}=t,i=(await _.initCrossDeviceAuthentication(r({},e&&{username:e}))).cross_device_ticket_id;return this.ticketStatus=exports.WebauthnCrossDeviceStatus.Pending,this.pollCrossDeviceSession(i,t.handlers)},approval:async t=>{const{username:e,approvalData:i}=t;j(i);const a=(await _.initCrossDeviceAuthentication({username:e,approvalData:i})).cross_device_ticket_id;return this.ticketStatus=exports.WebauthnCrossDeviceStatus.Pending,this.pollCrossDeviceSession(a,t.handlers)}},this.authenticate={modal:async t=>this.authenticationHandler.modal({crossDeviceTicketId:t})},this.approve={modal:async t=>this.approvalHandler.modal({crossDeviceTicketId:t})}}async register(t){return this.registrationHandler.register(t)}async attachDevice(t){const e=await _.attachDeviceToCrossDeviceSession({ticketId:t});return r({status:e.status,startedAt:e.started_at},e.approval_data&&{approvalData:e.approval_data})}async pollCrossDeviceSession(t,e){return this.poller=new O((async()=>{var i,a;const r=await _.getCrossDeviceTicketStatus({ticketId:t}),n=r.status;if(n!==this.ticketStatus)switch(this.ticketStatus=n,n){case exports.WebauthnCrossDeviceStatus.Scanned:await e.onDeviceAttach();break;case exports.WebauthnCrossDeviceStatus.Error:case exports.WebauthnCrossDeviceStatus.Timeout:case exports.WebauthnCrossDeviceStatus.Aborted:await e.onFailure(r),null===(i=this.poller)||void 0===i||i.stop();break;case exports.WebauthnCrossDeviceStatus.Success:if("onCredentialRegister"in e)await e.onCredentialRegister();else{if(!r.session_id)throw new C("Cross device session is complete without returning session_id",r);await e.onCredentialAuthenticate(r.session_id)}null===(a=this.poller)||void 0===a||a.stop()}}),1e3),this.poller.begin(),setTimeout((()=>{var t;null===(t=this.poller)||void 0===t||t.stop(),e.onFailure({status:exports.WebauthnCrossDeviceStatus.Timeout})}),3e5),{crossDeviceTicketId:t,stop:()=>{var t;null===(t=this.poller)||void 0===t||t.stop()}}}}class K{async register(t){var e,i,a;this.abortController=new AbortController;const s=r({allowCrossPlatformAuthenticators:!("crossDeviceTicketId"in t),registerAsDiscoverable:!0},t.options);try{const r="crossDeviceTicketId"in t?await _.startCrossDeviceRegistration({ticketId:t.crossDeviceTicketId}):await _.startRegistration({username:t.username,displayName:(null===(e=t.options)||void 0===e?void 0:e.displayName)||t.username,timeout:null===(i=t.options)||void 0===i?void 0:i.timeout,limitSingleCredentialToDevice:null===(a=t.options)||void 0===a?void 0:a.limitSingleCredentialToDevice}),o=I.processCredentialCreationOptions(r.credential_creation_options,s);setTimeout((()=>{this.abortRegistration()}),o.timeout);const c=await this.registerCredential(o),l={webauthnSessionId:r.webauthn_session_id,publicKeyCredential:c,userAgent:navigator.userAgent};return n.jsonToBase64(l)}catch(t){throw k.toRegistrationError(t)}}abortRegistration(){this.abortController&&this.abortController.abort(o.RegistrationAbortedTimeout)}async registerCredential(t){const e=await navigator.credentials.create({publicKey:t,signal:this.abortController&&this.abortController.signal}).catch((t=>{throw k.toRegistrationError(t)}));return I.encodeRegistrationResult(e)}}class B{async modal(t){try{const e=await this.performApproval(t);return n.jsonToBase64(e)}catch(t){throw k.toAuthenticationError(t)}}async performApproval(t){"approvalData"in t&&j(t.approvalData);const e="crossDeviceTicketId"in t?await _.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await _.startAuthentication({username:t.username,approvalData:t.approvalData}),i=e.credential_request_options,a=I.processCredentialRequestOptions(i),r=await navigator.credentials.get({publicKey:a}).catch((t=>{throw k.toAuthenticationError(t)}));return{webauthnSessionId:e.webauthn_session_id,publicKeyCredential:I.encodeAuthenticationResult(r),userAgent:navigator.userAgent}}}class E{constructor(){this._initialized=!1,this._authenticationHandler=new P,this._registrationHandler=new K,this._approvalHandler=new B,this._crossDeviceHandler=new x(this._authenticationHandler,this._registrationHandler,this._approvalHandler),this.authenticate={modal:async t=>(this.initCheck(),this._authenticationHandler.modal(t)),autofill:{activate:t=>(this.initCheck(),this._authenticationHandler.activateAutofill(t)),abort:()=>this._authenticationHandler.abortAutofill()}},this.approve={modal:async t=>(this.initCheck(),this._approvalHandler.modal(t))},this.register=async t=>(this.initCheck(),this._registrationHandler.register(t)),this.crossDevice={init:{registration:async t=>(this.initCheck(),this._crossDeviceHandler.init.registration(t)),authentication:async t=>(this.initCheck(),this._crossDeviceHandler.init.authentication(t)),approval:async t=>(this.initCheck(),this._crossDeviceHandler.init.approval(t))},authenticate:{modal:async t=>(this.initCheck(),this._crossDeviceHandler.authenticate.modal(t))},approve:{modal:async t=>(this.initCheck(),this._crossDeviceHandler.approve.modal(t))},register:async t=>(this.initCheck(),this._crossDeviceHandler.register(t)),attachDevice:async t=>(this.initCheck(),this._crossDeviceHandler.attachDevice(t))},this.isPlatformAuthenticatorSupported=async()=>{var t;try{return await(null===(t=E.StaticPublicKeyCredential)||void 0===t?void 0:t.isUserVerifyingPlatformAuthenticatorAvailable())}catch(t){return!1}},this.isAutofillSupported=async()=>{var t,e;return!(!(null===(t=E.StaticPublicKeyCredential)||void 0===t?void 0:t.isConditionalMediationAvailable)||!await(null===(e=E.StaticPublicKeyCredential)||void 0===e?void 0:e.isConditionalMediationAvailable()))}}async init(t){const{clientId:e,options:i}=t;try{if(!e)throw new u("Invalid clientId",{clientId:e});if(i.webauthnApiPaths){const t=_.getDefaultPaths();if(function(t,e){const i=new Set(t),a=new Set(e);return[...t.filter((t=>!a.has(t))),...e.filter((t=>!i.has(t)))]}(Object.keys(i.webauthnApiPaths),Object.keys(t)).length)throw new u("Invalid custom paths",{customApiPaths:i.webauthnApiPaths})}_.init(e,i),this._initialized=!0}catch(t){throw A(t)?t:new u("Failed to initialize SDK")}}getDefaultPaths(){return this.initCheck(),_.getDefaultPaths()}getApiPaths(){return this.initCheck(),_.getApiPaths()}initCheck(){if(!this._initialized)throw new u}}E.StaticPublicKeyCredential=window.PublicKeyCredential;const N=new t("webauthn"),H=new E;N.events.on(N.events.MODULE_INITIALIZED,(()=>{var t;const e=N.moduleMetadata.getInitConfig();if(!(null===(t=null==e?void 0:e.webauthn)||void 0===t?void 0:t.serverPath))return;const{clientId:i,webauthn:a}=e;H.init({clientId:i,options:r({},a)})}));const W={modal:async t=>(H.initCheck(),H.authenticate.modal(t)),autofill:{activate:t=>{H.initCheck(),H.authenticate.autofill.activate(t)},abort:()=>{H.initCheck(),H.authenticate.autofill.abort()}}},q={modal:async t=>(H.initCheck(),H.approve.modal(t))};async function F(t){return H.initCheck(),H.register(t)}const{crossDevice:M}=H,{isPlatformAuthenticatorSupported:z}=H,{isAutofillSupported:J}=H,{getDefaultPaths:$}=H;window.localWebAuthnSDK=H;var U=Object.freeze({__proto__:null,get WebauthnCrossDeviceStatus(){return exports.WebauthnCrossDeviceStatus},approve:q,authenticate:W,crossDevice:M,getDefaultPaths:$,isAutofillSupported:J,isPlatformAuthenticatorSupported:z,register:F});const V={initialize:e.initialize,...U};Object.defineProperty(exports,"initialize",{enumerable:!0,get:function(){return e.initialize}}),exports.PACKAGE_VERSION="2.4.1",exports.approve=q,exports.authenticate=W,exports.crossDevice=M,exports.getDefaultPaths=$,exports.isAutofillSupported=J,exports.isPlatformAuthenticatorSupported=z,exports.register=F,exports.webauthn=V;
package/dist/webauthn.js CHANGED
@@ -1 +1 @@
1
- "undefined"==typeof globalThis&&("undefined"!=typeof window?(window.globalThis=window,window.global=window):"undefined"!=typeof self&&(self.globalThis=self,self.global=self));import t from"./common.js";import{initialize as e}from"./common.js";export{initialize}from"./common.js";function i(t,e,i){return(e=function(t){var e=function(t,e){if("object"!=typeof t||!t)return t;var i=t[Symbol.toPrimitive];if(void 0!==i){var a=i.call(t,e||"default");if("object"!=typeof a)return a;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(t,"string");return"symbol"==typeof e?e:e+""}(e))in t?Object.defineProperty(t,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):t[e]=i,t}function a(t,e){var i=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);e&&(a=a.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),i.push.apply(i,a)}return i}function n(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?a(Object(n),!0).forEach((function(e){i(t,e,n[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))}))}return t}class r{static arrayBufferToBase64(t){return btoa(String.fromCharCode(...new Uint8Array(t)))}static base64ToArrayBuffer(t){return Uint8Array.from(atob(t),(t=>t.charCodeAt(0)))}static stringToBase64(t){return btoa(t)}static jsonToBase64(t){const e=JSON.stringify(t);return btoa(e)}static base64ToJson(t){const e=atob(t);return JSON.parse(e)}}const s={log:console.log,error:console.error};var o,c;!function(t){t.NotInitialized="not_initialized",t.AuthenticationFailed="authentication_failed",t.AuthenticationAbortedTimeout="authentication_aborted_timeout",t.AuthenticationCanceled="webauthn_authentication_canceled",t.RegistrationFailed="registration_failed",t.AlreadyRegistered="username_already_registered",t.RegistrationAbortedTimeout="registration_aborted_timeout",t.RegistrationCanceled="webauthn_registration_canceled",t.AutofillAuthenticationAborted="autofill_authentication_aborted",t.AuthenticationProcessAlreadyActive="authentication_process_already_active",t.InvalidApprovalData="invalid_approval_data",t.FailedToInitCrossDeviceSession="cross_device_init_failed",t.FailedToGetCrossDeviceStatus="cross_device_status_failed",t.Unknown="unknown"}(o||(o={}));class l extends Error{constructor(t,e){super(t),this.errorCode=o.NotInitialized,this.data=e}}class d extends l{constructor(t,e){super(null!=t?t:"WebAuthnSdk is not initialized",e),this.errorCode=o.NotInitialized}}class u extends l{constructor(t,e){super(null!=t?t:"Authentication failed with an error",e),this.errorCode=o.AuthenticationFailed}}class h extends l{constructor(t,e){super(null!=t?t:"Authentication was canceled by the user or got timeout",e),this.errorCode=o.AuthenticationCanceled}}class p extends l{constructor(t,e){super(null!=t?t:"Registration failed with an error",e),this.errorCode=o.RegistrationFailed}}class v extends l{constructor(t,e){super(null!=t?t:"Registration was canceled by the user or got timeout",e),this.errorCode=o.RegistrationCanceled}}class g extends l{constructor(t){super(null!=t?t:"Autofill flow was aborted"),this.errorCode=o.AutofillAuthenticationAborted}}class m extends l{constructor(t){super(null!=t?t:"Operation was aborted by timeout"),this.errorCode=o.AutofillAuthenticationAborted}}class f extends l{constructor(t){super(null!=t?t:"Passkey with this username is already registered with the relying party."),this.errorCode=o.AlreadyRegistered}}class w extends l{constructor(t,e){super(null!=t?t:"Authentication process is already active",e),this.errorCode=o.AuthenticationProcessAlreadyActive}}class y extends l{constructor(t,e){super(null!=t?t:"Invalid approval data",e),this.errorCode=o.InvalidApprovalData}}class b extends l{constructor(t,e){super(null!=t?t:"Failed to init cross device authentication",e),this.errorCode=o.FailedToInitCrossDeviceSession}}class A extends l{constructor(t,e){super(null!=t?t:"Failed to get cross device status",e),this.errorCode=o.FailedToGetCrossDeviceStatus}}function C(t){return t.errorCode&&Object.values(o).includes(t.errorCode)}!function(t){t[t.persistent=0]="persistent",t[t.session=1]="session"}(c||(c={}));class _{static get(t){return _.getStorageMedium(_.allowedKeys[t]).getItem(_.getStorageKey(t))||void 0}static set(t,e){return _.getStorageMedium(_.allowedKeys[t]).setItem(_.getStorageKey(t),e)}static remove(t){_.getStorageMedium(_.allowedKeys[t]).removeItem(_.getStorageKey(t))}static clear(t){for(const[e,i]of Object.entries(_.allowedKeys)){const a=e;t&&this.configurationKeys.includes(a)||_.getStorageMedium(i).removeItem(_.getStorageKey(a))}}static getStorageKey(t){return`WebAuthnSdk:${t}`}static getStorageMedium(t){return t===c.session?sessionStorage:localStorage}}_.allowedKeys={clientId:c.session},_.configurationKeys=["clientId"];class D{static isNewApiDomain(t){return t&&(this.newApiDomains.includes(t)||t.startsWith("api.")&&t.endsWith(".transmitsecurity.io")||t.startsWith("api.")&&t.endsWith(".idsec-dev.com"))}static dnsPrefetch(t){const e=document.createElement("link");e.rel="dns-prefetch",e.href=t,document.head.appendChild(e)}static preconnect(t,e){const i=document.createElement("link");i.rel="preconnect",i.href=t,e&&(i.crossOrigin="anonymous"),document.head.appendChild(i)}static warmupConnection(t){this.dnsPrefetch(t),this.preconnect(t,!1),this.preconnect(t,!0)}static init(t,e){var i,a;try{this._serverPath=new URL(e.serverPath),this.isNewApiDomain(null===(i=this._serverPath)||void 0===i?void 0:i.hostname)&&this.warmupConnection(this._serverPath.origin),this._apiPaths=null!==(a=e.webauthnApiPaths)&&void 0!==a?a:this.getDefaultPaths(),this._clientId=t,_.set("clientId",t)}catch(t){throw new d("Invalid options.serverPath",{error:t})}}static getDefaultPaths(){var t;const e=this.isNewApiDomain(null===(t=this._serverPath)||void 0===t?void 0:t.hostname)?"/cis":"";return{startAuthentication:`${e}/v1/auth/webauthn/authenticate/start`,startRegistration:`${e}/v1/auth/webauthn/register/start`,initCrossDeviceAuthentication:`${e}/v1/auth/webauthn/cross-device/authenticate/init`,startCrossDeviceAuthentication:`${e}/v1/auth/webauthn/cross-device/authenticate/start`,startCrossDeviceRegistration:`${e}/v1/auth/webauthn/cross-device/register/start`,getCrossDeviceTicketStatus:`${e}/v1/auth/webauthn/cross-device/status`,attachDeviceToCrossDeviceSession:`${e}/v1/auth/webauthn/cross-device/attach-device`}}static getApiPaths(){return this._apiPaths}static async sendRequest(t,e,i){s.log(`[WebAuthn SDK] Calling ${e.method} ${t}...`);const a=new URL(this._serverPath);return a.pathname=t,i&&(a.search=i),fetch(a.toString(),e)}static async startRegistration(t){const e=await this.sendRequest(this._apiPaths.startRegistration,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n(n({client_id:this.getValidatedClientId(),username:t.username,display_name:t.displayName},t.timeout&&{timeout:t.timeout}),t.limitSingleCredentialToDevice&&{limit_single_credential_to_device:t.limitSingleCredentialToDevice}))});if(!(null==e?void 0:e.ok))throw new u("Failed to start registration",null==e?void 0:e.body);return await e.json()}static async startAuthentication(t){const e=await this.sendRequest(this._apiPaths.startAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n(n(n(n(n({client_id:this.getValidatedClientId()},t.username&&{username:t.username}),t.identifier&&{identifier:t.identifier}),t.identifierType&&{identifier_type:t.identifierType}),t.approvalData&&{approval_data:t.approvalData}),t.timeout&&{timeout:t.timeout}))});if(!(null==e?void 0:e.ok))throw new u("Failed to start authentication",null==e?void 0:e.body);return await e.json()}static async initCrossDeviceAuthentication(t){const e=await this.sendRequest(this._apiPaths.initCrossDeviceAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n(n({client_id:this.getValidatedClientId()},t.username&&{username:t.username}),t.approvalData&&{approval_data:t.approvalData}))});if(!(null==e?void 0:e.ok))throw new b(void 0,null==e?void 0:e.body);return await e.json()}static async getCrossDeviceTicketStatus(t){const e=await this.sendRequest(this._apiPaths.getCrossDeviceTicketStatus,{method:"GET"},`cross_device_ticket_id=${t.ticketId}`);if(!(null==e?void 0:e.ok))throw new A(void 0,null==e?void 0:e.body);return await e.json()}static async startCrossDeviceAuthentication(t){const e=await this.sendRequest(this._apiPaths.startCrossDeviceAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new u("Failed to start cross device authentication",null==e?void 0:e.body);return await e.json()}static async startCrossDeviceRegistration(t){const e=await this.sendRequest(this._apiPaths.startCrossDeviceRegistration,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new p("Failed to start cross device registration",null==e?void 0:e.body);return await e.json()}static async attachDeviceToCrossDeviceSession(t){const e=await this.sendRequest(this._apiPaths.attachDeviceToCrossDeviceSession,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new p("Failed to attach device to cross device session",null==e?void 0:e.body);return await e.json()}static getValidatedClientId(){var t;const e=null!==(t=this._clientId)&&void 0!==t?t:_.get("clientId");if(!e)throw new d("Missing clientId");return e}}var S,T,k,I;D.newApiDomains=["api.idsec-dev.com","api.idsec-stg.com"],function(t){t.InputAutofill="input-autofill",t.Modal="modal"}(S||(S={})),function(t){t.Pending="pending",t.Scanned="scanned",t.Success="success",t.Error="error",t.Timeout="timeout",t.Aborted="aborted"}(T||(T={})),function(t){t.toAuthenticationError=t=>C(t)?t:"NotAllowedError"===t.name?new h:"OperationError"===t.name?new w(t.message):"SecurityError"===t.name?new u(t.message):t===o.AuthenticationAbortedTimeout?new m:"AbortError"===t.name||t===o.AutofillAuthenticationAborted?new g:new u("Something went wrong during authentication",{error:t}),t.toRegistrationError=t=>C(t)?t:"NotAllowedError"===t.name?new v:"SecurityError"===t.name?new p(t.message):"InvalidStateError"===t.name?new f:t===o.RegistrationAbortedTimeout?new m:new p("Something went wrong during registration",{error:t})}(k||(k={})),function(t){t.processCredentialRequestOptions=t=>n(n({},t),{},{challenge:r.base64ToArrayBuffer(t.challenge),allowCredentials:t.allowCredentials.map((t=>n(n({},t),{},{id:r.base64ToArrayBuffer(t.id)})))}),t.processCredentialCreationOptions=(t,e)=>{var i;const a=JSON.parse(JSON.stringify(t));return a.challenge=r.base64ToArrayBuffer(t.challenge),a.user.id=r.base64ToArrayBuffer(t.user.id),(null==e?void 0:e.limitSingleCredentialToDevice)&&(a.excludeCredentials=null===(i=t.excludeCredentials)||void 0===i?void 0:i.map((t=>n(n({},t),{},{id:r.base64ToArrayBuffer(t.id)})))),(null==e?void 0:e.registerAsDiscoverable)?(a.authenticatorSelection.residentKey="preferred",a.authenticatorSelection.requireResidentKey=!0):(a.authenticatorSelection.residentKey="discouraged",a.authenticatorSelection.requireResidentKey=!1),a.authenticatorSelection.authenticatorAttachment=(null==e?void 0:e.allowCrossPlatformAuthenticators)?void 0:"platform",a},t.encodeAuthenticationResult=t=>{const{authenticatorAttachment:e}=t,i=t.response;return{id:t.id,rawId:r.arrayBufferToBase64(t.rawId),response:{authenticatorData:r.arrayBufferToBase64(i.authenticatorData),clientDataJSON:r.arrayBufferToBase64(i.clientDataJSON),signature:r.arrayBufferToBase64(i.signature),userHandle:r.arrayBufferToBase64(i.userHandle)},authenticatorAttachment:e,type:t.type}},t.encodeRegistrationResult=t=>{const{authenticatorAttachment:e}=t,i=t.response;return{id:t.id,rawId:r.arrayBufferToBase64(t.rawId),response:{attestationObject:r.arrayBufferToBase64(i.attestationObject),clientDataJSON:r.arrayBufferToBase64(i.clientDataJSON)},authenticatorAttachment:e,type:t.type}}}(I||(I={}));class P{async modal(t){try{const e=await this.performAuthentication(n(n({},t),{},{mediationType:S.Modal}));return r.jsonToBase64(e)}catch(t){throw k.toAuthenticationError(t)}}activateAutofill(t){const{handlers:e,username:i}=t,{onSuccess:a,onError:n,onReady:s}=e;this.performAuthentication({username:i,mediationType:S.InputAutofill,onReady:s}).then((t=>{a(r.jsonToBase64(t))})).catch((t=>{const e=k.toAuthenticationError(t);if(!n)throw e;n(e)}))}abortAutofill(){this.abortController&&this.abortController.abort(o.AutofillAuthenticationAborted)}abortAuthentication(){this.abortController&&this.abortController.abort(o.AuthenticationAbortedTimeout)}async performAuthentication(t){var e,i;const a="crossDeviceTicketId"in t?await D.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await D.startAuthentication({username:t.username,identifier:t.identifier,identifierType:t.identifierType,timeout:null===(e=t.options)||void 0===e?void 0:e.timeout}),n=a.credential_request_options,r=I.processCredentialRequestOptions(n),s=this.getMediatedCredentialRequest(r,t.mediationType);t.mediationType===S.InputAutofill&&(null===(i=t.onReady)||void 0===i||i.call(t));const o=await navigator.credentials.get(s).catch((t=>{throw k.toAuthenticationError(t)}));return{webauthnSessionId:a.webauthn_session_id,publicKeyCredential:I.encodeAuthenticationResult(o),userAgent:navigator.userAgent}}getMediatedCredentialRequest(t,e){const i={publicKey:t};return this.abortController=new AbortController,i.signal=this.abortController&&this.abortController.signal,e===S.InputAutofill?i.mediation="conditional":t.timeout&&setTimeout((()=>{this.abortAuthentication()}),t.timeout),i}}class O{constructor(t,e){this.handler=t,this.intervalInMs=e}begin(){var t;this.intervalId=window.setInterval((t=this.handler,async function(){t.isRunning||(t.isRunning=!0,await t(...arguments),t.isRunning=!1)}),this.intervalInMs)}stop(){clearInterval(this.intervalId)}}const R=/^[A-Za-z0-9\-_.: ]*$/;function j(t){if(t&&(!function(t){return Object.keys(t).length<=10}(t)||!function(t){const e=t=>"string"==typeof t,i=t=>R.test(t);return Object.keys(t).every((a=>e(a)&&e(t[a])&&i(a)&&i(t[a])))}(t)))throw s.error("Failed validating approval data"),new y("Provided approval data should have 10 properties max. Also, it should contain only \n alphanumeric characters, numbers, and the special characters: '-', '_', '.'")}class B{constructor(t,e,i){this.authenticationHandler=t,this.registrationHandler=e,this.approvalHandler=i,this.init={registration:async t=>(this.ticketStatus=T.Pending,this.pollCrossDeviceSession(t.crossDeviceTicketId,t.handlers)),authentication:async t=>{const{username:e}=t,i=(await D.initCrossDeviceAuthentication(n({},e&&{username:e}))).cross_device_ticket_id;return this.ticketStatus=T.Pending,this.pollCrossDeviceSession(i,t.handlers)},approval:async t=>{const{username:e,approvalData:i}=t;j(i);const a=(await D.initCrossDeviceAuthentication({username:e,approvalData:i})).cross_device_ticket_id;return this.ticketStatus=T.Pending,this.pollCrossDeviceSession(a,t.handlers)}},this.authenticate={modal:async t=>this.authenticationHandler.modal({crossDeviceTicketId:t})},this.approve={modal:async t=>this.approvalHandler.modal({crossDeviceTicketId:t})}}async register(t){return this.registrationHandler.register(t)}async attachDevice(t){const e=await D.attachDeviceToCrossDeviceSession({ticketId:t});return n({status:e.status,startedAt:e.started_at},e.approval_data&&{approvalData:e.approval_data})}async pollCrossDeviceSession(t,e){return this.poller=new O((async()=>{var i,a;const n=await D.getCrossDeviceTicketStatus({ticketId:t}),r=n.status;if(r!==this.ticketStatus)switch(this.ticketStatus=r,r){case T.Scanned:await e.onDeviceAttach();break;case T.Error:case T.Timeout:case T.Aborted:await e.onFailure(n),null===(i=this.poller)||void 0===i||i.stop();break;case T.Success:if("onCredentialRegister"in e)await e.onCredentialRegister();else{if(!n.session_id)throw new A("Cross device session is complete without returning session_id",n);await e.onCredentialAuthenticate(n.session_id)}null===(a=this.poller)||void 0===a||a.stop()}}),1e3),this.poller.begin(),setTimeout((()=>{var t;null===(t=this.poller)||void 0===t||t.stop(),e.onFailure({status:T.Timeout})}),3e5),{crossDeviceTicketId:t,stop:()=>{var t;null===(t=this.poller)||void 0===t||t.stop()}}}}class K{async register(t){var e,i,a;this.abortController=new AbortController;const s=n({allowCrossPlatformAuthenticators:!("crossDeviceTicketId"in t),registerAsDiscoverable:!0},t.options);try{const n="crossDeviceTicketId"in t?await D.startCrossDeviceRegistration({ticketId:t.crossDeviceTicketId}):await D.startRegistration({username:t.username,displayName:(null===(e=t.options)||void 0===e?void 0:e.displayName)||t.username,timeout:null===(i=t.options)||void 0===i?void 0:i.timeout,limitSingleCredentialToDevice:null===(a=t.options)||void 0===a?void 0:a.limitSingleCredentialToDevice}),o=I.processCredentialCreationOptions(n.credential_creation_options,s);setTimeout((()=>{this.abortRegistration()}),o.timeout);const c=await this.registerCredential(o),l={webauthnSessionId:n.webauthn_session_id,publicKeyCredential:c,userAgent:navigator.userAgent};return r.jsonToBase64(l)}catch(t){throw k.toRegistrationError(t)}}abortRegistration(){this.abortController&&this.abortController.abort(o.RegistrationAbortedTimeout)}async registerCredential(t){const e=await navigator.credentials.create({publicKey:t,signal:this.abortController&&this.abortController.signal}).catch((t=>{throw k.toRegistrationError(t)}));return I.encodeRegistrationResult(e)}}class E{async modal(t){try{const e=await this.performApproval(t);return r.jsonToBase64(e)}catch(t){throw k.toAuthenticationError(t)}}async performApproval(t){"approvalData"in t&&j(t.approvalData);const e="crossDeviceTicketId"in t?await D.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await D.startAuthentication({username:t.username,approvalData:t.approvalData}),i=e.credential_request_options,a=I.processCredentialRequestOptions(i),n=await navigator.credentials.get({publicKey:a}).catch((t=>{throw k.toAuthenticationError(t)}));return{webauthnSessionId:e.webauthn_session_id,publicKeyCredential:I.encodeAuthenticationResult(n),userAgent:navigator.userAgent}}}class H{constructor(){this._initialized=!1,this._authenticationHandler=new P,this._registrationHandler=new K,this._approvalHandler=new E,this._crossDeviceHandler=new B(this._authenticationHandler,this._registrationHandler,this._approvalHandler),this.authenticate={modal:async t=>(this.initCheck(),this._authenticationHandler.modal(t)),autofill:{activate:t=>(this.initCheck(),this._authenticationHandler.activateAutofill(t)),abort:()=>this._authenticationHandler.abortAutofill()}},this.approve={modal:async t=>(this.initCheck(),this._approvalHandler.modal(t))},this.register=async t=>(this.initCheck(),this._registrationHandler.register(t)),this.crossDevice={init:{registration:async t=>(this.initCheck(),this._crossDeviceHandler.init.registration(t)),authentication:async t=>(this.initCheck(),this._crossDeviceHandler.init.authentication(t)),approval:async t=>(this.initCheck(),this._crossDeviceHandler.init.approval(t))},authenticate:{modal:async t=>(this.initCheck(),this._crossDeviceHandler.authenticate.modal(t))},approve:{modal:async t=>(this.initCheck(),this._crossDeviceHandler.approve.modal(t))},register:async t=>(this.initCheck(),this._crossDeviceHandler.register(t)),attachDevice:async t=>(this.initCheck(),this._crossDeviceHandler.attachDevice(t))},this.isPlatformAuthenticatorSupported=async()=>{var t;try{return await(null===(t=H.StaticPublicKeyCredential)||void 0===t?void 0:t.isUserVerifyingPlatformAuthenticatorAvailable())}catch(t){return!1}},this.isAutofillSupported=async()=>{var t,e;return!(!(null===(t=H.StaticPublicKeyCredential)||void 0===t?void 0:t.isConditionalMediationAvailable)||!await(null===(e=H.StaticPublicKeyCredential)||void 0===e?void 0:e.isConditionalMediationAvailable()))}}async init(t){const{clientId:e,options:i}=t;try{if(!e)throw new d("Invalid clientId",{clientId:e});if(i.webauthnApiPaths){const t=D.getDefaultPaths();if(function(t,e){const i=new Set(t),a=new Set(e);return[...t.filter((t=>!a.has(t))),...e.filter((t=>!i.has(t)))]}(Object.keys(i.webauthnApiPaths),Object.keys(t)).length)throw new d("Invalid custom paths",{customApiPaths:i.webauthnApiPaths})}D.init(e,i),this._initialized=!0}catch(t){throw C(t)?t:new d("Failed to initialize SDK")}}getDefaultPaths(){return this.initCheck(),D.getDefaultPaths()}getApiPaths(){return this.initCheck(),D.getApiPaths()}initCheck(){if(!this._initialized)throw new d}}H.StaticPublicKeyCredential=window.PublicKeyCredential;const N=new t("webauthn"),F=new H;N.events.on(N.events.MODULE_INITIALIZED,(()=>{var t;const e=N.moduleMetadata.getInitConfig();if(!(null===(t=null==e?void 0:e.webauthn)||void 0===t?void 0:t.serverPath))return;const{clientId:i,webauthn:a}=e;F.init({clientId:i,options:n({},a)})}));const x={modal:async t=>(F.initCheck(),F.authenticate.modal(t)),autofill:{activate:t=>{F.initCheck(),F.authenticate.autofill.activate(t)},abort:()=>{F.initCheck(),F.authenticate.autofill.abort()}}},q={modal:async t=>(F.initCheck(),F.approve.modal(t))};async function M(t){return F.initCheck(),F.register(t)}const{crossDevice:J}=F,{isPlatformAuthenticatorSupported:z}=F,{isAutofillSupported:$}=F,{getDefaultPaths:W}=F;window.localWebAuthnSDK=F;const U="2.3.2-beta-26093939905.0",V={initialize:e,...Object.freeze({__proto__:null,get WebauthnCrossDeviceStatus(){return T},approve:q,authenticate:x,crossDevice:J,getDefaultPaths:W,isAutofillSupported:$,isPlatformAuthenticatorSupported:z,register:M})};export{U as PACKAGE_VERSION,T as WebauthnCrossDeviceStatus,q as approve,x as authenticate,J as crossDevice,W as getDefaultPaths,$ as isAutofillSupported,z as isPlatformAuthenticatorSupported,M as register,V as webauthn};
1
+ "undefined"==typeof globalThis&&("undefined"!=typeof window?(window.globalThis=window,window.global=window):"undefined"!=typeof self&&(self.globalThis=self,self.global=self));import t from"./common.js";import{initialize as e}from"./common.js";export{initialize}from"./common.js";function i(t,e,i){return(e=function(t){var e=function(t,e){if("object"!=typeof t||!t)return t;var i=t[Symbol.toPrimitive];if(void 0!==i){var a=i.call(t,e||"default");if("object"!=typeof a)return a;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(t,"string");return"symbol"==typeof e?e:e+""}(e))in t?Object.defineProperty(t,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):t[e]=i,t}function a(t,e){var i=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);e&&(a=a.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),i.push.apply(i,a)}return i}function n(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?a(Object(n),!0).forEach((function(e){i(t,e,n[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))}))}return t}class r{static arrayBufferToBase64(t){return btoa(String.fromCharCode(...new Uint8Array(t)))}static base64ToArrayBuffer(t){return Uint8Array.from(atob(t),(t=>t.charCodeAt(0)))}static stringToBase64(t){return btoa(t)}static jsonToBase64(t){const e=JSON.stringify(t);return btoa(e)}static base64ToJson(t){const e=atob(t);return JSON.parse(e)}}const s={log:console.log,error:console.error};var o,c;!function(t){t.NotInitialized="not_initialized",t.AuthenticationFailed="authentication_failed",t.AuthenticationAbortedTimeout="authentication_aborted_timeout",t.AuthenticationCanceled="webauthn_authentication_canceled",t.RegistrationFailed="registration_failed",t.AlreadyRegistered="username_already_registered",t.RegistrationAbortedTimeout="registration_aborted_timeout",t.RegistrationCanceled="webauthn_registration_canceled",t.AutofillAuthenticationAborted="autofill_authentication_aborted",t.AuthenticationProcessAlreadyActive="authentication_process_already_active",t.InvalidApprovalData="invalid_approval_data",t.FailedToInitCrossDeviceSession="cross_device_init_failed",t.FailedToGetCrossDeviceStatus="cross_device_status_failed",t.Unknown="unknown"}(o||(o={}));class l extends Error{constructor(t,e){super(t),this.errorCode=o.NotInitialized,this.data=e}}class d extends l{constructor(t,e){super(null!=t?t:"WebAuthnSdk is not initialized",e),this.errorCode=o.NotInitialized}}class u extends l{constructor(t,e){super(null!=t?t:"Authentication failed with an error",e),this.errorCode=o.AuthenticationFailed}}class h extends l{constructor(t,e){super(null!=t?t:"Authentication was canceled by the user or got timeout",e),this.errorCode=o.AuthenticationCanceled}}class p extends l{constructor(t,e){super(null!=t?t:"Registration failed with an error",e),this.errorCode=o.RegistrationFailed}}class v extends l{constructor(t,e){super(null!=t?t:"Registration was canceled by the user or got timeout",e),this.errorCode=o.RegistrationCanceled}}class g extends l{constructor(t){super(null!=t?t:"Autofill flow was aborted"),this.errorCode=o.AutofillAuthenticationAborted}}class m extends l{constructor(t){super(null!=t?t:"Operation was aborted by timeout"),this.errorCode=o.AutofillAuthenticationAborted}}class f extends l{constructor(t){super(null!=t?t:"Passkey with this username is already registered with the relying party."),this.errorCode=o.AlreadyRegistered}}class w extends l{constructor(t,e){super(null!=t?t:"Authentication process is already active",e),this.errorCode=o.AuthenticationProcessAlreadyActive}}class y extends l{constructor(t,e){super(null!=t?t:"Invalid approval data",e),this.errorCode=o.InvalidApprovalData}}class b extends l{constructor(t,e){super(null!=t?t:"Failed to init cross device authentication",e),this.errorCode=o.FailedToInitCrossDeviceSession}}class A extends l{constructor(t,e){super(null!=t?t:"Failed to get cross device status",e),this.errorCode=o.FailedToGetCrossDeviceStatus}}function C(t){return t.errorCode&&Object.values(o).includes(t.errorCode)}!function(t){t[t.persistent=0]="persistent",t[t.session=1]="session"}(c||(c={}));class _{static get(t){return _.getStorageMedium(_.allowedKeys[t]).getItem(_.getStorageKey(t))||void 0}static set(t,e){return _.getStorageMedium(_.allowedKeys[t]).setItem(_.getStorageKey(t),e)}static remove(t){_.getStorageMedium(_.allowedKeys[t]).removeItem(_.getStorageKey(t))}static clear(t){for(const[e,i]of Object.entries(_.allowedKeys)){const a=e;t&&this.configurationKeys.includes(a)||_.getStorageMedium(i).removeItem(_.getStorageKey(a))}}static getStorageKey(t){return`WebAuthnSdk:${t}`}static getStorageMedium(t){return t===c.session?sessionStorage:localStorage}}_.allowedKeys={clientId:c.session},_.configurationKeys=["clientId"];class D{static isNewApiDomain(t){return t&&(this.newApiDomains.includes(t)||t.startsWith("api.")&&t.endsWith(".transmitsecurity.io")||t.startsWith("api.")&&t.endsWith(".idsec-dev.com"))}static dnsPrefetch(t){const e=document.createElement("link");e.rel="dns-prefetch",e.href=t,document.head.appendChild(e)}static preconnect(t,e){const i=document.createElement("link");i.rel="preconnect",i.href=t,e&&(i.crossOrigin="anonymous"),document.head.appendChild(i)}static warmupConnection(t){this.dnsPrefetch(t),this.preconnect(t,!1),this.preconnect(t,!0)}static init(t,e){var i,a;try{this._serverPath=new URL(e.serverPath),this.isNewApiDomain(null===(i=this._serverPath)||void 0===i?void 0:i.hostname)&&this.warmupConnection(this._serverPath.origin),this._apiPaths=null!==(a=e.webauthnApiPaths)&&void 0!==a?a:this.getDefaultPaths(),this._clientId=t,_.set("clientId",t)}catch(t){throw new d("Invalid options.serverPath",{error:t})}}static getDefaultPaths(){var t;const e=this.isNewApiDomain(null===(t=this._serverPath)||void 0===t?void 0:t.hostname)?"/cis":"";return{startAuthentication:`${e}/v1/auth/webauthn/authenticate/start`,startRegistration:`${e}/v1/auth/webauthn/register/start`,initCrossDeviceAuthentication:`${e}/v1/auth/webauthn/cross-device/authenticate/init`,startCrossDeviceAuthentication:`${e}/v1/auth/webauthn/cross-device/authenticate/start`,startCrossDeviceRegistration:`${e}/v1/auth/webauthn/cross-device/register/start`,getCrossDeviceTicketStatus:`${e}/v1/auth/webauthn/cross-device/status`,attachDeviceToCrossDeviceSession:`${e}/v1/auth/webauthn/cross-device/attach-device`}}static getApiPaths(){return this._apiPaths}static async sendRequest(t,e,i){s.log(`[WebAuthn SDK] Calling ${e.method} ${t}...`);const a=new URL(this._serverPath);return a.pathname=t,i&&(a.search=i),fetch(a.toString(),e)}static async startRegistration(t){const e=await this.sendRequest(this._apiPaths.startRegistration,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n(n({client_id:this.getValidatedClientId(),username:t.username,display_name:t.displayName},t.timeout&&{timeout:t.timeout}),t.limitSingleCredentialToDevice&&{limit_single_credential_to_device:t.limitSingleCredentialToDevice}))});if(!(null==e?void 0:e.ok))throw new u("Failed to start registration",null==e?void 0:e.body);return await e.json()}static async startAuthentication(t){const e=await this.sendRequest(this._apiPaths.startAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n(n(n(n(n({client_id:this.getValidatedClientId()},t.username&&{username:t.username}),t.identifier&&{identifier:t.identifier}),t.identifierType&&{identifier_type:t.identifierType}),t.approvalData&&{approval_data:t.approvalData}),t.timeout&&{timeout:t.timeout}))});if(!(null==e?void 0:e.ok))throw new u("Failed to start authentication",null==e?void 0:e.body);return await e.json()}static async initCrossDeviceAuthentication(t){const e=await this.sendRequest(this._apiPaths.initCrossDeviceAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n(n({client_id:this.getValidatedClientId()},t.username&&{username:t.username}),t.approvalData&&{approval_data:t.approvalData}))});if(!(null==e?void 0:e.ok))throw new b(void 0,null==e?void 0:e.body);return await e.json()}static async getCrossDeviceTicketStatus(t){const e=await this.sendRequest(this._apiPaths.getCrossDeviceTicketStatus,{method:"GET"},`cross_device_ticket_id=${t.ticketId}`);if(!(null==e?void 0:e.ok))throw new A(void 0,null==e?void 0:e.body);return await e.json()}static async startCrossDeviceAuthentication(t){const e=await this.sendRequest(this._apiPaths.startCrossDeviceAuthentication,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new u("Failed to start cross device authentication",null==e?void 0:e.body);return await e.json()}static async startCrossDeviceRegistration(t){const e=await this.sendRequest(this._apiPaths.startCrossDeviceRegistration,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new p("Failed to start cross device registration",null==e?void 0:e.body);return await e.json()}static async attachDeviceToCrossDeviceSession(t){const e=await this.sendRequest(this._apiPaths.attachDeviceToCrossDeviceSession,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cross_device_ticket_id:t.ticketId})});if(!(null==e?void 0:e.ok))throw new p("Failed to attach device to cross device session",null==e?void 0:e.body);return await e.json()}static getValidatedClientId(){var t;const e=null!==(t=this._clientId)&&void 0!==t?t:_.get("clientId");if(!e)throw new d("Missing clientId");return e}}var S,T,k,I;D.newApiDomains=["api.idsec-dev.com","api.idsec-stg.com"],function(t){t.InputAutofill="input-autofill",t.Modal="modal"}(S||(S={})),function(t){t.Pending="pending",t.Scanned="scanned",t.Success="success",t.Error="error",t.Timeout="timeout",t.Aborted="aborted"}(T||(T={})),function(t){t.toAuthenticationError=t=>C(t)?t:"NotAllowedError"===t.name?new h:"OperationError"===t.name?new w(t.message):"SecurityError"===t.name?new u(t.message):t===o.AuthenticationAbortedTimeout?new m:"AbortError"===t.name||t===o.AutofillAuthenticationAborted?new g:new u("Something went wrong during authentication",{error:t}),t.toRegistrationError=t=>C(t)?t:"NotAllowedError"===t.name?new v:"SecurityError"===t.name?new p(t.message):"InvalidStateError"===t.name?new f:t===o.RegistrationAbortedTimeout?new m:new p("Something went wrong during registration",{error:t})}(k||(k={})),function(t){t.processCredentialRequestOptions=t=>n(n({},t),{},{challenge:r.base64ToArrayBuffer(t.challenge),allowCredentials:t.allowCredentials.map((t=>n(n({},t),{},{id:r.base64ToArrayBuffer(t.id)})))}),t.processCredentialCreationOptions=(t,e)=>{var i;const a=JSON.parse(JSON.stringify(t));return a.challenge=r.base64ToArrayBuffer(t.challenge),a.user.id=r.base64ToArrayBuffer(t.user.id),(null==e?void 0:e.limitSingleCredentialToDevice)&&(a.excludeCredentials=null===(i=t.excludeCredentials)||void 0===i?void 0:i.map((t=>n(n({},t),{},{id:r.base64ToArrayBuffer(t.id)})))),(null==e?void 0:e.registerAsDiscoverable)?(a.authenticatorSelection.residentKey="preferred",a.authenticatorSelection.requireResidentKey=!0):(a.authenticatorSelection.residentKey="discouraged",a.authenticatorSelection.requireResidentKey=!1),a.authenticatorSelection.authenticatorAttachment=(null==e?void 0:e.allowCrossPlatformAuthenticators)?void 0:"platform",a},t.encodeAuthenticationResult=t=>{const{authenticatorAttachment:e}=t,i=t.response;return{id:t.id,rawId:r.arrayBufferToBase64(t.rawId),response:{authenticatorData:r.arrayBufferToBase64(i.authenticatorData),clientDataJSON:r.arrayBufferToBase64(i.clientDataJSON),signature:r.arrayBufferToBase64(i.signature),userHandle:r.arrayBufferToBase64(i.userHandle)},authenticatorAttachment:e,type:t.type}},t.encodeRegistrationResult=t=>{const{authenticatorAttachment:e}=t,i=t.response;return{id:t.id,rawId:r.arrayBufferToBase64(t.rawId),response:{attestationObject:r.arrayBufferToBase64(i.attestationObject),clientDataJSON:r.arrayBufferToBase64(i.clientDataJSON)},authenticatorAttachment:e,type:t.type}}}(I||(I={}));class P{async modal(t){try{const e=await this.performAuthentication(n(n({},t),{},{mediationType:S.Modal}));return r.jsonToBase64(e)}catch(t){throw k.toAuthenticationError(t)}}activateAutofill(t){const{handlers:e,username:i}=t,{onSuccess:a,onError:n,onReady:s}=e;this.performAuthentication({username:i,mediationType:S.InputAutofill,onReady:s}).then((t=>{a(r.jsonToBase64(t))})).catch((t=>{const e=k.toAuthenticationError(t);if(!n)throw e;n(e)}))}abortAutofill(){this.abortController&&this.abortController.abort(o.AutofillAuthenticationAborted)}abortAuthentication(){this.abortController&&this.abortController.abort(o.AuthenticationAbortedTimeout)}async performAuthentication(t){var e,i;const a="crossDeviceTicketId"in t?await D.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await D.startAuthentication({username:t.username,identifier:t.identifier,identifierType:t.identifierType,timeout:null===(e=t.options)||void 0===e?void 0:e.timeout}),n=a.credential_request_options,r=I.processCredentialRequestOptions(n),s=this.getMediatedCredentialRequest(r,t.mediationType);t.mediationType===S.InputAutofill&&(null===(i=t.onReady)||void 0===i||i.call(t));const o=await navigator.credentials.get(s).catch((t=>{throw k.toAuthenticationError(t)}));return{webauthnSessionId:a.webauthn_session_id,publicKeyCredential:I.encodeAuthenticationResult(o),userAgent:navigator.userAgent}}getMediatedCredentialRequest(t,e){const i={publicKey:t};return this.abortController=new AbortController,i.signal=this.abortController&&this.abortController.signal,e===S.InputAutofill?i.mediation="conditional":t.timeout&&setTimeout((()=>{this.abortAuthentication()}),t.timeout),i}}class O{constructor(t,e){this.handler=t,this.intervalInMs=e}begin(){var t;this.intervalId=window.setInterval((t=this.handler,async function(){t.isRunning||(t.isRunning=!0,await t(...arguments),t.isRunning=!1)}),this.intervalInMs)}stop(){clearInterval(this.intervalId)}}const R=/^[A-Za-z0-9\-_.: ]*$/;function j(t){if(t&&(!function(t){return Object.keys(t).length<=10}(t)||!function(t){const e=t=>"string"==typeof t,i=t=>R.test(t);return Object.keys(t).every((a=>e(a)&&e(t[a])&&i(a)&&i(t[a])))}(t)))throw s.error("Failed validating approval data"),new y("Provided approval data should have 10 properties max. Also, it should contain only \n alphanumeric characters, numbers, and the special characters: '-', '_', '.'")}class B{constructor(t,e,i){this.authenticationHandler=t,this.registrationHandler=e,this.approvalHandler=i,this.init={registration:async t=>(this.ticketStatus=T.Pending,this.pollCrossDeviceSession(t.crossDeviceTicketId,t.handlers)),authentication:async t=>{const{username:e}=t,i=(await D.initCrossDeviceAuthentication(n({},e&&{username:e}))).cross_device_ticket_id;return this.ticketStatus=T.Pending,this.pollCrossDeviceSession(i,t.handlers)},approval:async t=>{const{username:e,approvalData:i}=t;j(i);const a=(await D.initCrossDeviceAuthentication({username:e,approvalData:i})).cross_device_ticket_id;return this.ticketStatus=T.Pending,this.pollCrossDeviceSession(a,t.handlers)}},this.authenticate={modal:async t=>this.authenticationHandler.modal({crossDeviceTicketId:t})},this.approve={modal:async t=>this.approvalHandler.modal({crossDeviceTicketId:t})}}async register(t){return this.registrationHandler.register(t)}async attachDevice(t){const e=await D.attachDeviceToCrossDeviceSession({ticketId:t});return n({status:e.status,startedAt:e.started_at},e.approval_data&&{approvalData:e.approval_data})}async pollCrossDeviceSession(t,e){return this.poller=new O((async()=>{var i,a;const n=await D.getCrossDeviceTicketStatus({ticketId:t}),r=n.status;if(r!==this.ticketStatus)switch(this.ticketStatus=r,r){case T.Scanned:await e.onDeviceAttach();break;case T.Error:case T.Timeout:case T.Aborted:await e.onFailure(n),null===(i=this.poller)||void 0===i||i.stop();break;case T.Success:if("onCredentialRegister"in e)await e.onCredentialRegister();else{if(!n.session_id)throw new A("Cross device session is complete without returning session_id",n);await e.onCredentialAuthenticate(n.session_id)}null===(a=this.poller)||void 0===a||a.stop()}}),1e3),this.poller.begin(),setTimeout((()=>{var t;null===(t=this.poller)||void 0===t||t.stop(),e.onFailure({status:T.Timeout})}),3e5),{crossDeviceTicketId:t,stop:()=>{var t;null===(t=this.poller)||void 0===t||t.stop()}}}}class K{async register(t){var e,i,a;this.abortController=new AbortController;const s=n({allowCrossPlatformAuthenticators:!("crossDeviceTicketId"in t),registerAsDiscoverable:!0},t.options);try{const n="crossDeviceTicketId"in t?await D.startCrossDeviceRegistration({ticketId:t.crossDeviceTicketId}):await D.startRegistration({username:t.username,displayName:(null===(e=t.options)||void 0===e?void 0:e.displayName)||t.username,timeout:null===(i=t.options)||void 0===i?void 0:i.timeout,limitSingleCredentialToDevice:null===(a=t.options)||void 0===a?void 0:a.limitSingleCredentialToDevice}),o=I.processCredentialCreationOptions(n.credential_creation_options,s);setTimeout((()=>{this.abortRegistration()}),o.timeout);const c=await this.registerCredential(o),l={webauthnSessionId:n.webauthn_session_id,publicKeyCredential:c,userAgent:navigator.userAgent};return r.jsonToBase64(l)}catch(t){throw k.toRegistrationError(t)}}abortRegistration(){this.abortController&&this.abortController.abort(o.RegistrationAbortedTimeout)}async registerCredential(t){const e=await navigator.credentials.create({publicKey:t,signal:this.abortController&&this.abortController.signal}).catch((t=>{throw k.toRegistrationError(t)}));return I.encodeRegistrationResult(e)}}class E{async modal(t){try{const e=await this.performApproval(t);return r.jsonToBase64(e)}catch(t){throw k.toAuthenticationError(t)}}async performApproval(t){"approvalData"in t&&j(t.approvalData);const e="crossDeviceTicketId"in t?await D.startCrossDeviceAuthentication({ticketId:t.crossDeviceTicketId}):await D.startAuthentication({username:t.username,approvalData:t.approvalData}),i=e.credential_request_options,a=I.processCredentialRequestOptions(i),n=await navigator.credentials.get({publicKey:a}).catch((t=>{throw k.toAuthenticationError(t)}));return{webauthnSessionId:e.webauthn_session_id,publicKeyCredential:I.encodeAuthenticationResult(n),userAgent:navigator.userAgent}}}class H{constructor(){this._initialized=!1,this._authenticationHandler=new P,this._registrationHandler=new K,this._approvalHandler=new E,this._crossDeviceHandler=new B(this._authenticationHandler,this._registrationHandler,this._approvalHandler),this.authenticate={modal:async t=>(this.initCheck(),this._authenticationHandler.modal(t)),autofill:{activate:t=>(this.initCheck(),this._authenticationHandler.activateAutofill(t)),abort:()=>this._authenticationHandler.abortAutofill()}},this.approve={modal:async t=>(this.initCheck(),this._approvalHandler.modal(t))},this.register=async t=>(this.initCheck(),this._registrationHandler.register(t)),this.crossDevice={init:{registration:async t=>(this.initCheck(),this._crossDeviceHandler.init.registration(t)),authentication:async t=>(this.initCheck(),this._crossDeviceHandler.init.authentication(t)),approval:async t=>(this.initCheck(),this._crossDeviceHandler.init.approval(t))},authenticate:{modal:async t=>(this.initCheck(),this._crossDeviceHandler.authenticate.modal(t))},approve:{modal:async t=>(this.initCheck(),this._crossDeviceHandler.approve.modal(t))},register:async t=>(this.initCheck(),this._crossDeviceHandler.register(t)),attachDevice:async t=>(this.initCheck(),this._crossDeviceHandler.attachDevice(t))},this.isPlatformAuthenticatorSupported=async()=>{var t;try{return await(null===(t=H.StaticPublicKeyCredential)||void 0===t?void 0:t.isUserVerifyingPlatformAuthenticatorAvailable())}catch(t){return!1}},this.isAutofillSupported=async()=>{var t,e;return!(!(null===(t=H.StaticPublicKeyCredential)||void 0===t?void 0:t.isConditionalMediationAvailable)||!await(null===(e=H.StaticPublicKeyCredential)||void 0===e?void 0:e.isConditionalMediationAvailable()))}}async init(t){const{clientId:e,options:i}=t;try{if(!e)throw new d("Invalid clientId",{clientId:e});if(i.webauthnApiPaths){const t=D.getDefaultPaths();if(function(t,e){const i=new Set(t),a=new Set(e);return[...t.filter((t=>!a.has(t))),...e.filter((t=>!i.has(t)))]}(Object.keys(i.webauthnApiPaths),Object.keys(t)).length)throw new d("Invalid custom paths",{customApiPaths:i.webauthnApiPaths})}D.init(e,i),this._initialized=!0}catch(t){throw C(t)?t:new d("Failed to initialize SDK")}}getDefaultPaths(){return this.initCheck(),D.getDefaultPaths()}getApiPaths(){return this.initCheck(),D.getApiPaths()}initCheck(){if(!this._initialized)throw new d}}H.StaticPublicKeyCredential=window.PublicKeyCredential;const N=new t("webauthn"),F=new H;N.events.on(N.events.MODULE_INITIALIZED,(()=>{var t;const e=N.moduleMetadata.getInitConfig();if(!(null===(t=null==e?void 0:e.webauthn)||void 0===t?void 0:t.serverPath))return;const{clientId:i,webauthn:a}=e;F.init({clientId:i,options:n({},a)})}));const x={modal:async t=>(F.initCheck(),F.authenticate.modal(t)),autofill:{activate:t=>{F.initCheck(),F.authenticate.autofill.activate(t)},abort:()=>{F.initCheck(),F.authenticate.autofill.abort()}}},q={modal:async t=>(F.initCheck(),F.approve.modal(t))};async function M(t){return F.initCheck(),F.register(t)}const{crossDevice:J}=F,{isPlatformAuthenticatorSupported:z}=F,{isAutofillSupported:$}=F,{getDefaultPaths:W}=F;window.localWebAuthnSDK=F;const U="2.4.1",V={initialize:e,...Object.freeze({__proto__:null,get WebauthnCrossDeviceStatus(){return T},approve:q,authenticate:x,crossDevice:J,getDefaultPaths:W,isAutofillSupported:$,isPlatformAuthenticatorSupported:z,register:M})};export{U as PACKAGE_VERSION,T as WebauthnCrossDeviceStatus,q as approve,x as authenticate,J as crossDevice,W as getDefaultPaths,$ as isAutofillSupported,z as isPlatformAuthenticatorSupported,M as register,V as webauthn};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transmitsecurity/platform-web-sdk",
3
- "version": "2.3.2-beta-26093939905.0",
3
+ "version": "2.4.1",
4
4
  "license": "MIT",
5
5
  "private": false,
6
6
  "type": "module",
@@ -75,12 +75,6 @@
75
75
  "devDependencies": {
76
76
  "@playwright/test": "^1.57.0",
77
77
  "@rollup/plugin-json": "6.1.0",
78
- "@transmit-security/authentication-sdk": "5.0.1",
79
- "@transmit-security/ido-web-sdk": "1.1.4",
80
- "@transmit-security/riskid_sdk": "2.2.1",
81
- "@transmit-security/ts-identity-verification": "1.4.29-alpha-26091689242.0",
82
- "@transmit-security/web-sdk-bundler": "0.2.0",
83
- "@transmit-security/web-sdk-common": "2.0.5",
84
78
  "@types/jest": "^29.5.0",
85
79
  "@types/node": "20.3.3",
86
80
  "jest": "^29.5.0",
@@ -100,5 +94,5 @@
100
94
  "identity"
101
95
  ],
102
96
  "description": "Transmit Security Web SDK - Browser-only authentication and identity verification",
103
- "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
97
+ "packageManager": "yarn@1.22.22+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610"
104
98
  }