@authhero/widget 0.9.0 → 0.11.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-145b5ecd.entry.js +1 -0
- package/dist/authhero-widget/p-695138d6.entry.js +1 -0
- package/dist/cjs/authhero-node.cjs.entry.js +26 -96
- package/dist/cjs/authhero-widget.cjs.entry.js +139 -1
- package/dist/collection/components/authhero-node/authhero-node.js +26 -96
- package/dist/collection/components/authhero-widget/authhero-widget.js +7 -1
- package/dist/collection/utils/sanitize-html.js +132 -0
- package/dist/components/authhero-node.js +1 -1
- package/dist/components/authhero-widget.js +1 -1
- package/dist/components/p-BMoS6Gag.js +1 -0
- package/dist/esm/authhero-node.entry.js +26 -96
- package/dist/esm/authhero-widget.entry.js +139 -1
- package/dist/types/components/authhero-node/authhero-node.d.ts +5 -0
- package/dist/types/utils/sanitize-html.d.ts +20 -0
- package/hydrate/index.js +165 -97
- package/hydrate/index.mjs +165 -97
- package/package.json +1 -1
- package/dist/authhero-widget/p-30808298.entry.js +0 -1
- package/dist/authhero-widget/p-3ae71c86.entry.js +0 -1
- package/dist/components/p-DITKGXA_.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{p as a,b as e}from"./p-ARKBiJrR.js";export{s as setNonce}from"./p-ARKBiJrR.js";import{g as t}from"./p-DQuL1Twl.js";(()=>{const e=import.meta.url,t={};return""!==e&&(t.resourcesUrl=new URL(".",e).href),a(t)})().then((async a=>(await t(),e([["p-
|
|
1
|
+
import{p as a,b as e}from"./p-ARKBiJrR.js";export{s as setNonce}from"./p-ARKBiJrR.js";import{g as t}from"./p-DQuL1Twl.js";(()=>{const e=import.meta.url,t={};return""!==e&&(t.resourcesUrl=new URL(".",e).href),a(t)})().then((async a=>(await t(),e([["p-695138d6",[[513,"authhero-node",{component:[16],value:[1],disabled:[4],passwordVisible:[32]}]]],["p-145b5ecd",[[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]},null,{screen:[{watchScreen:0}],branding:[{watchBranding:0}],theme:[{watchTheme:0}],authParams:[{watchAuthParams:0}]}]]]],a))));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as t,c as e,g as i,h as s}from"./p-ARKBiJrR.js";function r(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 a(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 o(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=r(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 a=r(i.inputs_style,i.input_border_radius);a&&(e["--ah-input-radius"]=a),void 0!==i.input_border_weight&&(e["--ah-input-border-width"]=`${i.input_border_weight}px`)}if(t.colors){const i=t.colors;i.primary_button&&(e["--ah-color-primary"]=i.primary_button,e["--ah-color-primary-hover"]=i.primary_button),i.primary_button_label&&(e["--ah-btn-primary-text"]=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"]=i.links_focused_components),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)}if(t.fonts){const i=t.fonts,s=i.reference_text_size||16;if(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){const t=Math.round(i.title.size/100*s);e["--ah-font-size-title"]=`${t}px`}if(i.subtitle?.size){const t=Math.round(i.subtitle.size/100*s);e["--ah-font-size-subtitle"]=`${t}px`}if(i.body_text?.size){const t=Math.round(i.body_text.size/100*s);e["--ah-font-size-body"]=`${t}px`}if(i.input_labels?.size){const t=Math.round(i.input_labels.size/100*s);e["--ah-font-size-label"]=`${t}px`}if(i.buttons_text?.size){const t=Math.round(i.buttons_text.size/100*s);e["--ah-font-size-btn"]=`${t}px`}if(i.links?.size){const t=Math.round(i.links.size/100*s);e["--ah-font-size-link"]=`${t}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 n={br:[],em:[],i:[],strong:[],b:[],u:[],span:["class"],a:["href","class"]};function h(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(n)){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 r=[];if(s){const t=s.replace(/"/g,'"').replace(/'/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),e=/([a-z-]+)=["']([^"']*)["']/gi;let a;for(;null!==(a=e.exec(t));){const[,t,e]=a;t&&i.includes(t.toLowerCase())&&("href"===t.toLowerCase()?c(e||"")&&r.push(`${t}="${l(e||"")}"`):r.push(`${t}="${l(e||"")}"`))}}"a"===t&&(r.push('target="_blank"'),r.push('rel="noopener noreferrer"'));const a=r.length?" "+r.join(" "):"";return`<${t}${a}>`}));const r=new RegExp(`</${t}>`,"gi");e=e.replace(r,`</${t}>`)}return e}function c(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 l(t){return t.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}const d=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;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.screenChange.emit(this._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,{...a(this._branding),...o(e)});var e;!function(t,e){Object.entries(e).forEach((([e,i])=>{t.style.setProperty(e,i)}))}(this.el,t)}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{}}async componentWillLoad(){this.watchScreen(this.screen),this.watchBranding(this.branding),this.watchTheme(this.theme),this.watchAuthParams(this.authParams),this.loadPersistedState(),this.apiUrl&&!this._screen&&await this.fetchScreen(this.screenId)}async fetchScreen(t,e){if(!this.apiUrl)return;const i=t||this.screenId;let s=this.apiUrl;i&&s.includes("{screenId}")&&(s=s.replace("{screenId}",encodeURIComponent(i)));const r=new URL(s,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();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&&(i&&i!==this.screenId&&(this.screenId=i),this.screenChange.emit(this._screen),this.persistState())}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}}handleInputChange=(t,e)=>{this.formData={...this.formData,[t]:e}};handleSubmit=async t=>{if(t.preventDefault(),this._screen&&(this.formSubmit.emit({screen:this._screen,data:this.formData}),this.autoSubmit)){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:this.formData})}),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)):e.screen?(this._screen=e.screen,this.formData={},this.screenChange.emit(e.screen),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.complete&&this.flowComplete.emit({}),!t.ok&&e.screen&&(this._screen=e.screen,this.screenChange.emit(e.screen))}}catch(t){console.error("Form submission failed:",t),this.flowError.emit({message:t instanceof Error?t.message:"Form submission failed"})}finally{this.loading=!1}}};handleButtonClick=t=>{"submit"!==t.type?(this.buttonClick.emit(t),"SOCIAL"===t.type&&t.value&&this.shouldAutoNavigate?this.handleSocialLogin(t.value):"RESEND_BUTTON"===t.type&&this.shouldAutoNavigate&&this.handleResend()):this.handleSubmit({preventDefault:()=>{}})};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)}}handleLinkClick=(t,e)=>{this.linkClick.emit({id:e.id,href:e.href,text:e.text}),this.shouldAutoNavigate||t.preventDefault()};getScreenErrors(){return this._screen?.messages?.filter((t=>"error"===t.type))||[]}getScreenSuccesses(){return this._screen?.messages?.filter((t=>"success"===t.type))||[]}getOrderedComponents(){return this._screen?[...this._screen.components].filter((t=>!1!==t.visible)).sort(((t,e)=>(t.order??0)-(e.order??0))):[]}isSocialComponent(t){return"SOCIAL"===t.type}isDividerComponent(t){return"DIVIDER"===t.type}render(){if(this.loading&&!this._screen)return s("div",{class:"widget-container"},s("div",{class:"loading-spinner"}));if(!this._screen)return s("div",{class:"widget-container"},s("div",{class:"error-message"},"No screen configuration provided"));const t=this.getScreenErrors(),e=this.getScreenSuccesses(),i=this.getOrderedComponents(),r=i.filter((t=>this.isSocialComponent(t))),a=i.filter((t=>!this.isSocialComponent(t)&&!this.isDividerComponent(t))),o=i.some((t=>this.isDividerComponent(t))),n=this._theme?.widget?.logo_url||this._branding?.logo_url;return s("div",{class:"widget-container",part:"container"},s("header",{class:"widget-header",part:"header"},n&&s("div",{class:"logo-wrapper",part:"logo-wrapper"},s("img",{class:"logo",part:"logo",src:n,alt:"Logo"})),this._screen.title&&s("h1",{class:"title",part:"title",innerHTML:h(this._screen.title)}),this._screen.description&&s("p",{class:"description",part:"description",innerHTML:h(this._screen.description)})),s("div",{class:"widget-body",part:"body"},t.map((t=>s("div",{class:"message message-error",part:"message message-error",key:t.id??t.text},t.text))),e.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"},s("div",{class:"form-content"},r.length>0&&s("div",{class:"social-section",part:"social-section"},r.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})))),r.length>0&&a.length>0&&o&&s("div",{class:"divider",part:"divider"},s("span",{class:"divider-text"},"Or")),s("div",{class:"fields-section",part:"fields-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})))))),this._screen.links&&this._screen.links.length>0&&s("div",{class:"links",part:"links"},this._screen.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)))))))}static get watchers(){return{screen:[{watchScreen:0}],branding:[{watchBranding:0}],theme:[{watchTheme:0}],authParams:[{watchAuthParams:0}]}}};d.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, 14px);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{max-width:var(--ah-widget-max-width, 400px);width:100%;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 8px);color:var(--ah-color-header, #1e212a);line-height:1.2}.description{font-size:var(--ah-font-size-description, 14px);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}.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;max-width:none;width:100%;margin:0}.widget-header{padding:24px 16px 16px}.widget-body{padding:0 16px 24px}}";export{d as authhero_widget}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as t,c as e,h as r}from"./p-ARKBiJrR.js";const i=class{constructor(r){t(this,r),this.fieldChange=e(this,"fieldChange"),this.buttonClick=e(this,"buttonClick")}component;value;disabled=!1;passwordVisible=!1;fieldChange;buttonClick;handleInput=t=>{this.fieldChange.emit({id:this.component.id,value:t.target.value})};handleCheckbox=t=>{this.fieldChange.emit({id:this.component.id,value:t.target.checked?"true":"false"})};sanitizeForCssToken(t){return t.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")}handleButtonClick=(t,e,r)=>{"submit"!==e&&t.preventDefault(),this.buttonClick.emit({id:this.component.id,type:e,value:r})};togglePasswordVisibility=()=>{this.passwordVisible=!this.passwordVisible};getErrors(){const t=this.component;return t.messages?.filter((t=>"error"===t.type))||[]}renderFloatingLabel(t,e,i,o){return t?r("label",{class:{"input-label":!0,floating:!!o},part:"label",htmlFor:e},t,i&&r("span",{class:"required"},"*")):null}renderLabel(t,e,i){return t?r("label",{class:"input-label",part:"label",htmlFor:e},t,i&&r("span",{class:"required"},"*")):null}renderPasswordToggle(){return this.passwordVisible?r("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},r("path",{d:"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"}),r("line",{x1:"1",y1:"1",x2:"23",y2:"23"})):r("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},r("path",{d:"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"}),r("circle",{cx:"12",cy:"12",r:"3"}))}renderErrors(){return this.getErrors().map((t=>r("span",{class:"error-text",part:"error-text",key:t.id??t.text},t.text)))}renderHint(t){return t?r("span",{class:"helper-text",part:"helper-text"},t):null}renderDivider(){return r("hr",{class:"divider",part:"divider"})}renderHtml(t){return r("div",{class:"html-content",part:"html-content",innerHTML:t.config?.content??""})}renderImage(t){const{src:e,alt:i,width:o,height:n}=t.config??{};return e?r("img",{class:"image",part:"image",src:e,alt:i??"",width:o,height:n,loading:"lazy"}):null}renderRichText(t){return r("div",{class:"rich-text",part:"rich-text",innerHTML:t.config?.content??""})}renderNextButton(t){return r("button",{type:"submit",class:"btn btn-primary",part:"button button-primary",disabled:this.disabled,onClick:t=>this.handleButtonClick(t,"submit","next")},t.config.text??"Continue")}renderPreviousButton(t){return r("button",{type:"button",class:"btn btn-secondary",part:"button button-secondary",disabled:this.disabled,onClick:t=>this.handleButtonClick(t,"previous","back")},t.config.text??"Back")}renderJumpButton(t){return r("button",{type:"button",class:"btn btn-link",part:"button button-link",disabled:this.disabled,onClick:e=>this.handleButtonClick(e,"jump",t.config.target_step)},t.config.text??"Go")}renderResendButton(t){return r("button",{type:"button",class:"btn btn-link",part:"button button-link",disabled:this.disabled,onClick:e=>this.handleButtonClick(e,"resend",t.config.resend_action)},t.config.text??"Resend")}renderTextField(t){const e=`input-${t.id}`,i=this.getErrors(),{multiline:o,max_length:n}=t.config??{},a=!!(this.value&&this.value.length>0);return o?r("div",{class:"input-wrapper",part:"input-wrapper"},this.renderLabel(t.label,e,t.required),r("textarea",{id:e,class:{"input-field":!0,"has-error":i.length>0},part:"input textarea",name:t.id,placeholder:" ",required:t.required,disabled:this.disabled,maxLength:n,onInput:this.handleInput},this.value??""),this.renderErrors(),0===i.length&&this.renderHint(t.hint)):r("div",{class:"input-wrapper",part:"input-wrapper"},r("div",{class:"input-container"},r("input",{id:e,class:{"input-field":!0,"has-error":i.length>0},part:"input",type:t.sensitive?"password":"text",name:t.id,value:this.value??"",placeholder:" ",required:t.required,disabled:this.disabled,maxLength:n,onInput:this.handleInput}),this.renderFloatingLabel(t.label,e,t.required,a)),this.renderErrors(),0===i.length&&this.renderHint(t.hint))}renderEmailField(t){const e=`input-${t.id}`,i=this.getErrors(),o=!!(this.value&&this.value.length>0);return r("div",{class:"input-wrapper",part:"input-wrapper"},r("div",{class:"input-container"},r("input",{id:e,class:{"input-field":!0,"has-error":i.length>0},part:"input",type:"email",name:t.id,value:this.value??"",placeholder:" ",required:t.required,disabled:this.disabled,autocomplete:"email",onInput:this.handleInput}),this.renderFloatingLabel(t.label,e,t.required,o)),this.renderErrors(),0===i.length&&this.renderHint(t.hint))}renderPasswordField(t){const e=`input-${t.id}`,i=this.getErrors(),o=!!(this.value&&this.value.length>0),n=t.config?.forgot_password_link;return r("div",{class:"input-wrapper",part:"input-wrapper"},r("div",{class:"input-container password-container"},r("input",{id:e,class:{"input-field":!0,"has-error":i.length>0},part:"input",type:this.passwordVisible?"text":"password",name:t.id,value:this.value??"",placeholder:" ",required:t.required,disabled:this.disabled,minLength:t.config?.min_length,autocomplete:"current-password",onInput:this.handleInput}),this.renderFloatingLabel(t.label,e,t.required,o),r("button",{type:"button",class:"password-toggle",part:"password-toggle",onClick:this.togglePasswordVisibility,"aria-label":"Toggle password visibility","aria-pressed":this.passwordVisible?"true":"false"},this.renderPasswordToggle())),this.renderErrors(),0===i.length&&this.renderHint(t.hint),n&&r("div",{class:"field-link",part:"field-link"},r("a",{href:n,class:"link",part:"link"},"Forgot password?")))}renderNumberField(t){const e=`input-${t.id}`,i=this.getErrors(),{placeholder:o,min:n,max:a,step:s}=t.config??{};return r("div",{class:"input-wrapper",part:"input-wrapper"},this.renderLabel(t.label,e,t.required),r("input",{id:e,class:{"input-field":!0,"has-error":i.length>0},part:"input",type:"number",name:t.id,value:this.value??"",placeholder:o,required:t.required,disabled:this.disabled,min:n,max:a,step:s,onInput:this.handleInput}),this.renderErrors(),0===i.length&&this.renderHint(t.hint))}renderTelField(t){const e=`input-${t.id}`,i=this.getErrors();return r("div",{class:"input-wrapper",part:"input-wrapper"},this.renderLabel(t.label,e,t.required),r("input",{id:e,class:{"input-field":!0,"has-error":i.length>0},part:"input",type:"tel",name:t.id,value:this.value??"",placeholder:t.config?.placeholder,required:t.required,disabled:this.disabled,autocomplete:"tel",onInput:this.handleInput}),this.renderErrors(),0===i.length&&this.renderHint(t.hint))}renderUrlField(t){const e=`input-${t.id}`,i=this.getErrors();return r("div",{class:"input-wrapper",part:"input-wrapper"},this.renderLabel(t.label,e,t.required),r("input",{id:e,class:{"input-field":!0,"has-error":i.length>0},part:"input",type:"url",name:t.id,value:this.value??"",placeholder:t.config?.placeholder,required:t.required,disabled:this.disabled,onInput:this.handleInput}),this.renderErrors(),0===i.length&&this.renderHint(t.hint))}renderDateField(t){const e=`input-${t.id}`,i=this.getErrors(),{min:o,max:n}=t.config??{};return r("div",{class:"input-wrapper",part:"input-wrapper"},this.renderLabel(t.label,e,t.required),r("input",{id:e,class:{"input-field":!0,"has-error":i.length>0},part:"input",type:"date",name:t.id,value:this.value??"",required:t.required,disabled:this.disabled,min:o,max:n,onInput:this.handleInput}),this.renderErrors(),0===i.length&&this.renderHint(t.hint))}renderBooleanField(t){return r("label",{class:"checkbox-wrapper",part:"checkbox-wrapper"},r("input",{type:"checkbox",part:"checkbox",name:t.id,checked:"true"===this.value||!0===t.config?.default_value,required:t.required,disabled:this.disabled,onChange:this.handleCheckbox}),r("span",{class:"checkbox-label",part:"checkbox-label"},t.label))}renderLegalField(t){const e=t.config?.text??t.label??"",i=!0===t.config?.html;return r("label",{class:"checkbox-wrapper",part:"checkbox-wrapper"},r("input",{type:"checkbox",part:"checkbox",name:t.id,checked:"true"===this.value,required:t.required,disabled:this.disabled,onChange:this.handleCheckbox}),i?r("span",{class:"checkbox-label",part:"checkbox-label",innerHTML:e}):r("span",{class:"checkbox-label",part:"checkbox-label"},e))}renderDropdownField(t){const e=`input-${t.id}`,i=this.getErrors(),{options:o,placeholder:n}=t.config??{};return r("div",{class:"input-wrapper",part:"input-wrapper"},this.renderLabel(t.label,e,t.required),r("select",{id:e,class:{"input-field":!0,"has-error":i.length>0},part:"input select",name:t.id,required:t.required,disabled:this.disabled,onChange:this.handleInput},n&&r("option",{value:"",disabled:!0,selected:!this.value},n),o?.map((t=>r("option",{value:t.value,selected:this.value===t.value,key:t.value},t.label)))),this.renderErrors(),0===i.length&&this.renderHint(t.hint))}renderChoiceField(t){const e=this.getErrors(),{options:i,display:o}=t.config??{},n="checkbox"===o,a=n?"checkbox":"radio";return r("div",{class:"choice-wrapper",part:"choice-wrapper"},t.label&&r("span",{class:"choice-label",part:"choice-label"},t.label,t.required&&r("span",{class:"required"},"*")),r("div",{class:"choice-options",part:"choice-options"},i?.map((e=>r("label",{class:"choice-option",part:"choice-option",key:e.value},r("input",{type:a,part:a,name:t.id,value:e.value,checked:this.value===e.value,required:t.required&&!n,disabled:this.disabled,onChange:this.handleInput}),r("span",null,e.label))))),this.renderErrors(),0===e.length&&this.renderHint(t.hint))}renderSocialField(t){const e=t.config?.providers??[],i=t.config?.provider_details,o=new Map(i?.map((t=>[t.name,t]))??[]);return r("div",{class:"social-buttons",part:"social-buttons"},e.map((t=>{const e=this.sanitizeForCssToken(t),i=(t=>{const e=o.get(t);return e?.icon_url?r("img",{class:"social-icon",src:e.icon_url,alt:e.display_name||t}):null})(t);return r("button",{type:"button",class:`btn btn-secondary btn-social btn-social-${e}${i?"":" no-icon"}`,part:`button button-secondary button-social button-social-${e}`,"data-provider":t,disabled:this.disabled,onClick:e=>this.handleButtonClick(e,"SOCIAL",t),key:t},i,r("span",{part:"button-social-text"},(t=>{const e=o.get(t);return e?.display_name?e.display_name:t.split("-").map((t=>t.charAt(0).toUpperCase()+t.slice(1))).join(" ")})(t)))})))}render(){if(!this.component)return null;if(!1===this.component.visible)return null;switch(this.component.type){case"DIVIDER":return this.renderDivider();case"HTML":return this.renderHtml(this.component);case"IMAGE":return this.renderImage(this.component);case"RICH_TEXT":return this.renderRichText(this.component);case"NEXT_BUTTON":return this.renderNextButton(this.component);case"PREVIOUS_BUTTON":return this.renderPreviousButton(this.component);case"JUMP_BUTTON":return this.renderJumpButton(this.component);case"RESEND_BUTTON":return this.renderResendButton(this.component);case"TEXT":return this.renderTextField(this.component);case"EMAIL":return this.renderEmailField(this.component);case"PASSWORD":return this.renderPasswordField(this.component);case"NUMBER":return this.renderNumberField(this.component);case"TEL":return this.renderTelField(this.component);case"URL":return this.renderUrlField(this.component);case"DATE":return this.renderDateField(this.component);case"BOOLEAN":return this.renderBooleanField(this.component);case"LEGAL":return this.renderLegalField(this.component);case"DROPDOWN":return this.renderDropdownField(this.component);case"CHOICE":return this.renderChoiceField(this.component);case"SOCIAL":return this.renderSocialField(this.component);case"AUTH0_VERIFIABLE_CREDENTIALS":case"GMAPS_ADDRESS":case"RECAPTCHA":return console.warn(`Widget component "${this.component.type}" not yet implemented`),null;case"CARDS":case"CUSTOM":case"FILE":case"PAYMENT":return console.warn(`Component "${this.component.type}" not yet implemented`),null;default:return console.warn(`Unknown component type: ${this.component.type}`),null}}};i.style=':host{display:block}.input-wrapper{display:flex;flex-direction:column;position:relative;margin-bottom:16px}.input-container{position:relative;width:100%}.input-label{position:absolute;left:16px;top:50%;transform:translateY(-50%);font-size:16px;font-weight:var(--ah-font-weight-label, 400);color:var(--ah-color-text-muted, #65676e);pointer-events:none;transition:all 0.15s ease-out;background-color:transparent;padding:0;z-index:1}.input-label.floating,.input-field:focus+.input-label,.input-field:not(:placeholder-shown)+.input-label{top:-8px;transform:translateY(0);font-size:12px;background-color:var(--ah-color-bg, #ffffff);padding:0 4px;left:12px;color:var(--ah-color-text-muted, #65676e)}.input-field:focus+.input-label{color:var(--ah-color-primary, #635dff)}.required{color:var(--ah-color-error, #d03c38);margin-left:2px}.input-field{width:100%;padding:16px;font-size:16px;font-family:inherit;color:var(--ah-color-text, #1e212a);background-color:var(--ah-color-input-bg, #ffffff);border:1px solid var(--ah-color-border, #c9cace);border-radius:var(--ah-input-radius, 3px);outline:none;transition:border-color 0.15s ease-out, box-shadow 0.15s ease-out;box-sizing:border-box}.input-field::placeholder{color:transparent}.input-field:hover{border-color:var(--ah-color-border-hover, #65676e)}.input-field:focus{border-color:var(--ah-color-primary, #635dff);box-shadow:inset 0 0 0 1px var(--ah-color-primary, #635dff)}.input-field.has-error{border-color:var(--ah-color-error, #d03c38)}.input-field.has-error:focus{box-shadow:inset 0 0 0 1px var(--ah-color-error, #d03c38)}.input-field:disabled{background-color:var(--ah-color-bg-disabled, #f5f5f5);border-color:var(--ah-color-border-disabled, #e0e1e3);cursor:not-allowed;opacity:0.7}.password-container{position:relative;display:flex;align-items:center}.password-container .input-field{padding-right:48px}.password-toggle{position:absolute;right:12px;top:50%;transform:translateY(-50%);background:none;border:none;cursor:pointer;padding:4px;display:flex;align-items:center;justify-content:center;color:var(--ah-color-text-muted, #65676e);transition:color 0.15s ease}.password-toggle:hover{color:var(--ah-color-text, #1e212a)}.password-toggle svg{width:20px;height:20px}.error-text{font-size:12px;color:var(--ah-color-error, #d03c38);margin-top:4px;line-height:1.4}.helper-text{font-size:12px;color:var(--ah-color-text-muted, #65676e);margin-top:4px;line-height:1.4}.field-link{display:block;text-align:left;margin-top:8px;margin-bottom:16px}.field-link a{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:14px;font-weight:var(--ah-font-weight-link, 400)}.field-link a:hover{text-decoration:underline}.checkbox-wrapper{display:flex;align-items:flex-start;gap:10px;cursor:pointer;margin-bottom:16px}.checkbox-wrapper input[type="checkbox"]{width:18px;height:18px;margin:0;accent-color:var(--ah-color-primary, #635dff);cursor:pointer;flex-shrink:0}.checkbox-label{font-size:14px;color:var(--ah-color-text, #1e212a);line-height:1.5}.btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;width:100%;padding:14px 20px;font-size:16px;font-weight:var(--ah-font-weight-btn, 400);font-family:inherit;line-height:1.25;text-align:center;text-decoration:none;border:none;border-radius:var(--ah-btn-radius, 3px);cursor:pointer;transition:background-color 0.15s ease, border-color 0.15s ease, transform 0.1s ease;box-sizing:border-box}.btn:disabled{opacity:0.6;cursor:not-allowed}.btn:not(:disabled):active{transform:scale(0.98)}.btn:focus-visible{outline:2px solid var(--ah-color-primary, #635dff);outline-offset:2px}.btn-primary{background-color:var(--ah-color-primary, #635dff);color:var(--ah-color-text-on-primary, #ffffff);margin-top:12px}.btn-primary:not(:disabled):hover{filter:brightness(0.85)}.btn-secondary{background-color:var(--ah-color-bg, #ffffff);color:var(--ah-color-text, #1e212a);border:1px solid var(--ah-color-border, #c9cace)}.btn-secondary:not(:disabled):hover{background-color:var(--ah-color-bg-hover, #f5f5f5);border-color:var(--ah-color-border-hover, #65676e)}.btn-link{background:none;border:none;color:var(--ah-color-link, #635dff);padding:8px 0;font-weight:var(--ah-font-weight-link, 400);text-decoration:none}.btn-link:hover{text-decoration:underline}.social-buttons{display:flex;flex-direction:column;gap:12px}.btn-social{display:flex;align-items:center;justify-content:center;gap:12px}.social-icon{width:20px;height:20px;flex-shrink:0}@media (max-width: 480px){.social-buttons:has(.btn-social:nth-child(3)){flex-direction:row;flex-wrap:nowrap;justify-content:stretch;gap:8px}.social-buttons:has(.btn-social:nth-child(3)) .btn-social{width:auto;min-width:0;padding:12px;flex:1 1 0}.social-buttons:has(.btn-social:nth-child(3)) .btn-social span{display:none}.social-buttons:has(.btn-social:nth-child(3)) .social-icon{width:24px;height:24px}}.btn-icon{width:20px;height:20px;flex-shrink:0}.btn-icon img{width:100%;height:100%;object-fit:contain}.text-title{font-size:20px;font-weight:400;color:var(--ah-color-text, #1e212a);margin:8px 0;line-height:1.3}.text-title.text-success{color:var(--ah-color-success, #13a769)}.text-description{font-size:14px;color:var(--ah-color-text-muted, #65676e);margin:4px 0;line-height:1.5}.image{display:block;max-width:100%;height:auto;border-radius:4px}.image-centered{margin:0 auto 16px;width:52px;height:52px;object-fit:contain}.link{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:14px;transition:color 0.15s ease}.link:hover{text-decoration:underline}.link:focus-visible{outline:2px solid var(--ah-color-link, #635dff);outline-offset:2px;border-radius:2px}.node-error{padding:12px 16px;background-color:var(--ah-color-error-bg, #ffeaea);color:var(--ah-color-error, #d03c38);border-left:3px solid var(--ah-color-error, #d03c38);border-radius:0;font-size:14px;margin-bottom:16px}.node-success{padding:12px 16px;background-color:var(--ah-color-success-bg, #e6f9f1);color:var(--ah-color-success, #13a769);border-left:3px solid var(--ah-color-success, #13a769);border-radius:0;font-size:14px;margin-bottom:16px}.divider{display:flex;align-items:center;text-align:center;margin:16px 0}.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.5px}';export{i as authhero_node}
|
|
@@ -46,6 +46,17 @@ const AuthheroNode = class {
|
|
|
46
46
|
value: target.checked ? "true" : "false",
|
|
47
47
|
});
|
|
48
48
|
};
|
|
49
|
+
/**
|
|
50
|
+
* Sanitize a string for use in CSS class names and part tokens.
|
|
51
|
+
* Replaces spaces and special characters with hyphens, converts to lowercase.
|
|
52
|
+
*/
|
|
53
|
+
sanitizeForCssToken(value) {
|
|
54
|
+
return value
|
|
55
|
+
.toLowerCase()
|
|
56
|
+
.replace(/[^a-z0-9-]/g, "-") // Replace non-alphanumeric chars with hyphen
|
|
57
|
+
.replace(/-+/g, "-") // Collapse multiple hyphens
|
|
58
|
+
.replace(/^-|-$/g, ""); // Remove leading/trailing hyphens
|
|
59
|
+
}
|
|
49
60
|
handleButtonClick = (e, type, value) => {
|
|
50
61
|
if (type !== "submit") {
|
|
51
62
|
e.preventDefault();
|
|
@@ -208,113 +219,32 @@ const AuthheroNode = class {
|
|
|
208
219
|
const providerDetails = component.config?.provider_details;
|
|
209
220
|
// Create a map of provider details for quick lookup
|
|
210
221
|
const detailsMap = new Map(providerDetails?.map((d) => [d.name, d]) ?? []);
|
|
211
|
-
//
|
|
212
|
-
const
|
|
213
|
-
"google-oauth2",
|
|
214
|
-
"google",
|
|
215
|
-
"facebook",
|
|
216
|
-
"apple",
|
|
217
|
-
"github",
|
|
218
|
-
"microsoft",
|
|
219
|
-
"windowslive",
|
|
220
|
-
"linkedin",
|
|
221
|
-
"vipps",
|
|
222
|
-
];
|
|
223
|
-
// Find matching known provider from name or strategy
|
|
224
|
-
const findKnownProvider = (name, strategy) => {
|
|
225
|
-
const nameLower = name.toLowerCase();
|
|
226
|
-
const strategyLower = strategy?.toLowerCase();
|
|
227
|
-
// First check exact match on strategy
|
|
228
|
-
if (strategyLower && knownProviders.includes(strategyLower)) {
|
|
229
|
-
return strategyLower;
|
|
230
|
-
}
|
|
231
|
-
// Then check exact match on name
|
|
232
|
-
if (knownProviders.includes(nameLower)) {
|
|
233
|
-
return nameLower;
|
|
234
|
-
}
|
|
235
|
-
// Check if name contains a known provider (e.g., "Vipps Login" contains "vipps")
|
|
236
|
-
for (const known of knownProviders) {
|
|
237
|
-
if (nameLower.includes(known)) {
|
|
238
|
-
return known;
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
return null;
|
|
242
|
-
};
|
|
243
|
-
// Map provider IDs to display names
|
|
244
|
-
const getProviderDisplayName = (provider) => {
|
|
245
|
-
// First check provider_details
|
|
222
|
+
// Get button text from provider_details (already contains the full button text from server)
|
|
223
|
+
const getButtonText = (provider) => {
|
|
246
224
|
const details = detailsMap.get(provider);
|
|
247
225
|
if (details?.display_name) {
|
|
248
226
|
return details.display_name;
|
|
249
227
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
linkedin: "LinkedIn",
|
|
256
|
-
apple: "Apple",
|
|
257
|
-
microsoft: "Microsoft",
|
|
258
|
-
windowslive: "Microsoft",
|
|
259
|
-
amazon: "Amazon",
|
|
260
|
-
dropbox: "Dropbox",
|
|
261
|
-
bitbucket: "Bitbucket",
|
|
262
|
-
spotify: "Spotify",
|
|
263
|
-
slack: "Slack",
|
|
264
|
-
discord: "Discord",
|
|
265
|
-
twitch: "Twitch",
|
|
266
|
-
line: "LINE",
|
|
267
|
-
shopify: "Shopify",
|
|
268
|
-
paypal: "PayPal",
|
|
269
|
-
"paypal-sandbox": "PayPal",
|
|
270
|
-
box: "Box",
|
|
271
|
-
salesforce: "Salesforce",
|
|
272
|
-
"salesforce-sandbox": "Salesforce",
|
|
273
|
-
yahoo: "Yahoo",
|
|
274
|
-
auth0: "Auth0",
|
|
275
|
-
vipps: "Vipps",
|
|
276
|
-
};
|
|
277
|
-
return (displayNames[provider.toLowerCase()] ||
|
|
278
|
-
provider
|
|
279
|
-
.split("-")
|
|
280
|
-
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
281
|
-
.join(" "));
|
|
228
|
+
// Fallback: use provider name with basic formatting
|
|
229
|
+
return provider
|
|
230
|
+
.split("-")
|
|
231
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
232
|
+
.join(" ");
|
|
282
233
|
};
|
|
283
|
-
// Get provider icon
|
|
234
|
+
// Get provider icon from provider_details icon_url
|
|
284
235
|
const getProviderIcon = (provider) => {
|
|
285
|
-
// First check if we have a custom icon URL from provider_details
|
|
286
236
|
const details = detailsMap.get(provider);
|
|
287
237
|
if (details?.icon_url) {
|
|
288
238
|
return (index.h("img", { class: "social-icon", src: details.icon_url, alt: details.display_name || provider }));
|
|
289
239
|
}
|
|
290
|
-
//
|
|
291
|
-
|
|
292
|
-
const p = knownProvider || provider.toLowerCase();
|
|
293
|
-
if (p === "google-oauth2" || p === "google") {
|
|
294
|
-
return (index.h("svg", { class: "social-icon", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, index.h("path", { d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z", fill: "#4285F4" }), index.h("path", { d: "M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z", fill: "#34A853" }), index.h("path", { d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z", fill: "#FBBC05" }), index.h("path", { d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z", fill: "#EA4335" })));
|
|
295
|
-
}
|
|
296
|
-
if (p === "facebook") {
|
|
297
|
-
return (index.h("svg", { class: "social-icon", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, index.h("path", { d: "M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z", fill: "#1877F2" })));
|
|
298
|
-
}
|
|
299
|
-
if (p === "apple") {
|
|
300
|
-
return (index.h("svg", { class: "social-icon", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, index.h("path", { d: "M17.05 20.28c-.98.95-2.05.8-3.08.35-1.09-.46-2.09-.48-3.24 0-1.44.62-2.2.44-3.06-.35C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09l.01-.01zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z", fill: "#000000" })));
|
|
301
|
-
}
|
|
302
|
-
if (p === "github") {
|
|
303
|
-
return (index.h("svg", { class: "social-icon", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, index.h("path", { d: "M12 0C5.374 0 0 5.373 0 12c0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23A11.509 11.509 0 0112 5.803c1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576C20.566 21.797 24 17.3 24 12c0-6.627-5.373-12-12-12z", fill: "#181717" })));
|
|
304
|
-
}
|
|
305
|
-
if (p === "microsoft" || p === "windowslive") {
|
|
306
|
-
return (index.h("svg", { class: "social-icon", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, index.h("path", { d: "M0 0h11.377v11.372H0V0z", fill: "#f25022" }), index.h("path", { d: "M12.623 0H24v11.372H12.623V0z", fill: "#7fba00" }), index.h("path", { d: "M0 12.623h11.377V24H0v-11.377z", fill: "#00a4ef" }), index.h("path", { d: "M12.623 12.623H24V24H12.623v-11.377z", fill: "#ffb900" })));
|
|
307
|
-
}
|
|
308
|
-
if (p === "linkedin") {
|
|
309
|
-
return (index.h("svg", { class: "social-icon", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, index.h("path", { d: "M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z", fill: "#0A66C2" })));
|
|
310
|
-
}
|
|
311
|
-
if (p === "vipps") {
|
|
312
|
-
return (index.h("svg", { class: "social-icon", viewBox: "0 0 48 48", xmlns: "http://www.w3.org/2000/svg" }, index.h("path", { fill: "#FF5B24", d: "M3.5,8h41c1.9,0,3.5,1.6,3.5,3.5v25c0,1.9-1.6,3.5-3.5,3.5h-41C1.6,40,0,38.4,0,36.5v-25C0,9.6,1.6,8,3.5,8z" }), index.h("path", { fill: "#FFFFFF", d: "M27.9,20.3c1.4,0,2.6-1,2.6-2.5c0-1.5-1.2-2.5-2.6-2.5c-1.4,0-2.6,1-2.6,2.5C25.3,19.2,26.5,20.3,27.9,20.3z" }), index.h("path", { fill: "#FFFFFF", d: "M31.2,24.4c-1.7,2.2-3.5,3.8-6.7,3.8c-3.2,0-5.8-2-7.7-4.8c-0.8-1.2-2-1.4-2.9-0.8c-0.8,0.6-1,1.8-0.3,2.9c2.7,4.1,6.5,6.6,10.9,6.6c4,0,7.2-2,9.6-5.2c0.9-1.2,0.9-2.5,0-3.1C33.3,22.9,32.1,23.2,31.2,24.4z" })));
|
|
313
|
-
}
|
|
314
|
-
// Default: generic globe icon for unknown providers
|
|
315
|
-
return (index.h("svg", { class: "social-icon", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, index.h("circle", { cx: "12", cy: "12", r: "10", fill: "none", stroke: "#666", "stroke-width": "2" }), index.h("path", { d: "M2 12h20M12 2c-2.5 2.5-4 5.5-4 10s1.5 7.5 4 10c2.5-2.5 4-5.5 4-10s-1.5-7.5-4-10z", fill: "none", stroke: "#666", "stroke-width": "2" })));
|
|
240
|
+
// No icon provided - return null (button will just show text)
|
|
241
|
+
return null;
|
|
316
242
|
};
|
|
317
|
-
return (index.h("div", { class: "social-buttons", part: "social-buttons" }, providers.map((provider) =>
|
|
243
|
+
return (index.h("div", { class: "social-buttons", part: "social-buttons" }, providers.map((provider) => {
|
|
244
|
+
const safeProvider = this.sanitizeForCssToken(provider);
|
|
245
|
+
const icon = getProviderIcon(provider);
|
|
246
|
+
return (index.h("button", { type: "button", class: `btn btn-secondary btn-social btn-social-${safeProvider}${icon ? "" : " no-icon"}`, part: `button button-secondary button-social button-social-${safeProvider}`, "data-provider": provider, disabled: this.disabled, onClick: (e) => this.handleButtonClick(e, "SOCIAL", provider), key: provider }, icon, index.h("span", { part: "button-social-text" }, getButtonText(provider))));
|
|
247
|
+
})));
|
|
318
248
|
}
|
|
319
249
|
// ===========================================================================
|
|
320
250
|
// Main Render
|
|
@@ -290,6 +290,139 @@ function applyCssVars(element, vars) {
|
|
|
290
290
|
});
|
|
291
291
|
}
|
|
292
292
|
|
|
293
|
+
/**
|
|
294
|
+
* Sanitize HTML to only allow safe formatting tags
|
|
295
|
+
*
|
|
296
|
+
* Allowed tags:
|
|
297
|
+
* - <br>, <br/> - Line breaks
|
|
298
|
+
* - <em>, <i> - Italic
|
|
299
|
+
* - <strong>, <b> - Bold
|
|
300
|
+
* - <u> - Underline
|
|
301
|
+
* - <span> - Generic inline container (for styling)
|
|
302
|
+
* - <a> - Links (href attribute only, with target="_blank" and rel="noopener")
|
|
303
|
+
*
|
|
304
|
+
* All other tags and attributes are stripped.
|
|
305
|
+
*/
|
|
306
|
+
// Allowed tags and their allowed attributes
|
|
307
|
+
const ALLOWED_TAGS = {
|
|
308
|
+
br: [],
|
|
309
|
+
em: [],
|
|
310
|
+
i: [],
|
|
311
|
+
strong: [],
|
|
312
|
+
b: [],
|
|
313
|
+
u: [],
|
|
314
|
+
span: ["class"],
|
|
315
|
+
a: ["href", "class"],
|
|
316
|
+
};
|
|
317
|
+
/**
|
|
318
|
+
* Sanitize HTML string to only allow safe formatting tags
|
|
319
|
+
*
|
|
320
|
+
* @param html - The HTML string to sanitize
|
|
321
|
+
* @returns Sanitized HTML string safe for innerHTML
|
|
322
|
+
*/
|
|
323
|
+
function sanitizeHtml(html) {
|
|
324
|
+
if (!html)
|
|
325
|
+
return "";
|
|
326
|
+
// If no < character present, return as-is (optimization)
|
|
327
|
+
// Must check for any < to prevent bypassing sanitization with malformed tags
|
|
328
|
+
// like "<img src=x onerror=..." which forgiving HTML parsers may still execute
|
|
329
|
+
if (!html.includes("<")) {
|
|
330
|
+
return html;
|
|
331
|
+
}
|
|
332
|
+
// Use a simple regex-based approach that's safe for our limited use case
|
|
333
|
+
// This avoids needing DOMParser which may not be available in all environments
|
|
334
|
+
let result = html;
|
|
335
|
+
// First, escape all HTML
|
|
336
|
+
result = result
|
|
337
|
+
.replace(/&/g, "&")
|
|
338
|
+
.replace(/</g, "<")
|
|
339
|
+
.replace(/>/g, ">")
|
|
340
|
+
.replace(/"/g, """)
|
|
341
|
+
.replace(/'/g, "'");
|
|
342
|
+
// Then selectively re-enable allowed tags
|
|
343
|
+
for (const [tag, allowedAttrs] of Object.entries(ALLOWED_TAGS)) {
|
|
344
|
+
// Self-closing tags (like <br> and <br/>)
|
|
345
|
+
if (tag === "br") {
|
|
346
|
+
result = result.replace(/<br\s*\/?>/gi, "<br>");
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
// Opening tags with optional attributes
|
|
350
|
+
const openingPattern = new RegExp(`<${tag}((?:\\s+[a-z-]+(?:="[^&]*"|='[^&]*')?)*)\\s*>`, "gi");
|
|
351
|
+
result = result.replace(openingPattern, (_match, attrsStr) => {
|
|
352
|
+
// Parse and filter attributes
|
|
353
|
+
const filteredAttrs = [];
|
|
354
|
+
if (attrsStr) {
|
|
355
|
+
// Unescape the attributes string for parsing
|
|
356
|
+
const unescapedAttrs = attrsStr
|
|
357
|
+
.replace(/"/g, '"')
|
|
358
|
+
.replace(/'/g, "'")
|
|
359
|
+
.replace(/&/g, "&")
|
|
360
|
+
.replace(/</g, "<")
|
|
361
|
+
.replace(/>/g, ">");
|
|
362
|
+
// Extract attributes
|
|
363
|
+
const attrPattern = /([a-z-]+)=["']([^"']*)["']/gi;
|
|
364
|
+
let attrMatch;
|
|
365
|
+
while ((attrMatch = attrPattern.exec(unescapedAttrs)) !== null) {
|
|
366
|
+
const [, attrName, attrValue] = attrMatch;
|
|
367
|
+
if (attrName && allowedAttrs.includes(attrName.toLowerCase())) {
|
|
368
|
+
// For href, validate it's a safe URL
|
|
369
|
+
if (attrName.toLowerCase() === "href") {
|
|
370
|
+
if (isSafeUrl(attrValue || "")) {
|
|
371
|
+
filteredAttrs.push(`${attrName}="${escapeAttr(attrValue || "")}"`);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
else {
|
|
375
|
+
filteredAttrs.push(`${attrName}="${escapeAttr(attrValue || "")}"`);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
// For <a> tags, always add security attributes
|
|
381
|
+
if (tag === "a") {
|
|
382
|
+
filteredAttrs.push('target="_blank"');
|
|
383
|
+
filteredAttrs.push('rel="noopener noreferrer"');
|
|
384
|
+
}
|
|
385
|
+
const attrsOutput = filteredAttrs.length
|
|
386
|
+
? " " + filteredAttrs.join(" ")
|
|
387
|
+
: "";
|
|
388
|
+
return `<${tag}${attrsOutput}>`;
|
|
389
|
+
});
|
|
390
|
+
// Closing tags
|
|
391
|
+
const closingPattern = new RegExp(`</${tag}>`, "gi");
|
|
392
|
+
result = result.replace(closingPattern, `</${tag}>`);
|
|
393
|
+
}
|
|
394
|
+
return result;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Check if a URL is safe (http, https, or relative)
|
|
398
|
+
*/
|
|
399
|
+
function isSafeUrl(url) {
|
|
400
|
+
if (!url)
|
|
401
|
+
return false;
|
|
402
|
+
// Allow relative URLs
|
|
403
|
+
if (url.startsWith("/") || url.startsWith("#") || url.startsWith("?")) {
|
|
404
|
+
return true;
|
|
405
|
+
}
|
|
406
|
+
// Allow http and https
|
|
407
|
+
try {
|
|
408
|
+
const parsed = new URL(url, "https://example.com");
|
|
409
|
+
return parsed.protocol === "http:" || parsed.protocol === "https:";
|
|
410
|
+
}
|
|
411
|
+
catch {
|
|
412
|
+
return false;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Escape attribute value
|
|
417
|
+
*/
|
|
418
|
+
function escapeAttr(value) {
|
|
419
|
+
return value
|
|
420
|
+
.replace(/&/g, "&")
|
|
421
|
+
.replace(/"/g, """)
|
|
422
|
+
.replace(/</g, "<")
|
|
423
|
+
.replace(/>/g, ">");
|
|
424
|
+
}
|
|
425
|
+
|
|
293
426
|
const authheroWidgetCss = () => `: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, 14px);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{max-width:var(--ah-widget-max-width, 400px);width:100%;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 8px);color:var(--ah-color-header, #1e212a);line-height:1.2}.description{font-size:var(--ah-font-size-description, 14px);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}.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;max-width:none;width:100%;margin:0}.widget-header{padding:24px 16px 16px}.widget-body{padding:0 16px 24px}}`;
|
|
294
427
|
|
|
295
428
|
const AuthheroWidget = class {
|
|
@@ -715,7 +848,12 @@ const AuthheroWidget = class {
|
|
|
715
848
|
if (result.screenId) {
|
|
716
849
|
this.screenId = result.screenId;
|
|
717
850
|
}
|
|
851
|
+
// Persist state (especially for session storage mode)
|
|
718
852
|
this.persistState();
|
|
853
|
+
// Update URL path if navigateUrl is provided (client-side navigation)
|
|
854
|
+
if (result.navigateUrl && this.shouldAutoNavigate) {
|
|
855
|
+
window.history.pushState({ screen: result.screenId, state: this.state }, "", result.navigateUrl);
|
|
856
|
+
}
|
|
719
857
|
// Apply branding if included
|
|
720
858
|
if (result.branding) {
|
|
721
859
|
this._branding = result.branding;
|
|
@@ -888,7 +1026,7 @@ const AuthheroWidget = class {
|
|
|
888
1026
|
const hasDivider = components.some((c) => this.isDividerComponent(c));
|
|
889
1027
|
// Get logo URL from theme.widget (takes precedence) or branding
|
|
890
1028
|
const logoUrl = this._theme?.widget?.logo_url || this._branding?.logo_url;
|
|
891
|
-
return (index.h("div", { class: "widget-container", part: "container" }, 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" }))), this._screen.title && (index.h("h1", { class: "title", part: "title"
|
|
1029
|
+
return (index.h("div", { class: "widget-container", part: "container" }, 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" }))), this._screen.title && (index.h("h1", { class: "title", part: "title", innerHTML: sanitizeHtml(this._screen.title) })), this._screen.description && (index.h("p", { class: "description", part: "description", innerHTML: sanitizeHtml(this._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 }))))), socialComponents.length > 0 &&
|
|
892
1030
|
fieldComponents.length > 0 &&
|
|
893
1031
|
hasDivider && (index.h("div", { class: "divider", part: "divider" }, index.h("span", { class: "divider-text" }, "Or"))), 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 })))))), this._screen.links && this._screen.links.length > 0 && (index.h("div", { class: "links", part: "links" }, this._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, {
|
|
894
1032
|
id: link.id,
|
|
@@ -36,6 +36,17 @@ export class AuthheroNode {
|
|
|
36
36
|
value: target.checked ? "true" : "false",
|
|
37
37
|
});
|
|
38
38
|
};
|
|
39
|
+
/**
|
|
40
|
+
* Sanitize a string for use in CSS class names and part tokens.
|
|
41
|
+
* Replaces spaces and special characters with hyphens, converts to lowercase.
|
|
42
|
+
*/
|
|
43
|
+
sanitizeForCssToken(value) {
|
|
44
|
+
return value
|
|
45
|
+
.toLowerCase()
|
|
46
|
+
.replace(/[^a-z0-9-]/g, "-") // Replace non-alphanumeric chars with hyphen
|
|
47
|
+
.replace(/-+/g, "-") // Collapse multiple hyphens
|
|
48
|
+
.replace(/^-|-$/g, ""); // Remove leading/trailing hyphens
|
|
49
|
+
}
|
|
39
50
|
handleButtonClick = (e, type, value) => {
|
|
40
51
|
if (type !== "submit") {
|
|
41
52
|
e.preventDefault();
|
|
@@ -198,113 +209,32 @@ export class AuthheroNode {
|
|
|
198
209
|
const providerDetails = component.config?.provider_details;
|
|
199
210
|
// Create a map of provider details for quick lookup
|
|
200
211
|
const detailsMap = new Map(providerDetails?.map((d) => [d.name, d]) ?? []);
|
|
201
|
-
//
|
|
202
|
-
const
|
|
203
|
-
"google-oauth2",
|
|
204
|
-
"google",
|
|
205
|
-
"facebook",
|
|
206
|
-
"apple",
|
|
207
|
-
"github",
|
|
208
|
-
"microsoft",
|
|
209
|
-
"windowslive",
|
|
210
|
-
"linkedin",
|
|
211
|
-
"vipps",
|
|
212
|
-
];
|
|
213
|
-
// Find matching known provider from name or strategy
|
|
214
|
-
const findKnownProvider = (name, strategy) => {
|
|
215
|
-
const nameLower = name.toLowerCase();
|
|
216
|
-
const strategyLower = strategy?.toLowerCase();
|
|
217
|
-
// First check exact match on strategy
|
|
218
|
-
if (strategyLower && knownProviders.includes(strategyLower)) {
|
|
219
|
-
return strategyLower;
|
|
220
|
-
}
|
|
221
|
-
// Then check exact match on name
|
|
222
|
-
if (knownProviders.includes(nameLower)) {
|
|
223
|
-
return nameLower;
|
|
224
|
-
}
|
|
225
|
-
// Check if name contains a known provider (e.g., "Vipps Login" contains "vipps")
|
|
226
|
-
for (const known of knownProviders) {
|
|
227
|
-
if (nameLower.includes(known)) {
|
|
228
|
-
return known;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
return null;
|
|
232
|
-
};
|
|
233
|
-
// Map provider IDs to display names
|
|
234
|
-
const getProviderDisplayName = (provider) => {
|
|
235
|
-
// First check provider_details
|
|
212
|
+
// Get button text from provider_details (already contains the full button text from server)
|
|
213
|
+
const getButtonText = (provider) => {
|
|
236
214
|
const details = detailsMap.get(provider);
|
|
237
215
|
if (details?.display_name) {
|
|
238
216
|
return details.display_name;
|
|
239
217
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
linkedin: "LinkedIn",
|
|
246
|
-
apple: "Apple",
|
|
247
|
-
microsoft: "Microsoft",
|
|
248
|
-
windowslive: "Microsoft",
|
|
249
|
-
amazon: "Amazon",
|
|
250
|
-
dropbox: "Dropbox",
|
|
251
|
-
bitbucket: "Bitbucket",
|
|
252
|
-
spotify: "Spotify",
|
|
253
|
-
slack: "Slack",
|
|
254
|
-
discord: "Discord",
|
|
255
|
-
twitch: "Twitch",
|
|
256
|
-
line: "LINE",
|
|
257
|
-
shopify: "Shopify",
|
|
258
|
-
paypal: "PayPal",
|
|
259
|
-
"paypal-sandbox": "PayPal",
|
|
260
|
-
box: "Box",
|
|
261
|
-
salesforce: "Salesforce",
|
|
262
|
-
"salesforce-sandbox": "Salesforce",
|
|
263
|
-
yahoo: "Yahoo",
|
|
264
|
-
auth0: "Auth0",
|
|
265
|
-
vipps: "Vipps",
|
|
266
|
-
};
|
|
267
|
-
return (displayNames[provider.toLowerCase()] ||
|
|
268
|
-
provider
|
|
269
|
-
.split("-")
|
|
270
|
-
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
271
|
-
.join(" "));
|
|
218
|
+
// Fallback: use provider name with basic formatting
|
|
219
|
+
return provider
|
|
220
|
+
.split("-")
|
|
221
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
222
|
+
.join(" ");
|
|
272
223
|
};
|
|
273
|
-
// Get provider icon
|
|
224
|
+
// Get provider icon from provider_details icon_url
|
|
274
225
|
const getProviderIcon = (provider) => {
|
|
275
|
-
// First check if we have a custom icon URL from provider_details
|
|
276
226
|
const details = detailsMap.get(provider);
|
|
277
227
|
if (details?.icon_url) {
|
|
278
228
|
return (h("img", { class: "social-icon", src: details.icon_url, alt: details.display_name || provider }));
|
|
279
229
|
}
|
|
280
|
-
//
|
|
281
|
-
|
|
282
|
-
const p = knownProvider || provider.toLowerCase();
|
|
283
|
-
if (p === "google-oauth2" || p === "google") {
|
|
284
|
-
return (h("svg", { class: "social-icon", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, h("path", { d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z", fill: "#4285F4" }), h("path", { d: "M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z", fill: "#34A853" }), h("path", { d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z", fill: "#FBBC05" }), h("path", { d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z", fill: "#EA4335" })));
|
|
285
|
-
}
|
|
286
|
-
if (p === "facebook") {
|
|
287
|
-
return (h("svg", { class: "social-icon", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, h("path", { d: "M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z", fill: "#1877F2" })));
|
|
288
|
-
}
|
|
289
|
-
if (p === "apple") {
|
|
290
|
-
return (h("svg", { class: "social-icon", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, h("path", { d: "M17.05 20.28c-.98.95-2.05.8-3.08.35-1.09-.46-2.09-.48-3.24 0-1.44.62-2.2.44-3.06-.35C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09l.01-.01zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z", fill: "#000000" })));
|
|
291
|
-
}
|
|
292
|
-
if (p === "github") {
|
|
293
|
-
return (h("svg", { class: "social-icon", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, h("path", { d: "M12 0C5.374 0 0 5.373 0 12c0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23A11.509 11.509 0 0112 5.803c1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576C20.566 21.797 24 17.3 24 12c0-6.627-5.373-12-12-12z", fill: "#181717" })));
|
|
294
|
-
}
|
|
295
|
-
if (p === "microsoft" || p === "windowslive") {
|
|
296
|
-
return (h("svg", { class: "social-icon", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, h("path", { d: "M0 0h11.377v11.372H0V0z", fill: "#f25022" }), h("path", { d: "M12.623 0H24v11.372H12.623V0z", fill: "#7fba00" }), h("path", { d: "M0 12.623h11.377V24H0v-11.377z", fill: "#00a4ef" }), h("path", { d: "M12.623 12.623H24V24H12.623v-11.377z", fill: "#ffb900" })));
|
|
297
|
-
}
|
|
298
|
-
if (p === "linkedin") {
|
|
299
|
-
return (h("svg", { class: "social-icon", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, h("path", { d: "M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z", fill: "#0A66C2" })));
|
|
300
|
-
}
|
|
301
|
-
if (p === "vipps") {
|
|
302
|
-
return (h("svg", { class: "social-icon", viewBox: "0 0 48 48", xmlns: "http://www.w3.org/2000/svg" }, h("path", { fill: "#FF5B24", d: "M3.5,8h41c1.9,0,3.5,1.6,3.5,3.5v25c0,1.9-1.6,3.5-3.5,3.5h-41C1.6,40,0,38.4,0,36.5v-25C0,9.6,1.6,8,3.5,8z" }), h("path", { fill: "#FFFFFF", d: "M27.9,20.3c1.4,0,2.6-1,2.6-2.5c0-1.5-1.2-2.5-2.6-2.5c-1.4,0-2.6,1-2.6,2.5C25.3,19.2,26.5,20.3,27.9,20.3z" }), h("path", { fill: "#FFFFFF", d: "M31.2,24.4c-1.7,2.2-3.5,3.8-6.7,3.8c-3.2,0-5.8-2-7.7-4.8c-0.8-1.2-2-1.4-2.9-0.8c-0.8,0.6-1,1.8-0.3,2.9c2.7,4.1,6.5,6.6,10.9,6.6c4,0,7.2-2,9.6-5.2c0.9-1.2,0.9-2.5,0-3.1C33.3,22.9,32.1,23.2,31.2,24.4z" })));
|
|
303
|
-
}
|
|
304
|
-
// Default: generic globe icon for unknown providers
|
|
305
|
-
return (h("svg", { class: "social-icon", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, h("circle", { cx: "12", cy: "12", r: "10", fill: "none", stroke: "#666", "stroke-width": "2" }), h("path", { d: "M2 12h20M12 2c-2.5 2.5-4 5.5-4 10s1.5 7.5 4 10c2.5-2.5 4-5.5 4-10s-1.5-7.5-4-10z", fill: "none", stroke: "#666", "stroke-width": "2" })));
|
|
230
|
+
// No icon provided - return null (button will just show text)
|
|
231
|
+
return null;
|
|
306
232
|
};
|
|
307
|
-
return (h("div", { class: "social-buttons", part: "social-buttons" }, providers.map((provider) =>
|
|
233
|
+
return (h("div", { class: "social-buttons", part: "social-buttons" }, providers.map((provider) => {
|
|
234
|
+
const safeProvider = this.sanitizeForCssToken(provider);
|
|
235
|
+
const icon = getProviderIcon(provider);
|
|
236
|
+
return (h("button", { type: "button", class: `btn btn-secondary btn-social btn-social-${safeProvider}${icon ? "" : " no-icon"}`, part: `button button-secondary button-social button-social-${safeProvider}`, "data-provider": provider, disabled: this.disabled, onClick: (e) => this.handleButtonClick(e, "SOCIAL", provider), key: provider }, icon, h("span", { part: "button-social-text" }, getButtonText(provider))));
|
|
237
|
+
})));
|
|
308
238
|
}
|
|
309
239
|
// ===========================================================================
|
|
310
240
|
// Main Render
|