@authsignal/browser 0.3.7 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { AddAuthenticatorRequest, AddAuthenticatorResponse, AuthenticationOptsRequest, AuthenticationOptsResponse, RegistrationOptsRequest, RegistrationOptsResponse, VerifyRequest, VerifyResponse } from "./types";
1
+ import { AddAuthenticatorRequest, AddAuthenticatorResponse, AuthenticationOptsRequest, AuthenticationOptsResponse, PasskeyAuthenticatorResponse, RegistrationOptsRequest, RegistrationOptsResponse, VerifyRequest, VerifyResponse } from "./types";
2
2
  declare type PasskeyApiClientOptions = {
3
3
  baseUrl: string;
4
4
  tenantId: string;
@@ -7,10 +7,11 @@ export declare class PasskeyApiClient {
7
7
  tenantId: string;
8
8
  baseUrl: string;
9
9
  constructor({ baseUrl, tenantId }: PasskeyApiClientOptions);
10
- registrationOptions({ token, userName }: RegistrationOptsRequest): Promise<RegistrationOptsResponse>;
10
+ registrationOptions({ token, userName, authenticatorAttachment, }: RegistrationOptsRequest): Promise<RegistrationOptsResponse>;
11
11
  authenticationOptions({ token }: AuthenticationOptsRequest): Promise<AuthenticationOptsResponse>;
12
12
  addAuthenticator({ token, ...rest }: AddAuthenticatorRequest): Promise<AddAuthenticatorResponse>;
13
13
  verify({ token, ...rest }: VerifyRequest): Promise<VerifyResponse>;
14
+ getPasskeyAuthenticator(credentialId: string): Promise<PasskeyAuthenticatorResponse>;
14
15
  private buildHeaders;
15
16
  }
16
17
  export {};
@@ -1,7 +1,8 @@
1
- import { AuthenticationResponseJSON, PublicKeyCredentialCreationOptionsJSON, RegistrationResponseJSON } from "@simplewebauthn/types";
1
+ import { AuthenticationResponseJSON, AuthenticatorAttachment, PublicKeyCredentialCreationOptionsJSON, RegistrationResponseJSON } from "@simplewebauthn/types";
2
2
  export declare type RegistrationOptsRequest = {
3
3
  userName?: string;
4
4
  token: string;
5
+ authenticatorAttachment?: AuthenticatorAttachment | null;
5
6
  };
6
7
  export declare type RegistrationOptsResponse = {
7
8
  challengeId: string;
@@ -33,3 +34,7 @@ export declare type VerifyResponse = {
33
34
  isVerified: boolean;
34
35
  accessToken?: string;
35
36
  };
37
+ export declare type PasskeyAuthenticatorResponse = {
38
+ credentialId: string;
39
+ verifiedAt: string;
40
+ };
package/dist/index.js CHANGED
@@ -543,18 +543,21 @@ var PasskeyApiClient = /** @class */ (function () {
543
543
  this.baseUrl = baseUrl;
544
544
  }
545
545
  PasskeyApiClient.prototype.registrationOptions = function (_a) {
546
- var token = _a.token, userName = _a.userName;
546
+ var token = _a.token, userName = _a.userName, authenticatorAttachment = _a.authenticatorAttachment;
547
547
  return __awaiter(this, void 0, void 0, function () {
548
- var request;
548
+ var body, response;
549
549
  return __generator(this, function (_b) {
550
550
  switch (_b.label) {
551
551
  case 0:
552
- request = fetch("".concat(this.baseUrl, "/client/user-authenticators/passkey/registration-options"), {
552
+ body = Boolean(authenticatorAttachment)
553
+ ? { username: userName, authenticatorAttachment: authenticatorAttachment }
554
+ : { username: userName };
555
+ response = fetch("".concat(this.baseUrl, "/client/user-authenticators/passkey/registration-options"), {
553
556
  method: "POST",
554
557
  headers: this.buildHeaders(token),
555
- body: JSON.stringify({ username: userName })
558
+ body: JSON.stringify(body)
556
559
  });
557
- return [4 /*yield*/, request];
560
+ return [4 /*yield*/, response];
558
561
  case 1: return [2 /*return*/, (_b.sent()).json()];
559
562
  }
560
563
  });
@@ -563,16 +566,16 @@ var PasskeyApiClient = /** @class */ (function () {
563
566
  PasskeyApiClient.prototype.authenticationOptions = function (_a) {
564
567
  var token = _a.token;
565
568
  return __awaiter(this, void 0, void 0, function () {
566
- var request;
569
+ var response;
567
570
  return __generator(this, function (_b) {
568
571
  switch (_b.label) {
569
572
  case 0:
570
- request = fetch("".concat(this.baseUrl, "/client/user-authenticators/passkey/authentication-options"), {
573
+ response = fetch("".concat(this.baseUrl, "/client/user-authenticators/passkey/authentication-options"), {
571
574
  method: "POST",
572
575
  headers: this.buildHeaders(token),
573
576
  body: JSON.stringify({})
574
577
  });
575
- return [4 /*yield*/, request];
578
+ return [4 /*yield*/, response];
576
579
  case 1: return [2 /*return*/, (_b.sent()).json()];
577
580
  }
578
581
  });
@@ -581,16 +584,16 @@ var PasskeyApiClient = /** @class */ (function () {
581
584
  PasskeyApiClient.prototype.addAuthenticator = function (_a) {
582
585
  var token = _a.token, rest = __rest(_a, ["token"]);
583
586
  return __awaiter(this, void 0, void 0, function () {
584
- var request;
587
+ var response;
585
588
  return __generator(this, function (_b) {
586
589
  switch (_b.label) {
587
590
  case 0:
588
- request = fetch("".concat(this.baseUrl, "/client/user-authenticators/passkey"), {
591
+ response = fetch("".concat(this.baseUrl, "/client/user-authenticators/passkey"), {
589
592
  method: "POST",
590
593
  headers: this.buildHeaders(token),
591
594
  body: JSON.stringify(rest)
592
595
  });
593
- return [4 /*yield*/, request];
596
+ return [4 /*yield*/, response];
594
597
  case 1: return [2 /*return*/, (_b.sent()).json()];
595
598
  }
596
599
  });
@@ -599,21 +602,40 @@ var PasskeyApiClient = /** @class */ (function () {
599
602
  PasskeyApiClient.prototype.verify = function (_a) {
600
603
  var token = _a.token, rest = __rest(_a, ["token"]);
601
604
  return __awaiter(this, void 0, void 0, function () {
602
- var request;
605
+ var response;
603
606
  return __generator(this, function (_b) {
604
607
  switch (_b.label) {
605
608
  case 0:
606
- request = fetch("".concat(this.baseUrl, "/client/verify/passkey"), {
609
+ response = fetch("".concat(this.baseUrl, "/client/verify/passkey"), {
607
610
  method: "POST",
608
611
  headers: this.buildHeaders(token),
609
612
  body: JSON.stringify(rest)
610
613
  });
611
- return [4 /*yield*/, request];
614
+ return [4 /*yield*/, response];
612
615
  case 1: return [2 /*return*/, (_b.sent()).json()];
613
616
  }
614
617
  });
615
618
  });
616
619
  };
620
+ PasskeyApiClient.prototype.getPasskeyAuthenticator = function (credentialId) {
621
+ return __awaiter(this, void 0, void 0, function () {
622
+ var response;
623
+ return __generator(this, function (_a) {
624
+ switch (_a.label) {
625
+ case 0: return [4 /*yield*/, fetch("".concat(this.baseUrl, "/client/user-authenticators/passkey?credentialId=").concat(credentialId), {
626
+ method: "GET",
627
+ headers: this.buildHeaders()
628
+ })];
629
+ case 1:
630
+ response = _a.sent();
631
+ if (!response.ok) {
632
+ throw new Error(response.statusText);
633
+ }
634
+ return [2 /*return*/, response.json()];
635
+ }
636
+ });
637
+ });
638
+ };
617
639
  PasskeyApiClient.prototype.buildHeaders = function (token) {
618
640
  var authorizationHeader = token ? "Bearer ".concat(token) : "Basic ".concat(window.btoa(encodeURIComponent(this.tenantId)));
619
641
  return {
@@ -627,27 +649,31 @@ var PasskeyApiClient = /** @class */ (function () {
627
649
  var Passkey = /** @class */ (function () {
628
650
  function Passkey(_a) {
629
651
  var baseUrl = _a.baseUrl, tenantId = _a.tenantId;
652
+ this.passkeyLocalStorageKey = "as_passkey_credential_id";
630
653
  this.api = new PasskeyApiClient({ baseUrl: baseUrl, tenantId: tenantId });
631
654
  }
632
655
  Passkey.prototype.signUp = function (_a) {
633
- var userName = _a.userName, token = _a.token;
656
+ var userName = _a.userName, token = _a.token, _b = _a.authenticatorAttachment, authenticatorAttachment = _b === void 0 ? "platform" : _b;
634
657
  return __awaiter(this, void 0, void 0, function () {
635
658
  var optionsResponse, registrationResponse, addAuthenticatorResponse;
636
- return __generator(this, function (_b) {
637
- switch (_b.label) {
638
- case 0: return [4 /*yield*/, this.api.registrationOptions({ userName: userName, token: token })];
659
+ return __generator(this, function (_c) {
660
+ switch (_c.label) {
661
+ case 0: return [4 /*yield*/, this.api.registrationOptions({ userName: userName, token: token, authenticatorAttachment: authenticatorAttachment })];
639
662
  case 1:
640
- optionsResponse = _b.sent();
663
+ optionsResponse = _c.sent();
641
664
  return [4 /*yield*/, startRegistration(optionsResponse.options)];
642
665
  case 2:
643
- registrationResponse = _b.sent();
666
+ registrationResponse = _c.sent();
644
667
  return [4 /*yield*/, this.api.addAuthenticator({
645
668
  challengeId: optionsResponse.challengeId,
646
669
  registrationCredential: registrationResponse,
647
670
  token: token
648
671
  })];
649
672
  case 3:
650
- addAuthenticatorResponse = _b.sent();
673
+ addAuthenticatorResponse = _c.sent();
674
+ if (addAuthenticatorResponse === null || addAuthenticatorResponse === void 0 ? void 0 : addAuthenticatorResponse.isVerified) {
675
+ this.storeCredentialAgainstDevice(registrationResponse);
676
+ }
651
677
  return [2 /*return*/, addAuthenticatorResponse === null || addAuthenticatorResponse === void 0 ? void 0 : addAuthenticatorResponse.accessToken];
652
678
  }
653
679
  });
@@ -675,11 +701,46 @@ var Passkey = /** @class */ (function () {
675
701
  })];
676
702
  case 3:
677
703
  verifyResponse = _a.sent();
704
+ if (verifyResponse === null || verifyResponse === void 0 ? void 0 : verifyResponse.isVerified) {
705
+ this.storeCredentialAgainstDevice(authenticationResponse);
706
+ }
678
707
  return [2 /*return*/, verifyResponse === null || verifyResponse === void 0 ? void 0 : verifyResponse.accessToken];
679
708
  }
680
709
  });
681
710
  });
682
711
  };
712
+ Passkey.prototype.isAvailableOnDevice = function () {
713
+ return __awaiter(this, void 0, void 0, function () {
714
+ var credentialId;
715
+ return __generator(this, function (_b) {
716
+ switch (_b.label) {
717
+ case 0:
718
+ credentialId = localStorage.getItem(this.passkeyLocalStorageKey);
719
+ if (!credentialId) {
720
+ return [2 /*return*/, false];
721
+ }
722
+ _b.label = 1;
723
+ case 1:
724
+ _b.trys.push([1, 3, , 4]);
725
+ return [4 /*yield*/, this.api.getPasskeyAuthenticator(credentialId)];
726
+ case 2:
727
+ _b.sent();
728
+ return [2 /*return*/, true];
729
+ case 3:
730
+ _b.sent();
731
+ return [2 /*return*/, false];
732
+ case 4: return [2 /*return*/];
733
+ }
734
+ });
735
+ });
736
+ };
737
+ Passkey.prototype.storeCredentialAgainstDevice = function (_a) {
738
+ var id = _a.id, authenticatorAttachment = _a.authenticatorAttachment;
739
+ if (authenticatorAttachment === "cross-platform") {
740
+ return;
741
+ }
742
+ localStorage.setItem(this.passkeyLocalStorageKey, id);
743
+ };
683
744
  return Passkey;
684
745
  }());
685
746
 
package/dist/index.min.js CHANGED
@@ -1 +1 @@
1
- var authsignal=function(t){"use strict";let e;const n=new Uint8Array(16);function o(){if(!e&&(e="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!e))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return e(n)}const i=[];for(let t=0;t<256;++t)i.push((t+256).toString(16).slice(1));var r={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};function a(t,e,n){if(r.randomUUID&&!e&&!t)return r.randomUUID();const a=(t=t||{}).random||(t.rng||o)();if(a[6]=15&a[6]|64,a[8]=63&a[8]|128,e){n=n||0;for(let t=0;t<16;++t)e[n+t]=a[t];return e}return function(t,e=0){return(i[t[e+0]]+i[t[e+1]]+i[t[e+2]]+i[t[e+3]]+"-"+i[t[e+4]]+i[t[e+5]]+"-"+i[t[e+6]]+i[t[e+7]]+"-"+i[t[e+8]]+i[t[e+9]]+"-"+i[t[e+10]]+i[t[e+11]]+i[t[e+12]]+i[t[e+13]]+i[t[e+14]]+i[t[e+15]]).toLowerCase()}(a)}var s=function(t){var e=t.name,n=t.value,o=t.expire,i=t.domain,r=t.secure,a=o===1/0?" expires=Fri, 31 Dec 9999 23:59:59 GMT":"; max-age="+o;document.cookie=encodeURIComponent(e)+"="+n+"; path=/;"+a+(i?"; domain="+i:"")+(r?"; secure":"")};function c(t,e){var n={};for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&e.indexOf(o)<0&&(n[o]=t[o]);if(null!=t&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(o=Object.getOwnPropertySymbols(t);i<o.length;i++)e.indexOf(o[i])<0&&Object.prototype.propertyIsEnumerable.call(t,o[i])&&(n[o[i]]=t[o[i]])}return n}function u(t,e,n,o){return new(n||(n=Promise))((function(i,r){function a(t){try{c(o.next(t))}catch(t){r(t)}}function s(t){try{c(o.throw(t))}catch(t){r(t)}}function c(t){var e;t.done?i(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(a,s)}c((o=o.apply(t,e||[])).next())}))}function d(t,e){var n,o,i,r,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return r={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(r[Symbol.iterator]=function(){return this}),r;function s(r){return function(s){return function(r){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,o&&(i=2&r[0]?o.return:r[0]?o.throw||((i=o.return)&&i.call(o),0):o.next)&&!(i=i.call(o,r[1])).done)return i;switch(o=0,i&&(r=[2&r[0],i.value]),r[0]){case 0:case 1:i=r;break;case 4:return a.label++,{value:r[1],done:!1};case 5:a.label++,o=r[1],r=[0];continue;case 7:r=a.ops.pop(),a.trys.pop();continue;default:if(!(i=a.trys,(i=i.length>0&&i[i.length-1])||6!==r[0]&&2!==r[0])){a=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]<i[3])){a.label=r[1];break}if(6===r[0]&&a.label<i[1]){a.label=i[1],i=r;break}if(i&&a.label<i[2]){a.label=i[2],a.ops.push(r);break}i[2]&&a.ops.pop(),a.trys.pop();continue}r=e.call(t,a)}catch(t){r=[6,t],o=0}finally{n=i=0}if(5&r[0])throw r[1];return{value:r[0]?r[1]:void 0,done:!0}}([r,s])}}}function l(t){const e=new Uint8Array(t);let n="";for(const t of e)n+=String.fromCharCode(t);return btoa(n).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function h(t){const e=t.replace(/-/g,"+").replace(/_/g,"/"),n=(4-e.length%4)%4,o=e.padEnd(e.length+n,"="),i=atob(o),r=new ArrayBuffer(i.length),a=new Uint8Array(r);for(let t=0;t<i.length;t++)a[t]=i.charCodeAt(t);return r}function p(){return void 0!==window?.PublicKeyCredential&&"function"==typeof window.PublicKeyCredential}function f(t){const{id:e}=t;return{...t,id:h(e),transports:t.transports}}function w(t){return"localhost"===t||/^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/i.test(t)}t.AuthsignalWindowMessage=void 0,(t.AuthsignalWindowMessage||(t.AuthsignalWindowMessage={})).AUTHSIGNAL_CLOSE_POPUP="AUTHSIGNAL_CLOSE_POPUP";class m extends Error{constructor({message:t,code:e,cause:n,name:o}){super(t,{cause:n}),this.name=o??n.name,this.code=e}}const y=new class{createNewAbortSignal(){if(this.controller){const t=new Error("Cancelling existing WebAuthn API call for new one");t.name="AbortError",this.controller.abort(t)}const t=new AbortController;return this.controller=t,t.signal}cancelCeremony(){if(this.controller){const t=new Error("Manually cancelling existing WebAuthn API call");t.name="AbortError",this.controller.abort(t),this.controller=void 0}}},b=["cross-platform","platform"];function g(t){if(t&&!(b.indexOf(t)<0))return t}async function v(t){if(!p())throw new Error("WebAuthn is not supported in this browser");var e;const n={publicKey:{...t,challenge:h(t.challenge),user:{...t.user,id:(e=t.user.id,(new TextEncoder).encode(e))},excludeCredentials:t.excludeCredentials?.map(f)}};let o;n.signal=y.createNewAbortSignal();try{o=await navigator.credentials.create(n)}catch(t){throw function({error:t,options:e}){const{publicKey:n}=e;if(!n)throw Error("options was missing required publicKey property");if("AbortError"===t.name){if(e.signal instanceof AbortSignal)return new m({message:"Registration ceremony was sent an abort signal",code:"ERROR_CEREMONY_ABORTED",cause:t})}else if("ConstraintError"===t.name){if(!0===n.authenticatorSelection?.requireResidentKey)return new m({message:"Discoverable credentials were required but no available authenticator supported it",code:"ERROR_AUTHENTICATOR_MISSING_DISCOVERABLE_CREDENTIAL_SUPPORT",cause:t});if("required"===n.authenticatorSelection?.userVerification)return new m({message:"User verification was required but no available authenticator supported it",code:"ERROR_AUTHENTICATOR_MISSING_USER_VERIFICATION_SUPPORT",cause:t})}else{if("InvalidStateError"===t.name)return new m({message:"The authenticator was previously registered",code:"ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED",cause:t});if("NotAllowedError"===t.name)return new m({message:t.message,code:"ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",cause:t});if("NotSupportedError"===t.name)return 0===n.pubKeyCredParams.filter((t=>"public-key"===t.type)).length?new m({message:'No entry in pubKeyCredParams was of type "public-key"',code:"ERROR_MALFORMED_PUBKEYCREDPARAMS",cause:t}):new m({message:"No available authenticator supported any of the specified pubKeyCredParams algorithms",code:"ERROR_AUTHENTICATOR_NO_SUPPORTED_PUBKEYCREDPARAMS_ALG",cause:t});if("SecurityError"===t.name){const e=window.location.hostname;if(!w(e))return new m({message:`${window.location.hostname} is an invalid domain`,code:"ERROR_INVALID_DOMAIN",cause:t});if(n.rp.id!==e)return new m({message:`The RP ID "${n.rp.id}" is invalid for this domain`,code:"ERROR_INVALID_RP_ID",cause:t})}else if("TypeError"===t.name){if(n.user.id.byteLength<1||n.user.id.byteLength>64)return new m({message:"User ID was not between 1 and 64 characters",code:"ERROR_INVALID_USER_ID_LENGTH",cause:t})}else if("UnknownError"===t.name)return new m({message:"The authenticator was unable to process the specified options, or could not create a new credential",code:"ERROR_AUTHENTICATOR_GENERAL_ERROR",cause:t})}return t}({error:t,options:n})}if(!o)throw new Error("Registration was not completed");const{id:i,rawId:r,response:a,type:s}=o;let c,u,d,b;if("function"==typeof a.getTransports&&(c=a.getTransports()),"function"==typeof a.getPublicKeyAlgorithm)try{u=a.getPublicKeyAlgorithm()}catch(t){_("getPublicKeyAlgorithm()",t)}if("function"==typeof a.getPublicKey)try{const t=a.getPublicKey();null!==t&&(d=l(t))}catch(t){_("getPublicKey()",t)}if("function"==typeof a.getAuthenticatorData)try{b=l(a.getAuthenticatorData())}catch(t){_("getAuthenticatorData()",t)}return{id:i,rawId:l(r),response:{attestationObject:l(a.attestationObject),clientDataJSON:l(a.clientDataJSON),transports:c,publicKeyAlgorithm:u,publicKey:d,authenticatorData:b},type:s,clientExtensionResults:o.getClientExtensionResults(),authenticatorAttachment:g(o.authenticatorAttachment)}}function _(t,e){console.warn(`The browser extension that intercepted this WebAuthn API call incorrectly implemented ${t}. You should report this error to them.\n`,e)}async function E(t,e=!1){if(!p())throw new Error("WebAuthn is not supported in this browser");let n;0!==t.allowCredentials?.length&&(n=t.allowCredentials?.map(f));const o={...t,challenge:h(t.challenge),allowCredentials:n},i={};if(e){if(!await function(){const t=window.PublicKeyCredential;return void 0===t.isConditionalMediationAvailable?new Promise((t=>t(!1))):t.isConditionalMediationAvailable()}())throw Error("Browser does not support WebAuthn autofill");if(document.querySelectorAll("input[autocomplete$='webauthn']").length<1)throw Error('No <input> with "webauthn" as the only or last value in its `autocomplete` attribute was detected');i.mediation="conditional",o.allowCredentials=[]}let r;i.publicKey=o,i.signal=y.createNewAbortSignal();try{r=await navigator.credentials.get(i)}catch(t){throw function({error:t,options:e}){const{publicKey:n}=e;if(!n)throw Error("options was missing required publicKey property");if("AbortError"===t.name){if(e.signal instanceof AbortSignal)return new m({message:"Authentication ceremony was sent an abort signal",code:"ERROR_CEREMONY_ABORTED",cause:t})}else{if("NotAllowedError"===t.name)return new m({message:t.message,code:"ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",cause:t});if("SecurityError"===t.name){const e=window.location.hostname;if(!w(e))return new m({message:`${window.location.hostname} is an invalid domain`,code:"ERROR_INVALID_DOMAIN",cause:t});if(n.rpId!==e)return new m({message:`The RP ID "${n.rpId}" is invalid for this domain`,code:"ERROR_INVALID_RP_ID",cause:t})}else if("UnknownError"===t.name)return new m({message:"The authenticator was unable to process the specified options, or could not create a new assertion signature",code:"ERROR_AUTHENTICATOR_GENERAL_ERROR",cause:t})}return t}({error:t,options:i})}if(!r)throw new Error("Authentication was not completed");const{id:a,rawId:s,response:c,type:u}=r;let d;var b;return c.userHandle&&(b=c.userHandle,d=new TextDecoder("utf-8").decode(b)),{id:a,rawId:l(s),response:{authenticatorData:l(c.authenticatorData),clientDataJSON:l(c.clientDataJSON),signature:l(c.signature),userHandle:d},type:u,clientExtensionResults:r.getClientExtensionResults(),authenticatorAttachment:g(r.authenticatorAttachment)}}var A=function(){function t(t){var e=t.baseUrl,n=t.tenantId;this.tenantId=n,this.baseUrl=e}return t.prototype.registrationOptions=function(t){var e=t.token,n=t.userName;return u(this,void 0,void 0,(function(){return d(this,(function(t){switch(t.label){case 0:return[4,fetch("".concat(this.baseUrl,"/client/user-authenticators/passkey/registration-options"),{method:"POST",headers:this.buildHeaders(e),body:JSON.stringify({username:n})})];case 1:return[2,t.sent().json()]}}))}))},t.prototype.authenticationOptions=function(t){var e=t.token;return u(this,void 0,void 0,(function(){return d(this,(function(t){switch(t.label){case 0:return[4,fetch("".concat(this.baseUrl,"/client/user-authenticators/passkey/authentication-options"),{method:"POST",headers:this.buildHeaders(e),body:JSON.stringify({})})];case 1:return[2,t.sent().json()]}}))}))},t.prototype.addAuthenticator=function(t){var e=t.token,n=c(t,["token"]);return u(this,void 0,void 0,(function(){return d(this,(function(t){switch(t.label){case 0:return[4,fetch("".concat(this.baseUrl,"/client/user-authenticators/passkey"),{method:"POST",headers:this.buildHeaders(e),body:JSON.stringify(n)})];case 1:return[2,t.sent().json()]}}))}))},t.prototype.verify=function(t){var e=t.token,n=c(t,["token"]);return u(this,void 0,void 0,(function(){return d(this,(function(t){switch(t.label){case 0:return[4,fetch("".concat(this.baseUrl,"/client/verify/passkey"),{method:"POST",headers:this.buildHeaders(e),body:JSON.stringify(n)})];case 1:return[2,t.sent().json()]}}))}))},t.prototype.buildHeaders=function(t){return{"Content-Type":"application/json",Authorization:t?"Bearer ".concat(t):"Basic ".concat(window.btoa(encodeURIComponent(this.tenantId)))}},t}(),R=function(){function t(t){var e=t.baseUrl,n=t.tenantId;this.api=new A({baseUrl:e,tenantId:n})}return t.prototype.signUp=function(t){var e=t.userName,n=t.token;return u(this,void 0,void 0,(function(){var t,o,i;return d(this,(function(r){switch(r.label){case 0:return[4,this.api.registrationOptions({userName:e,token:n})];case 1:return[4,v((t=r.sent()).options)];case 2:return o=r.sent(),[4,this.api.addAuthenticator({challengeId:t.challengeId,registrationCredential:o,token:n})];case 3:return[2,null==(i=r.sent())?void 0:i.accessToken]}}))}))},t.prototype.signIn=function(t){return u(this,void 0,void 0,(function(){var e,n,o;return d(this,(function(i){switch(i.label){case 0:if((null==t?void 0:t.token)&&t.autofill)throw new Error("Autofill is not supported when providing a token");return[4,this.api.authenticationOptions({token:null==t?void 0:t.token})];case 1:return[4,E((e=i.sent()).options,null==t?void 0:t.autofill)];case 2:return n=i.sent(),[4,this.api.verify({challengeId:e.challengeId,authenticationCredential:n,token:null==t?void 0:t.token})];case 3:return[2,null==(o=i.sent())?void 0:o.accessToken]}}))}))},t}(),O=function(){function t(){this.windowRef=null}return t.prototype.show=function(t){var e=t.url,n=t.width,o=void 0===n?400:n,i=t.height,r=function(t){var e=t.url,n=t.width,o=t.height,i=t.win;if(!i.top)return null;var r=i.top.outerHeight/2+i.top.screenY-o/2,a=i.top.outerWidth/2+i.top.screenX-n/2;return window.open(e,"","toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=".concat(n,", height=").concat(o,", top=").concat(r,", left=").concat(a))}({url:e,width:o,height:void 0===i?500:i,win:window});if(!r)throw new Error("Window is not initialized");return this.windowRef=r,r},t.prototype.close=function(){if(!this.windowRef)throw new Error("Window is not initialized");this.windowRef.close()},t}();var I=['a[href]:not([tabindex^="-"])','area[href]:not([tabindex^="-"])','input:not([type="hidden"]):not([type="radio"]):not([disabled]):not([tabindex^="-"])','input[type="radio"]:not([disabled]):not([tabindex^="-"])','select:not([disabled]):not([tabindex^="-"])','textarea:not([disabled]):not([tabindex^="-"])','button:not([disabled]):not([tabindex^="-"])','iframe:not([tabindex^="-"])','audio[controls]:not([tabindex^="-"])','video[controls]:not([tabindex^="-"])','[contenteditable]:not([tabindex^="-"])','[tabindex]:not([tabindex^="-"])'];function S(t){this._show=this.show.bind(this),this._hide=this.hide.bind(this),this._maintainFocus=this._maintainFocus.bind(this),this._bindKeypress=this._bindKeypress.bind(this),this.$el=t,this.shown=!1,this._id=this.$el.getAttribute("data-a11y-dialog")||this.$el.id,this._previouslyFocused=null,this._listeners={},this.create()}function C(t,e){return n=(e||document).querySelectorAll(t),Array.prototype.slice.call(n);var n}function P(t){(t.querySelector("[autofocus]")||t).focus()}function k(){C("[data-a11y-dialog]").forEach((function(t){new S(t)}))}S.prototype.create=function(){this.$el.setAttribute("aria-hidden",!0),this.$el.setAttribute("aria-modal",!0),this.$el.setAttribute("tabindex",-1),this.$el.hasAttribute("role")||this.$el.setAttribute("role","dialog"),this._openers=C('[data-a11y-dialog-show="'+this._id+'"]'),this._openers.forEach(function(t){t.addEventListener("click",this._show)}.bind(this));const t=this.$el;return this._closers=C("[data-a11y-dialog-hide]",this.$el).filter((function(e){return e.closest('[aria-modal="true"], [data-a11y-dialog]')===t})).concat(C('[data-a11y-dialog-hide="'+this._id+'"]')),this._closers.forEach(function(t){t.addEventListener("click",this._hide)}.bind(this)),this._fire("create"),this},S.prototype.show=function(t){return this.shown||(this._previouslyFocused=document.activeElement,this.$el.removeAttribute("aria-hidden"),this.shown=!0,P(this.$el),document.body.addEventListener("focus",this._maintainFocus,!0),document.addEventListener("keydown",this._bindKeypress),this._fire("show",t)),this},S.prototype.hide=function(t){return this.shown?(this.shown=!1,this.$el.setAttribute("aria-hidden","true"),this._previouslyFocused&&this._previouslyFocused.focus&&this._previouslyFocused.focus(),document.body.removeEventListener("focus",this._maintainFocus,!0),document.removeEventListener("keydown",this._bindKeypress),this._fire("hide",t),this):this},S.prototype.destroy=function(){return this.hide(),this._openers.forEach(function(t){t.removeEventListener("click",this._show)}.bind(this)),this._closers.forEach(function(t){t.removeEventListener("click",this._hide)}.bind(this)),this._fire("destroy"),this._listeners={},this},S.prototype.on=function(t,e){return void 0===this._listeners[t]&&(this._listeners[t]=[]),this._listeners[t].push(e),this},S.prototype.off=function(t,e){var n=(this._listeners[t]||[]).indexOf(e);return n>-1&&this._listeners[t].splice(n,1),this},S.prototype._fire=function(t,e){var n=this._listeners[t]||[],o=new CustomEvent(t,{detail:e});this.$el.dispatchEvent(o),n.forEach(function(t){t(this.$el,e)}.bind(this))},S.prototype._bindKeypress=function(t){const e=document.activeElement;e&&e.closest('[aria-modal="true"]')!==this.$el||(this.shown&&"Escape"===t.key&&"alertdialog"!==this.$el.getAttribute("role")&&(t.preventDefault(),this.hide(t)),this.shown&&"Tab"===t.key&&function(t,e){var n=function(t){return C(I.join(","),t).filter((function(t){return!!(t.offsetWidth||t.offsetHeight||t.getClientRects().length)}))}(t),o=n.indexOf(document.activeElement);e.shiftKey&&0===o?(n[n.length-1].focus(),e.preventDefault()):e.shiftKey||o!==n.length-1||(n[0].focus(),e.preventDefault())}(this.$el,t))},S.prototype._maintainFocus=function(t){!this.shown||t.target.closest('[aria-modal="true"]')||t.target.closest("[data-a11y-dialog-ignore-focus-trap]")||P(this.$el)},"undefined"!=typeof document&&("loading"===document.readyState?document.addEventListener("DOMContentLoaded",k):window.requestAnimationFrame?window.requestAnimationFrame(k):window.setTimeout(k,16));var x="__authsignal-popup-container",U="__authsignal-popup-content",T="__authsignal-popup-overlay",N="__authsignal-popup-style",D="__authsignal-popup-iframe",L="385px",K=function(){function t(t){var e=t.width;if(this.popup=null,document.querySelector("#".concat(x)))throw new Error("Multiple instances of Authsignal popup is not supported.");this.create({width:e})}return t.prototype.create=function(t){var e=this,n=t.width,o=void 0===n?L:n,i=o;CSS.supports("width",o)||(console.warn("Invalid CSS value for `popupOptions.width`. Using default value instead."),i=L);var r=document.createElement("div");r.setAttribute("id",x),r.setAttribute("aria-hidden","true");var a=document.createElement("div");a.setAttribute("id",T),a.setAttribute("data-a11y-dialog-hide","true");var s=document.createElement("div");s.setAttribute("id",U),document.body.appendChild(r);var c=document.createElement("style");c.setAttribute("id",N),c.textContent="\n #".concat(x,",\n #").concat(T," {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n }\n\n #").concat(x," {\n z-index: 2147483647;\n display: flex;\n }\n\n #").concat(x,"[aria-hidden='true'] {\n display: none;\n }\n\n #").concat(T," {\n background-color: rgba(0, 0, 0, 0.18);\n }\n\n #").concat(U," {\n margin: auto;\n z-index: 2147483647;\n position: relative;\n background-color: transparent;\n border-radius: 8px;\n width: ").concat(i,";\n }\n\n #").concat(U," iframe {\n width: 1px;\n min-width: 100%;\n border-radius: inherit;\n max-height: 95vh;\n height: ").concat("384px",";\n }\n "),document.head.insertAdjacentElement("beforeend",c),r.appendChild(a),r.appendChild(s),this.popup=new S(r),this.popup.on("hide",(function(){e.destroy()}))},t.prototype.destroy=function(){var t=document.querySelector("#".concat(x)),e=document.querySelector("#".concat(N));t&&e&&(document.body.removeChild(t),document.head.removeChild(e)),window.removeEventListener("message",$)},t.prototype.show=function(t){var e,n=t.url;if(!this.popup)throw new Error("Popup is not initialized");var o=document.createElement("iframe");o.setAttribute("id",D),o.setAttribute("name","authsignal"),o.setAttribute("title","Authsignal multi-factor authentication"),o.setAttribute("src",n),o.setAttribute("frameborder","0"),o.setAttribute("allow","publickey-credentials-get *; publickey-credentials-create *; clipboard-write");var i=document.querySelector("#".concat(U));i&&i.appendChild(o),window.addEventListener("message",$),null===(e=this.popup)||void 0===e||e.show()},t.prototype.close=function(){if(!this.popup)throw new Error("Popup is not initialized");this.popup.hide()},t.prototype.on=function(t,e){if(!this.popup)throw new Error("Popup is not initialized");this.popup.on(t,e)},t}();function $(t){var e=document.querySelector("#".concat(D));e&&t.data.height&&(e.style.height=t.data.height+"px")}var H="4a08uqve",W=function(){function e(t){var e=t.cookieDomain,n=t.cookieName,o=void 0===n?"__as_aid":n,i=t.baseUrl,r=void 0===i?"https://api.authsignal.com/v1":i,c=t.tenantId;if(this.anonymousId="",this.profilingId="",this.cookieDomain="",this.anonymousIdCookieName="",this._token=void 0,this.cookieDomain=e||document.location.hostname.replace("www.",""),this.anonymousIdCookieName=o,!c)throw new Error("tenantId is required");this.passkey=new R({tenantId:c,baseUrl:r});var u,d=(u=this.anonymousIdCookieName)&&decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*"+encodeURIComponent(u).replace(/[\-\.\+\*]/g,"\\$&")+"\\s*\\=\\s*([^;]*).*$)|^.*$"),"$1"))||null;d?this.anonymousId=d:(this.anonymousId=a(),s({name:this.anonymousIdCookieName,value:this.anonymousId,expire:1/0,domain:this.cookieDomain,secure:"http:"!==document.location.protocol}))}return e.prototype.launch=function(t,e){switch(null==e?void 0:e.mode){case"window":return this.launchWithWindow(t,e);case"popup":return this.launchWithPopup(t,e);default:this.launchWithRedirect(t)}},e.prototype.initAdvancedProfiling=function(t){var e=a();this.profilingId=e,s({name:"__as_pid",value:e,expire:1/0,domain:this.cookieDomain,secure:"http:"!==document.location.protocol});var n=t?"".concat(t,"/fp/tags.js?org_id=").concat(H,"&session_id=").concat(e):"https://h.online-metrix.net/fp/tags.js?org_id=".concat(H,"&session_id=").concat(e),o=document.createElement("script");o.src=n,o.async=!1,o.id="as_adv_profile",document.head.appendChild(o);var i=document.createElement("noscript");i.setAttribute("id","as_adv_profile_pixel"),i.setAttribute("aria-hidden","true");var r=document.createElement("iframe"),c=t?"".concat(t,"/fp/tags?org_id=").concat(H,"&session_id=").concat(e):"https://h.online-metrix.net/fp/tags?org_id=".concat(H,"&session_id=").concat(e);r.setAttribute("id","as_adv_profile_pixel"),r.setAttribute("src",c),r.setAttribute("style","width: 100px; height: 100px; border: 0; position: absolute; top: -5000px;"),i&&(i.appendChild(r),document.body.prepend(i))},e.prototype.launchWithRedirect=function(t){window.location.href=t},e.prototype.launchWithPopup=function(e,n){var o=this,i=n.popupOptions,r=new K({width:null==i?void 0:i.width}),a="".concat(e,"&mode=popup");return r.show({url:a}),new Promise((function(e){r.on("hide",(function(){e({token:o._token})})),window.addEventListener("message",(function(e){var n=null;try{n=JSON.parse(e.data)}catch(t){}(null==n?void 0:n.event)===t.AuthsignalWindowMessage.AUTHSIGNAL_CLOSE_POPUP&&(o._token=n.token,r.close())}),!1)}))},e.prototype.launchWithWindow=function(e,n){var o=this,i=n.windowOptions,r=new O,a="".concat(e,"&mode=popup");return r.show({url:a,width:null==i?void 0:i.width,height:null==i?void 0:i.height}),new Promise((function(e){window.addEventListener("message",(function(n){var i=null;try{i=JSON.parse(n.data)}catch(t){}(null==i?void 0:i.event)===t.AuthsignalWindowMessage.AUTHSIGNAL_CLOSE_POPUP&&(o._token=i.token,r.close(),e({token:o._token}))}),!1)}))},e}();return t.Authsignal=W,Object.defineProperty(t,"__esModule",{value:!0}),t}({});
1
+ var authsignal=function(t){"use strict";let e;const n=new Uint8Array(16);function i(){if(!e&&(e="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!e))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return e(n)}const o=[];for(let t=0;t<256;++t)o.push((t+256).toString(16).slice(1));var r={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};function a(t,e,n){if(r.randomUUID&&!e&&!t)return r.randomUUID();const a=(t=t||{}).random||(t.rng||i)();if(a[6]=15&a[6]|64,a[8]=63&a[8]|128,e){n=n||0;for(let t=0;t<16;++t)e[n+t]=a[t];return e}return function(t,e=0){return(o[t[e+0]]+o[t[e+1]]+o[t[e+2]]+o[t[e+3]]+"-"+o[t[e+4]]+o[t[e+5]]+"-"+o[t[e+6]]+o[t[e+7]]+"-"+o[t[e+8]]+o[t[e+9]]+"-"+o[t[e+10]]+o[t[e+11]]+o[t[e+12]]+o[t[e+13]]+o[t[e+14]]+o[t[e+15]]).toLowerCase()}(a)}var s=function(t){var e=t.name,n=t.value,i=t.expire,o=t.domain,r=t.secure,a=i===1/0?" expires=Fri, 31 Dec 9999 23:59:59 GMT":"; max-age="+i;document.cookie=encodeURIComponent(e)+"="+n+"; path=/;"+a+(o?"; domain="+o:"")+(r?"; secure":"")};function c(t,e){var n={};for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&e.indexOf(i)<0&&(n[i]=t[i]);if(null!=t&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(i=Object.getOwnPropertySymbols(t);o<i.length;o++)e.indexOf(i[o])<0&&Object.prototype.propertyIsEnumerable.call(t,i[o])&&(n[i[o]]=t[i[o]])}return n}function u(t,e,n,i){return new(n||(n=Promise))((function(o,r){function a(t){try{c(i.next(t))}catch(t){r(t)}}function s(t){try{c(i.throw(t))}catch(t){r(t)}}function c(t){var e;t.done?o(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(a,s)}c((i=i.apply(t,e||[])).next())}))}function l(t,e){var n,i,o,r,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return r={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(r[Symbol.iterator]=function(){return this}),r;function s(r){return function(s){return function(r){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,i&&(o=2&r[0]?i.return:r[0]?i.throw||((o=i.return)&&o.call(i),0):i.next)&&!(o=o.call(i,r[1])).done)return o;switch(i=0,o&&(r=[2&r[0],o.value]),r[0]){case 0:case 1:o=r;break;case 4:return a.label++,{value:r[1],done:!1};case 5:a.label++,i=r[1],r=[0];continue;case 7:r=a.ops.pop(),a.trys.pop();continue;default:if(!(o=a.trys,(o=o.length>0&&o[o.length-1])||6!==r[0]&&2!==r[0])){a=0;continue}if(3===r[0]&&(!o||r[1]>o[0]&&r[1]<o[3])){a.label=r[1];break}if(6===r[0]&&a.label<o[1]){a.label=o[1],o=r;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(r);break}o[2]&&a.ops.pop(),a.trys.pop();continue}r=e.call(t,a)}catch(t){r=[6,t],i=0}finally{n=o=0}if(5&r[0])throw r[1];return{value:r[0]?r[1]:void 0,done:!0}}([r,s])}}}function d(t){const e=new Uint8Array(t);let n="";for(const t of e)n+=String.fromCharCode(t);return btoa(n).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function h(t){const e=t.replace(/-/g,"+").replace(/_/g,"/"),n=(4-e.length%4)%4,i=e.padEnd(e.length+n,"="),o=atob(i),r=new ArrayBuffer(o.length),a=new Uint8Array(r);for(let t=0;t<o.length;t++)a[t]=o.charCodeAt(t);return r}function p(){return void 0!==window?.PublicKeyCredential&&"function"==typeof window.PublicKeyCredential}function f(t){const{id:e}=t;return{...t,id:h(e),transports:t.transports}}function w(t){return"localhost"===t||/^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/i.test(t)}t.AuthsignalWindowMessage=void 0,(t.AuthsignalWindowMessage||(t.AuthsignalWindowMessage={})).AUTHSIGNAL_CLOSE_POPUP="AUTHSIGNAL_CLOSE_POPUP";class m extends Error{constructor({message:t,code:e,cause:n,name:i}){super(t,{cause:n}),this.name=i??n.name,this.code=e}}const y=new class{createNewAbortSignal(){if(this.controller){const t=new Error("Cancelling existing WebAuthn API call for new one");t.name="AbortError",this.controller.abort(t)}const t=new AbortController;return this.controller=t,t.signal}cancelCeremony(){if(this.controller){const t=new Error("Manually cancelling existing WebAuthn API call");t.name="AbortError",this.controller.abort(t),this.controller=void 0}}},b=["cross-platform","platform"];function g(t){if(t&&!(b.indexOf(t)<0))return t}async function v(t){if(!p())throw new Error("WebAuthn is not supported in this browser");var e;const n={publicKey:{...t,challenge:h(t.challenge),user:{...t.user,id:(e=t.user.id,(new TextEncoder).encode(e))},excludeCredentials:t.excludeCredentials?.map(f)}};let i;n.signal=y.createNewAbortSignal();try{i=await navigator.credentials.create(n)}catch(t){throw function({error:t,options:e}){const{publicKey:n}=e;if(!n)throw Error("options was missing required publicKey property");if("AbortError"===t.name){if(e.signal instanceof AbortSignal)return new m({message:"Registration ceremony was sent an abort signal",code:"ERROR_CEREMONY_ABORTED",cause:t})}else if("ConstraintError"===t.name){if(!0===n.authenticatorSelection?.requireResidentKey)return new m({message:"Discoverable credentials were required but no available authenticator supported it",code:"ERROR_AUTHENTICATOR_MISSING_DISCOVERABLE_CREDENTIAL_SUPPORT",cause:t});if("required"===n.authenticatorSelection?.userVerification)return new m({message:"User verification was required but no available authenticator supported it",code:"ERROR_AUTHENTICATOR_MISSING_USER_VERIFICATION_SUPPORT",cause:t})}else{if("InvalidStateError"===t.name)return new m({message:"The authenticator was previously registered",code:"ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED",cause:t});if("NotAllowedError"===t.name)return new m({message:t.message,code:"ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",cause:t});if("NotSupportedError"===t.name)return 0===n.pubKeyCredParams.filter((t=>"public-key"===t.type)).length?new m({message:'No entry in pubKeyCredParams was of type "public-key"',code:"ERROR_MALFORMED_PUBKEYCREDPARAMS",cause:t}):new m({message:"No available authenticator supported any of the specified pubKeyCredParams algorithms",code:"ERROR_AUTHENTICATOR_NO_SUPPORTED_PUBKEYCREDPARAMS_ALG",cause:t});if("SecurityError"===t.name){const e=window.location.hostname;if(!w(e))return new m({message:`${window.location.hostname} is an invalid domain`,code:"ERROR_INVALID_DOMAIN",cause:t});if(n.rp.id!==e)return new m({message:`The RP ID "${n.rp.id}" is invalid for this domain`,code:"ERROR_INVALID_RP_ID",cause:t})}else if("TypeError"===t.name){if(n.user.id.byteLength<1||n.user.id.byteLength>64)return new m({message:"User ID was not between 1 and 64 characters",code:"ERROR_INVALID_USER_ID_LENGTH",cause:t})}else if("UnknownError"===t.name)return new m({message:"The authenticator was unable to process the specified options, or could not create a new credential",code:"ERROR_AUTHENTICATOR_GENERAL_ERROR",cause:t})}return t}({error:t,options:n})}if(!i)throw new Error("Registration was not completed");const{id:o,rawId:r,response:a,type:s}=i;let c,u,l,b;if("function"==typeof a.getTransports&&(c=a.getTransports()),"function"==typeof a.getPublicKeyAlgorithm)try{u=a.getPublicKeyAlgorithm()}catch(t){_("getPublicKeyAlgorithm()",t)}if("function"==typeof a.getPublicKey)try{const t=a.getPublicKey();null!==t&&(l=d(t))}catch(t){_("getPublicKey()",t)}if("function"==typeof a.getAuthenticatorData)try{b=d(a.getAuthenticatorData())}catch(t){_("getAuthenticatorData()",t)}return{id:o,rawId:d(r),response:{attestationObject:d(a.attestationObject),clientDataJSON:d(a.clientDataJSON),transports:c,publicKeyAlgorithm:u,publicKey:l,authenticatorData:b},type:s,clientExtensionResults:i.getClientExtensionResults(),authenticatorAttachment:g(i.authenticatorAttachment)}}function _(t,e){console.warn(`The browser extension that intercepted this WebAuthn API call incorrectly implemented ${t}. You should report this error to them.\n`,e)}async function E(t,e=!1){if(!p())throw new Error("WebAuthn is not supported in this browser");let n;0!==t.allowCredentials?.length&&(n=t.allowCredentials?.map(f));const i={...t,challenge:h(t.challenge),allowCredentials:n},o={};if(e){if(!await function(){const t=window.PublicKeyCredential;return void 0===t.isConditionalMediationAvailable?new Promise((t=>t(!1))):t.isConditionalMediationAvailable()}())throw Error("Browser does not support WebAuthn autofill");if(document.querySelectorAll("input[autocomplete$='webauthn']").length<1)throw Error('No <input> with "webauthn" as the only or last value in its `autocomplete` attribute was detected');o.mediation="conditional",i.allowCredentials=[]}let r;o.publicKey=i,o.signal=y.createNewAbortSignal();try{r=await navigator.credentials.get(o)}catch(t){throw function({error:t,options:e}){const{publicKey:n}=e;if(!n)throw Error("options was missing required publicKey property");if("AbortError"===t.name){if(e.signal instanceof AbortSignal)return new m({message:"Authentication ceremony was sent an abort signal",code:"ERROR_CEREMONY_ABORTED",cause:t})}else{if("NotAllowedError"===t.name)return new m({message:t.message,code:"ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",cause:t});if("SecurityError"===t.name){const e=window.location.hostname;if(!w(e))return new m({message:`${window.location.hostname} is an invalid domain`,code:"ERROR_INVALID_DOMAIN",cause:t});if(n.rpId!==e)return new m({message:`The RP ID "${n.rpId}" is invalid for this domain`,code:"ERROR_INVALID_RP_ID",cause:t})}else if("UnknownError"===t.name)return new m({message:"The authenticator was unable to process the specified options, or could not create a new assertion signature",code:"ERROR_AUTHENTICATOR_GENERAL_ERROR",cause:t})}return t}({error:t,options:o})}if(!r)throw new Error("Authentication was not completed");const{id:a,rawId:s,response:c,type:u}=r;let l;var b;return c.userHandle&&(b=c.userHandle,l=new TextDecoder("utf-8").decode(b)),{id:a,rawId:d(s),response:{authenticatorData:d(c.authenticatorData),clientDataJSON:d(c.clientDataJSON),signature:d(c.signature),userHandle:l},type:u,clientExtensionResults:r.getClientExtensionResults(),authenticatorAttachment:g(r.authenticatorAttachment)}}var A=function(){function t(t){var e=t.baseUrl,n=t.tenantId;this.tenantId=n,this.baseUrl=e}return t.prototype.registrationOptions=function(t){var e=t.token,n=t.userName,i=t.authenticatorAttachment;return u(this,void 0,void 0,(function(){var t;return l(this,(function(o){switch(o.label){case 0:return t=Boolean(i)?{username:n,authenticatorAttachment:i}:{username:n},[4,fetch("".concat(this.baseUrl,"/client/user-authenticators/passkey/registration-options"),{method:"POST",headers:this.buildHeaders(e),body:JSON.stringify(t)})];case 1:return[2,o.sent().json()]}}))}))},t.prototype.authenticationOptions=function(t){var e=t.token;return u(this,void 0,void 0,(function(){return l(this,(function(t){switch(t.label){case 0:return[4,fetch("".concat(this.baseUrl,"/client/user-authenticators/passkey/authentication-options"),{method:"POST",headers:this.buildHeaders(e),body:JSON.stringify({})})];case 1:return[2,t.sent().json()]}}))}))},t.prototype.addAuthenticator=function(t){var e=t.token,n=c(t,["token"]);return u(this,void 0,void 0,(function(){return l(this,(function(t){switch(t.label){case 0:return[4,fetch("".concat(this.baseUrl,"/client/user-authenticators/passkey"),{method:"POST",headers:this.buildHeaders(e),body:JSON.stringify(n)})];case 1:return[2,t.sent().json()]}}))}))},t.prototype.verify=function(t){var e=t.token,n=c(t,["token"]);return u(this,void 0,void 0,(function(){return l(this,(function(t){switch(t.label){case 0:return[4,fetch("".concat(this.baseUrl,"/client/verify/passkey"),{method:"POST",headers:this.buildHeaders(e),body:JSON.stringify(n)})];case 1:return[2,t.sent().json()]}}))}))},t.prototype.getPasskeyAuthenticator=function(t){return u(this,void 0,void 0,(function(){var e;return l(this,(function(n){switch(n.label){case 0:return[4,fetch("".concat(this.baseUrl,"/client/user-authenticators/passkey?credentialId=").concat(t),{method:"GET",headers:this.buildHeaders()})];case 1:if(!(e=n.sent()).ok)throw new Error(e.statusText);return[2,e.json()]}}))}))},t.prototype.buildHeaders=function(t){return{"Content-Type":"application/json",Authorization:t?"Bearer ".concat(t):"Basic ".concat(window.btoa(encodeURIComponent(this.tenantId)))}},t}(),R=function(){function t(t){var e=t.baseUrl,n=t.tenantId;this.passkeyLocalStorageKey="as_passkey_credential_id",this.api=new A({baseUrl:e,tenantId:n})}return t.prototype.signUp=function(t){var e=t.userName,n=t.token,i=t.authenticatorAttachment,o=void 0===i?"platform":i;return u(this,void 0,void 0,(function(){var t,i,r;return l(this,(function(a){switch(a.label){case 0:return[4,this.api.registrationOptions({userName:e,token:n,authenticatorAttachment:o})];case 1:return[4,v((t=a.sent()).options)];case 2:return i=a.sent(),[4,this.api.addAuthenticator({challengeId:t.challengeId,registrationCredential:i,token:n})];case 3:return(null==(r=a.sent())?void 0:r.isVerified)&&this.storeCredentialAgainstDevice(i),[2,null==r?void 0:r.accessToken]}}))}))},t.prototype.signIn=function(t){return u(this,void 0,void 0,(function(){var e,n,i;return l(this,(function(o){switch(o.label){case 0:if((null==t?void 0:t.token)&&t.autofill)throw new Error("Autofill is not supported when providing a token");return[4,this.api.authenticationOptions({token:null==t?void 0:t.token})];case 1:return[4,E((e=o.sent()).options,null==t?void 0:t.autofill)];case 2:return n=o.sent(),[4,this.api.verify({challengeId:e.challengeId,authenticationCredential:n,token:null==t?void 0:t.token})];case 3:return(null==(i=o.sent())?void 0:i.isVerified)&&this.storeCredentialAgainstDevice(n),[2,null==i?void 0:i.accessToken]}}))}))},t.prototype.isAvailableOnDevice=function(){return u(this,void 0,void 0,(function(){var t;return l(this,(function(e){switch(e.label){case 0:if(!(t=localStorage.getItem(this.passkeyLocalStorageKey)))return[2,!1];e.label=1;case 1:return e.trys.push([1,3,,4]),[4,this.api.getPasskeyAuthenticator(t)];case 2:return e.sent(),[2,!0];case 3:return e.sent(),[2,!1];case 4:return[2]}}))}))},t.prototype.storeCredentialAgainstDevice=function(t){var e=t.id;"cross-platform"!==t.authenticatorAttachment&&localStorage.setItem(this.passkeyLocalStorageKey,e)},t}(),O=function(){function t(){this.windowRef=null}return t.prototype.show=function(t){var e=t.url,n=t.width,i=void 0===n?400:n,o=t.height,r=function(t){var e=t.url,n=t.width,i=t.height,o=t.win;if(!o.top)return null;var r=o.top.outerHeight/2+o.top.screenY-i/2,a=o.top.outerWidth/2+o.top.screenX-n/2;return window.open(e,"","toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=".concat(n,", height=").concat(i,", top=").concat(r,", left=").concat(a))}({url:e,width:i,height:void 0===o?500:o,win:window});if(!r)throw new Error("Window is not initialized");return this.windowRef=r,r},t.prototype.close=function(){if(!this.windowRef)throw new Error("Window is not initialized");this.windowRef.close()},t}();var I=['a[href]:not([tabindex^="-"])','area[href]:not([tabindex^="-"])','input:not([type="hidden"]):not([type="radio"]):not([disabled]):not([tabindex^="-"])','input[type="radio"]:not([disabled]):not([tabindex^="-"])','select:not([disabled]):not([tabindex^="-"])','textarea:not([disabled]):not([tabindex^="-"])','button:not([disabled]):not([tabindex^="-"])','iframe:not([tabindex^="-"])','audio[controls]:not([tabindex^="-"])','video[controls]:not([tabindex^="-"])','[contenteditable]:not([tabindex^="-"])','[tabindex]:not([tabindex^="-"])'];function S(t){this._show=this.show.bind(this),this._hide=this.hide.bind(this),this._maintainFocus=this._maintainFocus.bind(this),this._bindKeypress=this._bindKeypress.bind(this),this.$el=t,this.shown=!1,this._id=this.$el.getAttribute("data-a11y-dialog")||this.$el.id,this._previouslyFocused=null,this._listeners={},this.create()}function k(t,e){return n=(e||document).querySelectorAll(t),Array.prototype.slice.call(n);var n}function C(t){(t.querySelector("[autofocus]")||t).focus()}function P(){k("[data-a11y-dialog]").forEach((function(t){new S(t)}))}S.prototype.create=function(){this.$el.setAttribute("aria-hidden",!0),this.$el.setAttribute("aria-modal",!0),this.$el.setAttribute("tabindex",-1),this.$el.hasAttribute("role")||this.$el.setAttribute("role","dialog"),this._openers=k('[data-a11y-dialog-show="'+this._id+'"]'),this._openers.forEach(function(t){t.addEventListener("click",this._show)}.bind(this));const t=this.$el;return this._closers=k("[data-a11y-dialog-hide]",this.$el).filter((function(e){return e.closest('[aria-modal="true"], [data-a11y-dialog]')===t})).concat(k('[data-a11y-dialog-hide="'+this._id+'"]')),this._closers.forEach(function(t){t.addEventListener("click",this._hide)}.bind(this)),this._fire("create"),this},S.prototype.show=function(t){return this.shown||(this._previouslyFocused=document.activeElement,this.$el.removeAttribute("aria-hidden"),this.shown=!0,C(this.$el),document.body.addEventListener("focus",this._maintainFocus,!0),document.addEventListener("keydown",this._bindKeypress),this._fire("show",t)),this},S.prototype.hide=function(t){return this.shown?(this.shown=!1,this.$el.setAttribute("aria-hidden","true"),this._previouslyFocused&&this._previouslyFocused.focus&&this._previouslyFocused.focus(),document.body.removeEventListener("focus",this._maintainFocus,!0),document.removeEventListener("keydown",this._bindKeypress),this._fire("hide",t),this):this},S.prototype.destroy=function(){return this.hide(),this._openers.forEach(function(t){t.removeEventListener("click",this._show)}.bind(this)),this._closers.forEach(function(t){t.removeEventListener("click",this._hide)}.bind(this)),this._fire("destroy"),this._listeners={},this},S.prototype.on=function(t,e){return void 0===this._listeners[t]&&(this._listeners[t]=[]),this._listeners[t].push(e),this},S.prototype.off=function(t,e){var n=(this._listeners[t]||[]).indexOf(e);return n>-1&&this._listeners[t].splice(n,1),this},S.prototype._fire=function(t,e){var n=this._listeners[t]||[],i=new CustomEvent(t,{detail:e});this.$el.dispatchEvent(i),n.forEach(function(t){t(this.$el,e)}.bind(this))},S.prototype._bindKeypress=function(t){const e=document.activeElement;e&&e.closest('[aria-modal="true"]')!==this.$el||(this.shown&&"Escape"===t.key&&"alertdialog"!==this.$el.getAttribute("role")&&(t.preventDefault(),this.hide(t)),this.shown&&"Tab"===t.key&&function(t,e){var n=function(t){return k(I.join(","),t).filter((function(t){return!!(t.offsetWidth||t.offsetHeight||t.getClientRects().length)}))}(t),i=n.indexOf(document.activeElement);e.shiftKey&&0===i?(n[n.length-1].focus(),e.preventDefault()):e.shiftKey||i!==n.length-1||(n[0].focus(),e.preventDefault())}(this.$el,t))},S.prototype._maintainFocus=function(t){!this.shown||t.target.closest('[aria-modal="true"]')||t.target.closest("[data-a11y-dialog-ignore-focus-trap]")||C(this.$el)},"undefined"!=typeof document&&("loading"===document.readyState?document.addEventListener("DOMContentLoaded",P):window.requestAnimationFrame?window.requestAnimationFrame(P):window.setTimeout(P,16));var x="__authsignal-popup-container",U="__authsignal-popup-content",T="__authsignal-popup-overlay",N="__authsignal-popup-style",D="__authsignal-popup-iframe",L="385px",K=function(){function t(t){var e=t.width;if(this.popup=null,document.querySelector("#".concat(x)))throw new Error("Multiple instances of Authsignal popup is not supported.");this.create({width:e})}return t.prototype.create=function(t){var e=this,n=t.width,i=void 0===n?L:n,o=i;CSS.supports("width",i)||(console.warn("Invalid CSS value for `popupOptions.width`. Using default value instead."),o=L);var r=document.createElement("div");r.setAttribute("id",x),r.setAttribute("aria-hidden","true");var a=document.createElement("div");a.setAttribute("id",T),a.setAttribute("data-a11y-dialog-hide","true");var s=document.createElement("div");s.setAttribute("id",U),document.body.appendChild(r);var c=document.createElement("style");c.setAttribute("id",N),c.textContent="\n #".concat(x,",\n #").concat(T," {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n }\n\n #").concat(x," {\n z-index: 2147483647;\n display: flex;\n }\n\n #").concat(x,"[aria-hidden='true'] {\n display: none;\n }\n\n #").concat(T," {\n background-color: rgba(0, 0, 0, 0.18);\n }\n\n #").concat(U," {\n margin: auto;\n z-index: 2147483647;\n position: relative;\n background-color: transparent;\n border-radius: 8px;\n width: ").concat(o,";\n }\n\n #").concat(U," iframe {\n width: 1px;\n min-width: 100%;\n border-radius: inherit;\n max-height: 95vh;\n height: ").concat("384px",";\n }\n "),document.head.insertAdjacentElement("beforeend",c),r.appendChild(a),r.appendChild(s),this.popup=new S(r),this.popup.on("hide",(function(){e.destroy()}))},t.prototype.destroy=function(){var t=document.querySelector("#".concat(x)),e=document.querySelector("#".concat(N));t&&e&&(document.body.removeChild(t),document.head.removeChild(e)),window.removeEventListener("message",$)},t.prototype.show=function(t){var e,n=t.url;if(!this.popup)throw new Error("Popup is not initialized");var i=document.createElement("iframe");i.setAttribute("id",D),i.setAttribute("name","authsignal"),i.setAttribute("title","Authsignal multi-factor authentication"),i.setAttribute("src",n),i.setAttribute("frameborder","0"),i.setAttribute("allow","publickey-credentials-get *; publickey-credentials-create *; clipboard-write");var o=document.querySelector("#".concat(U));o&&o.appendChild(i),window.addEventListener("message",$),null===(e=this.popup)||void 0===e||e.show()},t.prototype.close=function(){if(!this.popup)throw new Error("Popup is not initialized");this.popup.hide()},t.prototype.on=function(t,e){if(!this.popup)throw new Error("Popup is not initialized");this.popup.on(t,e)},t}();function $(t){var e=document.querySelector("#".concat(D));e&&t.data.height&&(e.style.height=t.data.height+"px")}var H="4a08uqve",W=function(){function e(t){var e=t.cookieDomain,n=t.cookieName,i=void 0===n?"__as_aid":n,o=t.baseUrl,r=void 0===o?"https://api.authsignal.com/v1":o,c=t.tenantId;if(this.anonymousId="",this.profilingId="",this.cookieDomain="",this.anonymousIdCookieName="",this._token=void 0,this.cookieDomain=e||document.location.hostname.replace("www.",""),this.anonymousIdCookieName=i,!c)throw new Error("tenantId is required");this.passkey=new R({tenantId:c,baseUrl:r});var u,l=(u=this.anonymousIdCookieName)&&decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*"+encodeURIComponent(u).replace(/[\-\.\+\*]/g,"\\$&")+"\\s*\\=\\s*([^;]*).*$)|^.*$"),"$1"))||null;l?this.anonymousId=l:(this.anonymousId=a(),s({name:this.anonymousIdCookieName,value:this.anonymousId,expire:1/0,domain:this.cookieDomain,secure:"http:"!==document.location.protocol}))}return e.prototype.launch=function(t,e){switch(null==e?void 0:e.mode){case"window":return this.launchWithWindow(t,e);case"popup":return this.launchWithPopup(t,e);default:this.launchWithRedirect(t)}},e.prototype.initAdvancedProfiling=function(t){var e=a();this.profilingId=e,s({name:"__as_pid",value:e,expire:1/0,domain:this.cookieDomain,secure:"http:"!==document.location.protocol});var n=t?"".concat(t,"/fp/tags.js?org_id=").concat(H,"&session_id=").concat(e):"https://h.online-metrix.net/fp/tags.js?org_id=".concat(H,"&session_id=").concat(e),i=document.createElement("script");i.src=n,i.async=!1,i.id="as_adv_profile",document.head.appendChild(i);var o=document.createElement("noscript");o.setAttribute("id","as_adv_profile_pixel"),o.setAttribute("aria-hidden","true");var r=document.createElement("iframe"),c=t?"".concat(t,"/fp/tags?org_id=").concat(H,"&session_id=").concat(e):"https://h.online-metrix.net/fp/tags?org_id=".concat(H,"&session_id=").concat(e);r.setAttribute("id","as_adv_profile_pixel"),r.setAttribute("src",c),r.setAttribute("style","width: 100px; height: 100px; border: 0; position: absolute; top: -5000px;"),o&&(o.appendChild(r),document.body.prepend(o))},e.prototype.launchWithRedirect=function(t){window.location.href=t},e.prototype.launchWithPopup=function(e,n){var i=this,o=n.popupOptions,r=new K({width:null==o?void 0:o.width}),a="".concat(e,"&mode=popup");return r.show({url:a}),new Promise((function(e){r.on("hide",(function(){e({token:i._token})})),window.addEventListener("message",(function(e){var n=null;try{n=JSON.parse(e.data)}catch(t){}(null==n?void 0:n.event)===t.AuthsignalWindowMessage.AUTHSIGNAL_CLOSE_POPUP&&(i._token=n.token,r.close())}),!1)}))},e.prototype.launchWithWindow=function(e,n){var i=this,o=n.windowOptions,r=new O,a="".concat(e,"&mode=popup");return r.show({url:a,width:null==o?void 0:o.width,height:null==o?void 0:o.height}),new Promise((function(e){window.addEventListener("message",(function(n){var o=null;try{o=JSON.parse(n.data)}catch(t){}(null==o?void 0:o.event)===t.AuthsignalWindowMessage.AUTHSIGNAL_CLOSE_POPUP&&(i._token=o.token,r.close(),e({token:i._token}))}),!1)}))},e}();return t.Authsignal=W,Object.defineProperty(t,"__esModule",{value:!0}),t}({});
package/dist/passkey.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { PasskeyApiClient } from "./api";
2
+ import { AuthenticatorAttachment } from "@simplewebauthn/types";
2
3
  declare type PasskeyOptions = {
3
4
  baseUrl: string;
4
5
  tenantId: string;
@@ -6,11 +7,13 @@ declare type PasskeyOptions = {
6
7
  declare type SignUpParams = {
7
8
  userName?: string;
8
9
  token: string;
10
+ authenticatorAttachment?: AuthenticatorAttachment | null;
9
11
  };
10
12
  export declare class Passkey {
11
13
  api: PasskeyApiClient;
14
+ private passkeyLocalStorageKey;
12
15
  constructor({ baseUrl, tenantId }: PasskeyOptions);
13
- signUp({ userName, token }: SignUpParams): Promise<string | undefined>;
16
+ signUp({ userName, token, authenticatorAttachment }: SignUpParams): Promise<string | undefined>;
14
17
  signIn(): Promise<string | undefined>;
15
18
  signIn(params?: {
16
19
  token: string;
@@ -18,5 +21,7 @@ export declare class Passkey {
18
21
  signIn(params?: {
19
22
  autofill: boolean;
20
23
  }): Promise<string | undefined>;
24
+ isAvailableOnDevice(): Promise<boolean>;
25
+ private storeCredentialAgainstDevice;
21
26
  }
22
27
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@authsignal/browser",
3
- "version": "0.3.7",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",