UNPKG

@teamhanko/hanko-frontend-sdk

Version:

A package for simplifying UI integration with the Hanko API. It is meant for use in browsers only.

3 lines (2 loc) 27.7 kB
function e(){return e=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var s=arguments[t];for(var i in s)Object.prototype.hasOwnProperty.call(s,i)&&(e[i]=s[i])}return e},e.apply(this,arguments)}class t{static throttle(e,t,s={}){const{leading:i=!0,trailing:n=!0}=s;let o,a,r,c=0;const h=()=>{c=!1===i?0:Date.now(),r=null,e.apply(o,a)};return function(...s){const l=Date.now();c||!1!==i||(c=l);const d=t-(l-c);o=this,a=s,d<=0||d>t?(r&&(window.clearTimeout(r),r=null),c=l,e.apply(o,a)):r||!1===n||(r=window.setTimeout(h,d))}}}const s="hanko-session-created",i="hanko-session-expired",n="hanko-user-logged-out",o="hanko-user-deleted",a="hanko-after-state-change",r="hanko-before-state-change";class c extends CustomEvent{constructor(e,t){super(e,{detail:t})}}class h{constructor(){this.throttleLimit=1e3,this._addEventListener=document.addEventListener.bind(document),this._removeEventListener=document.removeEventListener.bind(document),this._throttle=t.throttle}wrapCallback(e,t){const s=t=>{e(t.detail)};return t?this._throttle(s,this.throttleLimit,{leading:!0,trailing:!1}):s}addEventListenerWithType({type:e,callback:t,once:s=!1,throttle:i=!1}){const n=this.wrapCallback(t,i);return this._addEventListener(e,n,{once:s}),()=>this._removeEventListener(e,n)}static mapAddEventListenerParams(e,{once:t,callback:s},i){return{type:e,callback:s,once:t,throttle:i}}addEventListener(e,t,s){return this.addEventListenerWithType(h.mapAddEventListenerParams(e,t,s))}onSessionCreated(e,t){return this.addEventListener(s,{callback:e,once:t},!0)}onSessionExpired(e,t){return this.addEventListener(i,{callback:e,once:t},!0)}onUserLoggedOut(e,t){return this.addEventListener(n,{callback:e,once:t})}onUserDeleted(e,t){return this.addEventListener(o,{callback:e,once:t})}onAfterStateChange(e,t){return this.addEventListener(a,{callback:e,once:t},!1)}onBeforeStateChange(e,t){return this.addEventListener(r,{callback:e,once:t},!1)}}class l{constructor(){this._dispatchEvent=document.dispatchEvent.bind(document)}dispatch(e,t){this._dispatchEvent(new c(e,t))}dispatchSessionCreatedEvent(e){this.dispatch(s,e)}dispatchSessionExpiredEvent(){this.dispatch(i,null)}dispatchUserLoggedOutEvent(){this.dispatch(n,null)}dispatchUserDeletedEvent(){this.dispatch(o,null)}dispatchAfterStateChangeEvent(e){this.dispatch(a,e)}dispatchBeforeStateChangeEvent(e){this.dispatch(r,e)}}class d extends Error{constructor(e,t,s){super(e),this.code=void 0,this.cause=void 0,this.code=t,this.cause=s,Object.setPrototypeOf(this,d.prototype)}}class u extends d{constructor(e){super("Technical error","somethingWentWrong",e),Object.setPrototypeOf(this,u.prototype)}}class p extends d{constructor(e,t){super("Conflict error","conflict",t),Object.setPrototypeOf(this,p.prototype)}}class v extends d{constructor(e){super("Request timed out error","requestTimeout",e),Object.setPrototypeOf(this,v.prototype)}}class g extends d{constructor(e){super("Request cancelled error","requestCancelled",e),Object.setPrototypeOf(this,g.prototype)}}class m extends d{constructor(e){super("Invalid password error","invalidPassword",e),Object.setPrototypeOf(this,m.prototype)}}class y extends d{constructor(e){super("Invalid Passcode error","invalidPasscode",e),Object.setPrototypeOf(this,y.prototype)}}class f extends d{constructor(e){super("Invalid WebAuthn credential error","invalidWebauthnCredential",e),Object.setPrototypeOf(this,f.prototype)}}class w extends d{constructor(e){super("Passcode expired error","passcodeExpired",e),Object.setPrototypeOf(this,w.prototype)}}class S extends d{constructor(e){super("Maximum number of Passcode attempts reached error","passcodeAttemptsReached",e),Object.setPrototypeOf(this,S.prototype)}}class k extends d{constructor(e){super("Not found error","notFound",e),Object.setPrototypeOf(this,k.prototype)}}class C extends d{constructor(e,t){super("Too many requests error","tooManyRequests",t),this.retryAfter=void 0,this.retryAfter=e,Object.setPrototypeOf(this,C.prototype)}}class b extends d{constructor(e){super("Unauthorized error","unauthorized",e),Object.setPrototypeOf(this,b.prototype)}}class x extends d{constructor(e){super("Forbidden error","forbidden",e),Object.setPrototypeOf(this,x.prototype)}}class E extends d{constructor(e){super("User verification error","userVerification",e),Object.setPrototypeOf(this,E.prototype)}}class A extends d{constructor(e){super("Maximum number of email addresses reached error","maxNumOfEmailAddressesReached",e),Object.setPrototypeOf(this,A.prototype)}}class _ extends d{constructor(e){super("The email address already exists","emailAddressAlreadyExistsError",e),Object.setPrototypeOf(this,_.prototype)}}class I extends d{constructor(e,t){super("An error occurred during third party sign up/sign in",e,t),Object.setPrototypeOf(this,I.prototype)}}function L(e){for(var t=1;t<arguments.length;t++){var s=arguments[t];for(var i in s)e[i]=s[i]}return e}var O=function e(t,s){function i(e,i,n){if("undefined"!=typeof document){"number"==typeof(n=L({},s,n)).expires&&(n.expires=new Date(Date.now()+864e5*n.expires)),n.expires&&(n.expires=n.expires.toUTCString()),e=encodeURIComponent(e).replace(/%(2[346B]|5E|60|7C)/g,decodeURIComponent).replace(/[()]/g,escape);var o="";for(var a in n)n[a]&&(o+="; "+a,!0!==n[a]&&(o+="="+n[a].split(";")[0]));return document.cookie=e+"="+t.write(i,e)+o}}return Object.create({set:i,get:function(e){if("undefined"!=typeof document&&(!arguments.length||e)){for(var s=document.cookie?document.cookie.split("; "):[],i={},n=0;n<s.length;n++){var o=s[n].split("="),a=o.slice(1).join("=");try{var r=decodeURIComponent(o[0]);if(i[r]=t.read(a,r),e===r)break}catch(e){}}return e?i[e]:i}},remove:function(e,t){i(e,"",L({},t,{expires:-1}))},withAttributes:function(t){return e(this.converter,L({},this.attributes,t))},withConverter:function(t){return e(L({},this.converter,t),this.attributes)}},{attributes:{value:Object.freeze(s)},converter:{value:Object.freeze(t)}})}({read:function(e){return'"'===e[0]&&(e=e.slice(1,-1)),e.replace(/(%[\dA-F]{2})+/gi,decodeURIComponent)},write:function(e){return encodeURIComponent(e).replace(/%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,decodeURIComponent)}},{path:"/"});class T{constructor(e){var t,s;this.authCookieName=void 0,this.authCookieDomain=void 0,this.authCookieSameSite=void 0,this.authCookieName=null!=(t=e.cookieName)?t:"hanko",this.authCookieDomain=e.cookieDomain,this.authCookieSameSite=null!=(s=e.cookieSameSite)?s:"lax"}getAuthCookie(){return O.get(this.authCookieName)}setAuthCookie(t,s){const i={secure:!0,sameSite:this.authCookieSameSite};void 0!==this.authCookieDomain&&(i.domain=this.authCookieDomain);const n=e({},i,s);if(("none"===n.sameSite||"None"===n.sameSite)&&!1===n.secure)throw new u(new Error("Secure attribute must be set when SameSite=None"));O.set(this.authCookieName,t,n)}removeAuthCookie(){O.remove(this.authCookieName)}}class N{constructor(e){this.keyName=void 0,this.keyName=e.keyName}getSessionToken(){return sessionStorage.getItem(this.keyName)}setSessionToken(e){sessionStorage.setItem(this.keyName,e)}removeSessionToken(){sessionStorage.removeItem(this.keyName)}}class P{constructor(e){this._xhr=void 0,this._xhr=e}getResponseHeader(e){return this._xhr.getResponseHeader(e)}}class D{constructor(e){this.headers=void 0,this.ok=void 0,this.status=void 0,this.statusText=void 0,this.url=void 0,this._decodedJSON=void 0,this.xhr=void 0,this.headers=new P(e),this.ok=e.status>=200&&e.status<=299,this.status=e.status,this.statusText=e.statusText,this.url=e.responseURL,this.xhr=e}json(){return this._decodedJSON||(this._decodedJSON=JSON.parse(this.xhr.response)),this._decodedJSON}parseNumericHeader(e){const t=parseInt(this.headers.getResponseHeader(e),10);return isNaN(t)?0:t}}class R{constructor(t,s){var i;this.timeout=void 0,this.api=void 0,this.dispatcher=void 0,this.cookie=void 0,this.sessionTokenStorage=void 0,this.lang=void 0,this.sessionTokenLocation=void 0,this.api=t,this.timeout=null!=(i=s.timeout)?i:13e3,this.dispatcher=new l,this.cookie=new T(e({},s)),this.sessionTokenStorage=new N({keyName:s.cookieName}),this.lang=s.lang,this.sessionTokenLocation=s.sessionTokenLocation}_fetch(e,t,s=new XMLHttpRequest){const i=this,n=this.api+e,o=this.timeout,a=this.getAuthToken(),r=this.lang;return new Promise(function(e,c){s.open(t.method,n,!0),s.setRequestHeader("Accept","application/json"),s.setRequestHeader("Content-Type","application/json"),s.setRequestHeader("X-Language",r),a&&s.setRequestHeader("Authorization",`Bearer ${a}`),s.timeout=o,s.withCredentials=!0,s.onload=()=>{i.processHeaders(s),e(new D(s))},s.onerror=()=>{c(new u)},s.ontimeout=()=>{c(new v)},s.send(t.body?t.body.toString():null)})}processHeaders(e){let t="",s=0,i="";if(e.getAllResponseHeaders().split("\r\n").forEach(n=>{const o=n.toLowerCase();o.startsWith("x-auth-token")?t=e.getResponseHeader("X-Auth-Token"):o.startsWith("x-session-lifetime")?s=parseInt(e.getResponseHeader("X-Session-Lifetime"),10):o.startsWith("x-session-retention")&&(i=e.getResponseHeader("X-Session-Retention"))}),t){const e=new RegExp("^https://"),n=!!this.api.match(e)&&!!window.location.href.match(e),o="session"===i?void 0:new Date((new Date).getTime()+1e3*s);this.setAuthToken(t,{secure:n,expires:o})}}get(e){return this._fetch(e,{method:"GET"})}post(e,t){return this._fetch(e,{method:"POST",body:JSON.stringify(t)})}put(e,t){return this._fetch(e,{method:"PUT",body:JSON.stringify(t)})}patch(e,t){return this._fetch(e,{method:"PATCH",body:JSON.stringify(t)})}delete(e){return this._fetch(e,{method:"DELETE"})}getAuthToken(){let e="";switch(this.sessionTokenLocation){case"cookie":default:e=this.cookie.getAuthCookie();break;case"sessionStorage":e=this.sessionTokenStorage.getSessionToken()}return e}setAuthToken(e,t){switch(this.sessionTokenLocation){case"cookie":default:return this.cookie.setAuthCookie(e,t);case"sessionStorage":return this.sessionTokenStorage.setSessionToken(e)}}}class j{constructor(e,t){this.client=void 0,this.client=new R(e,t)}}class K extends j{async validate(){const e=await this.client.get("/sessions/validate");if(!e.ok)throw new u;return await e.json()}}class q{constructor(e){this.storageKey=void 0,this.defaultState={expiration:0,lastCheck:0},this.storageKey=e}load(){const e=window.localStorage.getItem(this.storageKey);return null==e?this.defaultState:JSON.parse(e)}save(e){window.localStorage.setItem(this.storageKey,JSON.stringify(e||this.defaultState))}}class U{constructor(e,t){this.onActivityCallback=void 0,this.onInactivityCallback=void 0,this.handleFocus=()=>{this.onActivityCallback()},this.handleBlur=()=>{this.onInactivityCallback()},this.handleVisibilityChange=()=>{"visible"===document.visibilityState?this.onActivityCallback():this.onInactivityCallback()},this.hasFocus=()=>document.hasFocus(),this.onActivityCallback=e,this.onInactivityCallback=t,window.addEventListener("focus",this.handleFocus),window.addEventListener("blur",this.handleBlur),document.addEventListener("visibilitychange",this.handleVisibilityChange)}}class F{constructor(e,t,s){this.intervalID=null,this.timeoutID=null,this.checkInterval=void 0,this.checkSession=void 0,this.onSessionExpired=void 0,this.checkInterval=e,this.checkSession=t,this.onSessionExpired=s}scheduleSessionExpiry(e){var t=this;this.stop(),this.timeoutID=setTimeout(async function(){t.stop(),t.onSessionExpired()},e)}start(e=0,t=0){var s=this;const i=this.calcTimeToNextCheck(e);this.sessionExpiresSoon(t)?this.scheduleSessionExpiry(i):this.timeoutID=setTimeout(async function(){let e=await s.checkSession();if(e.is_valid){if(s.sessionExpiresSoon(e.expiration))return void s.scheduleSessionExpiry(e.expiration-Date.now());s.intervalID=setInterval(async function(){e=await s.checkSession(),e.is_valid?s.sessionExpiresSoon(e.expiration)&&s.scheduleSessionExpiry(e.expiration-Date.now()):s.stop()},s.checkInterval)}else s.stop()},i)}stop(){this.timeoutID&&(clearTimeout(this.timeoutID),this.timeoutID=null),this.intervalID&&(clearInterval(this.intervalID),this.intervalID=null)}isRunning(){return null!==this.timeoutID||null!==this.intervalID}sessionExpiresSoon(e){return e>0&&e-Date.now()<=this.checkInterval}calcTimeToNextCheck(e){const t=Date.now()-e;return this.checkInterval>=t?this.checkInterval-t%this.checkInterval:0}}class M{constructor(e="hanko_session",t,s,i){this.channel=void 0,this.onSessionExpired=void 0,this.onSessionCreated=void 0,this.onLeadershipRequested=void 0,this.handleMessage=e=>{const t=e.data;switch(t.action){case"sessionExpired":this.onSessionExpired(t);break;case"sessionCreated":this.onSessionCreated(t);break;case"requestLeadership":this.onLeadershipRequested(t)}},this.onSessionExpired=t,this.onSessionCreated=s,this.onLeadershipRequested=i,this.channel=new BroadcastChannel(e),this.channel.onmessage=this.handleMessage}post(e){this.channel.postMessage(e)}}class H extends l{constructor(e,t){super(),this.listener=new h,this.checkInterval=3e4,this.client=void 0,this.sessionState=void 0,this.windowActivityManager=void 0,this.scheduler=void 0,this.sessionChannel=void 0,this.isLoggedIn=void 0,this.client=new K(e,t),t.sessionCheckInterval&&(this.checkInterval=t.sessionCheckInterval<3e3?3e3:t.sessionCheckInterval),this.sessionState=new q(`${t.cookieName}_session_state`),this.sessionChannel=new M(this.getSessionCheckChannelName(t.sessionTokenLocation,t.sessionCheckChannelName),()=>this.onChannelSessionExpired(),e=>this.onChannelSessionCreated(e),()=>this.onChannelLeadershipRequested()),this.scheduler=new F(this.checkInterval,()=>this.checkSession(),()=>this.onSessionExpired()),this.windowActivityManager=new U(()=>this.startSessionCheck(),()=>this.scheduler.stop());const s=Date.now(),{expiration:i}=this.sessionState.load();this.isLoggedIn=s<i,this.initializeEventListeners(),this.startSessionCheck()}initializeEventListeners(){this.listener.onSessionCreated(e=>{const{claims:t}=e,s=Date.parse(t.expiration),i=Date.now();this.isLoggedIn=!0,this.sessionState.save({expiration:s,lastCheck:i}),this.sessionChannel.post({action:"sessionCreated",claims:t}),this.startSessionCheck()}),this.listener.onUserLoggedOut(()=>{this.isLoggedIn=!1,this.sessionChannel.post({action:"sessionExpired"}),this.sessionState.save(null),this.scheduler.stop()}),window.addEventListener("beforeunload",()=>this.scheduler.stop())}startSessionCheck(){if(!this.windowActivityManager.hasFocus())return;if(this.sessionChannel.post({action:"requestLeadership"}),this.scheduler.isRunning())return;const{lastCheck:e,expiration:t}=this.sessionState.load();this.isLoggedIn&&this.scheduler.start(e,t)}async checkSession(){const e=Date.now(),{is_valid:t,claims:s,expiration_time:i}=await this.client.validate(),n=i?Date.parse(i):0;return!t&&this.isLoggedIn&&this.dispatchSessionExpiredEvent(),t?(this.isLoggedIn=!0,this.sessionState.save({lastCheck:e,expiration:n})):(this.isLoggedIn=!1,this.sessionState.save(null),this.sessionChannel.post({action:"sessionExpired"})),{is_valid:t,claims:s,expiration:n}}onSessionExpired(){this.isLoggedIn&&(this.isLoggedIn=!1,this.sessionState.save(null),this.sessionChannel.post({action:"sessionExpired"}),this.dispatchSessionExpiredEvent())}onChannelSessionExpired(){this.isLoggedIn&&(this.isLoggedIn=!1,this.dispatchSessionExpiredEvent())}onChannelSessionCreated(e){const{claims:t}=e,s=Date.now(),i=Date.parse(t.expiration)-s;this.isLoggedIn=!0,this.dispatchSessionCreatedEvent({claims:t,expirationSeconds:i})}onChannelLeadershipRequested(){this.windowActivityManager.hasFocus()||this.scheduler.stop()}getSessionCheckChannelName(e,t){if("sessionStorage"!==e)return t;let s=sessionStorage.getItem("sessionCheckChannelName");return null!=s&&""!==s||(s=`${t}-${Math.floor(100*Math.random())+1}`,sessionStorage.setItem("sessionCheckChannelName",s)),s}}class W{static supported(){return!!(navigator.credentials&&navigator.credentials.create&&navigator.credentials.get&&window.PublicKeyCredential)}static async isPlatformAuthenticatorAvailable(){return!(!this.supported()||!window.PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable)&&window.PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()}static async isSecurityKeySupported(){return void 0!==window.PublicKeyCredential&&window.PublicKeyCredential.isExternalCTAP2SecurityKeySupported?window.PublicKeyCredential.isExternalCTAP2SecurityKeySupported():this.supported()}static async isConditionalMediationAvailable(){return!(!window.PublicKeyCredential||!window.PublicKeyCredential.isConditionalMediationAvailable)&&window.PublicKeyCredential.isConditionalMediationAvailable()}}function z(e){const t="==".slice(0,(4-e.length%4)%4),s=e.replace(/-/g,"+").replace(/_/g,"/")+t,i=atob(s),n=new ArrayBuffer(i.length),o=new Uint8Array(n);for(let e=0;e<i.length;e++)o[e]=i.charCodeAt(e);return n}function J(e){const t=new Uint8Array(e);let s="";for(const e of t)s+=String.fromCharCode(e);return btoa(s).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}var $="copy",B="convert";function V(e,t,s){if(t===$)return s;if(t===B)return e(s);if(t instanceof Array)return s.map(s=>V(e,t[0],s));if(t instanceof Object){const i={};for(const[n,o]of Object.entries(t)){if(o.derive){const e=o.derive(s);void 0!==e&&(s[n]=e)}if(n in s)i[n]=null!=s[n]?V(e,o.schema,s[n]):null;else if(o.required)throw new Error(`Missing key: ${n}`)}return i}}function X(e,t){return{required:!0,schema:e,derive:t}}function G(e){return{required:!0,schema:e}}function Q(e){return{required:!1,schema:e}}var Y={type:G($),id:G(B),transports:Q($)},Z={appid:Q($),appidExclude:Q($),credProps:Q($)},ee={appid:Q($),appidExclude:Q($),credProps:Q($)},te={publicKey:G({rp:G($),user:G({id:G(B),name:G($),displayName:G($)}),challenge:G(B),pubKeyCredParams:G($),timeout:Q($),excludeCredentials:Q([Y]),authenticatorSelection:Q($),attestation:Q($),extensions:Q(Z)}),signal:Q($)},se={type:G($),id:G($),rawId:G(B),authenticatorAttachment:Q($),response:G({clientDataJSON:G(B),attestationObject:G(B),transports:X($,e=>{var t;return(null==(t=e.getTransports)?void 0:t.call(e))||[]})}),clientExtensionResults:X(ee,e=>e.getClientExtensionResults())},ie={mediation:Q($),publicKey:G({challenge:G(B),timeout:Q($),rpId:Q($),allowCredentials:Q([Y]),userVerification:Q($),extensions:Q(Z)}),signal:Q($)},ne={type:G($),id:G($),rawId:G(B),authenticatorAttachment:Q($),response:G({clientDataJSON:G(B),authenticatorData:G(B),signature:G(B),userHandle:G(B)}),clientExtensionResults:X(ee,e=>e.getClientExtensionResults())};async function oe(e){const t=await navigator.credentials.get(function(e){return V(z,ie,e)}(e));return function(e){return V(J,ne,e)}(t)}class ae{constructor(){this.abortController=new AbortController}static getInstance(){return ae.instance||(ae.instance=new ae),ae.instance}createAbortSignal(){return this.abortController.abort(),this.abortController=new AbortController,this.abortController.signal}async getWebauthnCredential(t){return await oe(e({},t,{signal:this.createAbortSignal()}))}async getConditionalWebauthnCredential(e){return await oe({publicKey:e,mediation:"conditional",signal:this.createAbortSignal()})}async createWebauthnCredential(t){return await async function(e){return t=await navigator.credentials.create(function(e){return V(z,te,e)}(e)),V(J,se,t);var t}(e({},t,{signal:this.createAbortSignal()}))}}async function re(e,t,s,i="webauthn_credential_already_exists",n="Webauthn credential already exists"){try{const i=await t.createWebauthnCredential(s);return await e.actions.webauthn_verify_attestation_response.run({public_key:i})}catch(t){const s=await e.actions.back.run();return s.error={code:i,message:n},s}}ae.instance=null;const ce={preflight:async e=>await e.actions.register_client_capabilities.run({webauthn_available:W.supported(),webauthn_conditional_mediation_available:await W.isConditionalMediationAvailable(),webauthn_platform_authenticator_available:await W.isPlatformAuthenticatorAvailable()}),login_passkey:async e=>{const t=ae.getInstance();try{const s=await t.getWebauthnCredential(e.payload.request_options);return await e.actions.webauthn_verify_assertion_response.run({assertion_response:s})}catch(t){const s=await e.actions.back.run();return e.error&&(s.error=e.error),s}},onboarding_verify_passkey_attestation:async e=>re(e,ae.getInstance(),e.payload.creation_options),webauthn_credential_verification:async e=>re(e,ae.getInstance(),e.payload.creation_options),async thirdparty(e){const t=new URLSearchParams(window.location.search),s=t.get("hanko_token"),i=t.get("error"),n=e=>{e.forEach(e=>t.delete(e));const s=t.toString()?`?${t.toString()}`:"";history.replaceState(null,null,`${window.location.pathname}${s}`)};if((null==s?void 0:s.length)>0)return n(["hanko_token"]),await e.actions.exchange_token.run({token:s});if((null==i?void 0:i.length)>0){const s="access_denied"===i?"third_party_access_denied":"technical_error",o=t.get("error_description");n(["error","error_description"]);const a=await e.actions.back.run(null,{dispatchAfterStateChangeEvent:!1});return a.error={code:s,message:o},a.dispatchAfterStateChangeEvent(),a}return e.isCached?await e.actions.back.run():(e.saveToLocalStorage(),window.location.assign(e.payload.redirect_url),e)},success:async e=>{const{claims:t}=e.payload,s=Date.parse(t.expiration)-Date.now();return e.removeFromLocalStorage(),e.hanko.relay.dispatchSessionCreatedEvent({claims:t,expirationSeconds:s}),e},account_deleted:async e=>(e.removeFromLocalStorage(),e.hanko.relay.dispatchUserDeletedEvent(),e)},he={login_init:async e=>{!async function(){const t=ae.getInstance();if(e.payload.request_options)try{const{publicKey:s}=e.payload.request_options,i=await t.getConditionalWebauthnCredential(s);await e.actions.webauthn_verify_assertion_response.run({assertion_response:i})}catch(e){return}}()}};class le{constructor(e,t,s,i={}){if(this.name=void 0,this.flowName=void 0,this.error=void 0,this.payload=void 0,this.actions=void 0,this.csrfToken=void 0,this.status=void 0,this.previousAction=void 0,this.isCached=void 0,this.cacheKey=void 0,this.hanko=void 0,this.invokedAction=void 0,this.excludeAutoSteps=void 0,this.autoStep=void 0,this.passkeyAutofillActivation=void 0,this.flowName=t,this.name=s.name,this.error=s.error,this.payload=s.payload,this.csrfToken=s.csrf_token,this.status=s.status,this.hanko=e,this.actions=this.buildActionMap(s.actions),this.name in ce){const e=ce[this.name];this.autoStep=()=>e(this)}if(this.name in he){const e=he[this.name];this.passkeyAutofillActivation=()=>e(this)}const{dispatchAfterStateChangeEvent:n=!0,excludeAutoSteps:o=null,previousAction:a=null,isCached:r=!1,cacheKey:c="hanko-flow-state"}=i;this.excludeAutoSteps=o,this.previousAction=a,this.isCached=r,this.cacheKey=c,n&&this.dispatchAfterStateChangeEvent()}buildActionMap(e){const t={};return Object.keys(e).forEach(s=>{t[s]=new de(e[s],this)}),new Proxy(t,{get:(e,t)=>{if(t in e)return e[t];const s="string"==typeof t?t:t.toString();return de.createDisabled(s,this)}})}dispatchAfterStateChangeEvent(){this.hanko.relay.dispatchAfterStateChangeEvent({state:this})}serialize(){return{flow_name:this.flowName,name:this.name,error:this.error,payload:this.payload,csrf_token:this.csrfToken,status:this.status,previous_action:this.previousAction,actions:Object.fromEntries(Object.entries(this.actions).map(([e,t])=>[e,{action:t.name,href:t.href,inputs:t.inputs,description:null}]))}}saveToLocalStorage(){localStorage.setItem(this.cacheKey,JSON.stringify(e({},this.serialize(),{is_cached:!0})))}removeFromLocalStorage(){localStorage.removeItem(this.cacheKey)}static async initializeFlowState(e,t,s,i={}){let n=new le(e,t,s,i);if("all"!=n.excludeAutoSteps)for(;n&&n.autoStep&&(null==(o=n.excludeAutoSteps)||!o.includes(n.name));){var o;const e=await n.autoStep();if(e.name==n.name)return e;n=e}return n}static readFromLocalStorage(e){const t=localStorage.getItem(e);if(t)try{return JSON.parse(t)}catch(e){return}}static async create(t,s,i={}){const{cacheKey:n="hanko-flow-state",loadFromCache:o=!0}=i;if(o){const s=le.readFromLocalStorage(n);if(s)return le.deserialize(t,s,e({},i,{cacheKey:n}))}const a=await le.fetchState(t,`/${s}`);return le.initializeFlowState(t,s,a,e({},i,{cacheKey:n}))}static async deserialize(t,s,i={}){return le.initializeFlowState(t,s.flow_name,s,e({},i,{previousAction:s.previous_action,isCached:s.is_cached}))}static async fetchState(e,t,s){try{return(await e.client.post(t,s)).json()}catch(e){return le.createErrorResponse(e)}}static createErrorResponse(e){return{actions:null,csrf_token:"",name:"error",payload:null,status:0,error:e}}}class de{constructor(e,t,s=!0){this.enabled=void 0,this.href=void 0,this.name=void 0,this.inputs=void 0,this.parentState=void 0,this.enabled=s,this.href=e.href,this.name=e.action,this.inputs=e.inputs,this.parentState=t}static createDisabled(e,t){return new de({action:e,href:"",inputs:{},description:"Disabled action"},t,!1)}async run(t=null,s={}){const{name:i,hanko:n,flowName:o,csrfToken:a,invokedAction:r,excludeAutoSteps:c,cacheKey:h}=this.parentState,{dispatchAfterStateChangeEvent:l=!0}=s;if(!this.enabled)throw new Error(`Action '${this.name}' is not enabled in state '${i}'`);if(r)throw new Error(`An action '${r.name}' has already been invoked on state '${r.relatedStateName}'. No further actions can be run.`);this.parentState.invokedAction={name:this.name,relatedStateName:i},n.relay.dispatchBeforeStateChangeEvent({state:this.parentState});const d={input_data:e({},Object.keys(this.inputs).reduce((e,t)=>{const s=this.inputs[t];return void 0!==s.value&&(e[t]=s.value),e},{}),t),csrf_token:a},u=await le.fetchState(n,this.href,d);return this.parentState.removeFromLocalStorage(),le.initializeFlowState(n,o,u,{dispatchAfterStateChangeEvent:l,excludeAutoSteps:c,previousAction:r,cacheKey:h})}}class ue extends j{async getCurrent(){const e=await this.client.get("/me");if(401===e.status)throw this.client.dispatcher.dispatchSessionExpiredEvent(),new b;if(!e.ok)throw new u;const t=e.json(),s=await this.client.get(`/users/${t.id}`);if(401===s.status)throw this.client.dispatcher.dispatchSessionExpiredEvent(),new b;if(!s.ok)throw new u;return s.json()}async logout(){const e=await this.client.post("/logout");if(this.client.sessionTokenStorage.removeSessionToken(),this.client.cookie.removeAuthCookie(),this.client.dispatcher.dispatchUserLoggedOutEvent(),401!==e.status&&!e.ok)throw new u}}class pe extends h{constructor(t,s){super(),this.session=void 0,this.user=void 0,this.cookie=void 0,this.client=void 0,this.relay=void 0;const i=e({timeout:13e3,cookieName:"hanko",localStorageKey:"hanko",sessionCheckInterval:3e4,sessionCheckChannelName:"hanko-session-check"},s);this.client=new R(t,i),this.session=new K(t,i),this.user=new ue(t,i),this.relay=new H(t,i),this.cookie=new T(i)}setLang(e){this.client.lang=e}createState(e,t={}){return le.create(this,e,t)}async getUser(){return this.user.getCurrent()}async validateSession(){return this.session.validate()}getSessionToken(){return this.cookie.getAuthCookie()}async logout(){return this.user.logout()}}export{de as Action,j as Client,p as ConflictError,c as CustomEventWithDetail,_ as EmailAddressAlreadyExistsError,x as ForbiddenError,pe as Hanko,d as HankoError,R as HttpClient,y as InvalidPasscodeError,m as InvalidPasswordError,f as InvalidWebauthnCredentialError,A as MaxNumOfEmailAddressesReachedError,S as MaxNumOfPasscodeAttemptsReachedError,k as NotFoundError,w as PasscodeExpiredError,H as Relay,v as RequestTimeoutError,K as SessionClient,le as State,u as TechnicalError,I as ThirdPartyError,C as TooManyRequestsError,b as UnauthorizedError,ue as UserClient,E as UserVerificationError,g as WebauthnRequestCancelledError,W as WebauthnSupport,s as sessionCreatedType,i as sessionExpiredType,o as userDeletedType,n as userLoggedOutType}; //# sourceMappingURL=sdk.modern.js.map