@authhero/widget 0.32.42 → 0.33.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 +1 @@
1
- import{t,p as e,H as i,c as n,h as r}from"./p-cKZ5hFj1.js";import{d as o}from"./p-BzbxtmOP.js";function s(t){const e=t.match(/^#([0-9a-f]{3})$/i)||t.match(/^#([0-9a-f]{6})$/i);if(!e)return null;let i=e[1];3===i.length&&(i=i[0]+i[0]+i[1]+i[1]+i[2]+i[2]);const n=parseInt(i,16);return[n>>16&255,n>>8&255,255&n]}function a(t){const e=s(t);if(!e)return NaN;const[i,n,r]=e.map((t=>{const e=t/255;return e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4)}));return.2126*i+.7152*n+.0722*r}function c(t,e){const i=a(t),n=a(e);return isNaN(i)||isNaN(n)?NaN:(Math.max(i,n)+.05)/(Math.min(i,n)+.05)}function h(t,e="light"){const i=c(t,"#000000"),n=c(t,"#ffffff");return"light"===e?i>1.35*n?"#000000":"#ffffff":1.35*i>n?"#000000":"#ffffff"}function l(t,e){const i=s(t);if(!i)return t;const[n,r,o]=i,a=t=>Math.max(0,Math.round(t*(1-e))).toString(16).padStart(2,"0");return`#${a(n)}${a(r)}${a(o)}`}function d(t,e){const i=s(t);if(!i)return t;const[n,r,o]=i,a=t=>Math.min(255,Math.round(t+(255-t)*e)).toString(16).padStart(2,"0");return`#${a(n)}${a(r)}${a(o)}`}function f(t,e,i=4.5){if(c(t,e)>=i)return t;const n=a(e)>.5;let r=t;for(let o=1;o<=10;o++)if(r=n?l(t,.1*o):d(t,.1*o),c(r,e)>=i)return r;return n?"#000000":"#ffffff"}function u(t,e){if(void 0!==e)return e+"px";switch(t){case"pill":return"9999px";case"rounded":return"8px";case"sharp":return"0";default:return}}function p(t){if(!t)return{};const e={};if(t.colors?.primary&&(e["--ah-color-primary"]=t.colors.primary),t.colors?.page_background){const i=t.colors.page_background;"solid"===i.type&&i.start?e["--ah-page-bg"]=i.start:"gradient"===i.type&&i.start&&i.end&&(e["--ah-page-bg"]=`linear-gradient(${i.angle_deg??180}deg, ${i.start}, ${i.end})`)}return t.logo_url&&(e["--ah-logo-url"]=`url(${t.logo_url})`),t.font?.url&&(e["--ah-font-url"]=t.font.url),e}function g(t){if(!t)return{};const e={};if(t.borders){const i=t.borders;void 0!==i.widget_corner_radius&&(e["--ah-widget-radius"]=i.widget_corner_radius+"px"),void 0!==i.widget_border_weight&&(e["--ah-widget-border-width"]=i.widget_border_weight+"px"),!1===i.show_widget_shadow&&(e["--ah-widget-shadow"]="none");const n=u(i.buttons_style,i.button_border_radius);n&&(e["--ah-btn-radius"]=n),void 0!==i.button_border_weight&&(e["--ah-btn-border-width"]=i.button_border_weight+"px");const r=u(i.inputs_style,i.input_border_radius);r&&(e["--ah-input-radius"]=r),void 0!==i.input_border_weight&&(e["--ah-input-border-width"]=i.input_border_weight+"px")}if(t.colors){const i=t.colors;if(i.primary_button)if(e["--ah-color-primary"]=i.primary_button,i.primary_button_label)e["--ah-color-text-on-primary"]=i.primary_button_label;else{e["--ah-color-text-on-primary"]=h(i.primary_button,"light");const t=h(i.primary_button,"dark");t!==e["--ah-color-text-on-primary"]&&(e["--ah-color-text-on-primary-dark"]=t)}else i.primary_button_label&&(e["--ah-color-text-on-primary"]=i.primary_button_label);i.secondary_button_border&&(e["--ah-btn-secondary-border"]=i.secondary_button_border),i.secondary_button_label&&(e["--ah-btn-secondary-text"]=i.secondary_button_label),i.body_text&&(e["--ah-color-text"]=i.body_text),i.header&&(e["--ah-color-text-header"]=i.header),i.input_labels_placeholders&&(e["--ah-color-text-label"]=i.input_labels_placeholders,e["--ah-color-text-muted"]=i.input_labels_placeholders),i.input_filled_text&&(e["--ah-color-input-text"]=i.input_filled_text),i.widget_background&&(e["--ah-color-bg"]=i.widget_background),i.input_background&&(e["--ah-color-input-bg"]=i.input_background),i.widget_border&&(e["--ah-widget-border-color"]=i.widget_border),i.input_border&&(e["--ah-color-border"]=i.input_border),i.links_focused_components&&(e["--ah-color-link"]=f(i.links_focused_components,i.widget_background||"#ffffff")),i.base_focus_color&&(e["--ah-color-focus-ring"]=i.base_focus_color),i.base_hover_color&&(e["--ah-color-primary-hover"]=i.base_hover_color),i.error&&(e["--ah-color-error"]=i.error),i.success&&(e["--ah-color-success"]=i.success),i.icons&&(e["--ah-color-icon"]=i.icons);const n=i.widget_background||"#ffffff",r=i.input_background||n,o=e["--ah-color-border"]||i.input_border||"#c9cace",s=c(o,n),a=c(o,r);Math.min(s,a)<3&&(e["--ah-color-border"]=f(o,s<a?n:r,3))}if(t.fonts){const i=t.fonts,n=i.reference_text_size||16,r=t=>t>=50?Math.round(t/100*n):t;i.font_url&&(e["--ah-font-url"]=i.font_url),i.reference_text_size&&(e["--ah-font-size-base"]=i.reference_text_size+"px"),i.title?.size&&(e["--ah-font-size-title"]=r(i.title.size)+"px"),i.subtitle?.size&&(e["--ah-font-size-subtitle"]=r(i.subtitle.size)+"px"),i.body_text?.size&&(e["--ah-font-size-body"]=r(i.body_text.size)+"px"),i.input_labels?.size&&(e["--ah-font-size-label"]=r(i.input_labels.size)+"px"),i.buttons_text?.size&&(e["--ah-font-size-btn"]=r(i.buttons_text.size)+"px"),i.links?.size&&(e["--ah-font-size-link"]=r(i.links.size)+"px"),"underlined"===i.links_style&&(e["--ah-link-decoration"]="underline"),void 0!==i.title?.bold&&(e["--ah-font-weight-title"]=i.title.bold?"700":"400"),void 0!==i.subtitle?.bold&&(e["--ah-font-weight-subtitle"]=i.subtitle.bold?"700":"400"),void 0!==i.body_text?.bold&&(e["--ah-font-weight-body"]=i.body_text.bold?"700":"400"),void 0!==i.input_labels?.bold&&(e["--ah-font-weight-label"]=i.input_labels.bold?"700":"400"),void 0!==i.buttons_text?.bold&&(e["--ah-font-weight-btn"]=i.buttons_text.bold?"600":"400"),void 0!==i.links?.bold&&(e["--ah-font-weight-link"]=i.links.bold?"700":"400")}if(t.widget){const i=t.widget;if(i.header_text_alignment&&(e["--ah-title-align"]=i.header_text_alignment),i.logo_height&&(e["--ah-logo-height"]=i.logo_height+"px"),i.logo_position){const t={center:"center",left:"flex-start",right:"flex-end"};"none"===i.logo_position?e["--ah-logo-display"]="none":e["--ah-logo-align"]=t[i.logo_position]??"center"}i.social_buttons_layout&&("top"===i.social_buttons_layout?(e["--ah-social-order"]="0",e["--ah-divider-order"]="1",e["--ah-fields-order"]="2"):(e["--ah-social-order"]="2",e["--ah-divider-order"]="1",e["--ah-fields-order"]="0"))}if(t.page_background){const i=t.page_background;i.background_color&&(e["--ah-page-bg"]=i.background_color),i.background_image_url&&(e["--ah-page-bg-image"]=`url(${i.background_image_url})`)}return e}const m={br:[],em:[],i:[],strong:[],b:[],u:[],span:["class"],a:["href","class"]};function w(t){if(!t)return"";if(!t.includes("<"))return t;let e=t;e=e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;");for(const[t,i]of Object.entries(m)){if("br"===t){e=e.replace(/&lt;br\s*\/?&gt;/gi,"<br>");continue}const n=RegExp(`&lt;${t}((?:\\s+[a-z-]+(?:=&quot;[^&]*&quot;|=&#39;[^&]*&#39;)?)*)\\s*&gt;`,"gi");e=e.replace(n,((e,n)=>{const r=[];if(n){const t=n.replace(/&quot;/g,'"').replace(/&#39;/g,"'").replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">"),e=/([a-z-]+)=["']([^"']*)["']/gi;let o;for(;null!==(o=e.exec(t));){const[,t,e]=o;t&&i.includes(t.toLowerCase())&&("href"===t.toLowerCase()?b(e||"")&&r.push(`${t}="${x(e||"")}"`):r.push(`${t}="${x(e||"")}"`))}}"a"===t&&(r.push('target="_blank"'),r.push('rel="noopener noreferrer"'));const o=r.length?" "+r.join(" "):"";return`<${t}${o}>`}));const r=RegExp(`&lt;/${t}&gt;`,"gi");e=e.replace(r,`</${t}>`)}return e}function b(t){if(!t)return!1;if(t.startsWith("/")||t.startsWith("#")||t.startsWith("?"))return!0;try{const e=new URL(t,"https://example.com");return"http:"===e.protocol||"https:"===e.protocol}catch{return!1}}function x(t){return t.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}const v=e(class extends i{constructor(t){super(),!1!==t&&this.__registerHost(),this.__attachShadow(),this.formSubmit=n(this,"formSubmit"),this.buttonClick=n(this,"buttonClick"),this.linkClick=n(this,"linkClick"),this.navigate=n(this,"navigate"),this.flowComplete=n(this,"flowComplete"),this.flowError=n(this,"flowError"),this.screenChange=n(this,"screenChange")}get el(){return this}screen;apiUrl;baseUrl;state;screenId;watchScreenId(){this.updateDataScreenAttribute()}authParams;statePersistence="memory";storageKey="authhero_widget";branding;theme;loading=!1;autoSubmit=!1;autoNavigate;_screen;_authParams;_branding;_theme;formData={};conditionalMediationAbort;loadedFontUrl;formSubmit;buttonClick;linkClick;navigate;flowComplete;flowError;screenChange;watchScreen(t){if(this.conditionalMediationAbort?.abort(),this.conditionalMediationAbort=void 0,"string"==typeof t)try{this._screen=JSON.parse(t)}catch{console.error("Failed to parse screen JSON")}else this._screen=t;this._screen&&(this.formData={},this.initFormDataFromDefaults(this._screen),this.screenChange.emit(this._screen),this.updateDataScreenAttribute())}initFormDataFromDefaults(t){const e={};for(const i of t.components||[])if("config"in i&&i.config&&"default_value"in i.config&&i.config.default_value){const t=i.config.default_value;"string"==typeof t&&""!==t&&(e[i.id]=t)}Object.keys(e).length>0&&(this.formData={...e,...this.formData})}updateDataScreenAttribute(){const t=this._screen?.name||this.screenId;t?this.el.setAttribute("data-screen",t):this.el.removeAttribute("data-screen");const e=this.el.closest("[data-authhero-widget-container]");e&&(t?e.setAttribute("data-screen",t):e.removeAttribute("data-screen"))}watchBranding(t){if("string"==typeof t)try{this._branding=JSON.parse(t)}catch{console.error("Failed to parse branding JSON")}else this._branding=t;this.applyThemeStyles()}watchTheme(t){if("string"==typeof t)try{this._theme=JSON.parse(t)}catch{console.error("Failed to parse theme JSON")}else this._theme=t;this.applyThemeStyles()}watchAuthParams(t){if("string"==typeof t)try{this._authParams=JSON.parse(t)}catch{console.error("Failed to parse authParams JSON")}else this._authParams=t}applyThemeStyles(){const t=function(t,e){return{...p(t),...g(e)}}(this._branding,this._theme);!function(t,e){Object.entries(e).forEach((([e,i])=>{t.style.setProperty(e,i)}))}(this.el,t),this.loadCustomFont()}loadCustomFont(){if("undefined"==typeof document)return;const t=this._theme?.fonts?.font_url||this._branding?.font?.url;if(t===this.loadedFontUrl)return;for(const t of Array.from(document.head.querySelectorAll("link[data-authhero-font]")))t.remove();if(this.loadedFontUrl=void 0,!t)return;const e=document.createElement("link");e.rel="stylesheet",e.href=t,e.setAttribute("data-authhero-font",t),document.head.appendChild(e),this.loadedFontUrl=t}focusFirstInput(){requestAnimationFrame((()=>{const t=this.el.shadowRoot;if(!t)return;const e=t.querySelectorAll("authhero-node");for(const t of Array.from(e)){const e=t.shadowRoot;if(e){const t=e.querySelector('input:not([type="hidden"]):not([type="checkbox"]):not([disabled]), textarea:not([disabled])');if(t)return void t.focus()}}}))}get shouldAutoNavigate(){return this.autoNavigate??this.autoSubmit}buildUrl(t){return this.baseUrl?""+new URL(t,this.baseUrl):t}loadPersistedState(){if("url"===this.statePersistence){const t=new URL(window.location.href).searchParams.get("state");t&&!this.state&&(this.state=t)}else if("session"===this.statePersistence)try{const t=sessionStorage.getItem(this.storageKey+"_state");t&&!this.state&&(this.state=t);const e=sessionStorage.getItem(this.storageKey+"_screenId");e&&!this.screenId&&(this.screenId=e)}catch{}}persistState(){if("url"===this.statePersistence){const t=new URL(window.location.href);this.state&&t.searchParams.set("state",this.state),this.screenId&&t.searchParams.set("screen",this.screenId),window.history.replaceState({},"",""+t)}else if("session"===this.statePersistence)try{this.state&&sessionStorage.setItem(this.storageKey+"_state",this.state),this.screenId&&sessionStorage.setItem(this.storageKey+"_screenId",this.screenId)}catch{}}handlePopState=t=>{if(!this.apiUrl)return;t.state?.state&&(this.state=t.state.state);const e=t.state?.screen??this.extractScreenIdFromHref(location.href);e&&this.fetchScreen(e)};connectedCallback(){window.addEventListener("popstate",this.handlePopState)}disconnectedCallback(){window.removeEventListener("popstate",this.handlePopState),this.conditionalMediationAbort?.abort(),this.conditionalMediationAbort=void 0}readJsonScript(t){if(!this.el)return;const e=this.el.querySelector(`script[type="application/json"][data-authhero="${t}"]`);return e?.textContent??void 0}async componentWillLoad(){if(!this._screen){const t=this.screen||this.readJsonScript("screen")||this.el?.getAttribute("screen");t&&this.watchScreen(t)}this._branding||this.watchBranding(this.branding??this.readJsonScript("branding")),this._theme||this.watchTheme(this.theme??this.readJsonScript("theme")),this._authParams||this.watchAuthParams(this.authParams??this.readJsonScript("auth-params")),this.loadPersistedState(),this.apiUrl&&!this._screen&&await this.fetchScreen(this.screenId)}async fetchScreen(t,e){if(!this.apiUrl)return!1;const i=t||this.screenId;let n=this.apiUrl;i&&n.includes("{screenId}")&&(n=n.replace("{screenId}",encodeURIComponent(i)));const r=new URL(n,this.baseUrl||window.location.origin);this.state&&r.searchParams.set("state",this.state),e&&r.searchParams.set("nodeId",e),this.loading=!0;try{const t=await fetch(this.buildUrl(r.pathname+r.search),{credentials:"include",headers:{Accept:"application/json"}});if(t.ok){const e=await t.json();if(e.screen?(this._screen=e.screen,e.branding&&(this._branding=e.branding,this.applyThemeStyles()),e.state&&(this.state=e.state),e.screenId&&(this.screenId=e.screenId)):this._screen=e,this._screen)return i&&i!==this.screenId&&(this.screenId=i),this.initFormDataFromDefaults(this._screen),this.screenChange.emit(this._screen),this.updateDataScreenAttribute(),this.persistState(),this.focusFirstInput(),e.ceremony&&this.performWebAuthnCeremony(e.ceremony),!0}else{const e=await t.json().catch((()=>({message:"Failed to load screen"})));this.flowError.emit({message:e.message||"Failed to load screen"})}}catch(t){console.error("Failed to fetch screen:",t),this.flowError.emit({message:t instanceof Error?t.message:"Failed to fetch screen"})}finally{this.loading=!1}return!1}handleInputChange=(t,e)=>{this.formData={...this.formData,[t]:e}};handleSubmit=async(t,e)=>{if(t.preventDefault(),!this._screen||this.loading)return;let i={...this.formData,...e||{}};const n=this.el.shadowRoot?.querySelector("form");if(n&&n.querySelectorAll('input[type="hidden"]').forEach((t=>{t.name&&t.value&&(i[t.name]=t.value)})),this.formSubmit.emit({screen:this._screen,data:i}),this.autoSubmit)if(this._screen.method&&"GET"!==this._screen.method.toUpperCase()){this.loading=!0;try{const t=await fetch(this.buildUrl(this._screen.action),{method:this._screen.method,credentials:"include",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({data:i})}),e=t.headers.get("content-type");if(e?.includes("text/html")){const e=await t.text();return document.open(),document.write(e),void document.close()}if(e?.includes("application/json")){const e=await t.json();e.redirect?(this.flowComplete.emit({redirectUrl:e.redirect}),this.navigate.emit({url:e.redirect}),this.shouldAutoNavigate&&(window.location.href=e.redirect)):!t.ok&&e.screen?(this._screen=e.screen,this.initFormDataFromDefaults(e.screen),this.screenChange.emit(e.screen),this.updateDataScreenAttribute(),this.focusFirstInput()):e.screen?(this._screen=e.screen,this.formData={},this.initFormDataFromDefaults(e.screen),this.screenChange.emit(e.screen),this.updateDataScreenAttribute(),e.screenId&&(this.screenId=e.screenId),this.persistState(),e.navigateUrl&&this.shouldAutoNavigate&&window.history.pushState({screen:e.screenId,state:this.state},"",e.navigateUrl),e.branding&&(this._branding=e.branding,this.applyThemeStyles()),e.state&&(this.state=e.state,this.persistState()),e.ceremony&&this.performWebAuthnCeremony(e.ceremony),this.focusFirstInput()):e.complete?this.flowComplete.emit({}):!t.ok&&e.error&&(this._screen&&(this._screen={...this._screen,messages:[...this._screen.messages||[],{text:e.error,type:"error"}]}),this.flowError.emit({message:e.error}))}}catch(t){console.error("Form submission failed:",t),this.flowError.emit({message:t instanceof Error?t.message:"Form submission failed"})}finally{this.loading=!1}}else window.location.href=this.buildUrl(this._screen.action)};overrideFormSubmit(){const t=this.el.shadowRoot;if(!t)return;const e=t.querySelector("form");e&&(e.submit=()=>{const t=new FormData(e),i={};t.forEach(((t,e)=>{"string"==typeof t&&(i[e]=t)})),this.handleSubmit({preventDefault:()=>{}},i)})}performWebAuthnCeremony(t){this.isValidWebAuthnCeremony(t)?"webauthn-authentication-conditional"!==t.type?requestAnimationFrame((()=>{this.overrideFormSubmit(),"webauthn-authentication"===t.type?this.executeWebAuthnAuthentication(t):this.executeWebAuthnRegistration(t)})):this.executeWebAuthnConditionalMediation(t):console.error("Invalid WebAuthn ceremony payload",t)}isValidWebAuthnCeremony(t){if("object"!=typeof t||null===t)return!1;const e=t;if("string"!=typeof e.successAction)return!1;const i=e.options;if("object"!=typeof i||null===i)return!1;if("string"!=typeof i.challenge)return!1;if("webauthn-registration"===e.type){const t=i.rp;if("object"!=typeof t||null===t)return!1;if("string"!=typeof t.id||"string"!=typeof t.name)return!1;const e=i.user;return"object"==typeof e&&null!==e&&("string"==typeof e.id&&"string"==typeof e.name&&"string"==typeof e.displayName&&!!Array.isArray(i.pubKeyCredParams))}return"webauthn-authentication"===e.type||"webauthn-authentication-conditional"===e.type}async executeWebAuthnRegistration(t){const e=t.options,i=t=>{for(t=t.replace(/-/g,"+").replace(/_/g,"/");t.length%4;)t+="=";const e=atob(t),i=new Uint8Array(e.length);for(let t=0;t<e.length;t++)i[t]=e.charCodeAt(t);return i.buffer},n=t=>{const e=new Uint8Array(t);let i="";for(let t=0;t<e.length;t++)i+=String.fromCharCode(e[t]);return btoa(i).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")},r=()=>{const t=this.el?.shadowRoot;if(t){const e=t.querySelector("form");if(e)return e}return document.querySelector("form")};try{const o={challenge:i(e.challenge),rp:{id:e.rp.id,name:e.rp.name},user:{id:i(e.user.id),name:e.user.name,displayName:e.user.displayName},pubKeyCredParams:e.pubKeyCredParams.map((t=>({alg:t.alg,type:t.type}))),timeout:e.timeout,attestation:e.attestation||"none",authenticatorSelection:e.authenticatorSelection?{residentKey:e.authenticatorSelection.residentKey||"preferred",userVerification:e.authenticatorSelection.userVerification||"preferred"}:void 0};e.excludeCredentials?.length&&(o.excludeCredentials=e.excludeCredentials.map((t=>({id:i(t.id),type:t.type,transports:t.transports||[]}))));const s=await navigator.credentials.create({publicKey:o}),a=s.response,c={id:s.id,rawId:n(s.rawId),type:s.type,response:{attestationObject:n(a.attestationObject),clientDataJSON:n(a.clientDataJSON)},clientExtensionResults:s.getClientExtensionResults(),authenticatorAttachment:s.authenticatorAttachment||void 0};"function"==typeof a.getTransports&&(c.response.transports=a.getTransports());const h=r();if(h){const e=h.querySelector('[name="credential-field"]')||h.querySelector("#credential-field"),i=h.querySelector('[name="action-field"]')||h.querySelector("#action-field");e&&(e.value=JSON.stringify(c)),i&&(i.value=t.successAction),h.submit()}}catch(t){console.error("WebAuthn registration error:",t);const e=r();if(e){const t=e.querySelector('[name="action-field"]')||e.querySelector("#action-field");t&&(t.value="error"),e.submit()}}}async executeWebAuthnAuthentication(t){const e=t.options,i=t=>{for(t=t.replace(/-/g,"+").replace(/_/g,"/");t.length%4;)t+="=";const e=atob(t),i=new Uint8Array(e.length);for(let t=0;t<e.length;t++)i[t]=e.charCodeAt(t);return i.buffer},n=t=>{const e=new Uint8Array(t);let i="";for(let t=0;t<e.length;t++)i+=String.fromCharCode(e[t]);return btoa(i).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")},r=()=>{const t=this.el?.shadowRoot;if(t){const e=t.querySelector("form");if(e)return e}return document.querySelector("form")};try{const o={challenge:i(e.challenge),rpId:e.rpId,timeout:e.timeout,userVerification:e.userVerification||"preferred"};e.allowCredentials?.length&&(o.allowCredentials=e.allowCredentials.map((t=>({id:i(t.id),type:t.type,transports:t.transports||[]}))));const s=await navigator.credentials.get({publicKey:o}),a=s.response,c={id:s.id,rawId:n(s.rawId),type:s.type,response:{authenticatorData:n(a.authenticatorData),clientDataJSON:n(a.clientDataJSON),signature:n(a.signature)},clientExtensionResults:s.getClientExtensionResults(),authenticatorAttachment:s.authenticatorAttachment||void 0};a.userHandle&&(c.response.userHandle=n(a.userHandle));const h=r();if(h){const e=h.querySelector('[name="credential-field"]')||h.querySelector("#credential-field"),i=h.querySelector('[name="action-field"]')||h.querySelector("#action-field");e&&(e.value=JSON.stringify(c)),i&&(i.value=t.successAction),h.submit()}}catch(t){console.error("WebAuthn authentication error:",t);const e=r();if(e){const t=e.querySelector('[name="action-field"]')||e.querySelector("#action-field");t&&(t.value="error"),e.submit()}}}async executeWebAuthnConditionalMediation(t){if(!window.PublicKeyCredential||!PublicKeyCredential.isConditionalMediationAvailable)return;if(!await PublicKeyCredential.isConditionalMediationAvailable())return;this.conditionalMediationAbort?.abort();const e=new AbortController;this.conditionalMediationAbort=e;const i=t.options,n=t=>{for(t=t.replace(/-/g,"+").replace(/_/g,"/");t.length%4;)t+="=";const e=atob(t),i=new Uint8Array(e.length);for(let t=0;t<e.length;t++)i[t]=e.charCodeAt(t);return i.buffer},r=t=>{const e=new Uint8Array(t);let i="";for(let t=0;t<e.length;t++)i+=String.fromCharCode(e[t]);return btoa(i).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")};try{const o=await navigator.credentials.get({mediation:"conditional",signal:e.signal,publicKey:{challenge:n(i.challenge),rpId:i.rpId,timeout:i.timeout,userVerification:i.userVerification||"preferred"}}),s=o.response,a={id:o.id,rawId:r(o.rawId),type:o.type,response:{authenticatorData:r(s.authenticatorData),clientDataJSON:r(s.clientDataJSON),signature:r(s.signature)},clientExtensionResults:o.getClientExtensionResults(),authenticatorAttachment:o.authenticatorAttachment||void 0};s.userHandle&&(a.response.userHandle=r(s.userHandle)),this.formData["credential-field"]=JSON.stringify(a),this.formData["action-field"]=t.successAction,this.overrideFormSubmit();const c=this.el?.shadowRoot,h=c?.querySelector("form");if(h){const e=h.querySelector('[name="credential-field"]')||h.querySelector("#credential-field"),i=h.querySelector('[name="action-field"]')||h.querySelector("#action-field");e&&(e.value=JSON.stringify(a)),i&&(i.value=t.successAction),h.submit()}}catch(t){if("AbortError"===t?.name||"NotAllowedError"===t?.name)return;console.error("Conditional mediation error:",t)}}handleButtonClick=t=>{if("submit"!==t.type)if(this.buttonClick.emit(t),"SOCIAL"===t.type&&t.value&&this.shouldAutoNavigate){const e=this.getProviderHref(t.value);if(e){const t=this.extractScreenIdFromHref(e);return void(t&&this.apiUrl?this.navigateToScreen(t,e):window.location.href=e)}this.handleSocialLogin(t.value)}else"RESEND_BUTTON"===t.type&&this.shouldAutoNavigate&&this.handleResend();else{if((!this._screen?.method||"GET"===this._screen.method.toUpperCase())&&this._screen?.action)return void(window.location.href=this.buildUrl(this._screen.action));const e={...this.formData,[t.id]:"true"};this.formData=e,this.handleSubmit({preventDefault:()=>{}},e)}};handleSocialLogin(t){const e=this._authParams||{},i={connection:t};this.state?i.state=this.state:e.state&&(i.state=e.state),e.client_id&&(i.client_id=e.client_id),e.redirect_uri&&(i.redirect_uri=e.redirect_uri),e.scope&&(i.scope=e.scope),e.audience&&(i.audience=e.audience),e.nonce&&(i.nonce=e.nonce),e.response_type&&(i.response_type=e.response_type);const n=this.buildUrl("/authorize?"+new URLSearchParams(i));this.navigate.emit({url:n}),window.location.href=n}async handleResend(){if(this._screen?.action)try{const t=this._screen.action+(this._screen.action.includes("?")?"&":"?")+"action=resend";await fetch(this.buildUrl(t),{method:"POST",credentials:"include"})}catch(t){console.error("Resend failed:",t)}}extractScreenIdFromHref(t){try{const e=new URL(t,window.location.origin).pathname,i=e.match(/\/u2\/login\/([^/]+)$/);if(i)return i[1];const n=e.match(/\/u2\/([^/]+)$/);return n&&"login"!==n[1]&&"screen"!==n[1]?n[1]:null}catch{return null}}handleLinkClick=(t,e)=>{if(this.linkClick.emit({id:e.id,href:e.href,text:e.text}),!this.shouldAutoNavigate)return void t.preventDefault();const i=this.extractScreenIdFromHref(e.href);return i&&this.apiUrl?(t.preventDefault(),void this.navigateToScreen(i,e.href)):void 0};async navigateToScreen(t,e){await this.fetchScreen(t)?window.history.pushState({screen:t,state:this.state},"",e):window.location.href=e}getProviderHref(t){if(!this._screen)return null;for(const e of this._screen.components){const i=e;if("SOCIAL"===i.type&&i.config?.provider_details){const e=i.config.provider_details.find((e=>e.name===t));if(e?.href)return e.href}}return null}isSocialComponent(t){return"SOCIAL"===t.type}isDividerComponent(t){return"DIVIDER"===t.type}render(){const t=this._screen;if(this.loading&&!t)return r("div",{class:"widget-container"},r("div",{class:"loading-spinner"}));if(!t)return r("div",{class:"widget-container"},r("div",{class:"error-message"},"No screen configuration provided"));const e=t.messages?.filter((t=>"error"===t.type))||[],i=t.messages?.filter((t=>"success"===t.type))||[],n=[...t.components??[]],o=n.filter((t=>!1!==t.visible)).sort(((t,e)=>(t.order??0)-(e.order??0))),s=n.filter((t=>!1===t.visible)),a=o.filter((t=>this.isSocialComponent(t))),c=o.filter((t=>!this.isSocialComponent(t)&&!this.isDividerComponent(t))),h=o.find((t=>this.isDividerComponent(t))),l=!!h,d=h?.config?.text||"Or",f=t=>{const e=t.config;return["social-buttons","button","button-secondary","button-social","button-social-content","button-social-text","button-social-subtitle","social-icon",...(e?.providers??[]).flatMap((t=>{const e=t.replace(/[^a-zA-Z0-9-]/g,"-");return["button-social-"+e,"button-social-content-"+e,"button-social-text-"+e,"button-social-subtitle-"+e,"social-icon-"+e]}))].join(", ")},u=this._theme?.widget?.logo_url||this._branding?.logo_url;return r("div",{class:"widget-container",part:"container","data-authstack-container":!0},r("header",{class:"widget-header",part:"header"},u&&r("div",{class:"logo-wrapper",part:"logo-wrapper"},r("img",{class:"logo",part:"logo",src:u,alt:"Logo"})),t.title&&r("h1",{class:"title",part:"title",innerHTML:w(t.title)}),t.description&&r("p",{class:"description",part:"description",innerHTML:w(t.description)})),r("div",{class:"widget-body",part:"body"},e.map((t=>r("div",{class:"message message-error",part:"message message-error",key:t.id??t.text},t.text))),i.map((t=>r("div",{class:"message message-success",part:"message message-success",key:t.id??t.text},t.text))),r("form",{onSubmit:this.handleSubmit,action:t.action,method:t.method||"POST",part:"form"},s.map((t=>r("input",{type:"hidden",name:t.id,id:t.id,key:t.id,value:this.formData[t.id]||""}))),r("div",{class:"form-content"},a.length>0&&r("div",{class:"social-section",part:"social-section"},a.map((t=>r("authhero-node",{key:t.id,component:t,value:this.formData[t.id],onFieldChange:t=>this.handleInputChange(t.detail.id,t.detail.value),onButtonClick:t=>this.handleButtonClick(t.detail),disabled:this.loading,exportparts:f(t)})))),a.length>0&&c.length>0&&l&&r("div",{class:"divider",part:"divider"},r("span",{class:"divider-text"},d)),r("div",{class:"fields-section",part:"fields-section"},c.map((t=>r("authhero-node",{key:t.id,component:t,value:this.formData[t.id],onFieldChange:t=>this.handleInputChange(t.detail.id,t.detail.value),onButtonClick:t=>this.handleButtonClick(t.detail),disabled:this.loading})))))),t.links&&t.links.length>0&&r("div",{class:"links",part:"links"},t.links.map((t=>r("span",{class:"link-wrapper",part:"link-wrapper",key:t.id??t.href},t.linkText?r("span",null,t.text," ",r("a",{href:t.href,class:"link",part:"link",onClick:e=>this.handleLinkClick(e,{id:t.id,href:t.href,text:t.linkText||t.text})},t.linkText)):r("a",{href:t.href,class:"link",part:"link",onClick:e=>this.handleLinkClick(e,{id:t.id,href:t.href,text:t.text})},t.text))))),t.footer&&r("div",{class:"widget-footer",part:"footer",innerHTML:w(t.footer)})))}static get watchers(){return{screenId:[{watchScreenId:0}],screen:[{watchScreen:0}],branding:[{watchBranding:0}],theme:[{watchTheme:0}],authParams:[{watchAuthParams:0}]}}static get style(){return":host{display:block;font-family:var(--ah-font-family, 'ulp-font', -apple-system, BlinkMacSystemFont, Roboto, Helvetica, sans-serif);font-size:var(--ah-font-size-base, 16px);line-height:var(--ah-line-height-base, 1.5);color:var(--ah-color-text, #1e212a);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.widget-container{width:var(--ah-widget-max-width, 400px);margin:0 auto;background-color:var(--ah-color-bg, #ffffff);border-radius:var(--ah-widget-radius, 5px);border:var(--ah-widget-border-width, 0) solid var(--ah-widget-border-color, transparent);box-shadow:var(--ah-widget-shadow, 0 4px 22px 0 rgba(0, 0, 0, 0.11));box-sizing:border-box}.widget-header{padding:var(--ah-header-padding, 40px 48px 24px)}.widget-body{padding:var(--ah-body-padding, 0 48px 40px)}.logo-wrapper{display:var(--ah-logo-display, flex);justify-content:var(--ah-logo-align, center);margin-bottom:8px}.logo{display:block;height:var(--ah-logo-height, 52px);max-width:100%;width:auto;object-fit:contain}.title{font-size:var(--ah-font-size-title, 24px);font-weight:var(--ah-font-weight-title, 700);text-align:var(--ah-title-align, center);margin:var(--ah-title-margin, 24px 0 24px);color:var(--ah-color-text-header, var(--ah-color-header, #1e212a));line-height:1.2}.description{font-size:var(--ah-font-size-subtitle, 16px);font-weight:var(--ah-font-weight-subtitle, 400);text-align:var(--ah-title-align, center);margin:var(--ah-description-margin, 0 0 8px);color:var(--ah-color-text, #1e212a);line-height:1.5}.message{padding:12px 16px;border-radius:4px;margin-bottom:16px;font-size:14px;line-height:1.5}.message-error{background-color:var(--ah-color-error-bg, #ffeaea);color:var(--ah-color-error, #d03c38);border-left:3px solid var(--ah-color-error, #d03c38)}.message-success{background-color:var(--ah-color-success-bg, #e6f9f1);color:var(--ah-color-success, #13a769);border-left:3px solid var(--ah-color-success, #13a769)}form{display:flex;flex-direction:column}.form-content{display:flex;flex-direction:column}.social-section{display:flex;flex-direction:column;gap:8px;order:var(--ah-social-order, 2)}.fields-section{display:flex;flex-direction:column;order:var(--ah-fields-order, 0)}.divider{display:flex;align-items:center;text-align:center;margin:16px 0;order:var(--ah-divider-order, 1)}.divider::before,.divider::after{content:'';flex:1;border-bottom:1px solid var(--ah-color-border-muted, #c9cace)}.divider-text{padding:0 10px;font-size:12px;font-weight:400;color:var(--ah-color-text-muted, #65676e);text-transform:uppercase;letter-spacing:0}.links{display:flex;flex-direction:column;align-items:center;gap:8px;margin-top:16px}.link-wrapper{font-size:var(--ah-font-size-body, 14px);font-weight:var(--ah-font-weight-body, 400);color:var(--ah-color-text, #1e212a)}.link{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:var(--ah-font-size-link, 14px);font-weight:var(--ah-font-weight-link, 400);transition:color 150ms ease}.link:hover{text-decoration:underline}.link:focus-visible{outline:2px solid var(--ah-color-focus-ring, var(--ah-color-link, #635dff));outline-offset:2px;border-radius:2px}.widget-footer{margin-top:16px;text-align:center;font-size:12px;color:var(--ah-color-text-muted, #65676e)}.widget-footer a{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:12px;transition:color 150ms ease}.widget-footer a:hover{text-decoration:underline}.widget-footer a:focus-visible{outline:2px solid var(--ah-color-focus-ring, var(--ah-color-link, #635dff));outline-offset:2px;border-radius:2px}.loading-spinner{width:32px;height:32px;margin:24px auto;border:3px solid var(--ah-color-border-muted, #e0e1e3);border-top-color:var(--ah-color-primary, #635dff);border-radius:50%;animation:spin 0.8s linear infinite}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.error-message{text-align:center;color:var(--ah-color-error, #d03c38);padding:16px;font-size:14px}@media (max-width: 480px){:host{display:block;width:100%;min-height:100vh;background-color:var(--ah-color-bg, #ffffff)}.widget-container{box-shadow:none;border-radius:0;width:100%;margin:0}.widget-header{padding:24px 16px 16px}.widget-body{padding:0 16px 24px}}"}},[513,"authhero-widget",{screen:[1],apiUrl:[1,"api-url"],baseUrl:[1,"base-url"],state:[1025],screenId:[1025,"screen-id"],authParams:[1,"auth-params"],statePersistence:[1,"state-persistence"],storageKey:[1,"storage-key"],branding:[1],theme:[1],loading:[1028],autoSubmit:[4,"auto-submit"],autoNavigate:[4,"auto-navigate"],_screen:[32],_authParams:[32],_branding:[32],_theme:[32],formData:[32]},void 0,{screenId:[{watchScreenId:0}],screen:[{watchScreen:0}],branding:[{watchBranding:0}],theme:[{watchTheme:0}],authParams:[{watchAuthParams:0}]}]);function y(){"undefined"!=typeof customElements&&["authhero-widget","authhero-node"].forEach((e=>{switch(e){case"authhero-widget":customElements.get(t(e))||customElements.define(t(e),v);break;case"authhero-node":customElements.get(t(e))||o()}}))}y();const k=v,S=y;export{k as AuthheroWidget,S as defineCustomElement}
1
+ import{t,p as e,H as i,c as n,h as r}from"./p-cKZ5hFj1.js";import{d as o}from"./p-BzbxtmOP.js";function s(t){const e=t.match(/^#([0-9a-f]{3})$/i)||t.match(/^#([0-9a-f]{6})$/i);if(!e)return null;let i=e[1];3===i.length&&(i=i[0]+i[0]+i[1]+i[1]+i[2]+i[2]);const n=parseInt(i,16);return[n>>16&255,n>>8&255,255&n]}function a(t){const e=s(t);if(!e)return NaN;const[i,n,r]=e.map((t=>{const e=t/255;return e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4)}));return.2126*i+.7152*n+.0722*r}function c(t,e){const i=a(t),n=a(e);return isNaN(i)||isNaN(n)?NaN:(Math.max(i,n)+.05)/(Math.min(i,n)+.05)}function h(t,e="light"){const i=c(t,"#000000"),n=c(t,"#ffffff");return"light"===e?i>1.35*n?"#000000":"#ffffff":1.35*i>n?"#000000":"#ffffff"}function l(t,e){const i=s(t);if(!i)return t;const[n,r,o]=i,a=t=>Math.max(0,Math.round(t*(1-e))).toString(16).padStart(2,"0");return`#${a(n)}${a(r)}${a(o)}`}function d(t,e){const i=s(t);if(!i)return t;const[n,r,o]=i,a=t=>Math.min(255,Math.round(t+(255-t)*e)).toString(16).padStart(2,"0");return`#${a(n)}${a(r)}${a(o)}`}function f(t,e,i=4.5){if(c(t,e)>=i)return t;const n=a(e)>.5;let r=t;for(let o=1;o<=10;o++)if(r=n?l(t,.1*o):d(t,.1*o),c(r,e)>=i)return r;return n?"#000000":"#ffffff"}function u(t,e){if(void 0!==e)return e+"px";switch(t){case"pill":return"9999px";case"rounded":return"8px";case"sharp":return"0";default:return}}function p(t){if(!t)return{};const e={};if(t.colors?.primary&&(e["--ah-color-primary"]=t.colors.primary),t.colors?.page_background){const i=t.colors.page_background;"solid"===i.type&&i.start?e["--ah-page-bg"]=i.start:"gradient"===i.type&&i.start&&i.end&&(e["--ah-page-bg"]=`linear-gradient(${i.angle_deg??180}deg, ${i.start}, ${i.end})`)}return t.logo_url&&(e["--ah-logo-url"]=`url(${t.logo_url})`),t.font?.url&&(e["--ah-font-url"]=t.font.url),e}function g(t){if(!t)return{};const e={};if(t.borders){const i=t.borders;void 0!==i.widget_corner_radius&&(e["--ah-widget-radius"]=i.widget_corner_radius+"px"),void 0!==i.widget_border_weight&&(e["--ah-widget-border-width"]=i.widget_border_weight+"px"),!1===i.show_widget_shadow&&(e["--ah-widget-shadow"]="none");const n=u(i.buttons_style,i.button_border_radius);n&&(e["--ah-btn-radius"]=n),void 0!==i.button_border_weight&&(e["--ah-btn-border-width"]=i.button_border_weight+"px");const r=u(i.inputs_style,i.input_border_radius);r&&(e["--ah-input-radius"]=r),void 0!==i.input_border_weight&&(e["--ah-input-border-width"]=i.input_border_weight+"px")}if(t.colors){const i=t.colors;if(i.primary_button)if(e["--ah-color-primary"]=i.primary_button,i.primary_button_label)e["--ah-color-text-on-primary"]=i.primary_button_label;else{e["--ah-color-text-on-primary"]=h(i.primary_button,"light");const t=h(i.primary_button,"dark");t!==e["--ah-color-text-on-primary"]&&(e["--ah-color-text-on-primary-dark"]=t)}else i.primary_button_label&&(e["--ah-color-text-on-primary"]=i.primary_button_label);i.secondary_button_border&&(e["--ah-btn-secondary-border"]=i.secondary_button_border),i.secondary_button_label&&(e["--ah-btn-secondary-text"]=i.secondary_button_label),i.body_text&&(e["--ah-color-text"]=i.body_text),i.header&&(e["--ah-color-text-header"]=i.header),i.input_labels_placeholders&&(e["--ah-color-text-label"]=i.input_labels_placeholders,e["--ah-color-text-muted"]=i.input_labels_placeholders),i.input_filled_text&&(e["--ah-color-input-text"]=i.input_filled_text),i.widget_background&&(e["--ah-color-bg"]=i.widget_background),i.input_background&&(e["--ah-color-input-bg"]=i.input_background),i.widget_border&&(e["--ah-widget-border-color"]=i.widget_border),i.input_border&&(e["--ah-color-border"]=i.input_border),i.links_focused_components&&(e["--ah-color-link"]=f(i.links_focused_components,i.widget_background||"#ffffff")),i.base_focus_color&&(e["--ah-color-focus-ring"]=i.base_focus_color),i.base_hover_color&&(e["--ah-color-primary-hover"]=i.base_hover_color),i.error&&(e["--ah-color-error"]=i.error),i.success&&(e["--ah-color-success"]=i.success),i.icons&&(e["--ah-color-icon"]=i.icons);const n=i.widget_background||"#ffffff",r=i.input_background||n,o=e["--ah-color-border"]||i.input_border||"#c9cace",s=c(o,n),a=c(o,r);Math.min(s,a)<3&&(e["--ah-color-border"]=f(o,s<a?n:r,3))}if(t.fonts){const i=t.fonts,n=i.reference_text_size||16,r=t=>t>=50?Math.round(t/100*n):t;i.font_url&&(e["--ah-font-url"]=i.font_url),i.reference_text_size&&(e["--ah-font-size-base"]=i.reference_text_size+"px"),i.title?.size&&(e["--ah-font-size-title"]=r(i.title.size)+"px"),i.subtitle?.size&&(e["--ah-font-size-subtitle"]=r(i.subtitle.size)+"px"),i.body_text?.size&&(e["--ah-font-size-body"]=r(i.body_text.size)+"px"),i.input_labels?.size&&(e["--ah-font-size-label"]=r(i.input_labels.size)+"px"),i.buttons_text?.size&&(e["--ah-font-size-btn"]=r(i.buttons_text.size)+"px"),i.links?.size&&(e["--ah-font-size-link"]=r(i.links.size)+"px"),"underlined"===i.links_style&&(e["--ah-link-decoration"]="underline"),void 0!==i.title?.bold&&(e["--ah-font-weight-title"]=i.title.bold?"700":"400"),void 0!==i.subtitle?.bold&&(e["--ah-font-weight-subtitle"]=i.subtitle.bold?"700":"400"),void 0!==i.body_text?.bold&&(e["--ah-font-weight-body"]=i.body_text.bold?"700":"400"),void 0!==i.input_labels?.bold&&(e["--ah-font-weight-label"]=i.input_labels.bold?"700":"400"),void 0!==i.buttons_text?.bold&&(e["--ah-font-weight-btn"]=i.buttons_text.bold?"600":"400"),void 0!==i.links?.bold&&(e["--ah-font-weight-link"]=i.links.bold?"700":"400")}if(t.widget){const i=t.widget;if(i.header_text_alignment&&(e["--ah-title-align"]=i.header_text_alignment),i.logo_height&&(e["--ah-logo-height"]=i.logo_height+"px"),i.logo_position){const t={center:"center",left:"flex-start",right:"flex-end"};"none"===i.logo_position?e["--ah-logo-display"]="none":e["--ah-logo-align"]=t[i.logo_position]??"center"}i.social_buttons_layout&&("top"===i.social_buttons_layout?(e["--ah-social-order"]="0",e["--ah-divider-order"]="1",e["--ah-fields-order"]="2"):(e["--ah-social-order"]="2",e["--ah-divider-order"]="1",e["--ah-fields-order"]="0"))}if(t.page_background){const i=t.page_background;i.background_color&&(e["--ah-page-bg"]=i.background_color),i.background_image_url&&(e["--ah-page-bg-image"]=`url(${i.background_image_url})`)}return e}const m={br:[],em:[],i:[],strong:[],b:[],u:[],span:["class"],a:["href","class"]};function w(t){if(!t)return"";if(!t.includes("<"))return t;let e=t;e=e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;");for(const[t,i]of Object.entries(m)){if("br"===t){e=e.replace(/&lt;br\s*\/?&gt;/gi,"<br>");continue}const n=RegExp(`&lt;${t}((?:\\s+[a-z-]+(?:=&quot;[^&]*&quot;|=&#39;[^&]*&#39;)?)*)\\s*&gt;`,"gi");e=e.replace(n,((e,n)=>{const r=[];if(n){const t=n.replace(/&quot;/g,'"').replace(/&#39;/g,"'").replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">"),e=/([a-z-]+)=["']([^"']*)["']/gi;let o;for(;null!==(o=e.exec(t));){const[,t,e]=o;t&&i.includes(t.toLowerCase())&&("href"===t.toLowerCase()?b(e||"")&&r.push(`${t}="${x(e||"")}"`):r.push(`${t}="${x(e||"")}"`))}}"a"===t&&(r.push('target="_blank"'),r.push('rel="noopener noreferrer"'));const o=r.length?" "+r.join(" "):"";return`<${t}${o}>`}));const r=RegExp(`&lt;/${t}&gt;`,"gi");e=e.replace(r,`</${t}>`)}return e}function b(t){if(!t)return!1;if(t.startsWith("/")||t.startsWith("#")||t.startsWith("?"))return!0;try{const e=new URL(t,"https://example.com");return"http:"===e.protocol||"https:"===e.protocol}catch{return!1}}function x(t){return t.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}const v=e(class extends i{constructor(t){super(),!1!==t&&this.__registerHost(),this.__attachShadow(),this.formSubmit=n(this,"formSubmit"),this.buttonClick=n(this,"buttonClick"),this.linkClick=n(this,"linkClick"),this.navigate=n(this,"navigate"),this.flowComplete=n(this,"flowComplete"),this.flowError=n(this,"flowError"),this.screenChange=n(this,"screenChange")}get el(){return this}screen;apiUrl;baseUrl;state;screenId;watchScreenId(){this.updateDataScreenAttribute()}authParams;statePersistence="memory";storageKey="authhero_widget";branding;theme;loading=!1;autoSubmit=!1;autoNavigate;_screen;_authParams;_branding;_theme;formData={};conditionalMediationAbort;loadedFontUrl;formSubmit;buttonClick;linkClick;navigate;flowComplete;flowError;screenChange;watchScreen(t){if(this.conditionalMediationAbort?.abort(),this.conditionalMediationAbort=void 0,"string"==typeof t)try{this._screen=JSON.parse(t)}catch{console.error("Failed to parse screen JSON")}else this._screen=t;this._screen&&(this.formData={},this.initFormDataFromDefaults(this._screen),this.screenChange.emit(this._screen),this.updateDataScreenAttribute())}initFormDataFromDefaults(t){const e={};for(const i of t.components||[])if("config"in i&&i.config&&"default_value"in i.config&&i.config.default_value){const t=i.config.default_value;"string"==typeof t&&""!==t&&(e[i.id]=t)}Object.keys(e).length>0&&(this.formData={...e,...this.formData})}updateDataScreenAttribute(){const t=this._screen?.name||this.screenId;t?this.el.setAttribute("data-screen",t):this.el.removeAttribute("data-screen");const e=this.el.closest("[data-authhero-widget-container]");e&&(t?e.setAttribute("data-screen",t):e.removeAttribute("data-screen"))}watchBranding(t){if("string"==typeof t)try{this._branding=JSON.parse(t)}catch{console.error("Failed to parse branding JSON")}else this._branding=t;this.applyThemeStyles()}watchTheme(t){if("string"==typeof t)try{this._theme=JSON.parse(t)}catch{console.error("Failed to parse theme JSON")}else this._theme=t;this.applyThemeStyles()}watchAuthParams(t){if("string"==typeof t)try{this._authParams=JSON.parse(t)}catch{console.error("Failed to parse authParams JSON")}else this._authParams=t}applyThemeStyles(){const t=function(t,e){return{...p(t),...g(e)}}(this._branding,this._theme);!function(t,e){Object.entries(e).forEach((([e,i])=>{t.style.setProperty(e,i)}))}(this.el,t),this.loadCustomFont()}loadCustomFont(){if("undefined"==typeof document)return;const t=this._theme?.fonts?.font_url||this._branding?.font?.url;if(t===this.loadedFontUrl)return;for(const t of Array.from(document.head.querySelectorAll("link[data-authhero-font]")))t.remove();if(this.loadedFontUrl=void 0,!t)return;const e=document.createElement("link");e.rel="stylesheet",e.href=t,e.setAttribute("data-authhero-font",t),document.head.appendChild(e),this.loadedFontUrl=t}focusFirstInput(){requestAnimationFrame((()=>{const t=this.el.shadowRoot;if(!t)return;const e=t.querySelectorAll("authhero-node");for(const t of Array.from(e)){const e=t.shadowRoot;if(e){const t=e.querySelector('input:not([type="hidden"]):not([type="checkbox"]):not([disabled]), textarea:not([disabled])');if(t)return void t.focus()}}}))}pendingRenderResolvers=[];componentDidRender(){if(0===this.pendingRenderResolvers.length)return;const t=this.pendingRenderResolvers;this.pendingRenderResolvers=[],t.forEach((t=>t()))}nextRender(){return new Promise((t=>{let e=!1;const i=()=>{e||(e=!0,t())};this.pendingRenderResolvers.push(i),requestAnimationFrame((()=>requestAnimationFrame(i)))}))}async swapScreen(t){const e=this.el.shadowRoot?.querySelector(".widget-container"),i="function"==typeof window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches;if(!e||"function"!=typeof e.animate||i)return void t();const n=e.getBoundingClientRect().height;e.style.height=n+"px",e.style.overflow="hidden",t(),await this.nextRender();const r=()=>{e.style.height="",e.style.overflow=""};e.style.height="auto";const o=e.getBoundingClientRect().height;if(e.style.height=n+"px",e.getBoundingClientRect(),Math.abs(o-n)<1)return void r();const s=e.animate([{height:n+"px"},{height:o+"px"}],{duration:520,easing:"cubic-bezier(0.22, 1, 0.36, 1)"});try{await s.finished}catch{}finally{r()}}get shouldAutoNavigate(){return this.autoNavigate??this.autoSubmit}buildUrl(t){return this.baseUrl?""+new URL(t,this.baseUrl):t}loadPersistedState(){if("url"===this.statePersistence){const t=new URL(window.location.href).searchParams.get("state");t&&!this.state&&(this.state=t)}else if("session"===this.statePersistence)try{const t=sessionStorage.getItem(this.storageKey+"_state");t&&!this.state&&(this.state=t);const e=sessionStorage.getItem(this.storageKey+"_screenId");e&&!this.screenId&&(this.screenId=e)}catch{}}persistState(){if("url"===this.statePersistence){const t=new URL(window.location.href);this.state&&t.searchParams.set("state",this.state),this.screenId&&t.searchParams.set("screen",this.screenId),window.history.replaceState({},"",""+t)}else if("session"===this.statePersistence)try{this.state&&sessionStorage.setItem(this.storageKey+"_state",this.state),this.screenId&&sessionStorage.setItem(this.storageKey+"_screenId",this.screenId)}catch{}}handlePopState=t=>{if(!this.apiUrl)return;t.state?.state&&(this.state=t.state.state);const e=t.state?.screen??this.extractScreenIdFromHref(location.href);e&&this.fetchScreen(e)};connectedCallback(){window.addEventListener("popstate",this.handlePopState)}disconnectedCallback(){window.removeEventListener("popstate",this.handlePopState),this.conditionalMediationAbort?.abort(),this.conditionalMediationAbort=void 0}readJsonScript(t){if(!this.el)return;const e=this.el.querySelector(`script[type="application/json"][data-authhero="${t}"]`);return e?.textContent??void 0}async componentWillLoad(){if(!this._screen){const t=this.screen||this.readJsonScript("screen")||this.el?.getAttribute("screen");t&&this.watchScreen(t)}this._branding||this.watchBranding(this.branding??this.readJsonScript("branding")),this._theme||this.watchTheme(this.theme??this.readJsonScript("theme")),this._authParams||this.watchAuthParams(this.authParams??this.readJsonScript("auth-params")),this.loadPersistedState(),this.apiUrl&&!this._screen&&await this.fetchScreen(this.screenId)}async fetchScreen(t,e){if(!this.apiUrl)return!1;const i=t||this.screenId;let n=this.apiUrl;i&&n.includes("{screenId}")&&(n=n.replace("{screenId}",encodeURIComponent(i)));const r=new URL(n,this.baseUrl||window.location.origin);this.state&&r.searchParams.set("state",this.state),e&&r.searchParams.set("nodeId",e),this.loading=!0;try{const t=await fetch(this.buildUrl(r.pathname+r.search),{credentials:"include",headers:{Accept:"application/json"}});if(t.ok){const e=await t.json();if(e.screen?(this._screen=e.screen,e.branding&&(this._branding=e.branding,this.applyThemeStyles()),e.state&&(this.state=e.state),e.screenId&&(this.screenId=e.screenId)):this._screen=e,this._screen)return i&&i!==this.screenId&&(this.screenId=i),this.initFormDataFromDefaults(this._screen),this.screenChange.emit(this._screen),this.updateDataScreenAttribute(),this.persistState(),this.focusFirstInput(),e.ceremony&&this.performWebAuthnCeremony(e.ceremony),!0}else{const e=await t.json().catch((()=>({message:"Failed to load screen"})));this.flowError.emit({message:e.message||"Failed to load screen"})}}catch(t){console.error("Failed to fetch screen:",t),this.flowError.emit({message:t instanceof Error?t.message:"Failed to fetch screen"})}finally{this.loading=!1}return!1}handleInputChange=(t,e)=>{this.formData={...this.formData,[t]:e}};handleSubmit=async(t,e)=>{if(t.preventDefault(),!this._screen||this.loading)return;let i={...this.formData,...e||{}};const n=this.el.shadowRoot?.querySelector("form");if(n&&n.querySelectorAll('input[type="hidden"]').forEach((t=>{t.name&&t.value&&(i[t.name]=t.value)})),this.formSubmit.emit({screen:this._screen,data:i}),this.autoSubmit)if(this._screen.method&&"GET"!==this._screen.method.toUpperCase()){this.loading=!0;try{const t=await fetch(this.buildUrl(this._screen.action),{method:this._screen.method,credentials:"include",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({data:i})}),e=t.headers.get("content-type");if(e?.includes("text/html")){const e=await t.text();return document.open(),document.write(e),void document.close()}if(e?.includes("application/json")){const e=await t.json();e.redirect?(this.flowComplete.emit({redirectUrl:e.redirect}),this.navigate.emit({url:e.redirect}),this.shouldAutoNavigate&&(window.location.href=e.redirect)):!t.ok&&e.screen?await this.swapScreen((()=>{this.loading=!1,this._screen=e.screen,this.initFormDataFromDefaults(e.screen),this.screenChange.emit(e.screen),this.updateDataScreenAttribute(),this.focusFirstInput()})):e.screen?await this.swapScreen((()=>{this.loading=!1,this._screen=e.screen,this.formData={},this.initFormDataFromDefaults(e.screen),this.screenChange.emit(e.screen),this.updateDataScreenAttribute(),e.screenId&&(this.screenId=e.screenId),this.persistState(),e.navigateUrl&&this.shouldAutoNavigate&&window.history.pushState({screen:e.screenId,state:this.state},"",e.navigateUrl),e.branding&&(this._branding=e.branding,this.applyThemeStyles()),e.state&&(this.state=e.state,this.persistState()),e.ceremony&&this.performWebAuthnCeremony(e.ceremony),this.focusFirstInput()})):e.complete?this.flowComplete.emit({}):!t.ok&&e.error&&(this._screen&&(this._screen={...this._screen,messages:[...this._screen.messages||[],{text:e.error,type:"error"}]}),this.flowError.emit({message:e.error}))}}catch(t){console.error("Form submission failed:",t),this.flowError.emit({message:t instanceof Error?t.message:"Form submission failed"})}finally{this.loading=!1}}else window.location.href=this.buildUrl(this._screen.action)};overrideFormSubmit(){const t=this.el.shadowRoot;if(!t)return;const e=t.querySelector("form");e&&(e.submit=()=>{const t=new FormData(e),i={};t.forEach(((t,e)=>{"string"==typeof t&&(i[e]=t)})),this.handleSubmit({preventDefault:()=>{}},i)})}performWebAuthnCeremony(t){this.isValidWebAuthnCeremony(t)?"webauthn-authentication-conditional"!==t.type?requestAnimationFrame((()=>{this.overrideFormSubmit(),"webauthn-authentication"===t.type?this.executeWebAuthnAuthentication(t):this.executeWebAuthnRegistration(t)})):this.executeWebAuthnConditionalMediation(t):console.error("Invalid WebAuthn ceremony payload",t)}isValidWebAuthnCeremony(t){if("object"!=typeof t||null===t)return!1;const e=t;if("string"!=typeof e.successAction)return!1;const i=e.options;if("object"!=typeof i||null===i)return!1;if("string"!=typeof i.challenge)return!1;if("webauthn-registration"===e.type){const t=i.rp;if("object"!=typeof t||null===t)return!1;if("string"!=typeof t.id||"string"!=typeof t.name)return!1;const e=i.user;return"object"==typeof e&&null!==e&&("string"==typeof e.id&&"string"==typeof e.name&&"string"==typeof e.displayName&&!!Array.isArray(i.pubKeyCredParams))}return"webauthn-authentication"===e.type||"webauthn-authentication-conditional"===e.type}async executeWebAuthnRegistration(t){const e=t.options,i=t=>{for(t=t.replace(/-/g,"+").replace(/_/g,"/");t.length%4;)t+="=";const e=atob(t),i=new Uint8Array(e.length);for(let t=0;t<e.length;t++)i[t]=e.charCodeAt(t);return i.buffer},n=t=>{const e=new Uint8Array(t);let i="";for(let t=0;t<e.length;t++)i+=String.fromCharCode(e[t]);return btoa(i).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")},r=()=>{const t=this.el?.shadowRoot;if(t){const e=t.querySelector("form");if(e)return e}return document.querySelector("form")};try{const o={challenge:i(e.challenge),rp:{id:e.rp.id,name:e.rp.name},user:{id:i(e.user.id),name:e.user.name,displayName:e.user.displayName},pubKeyCredParams:e.pubKeyCredParams.map((t=>({alg:t.alg,type:t.type}))),timeout:e.timeout,attestation:e.attestation||"none",authenticatorSelection:e.authenticatorSelection?{residentKey:e.authenticatorSelection.residentKey||"preferred",userVerification:e.authenticatorSelection.userVerification||"preferred"}:void 0};e.excludeCredentials?.length&&(o.excludeCredentials=e.excludeCredentials.map((t=>({id:i(t.id),type:t.type,transports:t.transports||[]}))));const s=await navigator.credentials.create({publicKey:o}),a=s.response,c={id:s.id,rawId:n(s.rawId),type:s.type,response:{attestationObject:n(a.attestationObject),clientDataJSON:n(a.clientDataJSON)},clientExtensionResults:s.getClientExtensionResults(),authenticatorAttachment:s.authenticatorAttachment||void 0};"function"==typeof a.getTransports&&(c.response.transports=a.getTransports());const h=r();if(h){const e=h.querySelector('[name="credential-field"]')||h.querySelector("#credential-field"),i=h.querySelector('[name="action-field"]')||h.querySelector("#action-field");e&&(e.value=JSON.stringify(c)),i&&(i.value=t.successAction),h.submit()}}catch(t){console.error("WebAuthn registration error:",t);const e=r();if(e){const t=e.querySelector('[name="action-field"]')||e.querySelector("#action-field");t&&(t.value="error"),e.submit()}}}async executeWebAuthnAuthentication(t){const e=t.options,i=t=>{for(t=t.replace(/-/g,"+").replace(/_/g,"/");t.length%4;)t+="=";const e=atob(t),i=new Uint8Array(e.length);for(let t=0;t<e.length;t++)i[t]=e.charCodeAt(t);return i.buffer},n=t=>{const e=new Uint8Array(t);let i="";for(let t=0;t<e.length;t++)i+=String.fromCharCode(e[t]);return btoa(i).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")},r=()=>{const t=this.el?.shadowRoot;if(t){const e=t.querySelector("form");if(e)return e}return document.querySelector("form")};try{const o={challenge:i(e.challenge),rpId:e.rpId,timeout:e.timeout,userVerification:e.userVerification||"preferred"};e.allowCredentials?.length&&(o.allowCredentials=e.allowCredentials.map((t=>({id:i(t.id),type:t.type,transports:t.transports||[]}))));const s=await navigator.credentials.get({publicKey:o}),a=s.response,c={id:s.id,rawId:n(s.rawId),type:s.type,response:{authenticatorData:n(a.authenticatorData),clientDataJSON:n(a.clientDataJSON),signature:n(a.signature)},clientExtensionResults:s.getClientExtensionResults(),authenticatorAttachment:s.authenticatorAttachment||void 0};a.userHandle&&(c.response.userHandle=n(a.userHandle));const h=r();if(h){const e=h.querySelector('[name="credential-field"]')||h.querySelector("#credential-field"),i=h.querySelector('[name="action-field"]')||h.querySelector("#action-field");e&&(e.value=JSON.stringify(c)),i&&(i.value=t.successAction),h.submit()}}catch(t){console.error("WebAuthn authentication error:",t);const e=r();if(e){const t=e.querySelector('[name="action-field"]')||e.querySelector("#action-field");t&&(t.value="error"),e.submit()}}}async executeWebAuthnConditionalMediation(t){if(!window.PublicKeyCredential||!PublicKeyCredential.isConditionalMediationAvailable)return;if(!await PublicKeyCredential.isConditionalMediationAvailable())return;this.conditionalMediationAbort?.abort();const e=new AbortController;this.conditionalMediationAbort=e;const i=t.options,n=t=>{for(t=t.replace(/-/g,"+").replace(/_/g,"/");t.length%4;)t+="=";const e=atob(t),i=new Uint8Array(e.length);for(let t=0;t<e.length;t++)i[t]=e.charCodeAt(t);return i.buffer},r=t=>{const e=new Uint8Array(t);let i="";for(let t=0;t<e.length;t++)i+=String.fromCharCode(e[t]);return btoa(i).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")};try{const o=await navigator.credentials.get({mediation:"conditional",signal:e.signal,publicKey:{challenge:n(i.challenge),rpId:i.rpId,timeout:i.timeout,userVerification:i.userVerification||"preferred"}}),s=o.response,a={id:o.id,rawId:r(o.rawId),type:o.type,response:{authenticatorData:r(s.authenticatorData),clientDataJSON:r(s.clientDataJSON),signature:r(s.signature)},clientExtensionResults:o.getClientExtensionResults(),authenticatorAttachment:o.authenticatorAttachment||void 0};s.userHandle&&(a.response.userHandle=r(s.userHandle)),this.formData["credential-field"]=JSON.stringify(a),this.formData["action-field"]=t.successAction,this.overrideFormSubmit();const c=this.el?.shadowRoot,h=c?.querySelector("form");if(h){const e=h.querySelector('[name="credential-field"]')||h.querySelector("#credential-field"),i=h.querySelector('[name="action-field"]')||h.querySelector("#action-field");e&&(e.value=JSON.stringify(a)),i&&(i.value=t.successAction),h.submit()}}catch(t){if("AbortError"===t?.name||"NotAllowedError"===t?.name)return;console.error("Conditional mediation error:",t)}}handleButtonClick=t=>{if("submit"!==t.type)if(this.buttonClick.emit(t),"SOCIAL"===t.type&&t.value&&this.shouldAutoNavigate){const e=this.getProviderHref(t.value);if(e){const t=this.extractScreenIdFromHref(e);return void(t&&this.apiUrl?this.navigateToScreen(t,e):window.location.href=e)}this.handleSocialLogin(t.value)}else"RESEND_BUTTON"===t.type&&this.shouldAutoNavigate&&this.handleResend();else{if((!this._screen?.method||"GET"===this._screen.method.toUpperCase())&&this._screen?.action)return void(window.location.href=this.buildUrl(this._screen.action));const e={...this.formData,[t.id]:"true"};this.formData=e,this.handleSubmit({preventDefault:()=>{}},e)}};handleSocialLogin(t){const e=this._authParams||{},i={connection:t};this.state?i.state=this.state:e.state&&(i.state=e.state),e.client_id&&(i.client_id=e.client_id),e.redirect_uri&&(i.redirect_uri=e.redirect_uri),e.scope&&(i.scope=e.scope),e.audience&&(i.audience=e.audience),e.nonce&&(i.nonce=e.nonce),e.response_type&&(i.response_type=e.response_type);const n=this.buildUrl("/authorize?"+new URLSearchParams(i));this.navigate.emit({url:n}),window.location.href=n}async handleResend(){if(this._screen?.action)try{const t=this._screen.action+(this._screen.action.includes("?")?"&":"?")+"action=resend";await fetch(this.buildUrl(t),{method:"POST",credentials:"include"})}catch(t){console.error("Resend failed:",t)}}extractScreenIdFromHref(t){try{const e=new URL(t,window.location.origin).pathname,i=e.match(/\/u2\/login\/([^/]+)$/);if(i)return i[1];const n=e.match(/\/u2\/([^/]+)$/);return n&&"login"!==n[1]&&"screen"!==n[1]?n[1]:null}catch{return null}}handleLinkClick=(t,e)=>{if(this.linkClick.emit({id:e.id,href:e.href,text:e.text}),!this.shouldAutoNavigate)return void t.preventDefault();const i=this.extractScreenIdFromHref(e.href);return i&&this.apiUrl?(t.preventDefault(),void this.navigateToScreen(i,e.href)):void 0};async navigateToScreen(t,e){await this.fetchScreen(t)?window.history.pushState({screen:t,state:this.state},"",e):window.location.href=e}getProviderHref(t){if(!this._screen)return null;for(const e of this._screen.components){const i=e;if("SOCIAL"===i.type&&i.config?.provider_details){const e=i.config.provider_details.find((e=>e.name===t));if(e?.href)return e.href}}return null}isSocialComponent(t){return"SOCIAL"===t.type}isDividerComponent(t){return"DIVIDER"===t.type}render(){const t=this._screen;if(this.loading&&!t)return r("div",{class:"widget-container"},r("div",{class:"loading-spinner"}));if(!t)return r("div",{class:"widget-container"},r("div",{class:"error-message"},"No screen configuration provided"));const e=t.messages?.filter((t=>"error"===t.type))||[],i=t.messages?.filter((t=>"success"===t.type))||[],n=[...t.components??[]],o=n.filter((t=>!1!==t.visible)).sort(((t,e)=>(t.order??0)-(e.order??0))),s=n.filter((t=>!1===t.visible)),a=o.filter((t=>this.isSocialComponent(t))),c=o.filter((t=>!this.isSocialComponent(t)&&!this.isDividerComponent(t))),h=o.find((t=>this.isDividerComponent(t))),l=!!h,d=h?.config?.text||"Or",f=t=>{const e=t.config;return["social-buttons","button","button-secondary","button-social","button-social-content","button-social-text","button-social-subtitle","social-icon",...(e?.providers??[]).flatMap((t=>{const e=t.replace(/[^a-zA-Z0-9-]/g,"-");return["button-social-"+e,"button-social-content-"+e,"button-social-text-"+e,"button-social-subtitle-"+e,"social-icon-"+e]}))].join(", ")},u=this._theme?.widget?.logo_url||this._branding?.logo_url;return r("div",{class:"widget-container",part:"container","data-authstack-container":!0},r("header",{class:"widget-header",part:"header"},u&&r("div",{class:"logo-wrapper",part:"logo-wrapper"},r("img",{class:"logo",part:"logo",src:u,alt:"Logo"})),t.title&&r("h1",{class:"title",part:"title",innerHTML:w(t.title)}),t.description&&r("p",{class:"description",part:"description",innerHTML:w(t.description)})),r("div",{class:"widget-body",part:"body"},e.map((t=>r("div",{class:"message message-error",part:"message message-error",key:t.id??t.text},t.text))),i.map((t=>r("div",{class:"message message-success",part:"message message-success",key:t.id??t.text},t.text))),r("form",{onSubmit:this.handleSubmit,action:t.action,method:t.method||"POST",part:"form"},s.map((t=>r("input",{type:"hidden",name:t.id,id:t.id,key:t.id,value:this.formData[t.id]||""}))),r("div",{class:"form-content"},a.length>0&&r("div",{class:"social-section",part:"social-section"},a.map((t=>r("authhero-node",{key:t.id,component:t,value:this.formData[t.id],onFieldChange:t=>this.handleInputChange(t.detail.id,t.detail.value),onButtonClick:t=>this.handleButtonClick(t.detail),disabled:this.loading,exportparts:f(t)})))),a.length>0&&c.length>0&&l&&r("div",{class:"divider",part:"divider"},r("span",{class:"divider-text"},d)),r("div",{class:"fields-section",part:"fields-section"},c.map((t=>r("authhero-node",{key:t.id,component:t,value:this.formData[t.id],onFieldChange:t=>this.handleInputChange(t.detail.id,t.detail.value),onButtonClick:t=>this.handleButtonClick(t.detail),disabled:this.loading})))))),t.links&&t.links.length>0&&r("div",{class:"links",part:"links"},t.links.map((t=>r("span",{class:"link-wrapper",part:"link-wrapper",key:t.id??t.href},t.linkText?r("span",null,t.text," ",r("a",{href:t.href,class:"link",part:"link",onClick:e=>this.handleLinkClick(e,{id:t.id,href:t.href,text:t.linkText||t.text})},t.linkText)):r("a",{href:t.href,class:"link",part:"link",onClick:e=>this.handleLinkClick(e,{id:t.id,href:t.href,text:t.text})},t.text))))),t.footer&&r("div",{class:"widget-footer",part:"footer",innerHTML:w(t.footer)})))}static get watchers(){return{screenId:[{watchScreenId:0}],screen:[{watchScreen:0}],branding:[{watchBranding:0}],theme:[{watchTheme:0}],authParams:[{watchAuthParams:0}]}}static get style(){return":host{display:block;font-family:var(--ah-font-family, 'ulp-font', -apple-system, BlinkMacSystemFont, Roboto, Helvetica, sans-serif);font-size:var(--ah-font-size-base, 16px);line-height:var(--ah-line-height-base, 1.5);color:var(--ah-color-text, #1e212a);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.widget-container{width:var(--ah-widget-max-width, 400px);margin:0 auto;background-color:var(--ah-color-bg, #ffffff);border-radius:var(--ah-widget-radius, 5px);border:var(--ah-widget-border-width, 0) solid var(--ah-widget-border-color, transparent);box-shadow:var(--ah-widget-shadow, 0 4px 22px 0 rgba(0, 0, 0, 0.11));box-sizing:border-box}.widget-header{padding:var(--ah-header-padding, 40px 48px 24px)}.widget-body{padding:var(--ah-body-padding, 0 48px 40px)}.logo-wrapper{display:var(--ah-logo-display, flex);justify-content:var(--ah-logo-align, center);margin-bottom:8px}.logo{display:block;height:var(--ah-logo-height, 52px);max-width:100%;width:auto;object-fit:contain}.title{font-size:var(--ah-font-size-title, 24px);font-weight:var(--ah-font-weight-title, 700);text-align:var(--ah-title-align, center);margin:var(--ah-title-margin, 24px 0 24px);color:var(--ah-color-text-header, var(--ah-color-header, #1e212a));line-height:1.2}.description{font-size:var(--ah-font-size-subtitle, 16px);font-weight:var(--ah-font-weight-subtitle, 400);text-align:var(--ah-title-align, center);margin:var(--ah-description-margin, 0 0 8px);color:var(--ah-color-text, #1e212a);line-height:1.5}.message{padding:12px 16px;border-radius:4px;margin-bottom:16px;font-size:14px;line-height:1.5}.message-error{background-color:var(--ah-color-error-bg, #ffeaea);color:var(--ah-color-error, #d03c38);border-left:3px solid var(--ah-color-error, #d03c38)}.message-success{background-color:var(--ah-color-success-bg, #e6f9f1);color:var(--ah-color-success, #13a769);border-left:3px solid var(--ah-color-success, #13a769)}form{display:flex;flex-direction:column}.form-content{display:flex;flex-direction:column}.social-section{display:flex;flex-direction:column;gap:8px;order:var(--ah-social-order, 2)}.fields-section{display:flex;flex-direction:column;order:var(--ah-fields-order, 0)}.divider{display:flex;align-items:center;text-align:center;margin:16px 0;order:var(--ah-divider-order, 1)}.divider::before,.divider::after{content:'';flex:1;border-bottom:1px solid var(--ah-color-border-muted, #c9cace)}.divider-text{padding:0 10px;font-size:12px;font-weight:400;color:var(--ah-color-text-muted, #65676e);text-transform:uppercase;letter-spacing:0}.links{display:flex;flex-direction:column;align-items:center;gap:8px;margin-top:16px}.link-wrapper{font-size:var(--ah-font-size-body, 14px);font-weight:var(--ah-font-weight-body, 400);color:var(--ah-color-text, #1e212a)}.link{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:var(--ah-font-size-link, 14px);font-weight:var(--ah-font-weight-link, 400);transition:color 150ms ease}.link:hover{text-decoration:underline}.link:focus-visible{outline:2px solid var(--ah-color-focus-ring, var(--ah-color-link, #635dff));outline-offset:2px;border-radius:2px}.widget-footer{margin-top:16px;text-align:center;font-size:12px;color:var(--ah-color-text-muted, #65676e)}.widget-footer a{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:12px;transition:color 150ms ease}.widget-footer a:hover{text-decoration:underline}.widget-footer a:focus-visible{outline:2px solid var(--ah-color-focus-ring, var(--ah-color-link, #635dff));outline-offset:2px;border-radius:2px}.loading-spinner{width:32px;height:32px;margin:24px auto;border:3px solid var(--ah-color-border-muted, #e0e1e3);border-top-color:var(--ah-color-primary, #635dff);border-radius:50%;animation:spin 0.8s linear infinite}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.error-message{text-align:center;color:var(--ah-color-error, #d03c38);padding:16px;font-size:14px}@media (max-width: 480px){:host{display:block;width:100%;min-height:100vh;background-color:var(--ah-color-bg, #ffffff)}.widget-container{box-shadow:none;border-radius:0;width:100%;margin:0}.widget-header{padding:24px 16px 16px}.widget-body{padding:0 16px 24px}}"}},[513,"authhero-widget",{screen:[1],apiUrl:[1,"api-url"],baseUrl:[1,"base-url"],state:[1025],screenId:[1025,"screen-id"],authParams:[1,"auth-params"],statePersistence:[1,"state-persistence"],storageKey:[1,"storage-key"],branding:[1],theme:[1],loading:[1028],autoSubmit:[4,"auto-submit"],autoNavigate:[4,"auto-navigate"],_screen:[32],_authParams:[32],_branding:[32],_theme:[32],formData:[32]},void 0,{screenId:[{watchScreenId:0}],screen:[{watchScreen:0}],branding:[{watchBranding:0}],theme:[{watchTheme:0}],authParams:[{watchAuthParams:0}]}]);function y(){"undefined"!=typeof customElements&&["authhero-widget","authhero-node"].forEach((e=>{switch(e){case"authhero-widget":customElements.get(t(e))||customElements.define(t(e),v);break;case"authhero-node":customElements.get(t(e))||o()}}))}y();const k=v,S=y;export{k as AuthheroWidget,S as defineCustomElement}
@@ -853,6 +853,94 @@ const AuthheroWidget = class {
853
853
  }
854
854
  });
855
855
  }
856
+ /**
857
+ * Pending resolvers awaiting the next render, flushed by
858
+ * `componentDidRender`. Lets `swapScreen` wait until the new screen is
859
+ * actually in the DOM before measuring its height.
860
+ */
861
+ pendingRenderResolvers = [];
862
+ componentDidRender() {
863
+ if (this.pendingRenderResolvers.length === 0)
864
+ return;
865
+ const resolvers = this.pendingRenderResolvers;
866
+ this.pendingRenderResolvers = [];
867
+ resolvers.forEach((resolve) => resolve());
868
+ }
869
+ /**
870
+ * Resolves after Stencil flushes the next render, so `swapScreen` waits for
871
+ * the new screen to be in the DOM before measuring its height.
872
+ */
873
+ nextRender() {
874
+ return new Promise((resolve) => {
875
+ let settled = false;
876
+ const done = () => {
877
+ if (settled)
878
+ return;
879
+ settled = true;
880
+ resolve();
881
+ };
882
+ this.pendingRenderResolvers.push(done);
883
+ // Safety net: a screen swap always triggers a render here, but never
884
+ // hang the swap if one somehow doesn't fire — resolve after a couple of
885
+ // frames at the latest.
886
+ requestAnimationFrame(() => requestAnimationFrame(done));
887
+ });
888
+ }
889
+ /**
890
+ * Apply a screen swap, animating the widget card's height to the next
891
+ * screen's size (Stripe-style): lock the current height, swap the content,
892
+ * measure the new natural height, then animate between them. The content
893
+ * itself doesn't fade — the card just resizes.
894
+ *
895
+ * The card (.widget-container) is animated rather than the host because it
896
+ * carries the background, so its resize is visible; clipping its content
897
+ * (not the host) also keeps the card's drop-shadow intact.
898
+ *
899
+ * Degrades to an immediate swap when the Web Animations API is unavailable
900
+ * or the user prefers reduced motion.
901
+ */
902
+ async swapScreen(apply) {
903
+ const card = this.el.shadowRoot?.querySelector(".widget-container");
904
+ const prefersReducedMotion = typeof window.matchMedia === "function" &&
905
+ window.matchMedia("(prefers-reduced-motion: reduce)").matches;
906
+ if (!card || typeof card.animate !== "function" || prefersReducedMotion) {
907
+ apply();
908
+ return;
909
+ }
910
+ // Lock the current height and clip, so swapping the content doesn't jump
911
+ // before the animation runs.
912
+ const startHeight = card.getBoundingClientRect().height;
913
+ card.style.height = `${startHeight}px`;
914
+ card.style.overflow = "hidden";
915
+ apply();
916
+ // Wait for the new screen to render before measuring its height.
917
+ await this.nextRender();
918
+ const cleanup = () => {
919
+ card.style.height = "";
920
+ card.style.overflow = "";
921
+ };
922
+ // Measure the new content's natural height without painting: toggle to
923
+ // auto, read, restore — all synchronous, so there's no visible jump.
924
+ card.style.height = "auto";
925
+ const endHeight = card.getBoundingClientRect().height;
926
+ card.style.height = `${startHeight}px`;
927
+ card.getBoundingClientRect(); // force reflow from startHeight
928
+ if (Math.abs(endHeight - startHeight) < 1) {
929
+ cleanup();
930
+ return;
931
+ }
932
+ const animation = card.animate([{ height: `${startHeight}px` }, { height: `${endHeight}px` }], { duration: 520, easing: "cubic-bezier(0.22, 1, 0.36, 1)" });
933
+ try {
934
+ await animation.finished;
935
+ }
936
+ catch {
937
+ // Animation cancelled (e.g. superseded by a newer swap); the final
938
+ // DOM state is already correct, so just fall through to cleanup.
939
+ }
940
+ finally {
941
+ cleanup();
942
+ }
943
+ }
856
944
  /**
857
945
  * Get the effective autoNavigate value (defaults to autoSubmit if not set)
858
946
  */
@@ -1155,45 +1243,55 @@ const AuthheroWidget = class {
1155
1243
  }
1156
1244
  else if (!response.ok && result.screen) {
1157
1245
  // Handle validation errors (400 response) — preserve user input
1158
- this._screen = result.screen;
1159
- this.initFormDataFromDefaults(result.screen);
1160
- this.screenChange.emit(result.screen);
1161
- this.updateDataScreenAttribute();
1162
- this.focusFirstInput();
1246
+ await this.swapScreen(() => {
1247
+ // Clear loading first so the captured "after" snapshot doesn't
1248
+ // freeze a disabled button into the cross-fade.
1249
+ this.loading = false;
1250
+ this._screen = result.screen;
1251
+ this.initFormDataFromDefaults(result.screen);
1252
+ this.screenChange.emit(result.screen);
1253
+ this.updateDataScreenAttribute();
1254
+ this.focusFirstInput();
1255
+ });
1163
1256
  }
1164
1257
  else if (result.screen) {
1165
1258
  // Next screen (success)
1166
- this._screen = result.screen;
1167
- this.formData = {};
1168
- this.initFormDataFromDefaults(result.screen);
1169
- this.screenChange.emit(result.screen);
1170
- this.updateDataScreenAttribute();
1171
- // Update screenId if returned in response
1172
- if (result.screenId) {
1173
- this.screenId = result.screenId;
1174
- }
1175
- // Persist state (especially for session storage mode)
1176
- this.persistState();
1177
- // Update URL path if navigateUrl is provided (client-side navigation)
1178
- if (result.navigateUrl && this.shouldAutoNavigate) {
1179
- window.history.pushState({ screen: result.screenId, state: this.state }, "", result.navigateUrl);
1180
- }
1181
- // Apply branding if included
1182
- if (result.branding) {
1183
- this._branding = result.branding;
1184
- this.applyThemeStyles();
1185
- }
1186
- // Update state if returned
1187
- if (result.state) {
1188
- this.state = result.state;
1259
+ await this.swapScreen(() => {
1260
+ // Clear loading first so the captured "after" snapshot doesn't
1261
+ // freeze a disabled button into the cross-fade.
1262
+ this.loading = false;
1263
+ this._screen = result.screen;
1264
+ this.formData = {};
1265
+ this.initFormDataFromDefaults(result.screen);
1266
+ this.screenChange.emit(result.screen);
1267
+ this.updateDataScreenAttribute();
1268
+ // Update screenId if returned in response
1269
+ if (result.screenId) {
1270
+ this.screenId = result.screenId;
1271
+ }
1272
+ // Persist state (especially for session storage mode)
1189
1273
  this.persistState();
1190
- }
1191
- // Perform WebAuthn ceremony if present (structured data, not script)
1192
- if (result.ceremony) {
1193
- this.performWebAuthnCeremony(result.ceremony);
1194
- }
1195
- // Focus first input on new screen
1196
- this.focusFirstInput();
1274
+ // Update URL path if navigateUrl is provided (client-side navigation)
1275
+ if (result.navigateUrl && this.shouldAutoNavigate) {
1276
+ window.history.pushState({ screen: result.screenId, state: this.state }, "", result.navigateUrl);
1277
+ }
1278
+ // Apply branding if included
1279
+ if (result.branding) {
1280
+ this._branding = result.branding;
1281
+ this.applyThemeStyles();
1282
+ }
1283
+ // Update state if returned
1284
+ if (result.state) {
1285
+ this.state = result.state;
1286
+ this.persistState();
1287
+ }
1288
+ // Perform WebAuthn ceremony if present (structured data, not script)
1289
+ if (result.ceremony) {
1290
+ this.performWebAuthnCeremony(result.ceremony);
1291
+ }
1292
+ // Focus first input on new screen
1293
+ this.focusFirstInput();
1294
+ });
1197
1295
  }
1198
1296
  else if (result.complete) {
1199
1297
  // Flow complete without redirect
@@ -250,6 +250,32 @@ export declare class AuthheroWidget {
250
250
  * Called after screen changes to ensure keyboard navigation works properly.
251
251
  */
252
252
  private focusFirstInput;
253
+ /**
254
+ * Pending resolvers awaiting the next render, flushed by
255
+ * `componentDidRender`. Lets `swapScreen` wait until the new screen is
256
+ * actually in the DOM before measuring its height.
257
+ */
258
+ private pendingRenderResolvers;
259
+ componentDidRender(): void;
260
+ /**
261
+ * Resolves after Stencil flushes the next render, so `swapScreen` waits for
262
+ * the new screen to be in the DOM before measuring its height.
263
+ */
264
+ private nextRender;
265
+ /**
266
+ * Apply a screen swap, animating the widget card's height to the next
267
+ * screen's size (Stripe-style): lock the current height, swap the content,
268
+ * measure the new natural height, then animate between them. The content
269
+ * itself doesn't fade — the card just resizes.
270
+ *
271
+ * The card (.widget-container) is animated rather than the host because it
272
+ * carries the background, so its resize is visible; clipping its content
273
+ * (not the host) also keeps the card's drop-shadow intact.
274
+ *
275
+ * Degrades to an immediate swap when the Web Animations API is unavailable
276
+ * or the user prefers reduced motion.
277
+ */
278
+ private swapScreen;
253
279
  /**
254
280
  * Get the effective autoNavigate value (defaults to autoSubmit if not set)
255
281
  */
package/hydrate/index.js CHANGED
@@ -6958,6 +6958,94 @@ class AuthheroWidget {
6958
6958
  }
6959
6959
  });
6960
6960
  }
