@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.
- package/dist/authhero-widget/authhero-widget.esm.js +1 -1
- package/dist/authhero-widget/{p-5f7b7943.entry.js → p-5a319adc.entry.js} +1 -1
- package/dist/cjs/authhero-widget.cjs.entry.js +133 -35
- package/dist/collection/components/authhero-widget/authhero-widget.js +133 -35
- package/dist/components/authhero-widget.js +1 -1
- package/dist/esm/authhero-widget.entry.js +133 -35
- package/dist/types/components/authhero-widget/authhero-widget.d.ts +26 -0
- package/hydrate/index.js +133 -35
- package/hydrate/index.mjs +133 -35
- package/package.json +1 -1
|
@@ -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,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'");for(const[t,i]of Object.entries(m)){if("br"===t){e=e.replace(/<br\s*\/?>/gi,"<br>");continue}const n=RegExp(`<${t}((?:\\s+[a-z-]+(?:="[^&]*"|='[^&]*')?)*)\\s*>`,"gi");e=e.replace(n,((e,n)=>{const r=[];if(n){const t=n.replace(/"/g,'"').replace(/'/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/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(`</${t}>`,"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,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}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,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'");for(const[t,i]of Object.entries(m)){if("br"===t){e=e.replace(/<br\s*\/?>/gi,"<br>");continue}const n=RegExp(`<${t}((?:\\s+[a-z-]+(?:="[^&]*"|='[^&]*')?)*)\\s*>`,"gi");e=e.replace(n,((e,n)=>{const r=[];if(n){const t=n.replace(/"/g,'"').replace(/'/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/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(`</${t}>`,"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,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}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.
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
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.
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
this.
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
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
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
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.
|
|
7264
|
-
|
|
7265
|
-
|
|
7266
|
-
|
|
7267
|
-
|
|
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.
|
|
7272
|
-
|
|
7273
|
-
|
|
7274
|
-
|
|
7275
|
-
|
|
7276
|
-
|
|
7277
|
-
|
|
7278
|
-
this.
|
|
7279
|
-
|
|
7280
|
-
|
|
7281
|
-
|
|
7282
|
-
|
|
7283
|
-
|
|
7284
|
-
|
|
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
|
-
|
|
7297
|
-
|
|
7298
|
-
|
|
7299
|
-
|
|
7300
|
-
|
|
7301
|
-
|
|
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
|