@authhero/widget 0.28.1 → 0.29.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/index.esm.js +1 -1
- package/dist/authhero-widget/p-5428e2e1.entry.js +1 -0
- package/dist/cjs/authhero-widget.cjs.entry.js +206 -3
- package/dist/cjs/index.cjs.js +24 -6
- package/dist/collection/components/authhero-node/authhero-node.js +1 -1
- package/dist/collection/components/authhero-widget/authhero-widget.js +208 -5
- package/dist/components/authhero-widget.js +1 -1
- package/dist/components/index.js +1 -1
- package/dist/esm/authhero-widget.entry.js +206 -3
- package/dist/esm/index.js +24 -6
- package/dist/types/components/authhero-widget/authhero-widget.d.ts +22 -0
- package/hydrate/index.js +206 -3
- package/hydrate/index.mjs +206 -3
- package/package.json +2 -2
- package/dist/authhero-widget/p-b9ae0275.entry.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as t,c as e,g as i,h as s}from"./p-BFP_5sHV.js";function n(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 s=parseInt(i,16);return[s>>16&255,s>>8&255,255&s]}function r(t){const e=n(t);if(!e)return NaN;const[i,s,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*s+.0722*r}function o(t,e){const i=r(t),s=r(e);return isNaN(i)||isNaN(s)?NaN:(Math.max(i,s)+.05)/(Math.min(i,s)+.05)}function a(t,e="light"){const i=o(t,"#000000"),s=o(t,"#ffffff");return"light"===e?i>1.35*s?"#000000":"#ffffff":1.35*i>s?"#000000":"#ffffff"}function c(t,e){const i=n(t);if(!i)return t;const[s,r,o]=i,a=t=>Math.max(0,Math.round(t*(1-e))).toString(16).padStart(2,"0");return`#${a(s)}${a(r)}${a(o)}`}function h(t,e){const i=n(t);if(!i)return t;const[s,r,o]=i,a=t=>Math.min(255,Math.round(t+(255-t)*e)).toString(16).padStart(2,"0");return`#${a(s)}${a(r)}${a(o)}`}function l(t,e,i=4.5){if(o(t,e)>=i)return t;const s=r(e)>.5;let n=t;for(let r=1;r<=10;r++)if(n=s?c(t,.1*r):h(t,.1*r),o(n,e)>=i)return n;return s?"#000000":"#ffffff"}function d(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 f(t){if(!t)return{};const e={};if(t.colors?.primary&&(e["--ah-color-primary"]=t.colors.primary,e["--ah-color-primary-hover"]=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 u(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 s=d(i.buttons_style,i.button_border_radius);s&&(e["--ah-btn-radius"]=s),void 0!==i.button_border_weight&&(e["--ah-btn-border-width"]=`${i.button_border_weight}px`);const n=d(i.inputs_style,i.input_border_radius);n&&(e["--ah-input-radius"]=n),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,e["--ah-color-primary-hover"]=i.primary_button,i.primary_button_label&&o(i.primary_button_label,i.primary_button)>=4.5)e["--ah-color-text-on-primary"]=i.primary_button_label;else{e["--ah-color-text-on-primary"]=a(i.primary_button,"light");const t=a(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"]=l(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 s=i.widget_background||"#ffffff",n=i.input_background||s,r=e["--ah-color-border"]||i.input_border||"#c9cace",c=o(r,s),h=o(r,n);Math.min(c,h)<3&&(e["--ah-color-border"]=l(r,c<h?s:n,3))}if(t.fonts){const i=t.fonts,s=i.reference_text_size||16,n=t=>t>=50?Math.round(t/100*s):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"]=`${n(i.title.size)}px`),i.subtitle?.size&&(e["--ah-font-size-subtitle"]=`${n(i.subtitle.size)}px`),i.body_text?.size&&(e["--ah-font-size-body"]=`${n(i.body_text.size)}px`),i.input_labels?.size&&(e["--ah-font-size-label"]=`${n(i.input_labels.size)}px`),i.buttons_text?.size&&(e["--ah-font-size-btn"]=`${n(i.buttons_text.size)}px`),i.links?.size&&(e["--ah-font-size-link"]=`${n(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 p={br:[],em:[],i:[],strong:[],b:[],u:[],span:["class"],a:["href","class"]};function g(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(p)){if("br"===t){e=e.replace(/<br\s*\/?>/gi,"<br>");continue}const s=new RegExp(`<${t}((?:\\s+[a-z-]+(?:="[^&]*"|='[^&]*')?)*)\\s*>`,"gi");e=e.replace(s,((e,s)=>{const n=[];if(s){const t=s.replace(/"/g,'"').replace(/'/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),e=/([a-z-]+)=["']([^"']*)["']/gi;let r;for(;null!==(r=e.exec(t));){const[,t,e]=r;t&&i.includes(t.toLowerCase())&&("href"===t.toLowerCase()?m(e||"")&&n.push(`${t}="${x(e||"")}"`):n.push(`${t}="${x(e||"")}"`))}}"a"===t&&(n.push('target="_blank"'),n.push('rel="noopener noreferrer"'));const r=n.length?" "+n.join(" "):"";return`<${t}${r}>`}));const n=new RegExp(`</${t}>`,"gi");e=e.replace(n,`</${t}>`)}return e}function m(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 w=class{constructor(i){t(this,i),this.formSubmit=e(this,"formSubmit"),this.buttonClick=e(this,"buttonClick"),this.linkClick=e(this,"linkClick"),this.navigate=e(this,"navigate"),this.flowComplete=e(this,"flowComplete"),this.flowError=e(this,"flowError"),this.screenChange=e(this,"screenChange")}get el(){return i(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={};formSubmit;buttonClick;linkClick;navigate;flowComplete;flowError;screenChange;watchScreen(t){if("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=(e=this._theme,{...f(this._branding),...u(e)});var e;!function(t,e){Object.entries(e).forEach((([e,i])=>{t.style.setProperty(e,i)}))}(this.el,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).toString():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.toString())}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)}async componentWillLoad(){if(!this._screen){const t=this.screen||this.el?.getAttribute("screen");t&&this.watchScreen(t)}this._branding||this.watchBranding(this.branding),this._theme||this.watchTheme(this.theme),this._authParams||this.watchAuthParams(this.authParams),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 s=this.apiUrl;i&&s.includes("{screenId}")&&(s=s.replace("{screenId}",encodeURIComponent(i)));const n=new URL(s,this.baseUrl||window.location.origin);this.state&&n.searchParams.set("state",this.state),e&&n.searchParams.set("nodeId",e),this.loading=!0;try{const t=await fetch(this.buildUrl(n.pathname+n.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(),!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 s=this.el.shadowRoot?.querySelector("form");if(s&&s.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("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)?requestAnimationFrame((()=>{this.overrideFormSubmit(),this.executeWebAuthnRegistration(t)})):console.error("Invalid WebAuthn ceremony payload",t)}isValidWebAuthnCeremony(t){if("object"!=typeof t||null===t)return!1;if("webauthn-registration"!==t.type)return!1;if("string"!=typeof t.successAction)return!1;const e=t.options;if("object"!=typeof e||null===e)return!1;if("string"!=typeof e.challenge)return!1;const i=e.rp;if("object"!=typeof i||null===i)return!1;if("string"!=typeof i.id||"string"!=typeof i.name)return!1;const s=e.user;return"object"==typeof s&&null!==s&&("string"==typeof s.id&&"string"==typeof s.name&&"string"==typeof s.displayName&&!!Array.isArray(e.pubKeyCredParams))}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},s=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(/=+$/,"")},n=()=>{const t=this.el?.shadowRoot;if(t){const e=t.querySelector("form");if(e)return e}return document.querySelector("form")};try{const r={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&&(r.excludeCredentials=e.excludeCredentials.map((t=>({id:i(t.id),type:t.type,transports:t.transports||[]}))));const o=await navigator.credentials.create({publicKey:r}),a=o.response,c={id:o.id,rawId:s(o.rawId),type:o.type,response:{attestationObject:s(a.attestationObject),clientDataJSON:s(a.clientDataJSON)},clientExtensionResults:o.getClientExtensionResults(),authenticatorAttachment:o.authenticatorAttachment||void 0};"function"==typeof a.getTransports&&(c.response.transports=a.getTransports());const h=n();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=n();if(e){const t=e.querySelector('[name="action-field"]')||e.querySelector("#action-field");t&&(t.value="error"),e.submit()}}}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 s=this.buildUrl("/authorize?"+new URLSearchParams(i).toString());this.navigate.emit({url:s}),window.location.href=s}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 s=e.match(/\/u2\/([^/]+)$/);return s&&"login"!==s[1]&&"screen"!==s[1]?s[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 s("div",{class:"widget-container"},s("div",{class:"loading-spinner"}));if(!t)return s("div",{class:"widget-container"},s("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??[]],r=n.filter((t=>!1!==t.visible)).sort(((t,e)=>(t.order??0)-(e.order??0))),o=n.filter((t=>!1===t.visible)),a=r.filter((t=>this.isSocialComponent(t))),c=r.filter((t=>!this.isSocialComponent(t)&&!this.isDividerComponent(t))),h=r.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 s("div",{class:"widget-container",part:"container","data-authstack-container":!0},s("header",{class:"widget-header",part:"header"},u&&s("div",{class:"logo-wrapper",part:"logo-wrapper"},s("img",{class:"logo",part:"logo",src:u,alt:"Logo"})),t.title&&s("h1",{class:"title",part:"title",innerHTML:g(t.title)}),t.description&&s("p",{class:"description",part:"description",innerHTML:g(t.description)})),s("div",{class:"widget-body",part:"body"},e.map((t=>s("div",{class:"message message-error",part:"message message-error",key:t.id??t.text},t.text))),i.map((t=>s("div",{class:"message message-success",part:"message message-success",key:t.id??t.text},t.text))),s("form",{onSubmit:this.handleSubmit,part:"form"},o.map((t=>s("input",{type:"hidden",name:t.id,id:t.id,key:t.id,value:this.formData[t.id]||""}))),s("div",{class:"form-content"},a.length>0&&s("div",{class:"social-section",part:"social-section"},a.map((t=>s("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&&s("div",{class:"divider",part:"divider"},s("span",{class:"divider-text"},d)),s("div",{class:"fields-section",part:"fields-section"},c.map((t=>s("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&&s("div",{class:"links",part:"links"},t.links.map((t=>s("span",{class:"link-wrapper",part:"link-wrapper",key:t.id??t.href},t.linkText?s("span",null,t.text," ",s("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)):s("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&&s("div",{class:"widget-footer",part:"footer",innerHTML:g(t.footer)})))}static get watchers(){return{screenId:[{watchScreenId:0}],screen:[{watchScreen:0}],branding:[{watchBranding:0}],theme:[{watchTheme:0}],authParams:[{watchAuthParams:0}]}}};w.style=":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);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-header, #1e212a);line-height:1.2}.description{font-size:var(--ah-font-size-subtitle, 16px);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:14px;color:var(--ah-color-text, #1e212a)}.link{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size: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-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-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}}";export{w as authhero_widget}
|
|
@@ -1021,7 +1021,18 @@ const AuthheroWidget = class {
|
|
|
1021
1021
|
e.preventDefault();
|
|
1022
1022
|
if (!this._screen || this.loading)
|
|
1023
1023
|
return;
|
|
1024
|
-
|
|
1024
|
+
let submitData = { ...this.formData, ...(overrideData || {}) };
|
|
1025
|
+
// Merge hidden input values from DOM (may have been set programmatically
|
|
1026
|
+
// by inline scripts, e.g. passkey management buttons)
|
|
1027
|
+
const form = this.el.shadowRoot?.querySelector("form");
|
|
1028
|
+
if (form) {
|
|
1029
|
+
const hiddenInputs = form.querySelectorAll('input[type="hidden"]');
|
|
1030
|
+
hiddenInputs.forEach((input) => {
|
|
1031
|
+
if (input.name && input.value) {
|
|
1032
|
+
submitData[input.name] = input.value;
|
|
1033
|
+
}
|
|
1034
|
+
});
|
|
1035
|
+
}
|
|
1025
1036
|
// Always emit the submit event
|
|
1026
1037
|
this.formSubmit.emit({
|
|
1027
1038
|
screen: this._screen,
|
|
@@ -1097,6 +1108,10 @@ const AuthheroWidget = class {
|
|
|
1097
1108
|
this.state = result.state;
|
|
1098
1109
|
this.persistState();
|
|
1099
1110
|
}
|
|
1111
|
+
// Perform WebAuthn ceremony if present (structured data, not script)
|
|
1112
|
+
if (result.ceremony) {
|
|
1113
|
+
this.performWebAuthnCeremony(result.ceremony);
|
|
1114
|
+
}
|
|
1100
1115
|
// Focus first input on new screen
|
|
1101
1116
|
this.focusFirstInput();
|
|
1102
1117
|
}
|
|
@@ -1130,6 +1145,192 @@ const AuthheroWidget = class {
|
|
|
1130
1145
|
this.loading = false;
|
|
1131
1146
|
}
|
|
1132
1147
|
};
|
|
1148
|
+
/**
|
|
1149
|
+
* Override form.submit() so that scripts (e.g. WebAuthn ceremony) that call
|
|
1150
|
+
* form.submit() go through the widget's JSON fetch pipeline instead of a
|
|
1151
|
+
* native form-urlencoded POST.
|
|
1152
|
+
*/
|
|
1153
|
+
overrideFormSubmit() {
|
|
1154
|
+
const shadowRoot = this.el.shadowRoot;
|
|
1155
|
+
if (!shadowRoot)
|
|
1156
|
+
return;
|
|
1157
|
+
const form = shadowRoot.querySelector("form");
|
|
1158
|
+
if (!form)
|
|
1159
|
+
return;
|
|
1160
|
+
form.submit = () => {
|
|
1161
|
+
const formData = new FormData(form);
|
|
1162
|
+
const data = {};
|
|
1163
|
+
formData.forEach((value, key) => {
|
|
1164
|
+
if (typeof value === "string") {
|
|
1165
|
+
data[key] = value;
|
|
1166
|
+
}
|
|
1167
|
+
});
|
|
1168
|
+
const syntheticEvent = { preventDefault: () => { } };
|
|
1169
|
+
this.handleSubmit(syntheticEvent, data);
|
|
1170
|
+
};
|
|
1171
|
+
}
|
|
1172
|
+
/**
|
|
1173
|
+
* Validate and execute a structured WebAuthn ceremony returned by the server.
|
|
1174
|
+
* Instead of injecting arbitrary script content, this parses the ceremony JSON,
|
|
1175
|
+
* validates the expected fields, and calls the WebAuthn API natively.
|
|
1176
|
+
*/
|
|
1177
|
+
performWebAuthnCeremony(ceremony) {
|
|
1178
|
+
if (!this.isValidWebAuthnCeremony(ceremony)) {
|
|
1179
|
+
console.error("Invalid WebAuthn ceremony payload", ceremony);
|
|
1180
|
+
return;
|
|
1181
|
+
}
|
|
1182
|
+
requestAnimationFrame(() => {
|
|
1183
|
+
this.overrideFormSubmit();
|
|
1184
|
+
this.executeWebAuthnRegistration(ceremony);
|
|
1185
|
+
});
|
|
1186
|
+
}
|
|
1187
|
+
/**
|
|
1188
|
+
* Schema validation for WebAuthn ceremony payloads.
|
|
1189
|
+
* Checks required fields and types before invoking browser APIs.
|
|
1190
|
+
*/
|
|
1191
|
+
isValidWebAuthnCeremony(data) {
|
|
1192
|
+
if (typeof data !== "object" || data === null)
|
|
1193
|
+
return false;
|
|
1194
|
+
const obj = data;
|
|
1195
|
+
if (obj.type !== "webauthn-registration")
|
|
1196
|
+
return false;
|
|
1197
|
+
if (typeof obj.successAction !== "string")
|
|
1198
|
+
return false;
|
|
1199
|
+
const opts = obj.options;
|
|
1200
|
+
if (typeof opts !== "object" || opts === null)
|
|
1201
|
+
return false;
|
|
1202
|
+
const o = opts;
|
|
1203
|
+
if (typeof o.challenge !== "string")
|
|
1204
|
+
return false;
|
|
1205
|
+
const rp = o.rp;
|
|
1206
|
+
if (typeof rp !== "object" || rp === null)
|
|
1207
|
+
return false;
|
|
1208
|
+
if (typeof rp.id !== "string" ||
|
|
1209
|
+
typeof rp.name !== "string")
|
|
1210
|
+
return false;
|
|
1211
|
+
const user = o.user;
|
|
1212
|
+
if (typeof user !== "object" || user === null)
|
|
1213
|
+
return false;
|
|
1214
|
+
const u = user;
|
|
1215
|
+
if (typeof u.id !== "string" ||
|
|
1216
|
+
typeof u.name !== "string" ||
|
|
1217
|
+
typeof u.displayName !== "string")
|
|
1218
|
+
return false;
|
|
1219
|
+
if (!Array.isArray(o.pubKeyCredParams))
|
|
1220
|
+
return false;
|
|
1221
|
+
return true;
|
|
1222
|
+
}
|
|
1223
|
+
/**
|
|
1224
|
+
* Perform the WebAuthn navigator.credentials.create() ceremony and submit
|
|
1225
|
+
* the credential result via the form.
|
|
1226
|
+
*/
|
|
1227
|
+
async executeWebAuthnRegistration(ceremony) {
|
|
1228
|
+
const opts = ceremony.options;
|
|
1229
|
+
const b64uToBuf = (s) => {
|
|
1230
|
+
s = s.replace(/-/g, "+").replace(/_/g, "/");
|
|
1231
|
+
while (s.length % 4)
|
|
1232
|
+
s += "=";
|
|
1233
|
+
const b = atob(s);
|
|
1234
|
+
const a = new Uint8Array(b.length);
|
|
1235
|
+
for (let i = 0; i < b.length; i++)
|
|
1236
|
+
a[i] = b.charCodeAt(i);
|
|
1237
|
+
return a.buffer;
|
|
1238
|
+
};
|
|
1239
|
+
const bufToB64u = (b) => {
|
|
1240
|
+
const a = new Uint8Array(b);
|
|
1241
|
+
let s = "";
|
|
1242
|
+
for (let i = 0; i < a.length; i++)
|
|
1243
|
+
s += String.fromCharCode(a[i]);
|
|
1244
|
+
return btoa(s)
|
|
1245
|
+
.replace(/\+/g, "-")
|
|
1246
|
+
.replace(/\//g, "_")
|
|
1247
|
+
.replace(/=+$/, "");
|
|
1248
|
+
};
|
|
1249
|
+
const findForm = () => {
|
|
1250
|
+
const shadowRoot = this.el?.shadowRoot;
|
|
1251
|
+
if (shadowRoot) {
|
|
1252
|
+
const f = shadowRoot.querySelector("form");
|
|
1253
|
+
if (f)
|
|
1254
|
+
return f;
|
|
1255
|
+
}
|
|
1256
|
+
return document.querySelector("form");
|
|
1257
|
+
};
|
|
1258
|
+
try {
|
|
1259
|
+
const publicKey = {
|
|
1260
|
+
challenge: b64uToBuf(opts.challenge),
|
|
1261
|
+
rp: { id: opts.rp.id, name: opts.rp.name },
|
|
1262
|
+
user: {
|
|
1263
|
+
id: b64uToBuf(opts.user.id),
|
|
1264
|
+
name: opts.user.name,
|
|
1265
|
+
displayName: opts.user.displayName,
|
|
1266
|
+
},
|
|
1267
|
+
pubKeyCredParams: opts.pubKeyCredParams.map((p) => ({
|
|
1268
|
+
alg: p.alg,
|
|
1269
|
+
type: p.type,
|
|
1270
|
+
})),
|
|
1271
|
+
timeout: opts.timeout,
|
|
1272
|
+
attestation: (opts.attestation || "none"),
|
|
1273
|
+
authenticatorSelection: opts.authenticatorSelection
|
|
1274
|
+
? {
|
|
1275
|
+
residentKey: (opts.authenticatorSelection.residentKey ||
|
|
1276
|
+
"preferred"),
|
|
1277
|
+
userVerification: (opts.authenticatorSelection
|
|
1278
|
+
.userVerification ||
|
|
1279
|
+
"preferred"),
|
|
1280
|
+
}
|
|
1281
|
+
: undefined,
|
|
1282
|
+
};
|
|
1283
|
+
if (opts.excludeCredentials?.length) {
|
|
1284
|
+
publicKey.excludeCredentials = opts.excludeCredentials.map((c) => ({
|
|
1285
|
+
id: b64uToBuf(c.id),
|
|
1286
|
+
type: c.type,
|
|
1287
|
+
transports: (c.transports || []),
|
|
1288
|
+
}));
|
|
1289
|
+
}
|
|
1290
|
+
const cred = (await navigator.credentials.create({
|
|
1291
|
+
publicKey,
|
|
1292
|
+
}));
|
|
1293
|
+
const response = cred.response;
|
|
1294
|
+
const resp = {
|
|
1295
|
+
id: cred.id,
|
|
1296
|
+
rawId: bufToB64u(cred.rawId),
|
|
1297
|
+
type: cred.type,
|
|
1298
|
+
response: {
|
|
1299
|
+
attestationObject: bufToB64u(response.attestationObject),
|
|
1300
|
+
clientDataJSON: bufToB64u(response.clientDataJSON),
|
|
1301
|
+
},
|
|
1302
|
+
clientExtensionResults: cred.getClientExtensionResults(),
|
|
1303
|
+
authenticatorAttachment: cred.authenticatorAttachment || undefined,
|
|
1304
|
+
};
|
|
1305
|
+
if (typeof response.getTransports === "function") {
|
|
1306
|
+
resp.response.transports =
|
|
1307
|
+
response.getTransports();
|
|
1308
|
+
}
|
|
1309
|
+
const form = findForm();
|
|
1310
|
+
if (form) {
|
|
1311
|
+
const cf = form.querySelector('[name="credential-field"]') ||
|
|
1312
|
+
form.querySelector("#credential-field");
|
|
1313
|
+
const af = form.querySelector('[name="action-field"]') ||
|
|
1314
|
+
form.querySelector("#action-field");
|
|
1315
|
+
if (cf)
|
|
1316
|
+
cf.value = JSON.stringify(resp);
|
|
1317
|
+
if (af)
|
|
1318
|
+
af.value = ceremony.successAction;
|
|
1319
|
+
form.submit();
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
catch (e) {
|
|
1323
|
+
console.error("WebAuthn registration error:", e);
|
|
1324
|
+
const form = findForm();
|
|
1325
|
+
if (form) {
|
|
1326
|
+
const af = form.querySelector('[name="action-field"]') ||
|
|
1327
|
+
form.querySelector("#action-field");
|
|
1328
|
+
if (af)
|
|
1329
|
+
af.value = "error";
|
|
1330
|
+
form.submit();
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1133
1334
|
handleButtonClick = (detail) => {
|
|
1134
1335
|
// If this is a submit button click, trigger form submission
|
|
1135
1336
|
if (detail.type === "submit") {
|
|
@@ -1332,9 +1533,11 @@ const AuthheroWidget = class {
|
|
|
1332
1533
|
// Use the local screen variable for all rendering
|
|
1333
1534
|
const screenErrors = screen.messages?.filter((m) => m.type === "error") || [];
|
|
1334
1535
|
const screenSuccesses = screen.messages?.filter((m) => m.type === "success") || [];
|
|
1335
|
-
const
|
|
1536
|
+
const allComponents = [...(screen.components ?? [])];
|
|
1537
|
+
const components = allComponents
|
|
1336
1538
|
.filter((c) => c.visible !== false)
|
|
1337
1539
|
.sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
|
|
1540
|
+
const hiddenComponents = allComponents.filter((c) => c.visible === false);
|
|
1338
1541
|
// Separate social, divider, and field components for layout ordering
|
|
1339
1542
|
const socialComponents = components.filter((c) => this.isSocialComponent(c));
|
|
1340
1543
|
const fieldComponents = components.filter((c) => !this.isSocialComponent(c) && !this.isDividerComponent(c));
|
|
@@ -1369,7 +1572,7 @@ const AuthheroWidget = class {
|
|
|
1369
1572
|
};
|
|
1370
1573
|
// Get logo URL from theme.widget (takes precedence) or branding
|
|
1371
1574
|
const logoUrl = this._theme?.widget?.logo_url || this._branding?.logo_url;
|
|
1372
|
-
return (index.h("div", { class: "widget-container", part: "container", "data-authstack-container": true }, index.h("header", { class: "widget-header", part: "header" }, logoUrl && (index.h("div", { class: "logo-wrapper", part: "logo-wrapper" }, index.h("img", { class: "logo", part: "logo", src: logoUrl, alt: "Logo" }))), screen.title && (index.h("h1", { class: "title", part: "title", innerHTML: sanitizeHtml(screen.title) })), screen.description && (index.h("p", { class: "description", part: "description", innerHTML: sanitizeHtml(screen.description) }))), index.h("div", { class: "widget-body", part: "body" }, screenErrors.map((err) => (index.h("div", { class: "message message-error", part: "message message-error", key: err.id ?? err.text }, err.text))), screenSuccesses.map((msg) => (index.h("div", { class: "message message-success", part: "message message-success", key: msg.id ?? msg.text }, msg.text))), index.h("form", { onSubmit: this.handleSubmit, part: "form" }, index.h("div", { class: "form-content" }, socialComponents.length > 0 && (index.h("div", { class: "social-section", part: "social-section" }, socialComponents.map((component) => (index.h("authhero-node", { key: component.id, component: component, value: this.formData[component.id], onFieldChange: (e) => this.handleInputChange(e.detail.id, e.detail.value), onButtonClick: (e) => this.handleButtonClick(e.detail), disabled: this.loading, exportparts: getExportParts(component) }))))), socialComponents.length > 0 &&
|
|
1575
|
+
return (index.h("div", { class: "widget-container", part: "container", "data-authstack-container": true }, index.h("header", { class: "widget-header", part: "header" }, logoUrl && (index.h("div", { class: "logo-wrapper", part: "logo-wrapper" }, index.h("img", { class: "logo", part: "logo", src: logoUrl, alt: "Logo" }))), screen.title && (index.h("h1", { class: "title", part: "title", innerHTML: sanitizeHtml(screen.title) })), screen.description && (index.h("p", { class: "description", part: "description", innerHTML: sanitizeHtml(screen.description) }))), index.h("div", { class: "widget-body", part: "body" }, screenErrors.map((err) => (index.h("div", { class: "message message-error", part: "message message-error", key: err.id ?? err.text }, err.text))), screenSuccesses.map((msg) => (index.h("div", { class: "message message-success", part: "message message-success", key: msg.id ?? msg.text }, msg.text))), index.h("form", { onSubmit: this.handleSubmit, part: "form" }, hiddenComponents.map((c) => (index.h("input", { type: "hidden", name: c.id, id: c.id, key: c.id, value: this.formData[c.id] || "" }))), index.h("div", { class: "form-content" }, socialComponents.length > 0 && (index.h("div", { class: "social-section", part: "social-section" }, socialComponents.map((component) => (index.h("authhero-node", { key: component.id, component: component, value: this.formData[component.id], onFieldChange: (e) => this.handleInputChange(e.detail.id, e.detail.value), onButtonClick: (e) => this.handleButtonClick(e.detail), disabled: this.loading, exportparts: getExportParts(component) }))))), socialComponents.length > 0 &&
|
|
1373
1576
|
fieldComponents.length > 0 &&
|
|
1374
1577
|
hasDivider && (index.h("div", { class: "divider", part: "divider" }, index.h("span", { class: "divider-text" }, dividerText))), index.h("div", { class: "fields-section", part: "fields-section" }, fieldComponents.map((component) => (index.h("authhero-node", { key: component.id, component: component, value: this.formData[component.id], onFieldChange: (e) => this.handleInputChange(e.detail.id, e.detail.value), onButtonClick: (e) => this.handleButtonClick(e.detail), disabled: this.loading })))))), screen.links && screen.links.length > 0 && (index.h("div", { class: "links", part: "links" }, screen.links.map((link) => (index.h("span", { class: "link-wrapper", part: "link-wrapper", key: link.id ?? link.href }, link.linkText ? (index.h("span", null, link.text, " ", index.h("a", { href: link.href, class: "link", part: "link", onClick: (e) => this.handleLinkClick(e, {
|
|
1375
1578
|
id: link.id,
|