6961
+ /**
6962
+ * Pending resolvers awaiting the next render, flushed by
6963
+ * `componentDidRender`. Lets `swapScreen` wait until the new screen is
6964
+ * actually in the DOM before measuring its height.
6965
+ */
6966
+ pendingRenderResolvers = [];
6967
+ componentDidRender() {
6968
+ if (this.pendingRenderResolvers.length === 0)
6969
+ return;
6970
+ const resolvers = this.pendingRenderResolvers;
6971
+ this.pendingRenderResolvers = [];
6972
+ resolvers.forEach((resolve) => resolve());
6973
+ }
6974
+ /**
6975
+ * Resolves after Stencil flushes the next render, so `swapScreen` waits for
6976
+ * the new screen to be in the DOM before measuring its height.
6977
+ */
6978
+ nextRender() {
6979
+ return new Promise((resolve) => {
6980
+ let settled = false;
6981
+ const done = () => {
6982
+ if (settled)
6983
+ return;
6984
+ settled = true;
6985
+ resolve();
6986
+ };
6987
+ this.pendingRenderResolvers.push(done);
6988
+ // Safety net: a screen swap always triggers a render here, but never
6989
+ // hang the swap if one somehow doesn't fire — resolve after a couple of
6990
+ // frames at the latest.
6991
+ requestAnimationFrame(() => requestAnimationFrame(done));
6992
+ });
6993
+ }
6994
+ /**
6995
+ * Apply a screen swap, animating the widget card's height to the next
6996
+ * screen's size (Stripe-style): lock the current height, swap the content,
6997
+ * measure the new natural height, then animate between them. The content
6998
+ * itself doesn't fade — the card just resizes.
6999
+ *
7000
+ * The card (.widget-container) is animated rather than the host because it
7001
+ * carries the background, so its resize is visible; clipping its content
7002
+ * (not the host) also keeps the card's drop-shadow intact.
7003
+ *
7004
+ * Degrades to an immediate swap when the Web Animations API is unavailable
7005
+ * or the user prefers reduced motion.
7006
+ */
7007
+ async swapScreen(apply) {
7008
+ const card = this.el.shadowRoot?.querySelector(".widget-container");
7009
+ const prefersReducedMotion = typeof window.matchMedia === "function" &&
7010
+ window.matchMedia("(prefers-reduced-motion: reduce)").matches;
7011
+ if (!card || typeof card.animate !== "function" || prefersReducedMotion) {
7012
+ apply();
7013
+ return;
7014
+ }
7015
+ // Lock the current height and clip, so swapping the content doesn't jump
7016
+ // before the animation runs.
7017
+ const startHeight = card.getBoundingClientRect().height;
7018
+ card.style.height = `${startHeight}px`;
7019
+ card.style.overflow = "hidden";
7020
+ apply();
7021
+ // Wait for the new screen to render before measuring its height.
7022
+ await this.nextRender();
7023
+ const cleanup = () => {
7024
+ card.style.height = "";
7025
+ card.style.overflow = "";
7026
+ };
7027
+ // Measure the new content's natural height without painting: toggle to
7028
+ // auto, read, restore — all synchronous, so there's no visible jump.
7029
+ card.style.height = "auto";
7030
+ const endHeight = card.getBoundingClientRect().height;
7031
+ card.style.height = `${startHeight}px`;
7032
+ card.getBoundingClientRect(); // force reflow from startHeight
7033
+ if (Math.abs(endHeight - startHeight) < 1) {
7034
+ cleanup();
7035
+ return;
7036
+ }
7037
+ const animation = card.animate([{ height: `${startHeight}px` }, { height: `${endHeight}px` }], { duration: 520, easing: "cubic-bezier(0.22, 1, 0.36, 1)" });
7038
+ try {
7039
+ await animation.finished;
7040
+ }
7041
+ catch {
7042
+ // Animation cancelled (e.g. superseded by a newer swap); the final
7043
+ // DOM state is already correct, so just fall through to cleanup.
7044
+ }
7045
+ finally {
7046
+ cleanup();
7047
+ }
7048
+ }
6961
7049
  /**
6962
7050
  * Get the effective autoNavigate value (defaults to autoSubmit if not set)
6963
7051
  */
