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