@@ -7260,45 +7348,55 @@ class AuthheroWidget {
7260
7348
  }
7261
7349
  else if (!response.ok && result.screen) {
7262
7350
  // Handle validation errors (400 response) — preserve user input
7263
- this._screen = result.screen;
7264
- this.initFormDataFromDefaults(result.screen);
7265
- this.screenChange.emit(result.screen);
7266
- this.updateDataScreenAttribute();
7267
- this.focusFirstInput();
7351
+ await this.swapScreen(() => {
7352
+ // Clear loading first so the captured "after" snapshot doesn't
7353
+ // freeze a disabled button into the cross-fade.
7354
+ this.loading = false;
7355
+ this._screen = result.screen;
7356
+ this.initFormDataFromDefaults(result.screen);
7357
+ this.screenChange.emit(result.screen);
7358
+ this.updateDataScreenAttribute();
7359
+ this.focusFirstInput();
7360
+ });
7268
7361
  }
7269
7362
  else if (result.screen) {
7270
7363
  // Next screen (success)
7271
- this._screen = result.screen;
7272
- this.formData = {};
7273
- this.initFormDataFromDefaults(result.screen);
7274
- this.screenChange.emit(result.screen);
7275
- this.updateDataScreenAttribute();
7276
- // Update screenId if returned in response
7277
- if (result.screenId) {
7278
- this.screenId = result.screenId;
7279
- }
7280
- // Persist state (especially for session storage mode)
7281
- this.persistState();
7282
- // Update URL path if navigateUrl is provided (client-side navigation)
7283
- if (result.navigateUrl && this.shouldAutoNavigate) {
7284
- window.history.pushState({ screen: result.screenId, state: this.state }, "", result.navigateUrl);
7285
- }
7286
- // Apply branding if included
7287
- if (result.branding) {
7288
- this._branding = result.branding;
7289
- this.applyThemeStyles();
7290
- }
7291
- // Update state if returned
7292
- if (result.state) {
7293
- this.state = result.state;
7364
+ await this.swapScreen(() => {
7365
+ // Clear loading first so the captured "after" snapshot doesn't
7366
+ // freeze a disabled button into the cross-fade.
7367
+ this.loading = false;
7368
+ this._screen = result.screen;
7369
+ this.formData = {};
7370
+ this.initFormDataFromDefaults(result.screen);
7371
+ this.screenChange.emit(result.screen);
7372
+ this.updateDataScreenAttribute();
7373
+ // Update screenId if returned in response
7374
+ if (result.screenId) {
7375
+ this.screenId = result.screenId;
7376
+ }
7377
+ // Persist state (especially for session storage mode)
7294
7378
  this.persistState();
7295
- }
7296
- // Perform WebAuthn ceremony if present (structured data, not script)
7297
- if (result.ceremony) {
7298
- this.performWebAuthnCeremony(result.ceremony);
7299
- }
7300
- // Focus first input on new screen
7301
- this.focusFirstInput();
7379
+ // Update URL path if navigateUrl is provided (client-side navigation)
7380
+ if (result.navigateUrl && this.shouldAutoNavigate) {
7381
+ window.history.pushState({ screen: result.screenId, state: this.state }, "", result.navigateUrl);
7382
+ }
7383
+ // Apply branding if included
7384
+ if (result.branding) {
7385
+ this._branding = result.branding;
7386
+ this.applyThemeStyles();
7387
+ }
7388
+ // Update state if returned
7389
+ if (result.state) {
7390
+ this.state = result.state;
7391
+ this.persistState();
7392
+ }
7393
+ // Perform WebAuthn ceremony if present (structured data, not script)
7394
+ if (result.ceremony) {
7395
+ this.performWebAuthnCeremony(result.ceremony);
7396
+ }
7397
+ // Focus first input on new screen
7398
+ this.focusFirstInput();
7399
+ });
7302
7400
  }
7303
7401
  else if (result.complete) {
7304
7402
  // Flow complete without redirect