@authhero/widget 0.37.1 → 0.38.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-b5f14fa6.entry.js +1 -0
- package/dist/authhero-widget/p-f94037cd.entry.js +1 -0
- package/dist/cjs/authhero-node.cjs.entry.js +458 -13
- package/dist/cjs/authhero-widget.cjs.entry.js +79 -10
- package/dist/cjs/authhero-widget.cjs.js +1 -1
- package/dist/cjs/index.cjs.js +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/collection/components/authhero-node/authhero-node.css +94 -0
- package/dist/collection/components/authhero-node/authhero-node.js +302 -13
- package/dist/collection/components/authhero-widget/authhero-widget.js +98 -10
- package/dist/collection/utils/date-format.js +176 -0
- package/dist/components/authhero-node.js +1 -1
- package/dist/components/authhero-widget.js +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/p-C9ZfIQiS.js +1 -0
- package/dist/esm/authhero-node.entry.js +458 -13
- package/dist/esm/authhero-widget.entry.js +79 -10
- package/dist/esm/authhero-widget.js +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/types/components/authhero-node/authhero-node.d.ts +83 -0
- package/dist/types/components/authhero-widget/authhero-widget.d.ts +19 -0
- package/dist/types/components.d.ts +18 -0
- package/dist/types/utils/date-format.d.ts +52 -0
- package/hydrate/index.js +541 -24
- package/hydrate/index.mjs +541 -24
- package/package.json +2 -2
- package/dist/authhero-widget/p-cdfc4555.entry.js +0 -1
- package/dist/authhero-widget/p-e95c436f.entry.js +0 -1
- package/dist/components/p-BP46GHTc.js +0 -1
|
@@ -8,6 +8,27 @@ import { sanitizeHtml } from "../../utils/sanitize-html";
|
|
|
8
8
|
* buttons. Used by long pick-one screens such as tenant selection.
|
|
9
9
|
*/
|
|
10
10
|
const CHOICE_LIST_SEARCH_THRESHOLD = 5;
|
|
11
|
+
/**
|
|
12
|
+
* Component types the widget renders as something the user can actually fill
|
|
13
|
+
* in. Only these gate the primary action button: types that render nothing
|
|
14
|
+
* (CARDS, FILE, RECAPTCHA, …) can carry `required` in the schema too, and
|
|
15
|
+
* gating on them would leave Continue disabled with no way to satisfy it.
|
|
16
|
+
*/
|
|
17
|
+
const FILLABLE_FIELD_TYPES = new Set([
|
|
18
|
+
"TEXT",
|
|
19
|
+
"EMAIL",
|
|
20
|
+
"CODE",
|
|
21
|
+
"PASSWORD",
|
|
22
|
+
"NUMBER",
|
|
23
|
+
"TEL",
|
|
24
|
+
"URL",
|
|
25
|
+
"DATE",
|
|
26
|
+
"BOOLEAN",
|
|
27
|
+
"LEGAL",
|
|
28
|
+
"COUNTRY",
|
|
29
|
+
"DROPDOWN",
|
|
30
|
+
"CHOICE",
|
|
31
|
+
]);
|
|
11
32
|
export class AuthheroWidget {
|
|
12
33
|
el;
|
|
13
34
|
/**
|
|
@@ -90,6 +111,13 @@ export class AuthheroWidget {
|
|
|
90
111
|
* @default false (same as autoSubmit when not specified)
|
|
91
112
|
*/
|
|
92
113
|
autoNavigate;
|
|
114
|
+
/**
|
|
115
|
+
* BCP-47 locale for locale-dependent field layout, e.g. whether a DATE
|
|
116
|
+
* field reads DD/MM/YYYY, MM/DD/YYYY or YYYY-MM-DD. Resolve it server-side
|
|
117
|
+
* and pass it in so the server-rendered markup and the hydrated one agree;
|
|
118
|
+
* screen text itself is already localized by the server.
|
|
119
|
+
*/
|
|
120
|
+
locale;
|
|
93
121
|
/**
|
|
94
122
|
* Internal parsed screen state.
|
|
95
123
|
*/
|
|
@@ -190,14 +218,19 @@ export class AuthheroWidget {
|
|
|
190
218
|
initFormDataFromDefaults(screen) {
|
|
191
219
|
const defaults = {};
|
|
192
220
|
for (const comp of screen.components || []) {
|
|
193
|
-
if ("config" in comp
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
221
|
+
if (!("config" in comp) || !comp.config)
|
|
222
|
+
continue;
|
|
223
|
+
if (!("default_value" in comp.config))
|
|
224
|
+
continue;
|
|
225
|
+
const val = comp.config.default_value;
|
|
226
|
+
if (typeof val === "string" && val !== "") {
|
|
227
|
+
defaults[comp.id] = val;
|
|
228
|
+
}
|
|
229
|
+
else if (typeof val === "boolean") {
|
|
230
|
+
// A BOOLEAN's default decides whether the checkbox renders ticked, so
|
|
231
|
+
// seed the matching value — otherwise a field the user never touches
|
|
232
|
+
// submits nothing and the screen's state is lost.
|
|
233
|
+
defaults[comp.id] = val ? "true" : "false";
|
|
201
234
|
}
|
|
202
235
|
}
|
|
203
236
|
if (Object.keys(defaults).length > 0) {
|
|
@@ -1198,6 +1231,11 @@ export class AuthheroWidget {
|
|
|
1198
1231
|
handleButtonClick = (detail) => {
|
|
1199
1232
|
// If this is a submit button click, trigger form submission
|
|
1200
1233
|
if (detail.type === "submit") {
|
|
1234
|
+
// Enter in a text field submits too, so the required-field gate has to
|
|
1235
|
+
// live here and not only on the button's disabled state.
|
|
1236
|
+
if (this._screen && this.hasUnfilledRequiredFields(this._screen)) {
|
|
1237
|
+
return;
|
|
1238
|
+
}
|
|
1201
1239
|
// For GET screens (or missing method), navigate directly — no form submission needed
|
|
1202
1240
|
if ((!this._screen?.method ||
|
|
1203
1241
|
this._screen.method.toUpperCase() === "GET") &&
|
|
@@ -1386,6 +1424,32 @@ export class AuthheroWidget {
|
|
|
1386
1424
|
isDividerComponent(component) {
|
|
1387
1425
|
return component.type === "DIVIDER";
|
|
1388
1426
|
}
|
|
1427
|
+
/**
|
|
1428
|
+
* Whether a required component holds a value the user has supplied.
|
|
1429
|
+
*/
|
|
1430
|
+
isRequiredFieldFilled(component) {
|
|
1431
|
+
const value = this.formData[component.id];
|
|
1432
|
+
// Checkboxes are only "filled" when ticked. A BOOLEAN's default_value is
|
|
1433
|
+
// seeded into formData, so it needs no separate handling here.
|
|
1434
|
+
if (component.type === "BOOLEAN" || component.type === "LEGAL") {
|
|
1435
|
+
return value === "true";
|
|
1436
|
+
}
|
|
1437
|
+
return typeof value === "string" && value.trim() !== "";
|
|
1438
|
+
}
|
|
1439
|
+
/**
|
|
1440
|
+
* Whether the screen still has required fields the user has not filled in.
|
|
1441
|
+
* Used to hold the primary action button disabled: the widget submits via
|
|
1442
|
+
* its own handler rather than a native form submit, so the browser's
|
|
1443
|
+
* constraint validation never runs and an empty required field would
|
|
1444
|
+
* otherwise only surface as a server error after a round trip.
|
|
1445
|
+
*/
|
|
1446
|
+
hasUnfilledRequiredFields(screen) {
|
|
1447
|
+
return (screen.components ?? []).some((component) => component.visible !== false &&
|
|
1448
|
+
"required" in component &&
|
|
1449
|
+
component.required === true &&
|
|
1450
|
+
FILLABLE_FIELD_TYPES.has(component.type) &&
|
|
1451
|
+
!this.isRequiredFieldFilled(component));
|
|
1452
|
+
}
|
|
1389
1453
|
/**
|
|
1390
1454
|
* Visible label of a choice button, used to filter searchable choice lists.
|
|
1391
1455
|
*/
|
|
@@ -1421,6 +1485,9 @@ export class AuthheroWidget {
|
|
|
1421
1485
|
const choiceButtons = fieldComponents.filter((c) => c.type === "NEXT_BUTTON");
|
|
1422
1486
|
const isSearchableChoiceList = choiceButtons.length === fieldComponents.length &&
|
|
1423
1487
|
choiceButtons.length > CHOICE_LIST_SEARCH_THRESHOLD;
|
|
1488
|
+
// Hold the primary action button disabled until every required field has
|
|
1489
|
+
// a value.
|
|
1490
|
+
const requiredFieldsMissing = this.hasUnfilledRequiredFields(screen);
|
|
1424
1491
|
const filterQuery = this.listFilter.trim().toLowerCase();
|
|
1425
1492
|
const visibleChoiceButtons = isSearchableChoiceList && filterQuery
|
|
1426
1493
|
? choiceButtons.filter((c) => this.getChoiceButtonText(c).toLowerCase().includes(filterQuery))
|
|
@@ -1455,7 +1522,7 @@ export class AuthheroWidget {
|
|
|
1455
1522
|
};
|
|
1456
1523
|
// Get logo URL from theme.widget (takes precedence) or branding
|
|
1457
1524
|
const logoUrl = this._theme?.widget?.logo_url || this._branding?.logo_url;
|
|
1458
|
-
return (h("div", { class: "widget-container", part: "container", "data-authstack-container": true }, h("header", { class: "widget-header", part: "header" }, logoUrl && (h("div", { class: "logo-wrapper", part: "logo-wrapper" }, h("img", { class: "logo", part: "logo", src: logoUrl, alt: "Logo" }))), screen.title && (h("h1", { class: "title", part: "title", innerHTML: sanitizeHtml(screen.title) })), screen.description && (h("p", { class: "description", part: "description", innerHTML: sanitizeHtml(screen.description) }))), h("div", { class: "widget-body", part: "body" }, screenErrors.map((err) => (h("div", { class: "message message-error", part: "message message-error", key: err.id ?? err.text }, err.text))), screenSuccesses.map((msg) => (h("div", { class: "message message-success", part: "message message-success", key: msg.id ?? msg.text }, msg.text))), h("form", { onSubmit: this.handleSubmit, action: screen.action, method: screen.method || "POST", part: "form" }, hiddenComponents.map((c) => (h("input", { type: "hidden", name: c.id, id: c.id, key: c.id, value: this.formData[c.id] || "" }))), h("div", { class: "form-content" }, socialComponents.length > 0 && (h("div", { class: "social-section", part: "social-section" }, socialComponents.map((component) => (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 &&
|
|
1525
|
+
return (h("div", { class: "widget-container", part: "container", "data-authstack-container": true }, h("header", { class: "widget-header", part: "header" }, logoUrl && (h("div", { class: "logo-wrapper", part: "logo-wrapper" }, h("img", { class: "logo", part: "logo", src: logoUrl, alt: "Logo" }))), screen.title && (h("h1", { class: "title", part: "title", innerHTML: sanitizeHtml(screen.title) })), screen.description && (h("p", { class: "description", part: "description", innerHTML: sanitizeHtml(screen.description) }))), h("div", { class: "widget-body", part: "body" }, screenErrors.map((err) => (h("div", { class: "message message-error", part: "message message-error", key: err.id ?? err.text }, err.text))), screenSuccesses.map((msg) => (h("div", { class: "message message-success", part: "message message-success", key: msg.id ?? msg.text }, msg.text))), h("form", { onSubmit: this.handleSubmit, action: screen.action, method: screen.method || "POST", part: "form" }, hiddenComponents.map((c) => (h("input", { type: "hidden", name: c.id, id: c.id, key: c.id, value: this.formData[c.id] || "" }))), h("div", { class: "form-content" }, socialComponents.length > 0 && (h("div", { class: "social-section", part: "social-section" }, socialComponents.map((component) => (h("authhero-node", { key: component.id, component: component, locale: this.locale, 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 &&
|
|
1459
1526
|
fieldComponents.length > 0 &&
|
|
1460
1527
|
hasDivider && (h("div", { class: "divider", part: "divider" }, h("span", { class: "divider-text" }, dividerText))), h("div", { class: "fields-section", part: "fields-section" }, isSearchableChoiceList && (h("input", { type: "text", class: "choice-list-search", part: "choice-list-search", placeholder: "Search", "aria-label": "Search", autocomplete: "off", value: this.listFilter, onInput: (e) => (this.listFilter = e.target.value), onKeyDown: (e) => {
|
|
1461
1528
|
// The search box lives inside the form; Enter would
|
|
@@ -1468,7 +1535,9 @@ export class AuthheroWidget {
|
|
|
1468
1535
|
? "fields-list fields-list-scroll"
|
|
1469
1536
|
: "fields-list" }, (isSearchableChoiceList
|
|
1470
1537
|
? visibleChoiceButtons
|
|
1471
|
-
: fieldComponents).map((component) => (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
|
|
1538
|
+
: fieldComponents).map((component) => (h("authhero-node", { key: component.id, component: component, locale: this.locale, value: this.formData[component.id], onFieldChange: (e) => this.handleInputChange(e.detail.id, e.detail.value), onButtonClick: (e) => this.handleButtonClick(e.detail), disabled: this.loading ||
|
|
1539
|
+
(component.type === "NEXT_BUTTON" &&
|
|
1540
|
+
requiredFieldsMissing) }))), isSearchableChoiceList &&
|
|
1472
1541
|
visibleChoiceButtons.length === 0 && (h("div", { class: "choice-list-empty", part: "choice-list-empty" }, "No matches")))))), screen.links && screen.links.length > 0 && (h("div", { class: "links", part: "links" }, screen.links.map((link) => (h("span", { class: "link-wrapper", part: "link-wrapper", key: link.id ?? link.href }, link.linkText ? (h("span", null, link.text, " ", h("a", { href: link.href, class: "link", part: "link", onClick: (e) => this.handleLinkClick(e, {
|
|
1473
1542
|
id: link.id,
|
|
1474
1543
|
href: link.href,
|
|
@@ -1788,6 +1857,25 @@ export class AuthheroWidget {
|
|
|
1788
1857
|
"setter": false,
|
|
1789
1858
|
"reflect": false,
|
|
1790
1859
|
"attribute": "auto-navigate"
|
|
1860
|
+
},
|
|
1861
|
+
"locale": {
|
|
1862
|
+
"type": "string",
|
|
1863
|
+
"mutable": false,
|
|
1864
|
+
"complexType": {
|
|
1865
|
+
"original": "string",
|
|
1866
|
+
"resolved": "string | undefined",
|
|
1867
|
+
"references": {}
|
|
1868
|
+
},
|
|
1869
|
+
"required": false,
|
|
1870
|
+
"optional": true,
|
|
1871
|
+
"docs": {
|
|
1872
|
+
"tags": [],
|
|
1873
|
+
"text": "BCP-47 locale for locale-dependent field layout, e.g. whether a DATE\nfield reads DD/MM/YYYY, MM/DD/YYYY or YYYY-MM-DD. Resolve it server-side\nand pass it in so the server-rendered markup and the hydrated one agree;\nscreen text itself is already localized by the server."
|
|
1874
|
+
},
|
|
1875
|
+
"getter": false,
|
|
1876
|
+
"setter": false,
|
|
1877
|
+
"reflect": false,
|
|
1878
|
+
"attribute": "locale"
|
|
1791
1879
|
}
|
|
1792
1880
|
};
|
|
1793
1881
|
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Locale-aware layout for the segmented DATE input.
|
|
3
|
+
*
|
|
4
|
+
* The segment order is resolved from a static table rather than from
|
|
5
|
+
* `Intl.DateTimeFormat`, deliberately: the widget is server-rendered and then
|
|
6
|
+
* hydrated in the browser, and the two runtimes do not ship the same ICU data
|
|
7
|
+
* (a Workers runtime commonly falls back to en-US ordering). A static table
|
|
8
|
+
* gives the server and the client the same answer, so the hydrated DOM matches
|
|
9
|
+
* the rendered one.
|
|
10
|
+
*/
|
|
11
|
+
/** Languages that write dates big-endian: year, month, day. */
|
|
12
|
+
const YEAR_FIRST_LANGUAGES = new Set([
|
|
13
|
+
"bo",
|
|
14
|
+
"dz",
|
|
15
|
+
"hu",
|
|
16
|
+
"ja",
|
|
17
|
+
"ko",
|
|
18
|
+
"lt",
|
|
19
|
+
"mn",
|
|
20
|
+
"sv",
|
|
21
|
+
"ug",
|
|
22
|
+
"zh",
|
|
23
|
+
]);
|
|
24
|
+
/**
|
|
25
|
+
* Regions that write month before day. Month-first is essentially a US
|
|
26
|
+
* convention plus the places that adopted it.
|
|
27
|
+
*/
|
|
28
|
+
const MONTH_FIRST_REGIONS = new Set(["us", "ph", "fm", "mh", "pw", "as", "gu"]);
|
|
29
|
+
/**
|
|
30
|
+
* Locales whose language is normally year-first but which write dates
|
|
31
|
+
* day-first in a particular region — Finland-Swedish is d.m.yyyy, unlike
|
|
32
|
+
* Sweden-Swedish.
|
|
33
|
+
*/
|
|
34
|
+
const DAY_FIRST_TAGS = new Set(["sv-fi"]);
|
|
35
|
+
const DEFAULT_TOKENS = {
|
|
36
|
+
day: "DD",
|
|
37
|
+
month: "MM",
|
|
38
|
+
year: "YYYY",
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Split a BCP-47 tag into a lowercase language subtag and, when present, a
|
|
42
|
+
* two-letter region subtag. Script and variant subtags are ignored.
|
|
43
|
+
*/
|
|
44
|
+
function parseTag(locale) {
|
|
45
|
+
const tag = (locale || "").toLowerCase().replace(/_/g, "-");
|
|
46
|
+
const parts = tag.split("-").filter(Boolean);
|
|
47
|
+
const language = parts[0] || "";
|
|
48
|
+
const region = parts.slice(1).find((part) => /^[a-z]{2}$/.test(part));
|
|
49
|
+
return { language, region };
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Resolve the segment order for a locale. Falls back to day-month-year, which
|
|
53
|
+
* is what most of the world writes.
|
|
54
|
+
*/
|
|
55
|
+
export function getDateOrder(locale) {
|
|
56
|
+
const { language, region } = parseTag(locale);
|
|
57
|
+
if (region && MONTH_FIRST_REGIONS.has(region)) {
|
|
58
|
+
return ["month", "day", "year"];
|
|
59
|
+
}
|
|
60
|
+
if (region && DAY_FIRST_TAGS.has(`${language}-${region}`)) {
|
|
61
|
+
return ["day", "month", "year"];
|
|
62
|
+
}
|
|
63
|
+
if (YEAR_FIRST_LANGUAGES.has(language)) {
|
|
64
|
+
return ["year", "month", "day"];
|
|
65
|
+
}
|
|
66
|
+
// A bare "en" carries no region — treat it the way Intl does and assume
|
|
67
|
+
// en-US. Regional English (en-gb, en-au, …) falls through to day-first.
|
|
68
|
+
if (language === "en" && !region) {
|
|
69
|
+
return ["month", "day", "year"];
|
|
70
|
+
}
|
|
71
|
+
return ["day", "month", "year"];
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Parse an explicit format string from the component config, e.g.
|
|
75
|
+
* "DD/MM/YYYY" or "YYYY-MM-DD". Returns null when the string does not name
|
|
76
|
+
* all three segments.
|
|
77
|
+
*/
|
|
78
|
+
function parseFormat(format) {
|
|
79
|
+
const matches = format.match(/y+|m+|d+/gi);
|
|
80
|
+
if (!matches)
|
|
81
|
+
return null;
|
|
82
|
+
const order = [];
|
|
83
|
+
const tokens = { ...DEFAULT_TOKENS };
|
|
84
|
+
for (const match of matches) {
|
|
85
|
+
const initial = match[0].toLowerCase();
|
|
86
|
+
const segment = initial === "y" ? "year" : initial === "m" ? "month" : "day";
|
|
87
|
+
if (order.includes(segment))
|
|
88
|
+
continue;
|
|
89
|
+
order.push(segment);
|
|
90
|
+
// A "YY" format still collects a four-digit year — the segment holds four
|
|
91
|
+
// characters and `toIsoDate` rejects anything shorter, with a two-digit
|
|
92
|
+
// entry expanded on blur. Showing "YY" as the placeholder would promise an
|
|
93
|
+
// input the field does not accept, so short year tokens are widened.
|
|
94
|
+
tokens[segment] =
|
|
95
|
+
segment === "year" && match.length < 4 ? DEFAULT_TOKENS.year : match;
|
|
96
|
+
}
|
|
97
|
+
if (order.length !== 3)
|
|
98
|
+
return null;
|
|
99
|
+
const separator = format.match(/[^a-z\s]/i)?.[0] ?? "/";
|
|
100
|
+
return { order, tokens, separator };
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Resolve the full layout for a DATE field. An explicit `config.format` wins;
|
|
104
|
+
* otherwise the locale decides the order.
|
|
105
|
+
*/
|
|
106
|
+
export function getDateLayout(format, locale) {
|
|
107
|
+
if (format) {
|
|
108
|
+
const parsed = parseFormat(format);
|
|
109
|
+
if (parsed)
|
|
110
|
+
return parsed;
|
|
111
|
+
}
|
|
112
|
+
const order = getDateOrder(locale);
|
|
113
|
+
return {
|
|
114
|
+
order,
|
|
115
|
+
tokens: DEFAULT_TOKENS,
|
|
116
|
+
separator: order[0] === "year" ? "-" : "/",
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/** Number of days in a given month, honouring leap years. */
|
|
120
|
+
export function daysInMonth(year, month) {
|
|
121
|
+
if (month < 1 || month > 12)
|
|
122
|
+
return 0;
|
|
123
|
+
return new Date(Date.UTC(year, month, 0)).getUTCDate();
|
|
124
|
+
}
|
|
125
|
+
/** Split an ISO "YYYY-MM-DD" value into its segments. */
|
|
126
|
+
export function parseIsoDate(value) {
|
|
127
|
+
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec((value || "").trim());
|
|
128
|
+
if (!match)
|
|
129
|
+
return null;
|
|
130
|
+
return { year: match[1], month: match[2], day: match[3] };
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Build an ISO "YYYY-MM-DD" string from segment values. Returns "" unless all
|
|
134
|
+
* three segments are complete and form a real calendar date — a half-filled or
|
|
135
|
+
* impossible date (31 February) is not a value worth submitting.
|
|
136
|
+
*/
|
|
137
|
+
export function toIsoDate(segments) {
|
|
138
|
+
const { year, month, day } = segments;
|
|
139
|
+
if (year.length !== 4 || month.length === 0 || day.length === 0)
|
|
140
|
+
return "";
|
|
141
|
+
const y = Number(year);
|
|
142
|
+
const m = Number(month);
|
|
143
|
+
const d = Number(day);
|
|
144
|
+
if (!Number.isInteger(y) || !Number.isInteger(m) || !Number.isInteger(d)) {
|
|
145
|
+
return "";
|
|
146
|
+
}
|
|
147
|
+
if (m < 1 || m > 12)
|
|
148
|
+
return "";
|
|
149
|
+
if (d < 1 || d > daysInMonth(y, m))
|
|
150
|
+
return "";
|
|
151
|
+
return `${String(y).padStart(4, "0")}-${String(m).padStart(2, "0")}-${String(d).padStart(2, "0")}`;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Expand a two-digit year into the most recent matching year at or before
|
|
155
|
+
* `anchorYear` — "85" becomes 1985, "05" becomes 2005. Anything that is not
|
|
156
|
+
* exactly two digits is returned unchanged, so a fully typed year is never
|
|
157
|
+
* second-guessed.
|
|
158
|
+
*/
|
|
159
|
+
export function expandTwoDigitYear(year, anchorYear) {
|
|
160
|
+
if (!/^\d{2}$/.test(year))
|
|
161
|
+
return year;
|
|
162
|
+
const century = Math.floor(anchorYear / 100) * 100;
|
|
163
|
+
const candidate = century + Number(year);
|
|
164
|
+
return String(candidate > anchorYear ? candidate - 100 : candidate);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* The latest year a two-digit entry may expand to. `config.max` pins it when
|
|
168
|
+
* the field has an upper bound; otherwise we assume a date in the past (the
|
|
169
|
+
* birthdate case) and anchor on the current year.
|
|
170
|
+
*/
|
|
171
|
+
export function resolveYearAnchor(max, today) {
|
|
172
|
+
const parsed = parseIsoDate(max);
|
|
173
|
+
if (parsed)
|
|
174
|
+
return Number(parsed.year);
|
|
175
|
+
return today.getUTCFullYear();
|
|
176
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{A as o,d as s}from"./p-
|
|
1
|
+
import{A as o,d as s}from"./p-C9ZfIQiS.js";const p=o,r=s;export{p as AuthheroNode,r as defineCustomElement}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t,p as e,H as i,c as o,h as n}from"./p-cKZ5hFj1.js";import{d as r}from"./p-BP46GHTc.js";function s(t){const e=t.match(/^#([0-9a-f]{3})$/i)||t.match(/^#([0-9a-f]{6})$/i);if(!e)return null;let i=e[1];3===i.length&&(i=i[0]+i[0]+i[1]+i[1]+i[2]+i[2]);const o=parseInt(i,16);return[o>>16&255,o>>8&255,255&o]}function a(t){const e=s(t);if(!e)return NaN;const[i,o,n]=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*o+.0722*n}function c(t,e){const i=a(t),o=a(e);return isNaN(i)||isNaN(o)?NaN:(Math.max(i,o)+.05)/(Math.min(i,o)+.05)}function h(t,e="light"){const i=c(t,"#000000"),o=c(t,"#ffffff");return"light"===e?i>1.35*o?"#000000":"#ffffff":1.35*i>o?"#000000":"#ffffff"}function l(t,e){const i=s(t);if(!i)return t;const[o,n,r]=i,a=t=>Math.max(0,Math.round(t*(1-e))).toString(16).padStart(2,"0");return`#${a(o)}${a(n)}${a(r)}`}function d(t,e){const i=s(t);if(!i)return t;const[o,n,r]=i,a=t=>Math.min(255,Math.round(t+(255-t)*e)).toString(16).padStart(2,"0");return`#${a(o)}${a(n)}${a(r)}`}function f(t,e,i=4.5){if(c(t,e)>=i)return t;const o=a(e)>.5;let n=t;for(let r=1;r<=10;r++)if(n=o?l(t,.1*r):d(t,.1*r),c(n,e)>=i)return n;return o?"#000000":"#ffffff"}function u(t,e){if(void 0!==e)return e+"px";switch(t){case"pill":return"9999px";case"rounded":return"8px";case"sharp":return"0";default:return}}function p(t){if(!t)return{};const e={};if(t.colors?.primary&&(e["--ah-color-primary"]=t.colors.primary),t.colors?.page_background){const i=t.colors.page_background;"solid"===i.type&&i.start?e["--ah-page-bg"]=i.start:"gradient"===i.type&&i.start&&i.end&&(e["--ah-page-bg"]=`linear-gradient(${i.angle_deg??180}deg, ${i.start}, ${i.end})`)}return t.logo_url&&(e["--ah-logo-url"]=`url(${t.logo_url})`),t.font?.url&&(e["--ah-font-url"]=t.font.url),e}function g(t){if(!t)return{};const e={};if(t.borders){const i=t.borders;void 0!==i.widget_corner_radius&&(e["--ah-widget-radius"]=i.widget_corner_radius+"px"),void 0!==i.widget_border_weight&&(e["--ah-widget-border-width"]=i.widget_border_weight+"px"),!1===i.show_widget_shadow&&(e["--ah-widget-shadow"]="none");const o=u(i.buttons_style,i.button_border_radius);o&&(e["--ah-btn-radius"]=o),void 0!==i.button_border_weight&&(e["--ah-btn-border-width"]=i.button_border_weight+"px");const n=u(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,i.primary_button_label)e["--ah-color-text-on-primary"]=i.primary_button_label;else{e["--ah-color-text-on-primary"]=h(i.primary_button,"light");const t=h(i.primary_button,"dark");t!==e["--ah-color-text-on-primary"]&&(e["--ah-color-text-on-primary-dark"]=t)}else i.primary_button_label&&(e["--ah-color-text-on-primary"]=i.primary_button_label);i.secondary_button_border&&(e["--ah-btn-secondary-border"]=i.secondary_button_border),i.secondary_button_label&&(e["--ah-btn-secondary-text"]=i.secondary_button_label),i.body_text&&(e["--ah-color-text"]=i.body_text),i.header&&(e["--ah-color-text-header"]=i.header),i.input_labels_placeholders&&(e["--ah-color-text-label"]=i.input_labels_placeholders,e["--ah-color-text-muted"]=i.input_labels_placeholders),i.input_filled_text&&(e["--ah-color-input-text"]=i.input_filled_text),i.widget_background&&(e["--ah-color-bg"]=i.widget_background),i.input_background&&(e["--ah-color-input-bg"]=i.input_background),i.widget_border&&(e["--ah-widget-border-color"]=i.widget_border),i.input_border&&(e["--ah-color-border"]=i.input_border),i.links_focused_components&&(e["--ah-color-link"]=f(i.links_focused_components,i.widget_background||"#ffffff")),i.base_focus_color&&(e["--ah-color-focus-ring"]=i.base_focus_color),i.base_hover_color&&(e["--ah-color-primary-hover"]=i.base_hover_color),i.error&&(e["--ah-color-error"]=i.error),i.success&&(e["--ah-color-success"]=i.success),i.icons&&(e["--ah-color-icon"]=i.icons);const o=i.widget_background||"#ffffff",n=i.input_background||o,r=e["--ah-color-border"]||i.input_border||"#c9cace",s=c(r,o),a=c(r,n);Math.min(s,a)<3&&(e["--ah-color-border"]=f(r,s<a?o:n,3))}if(t.fonts){const i=t.fonts,o=i.reference_text_size||16,n=t=>t>=50?Math.round(t/100*o):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 m={br:[],em:[],i:[],strong:[],b:[],u:[],span:["class"],a:["href","class"]};function b(t){if(!t)return"";if(!t.includes("<"))return t;let e=t;e=e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'");for(const[t,i]of Object.entries(m)){if("br"===t){e=e.replace(/<br\s*\/?>/gi,"<br>");continue}const o=RegExp(`<${t}((?:\\s+[a-z-]+(?:="[^&]*"|='[^&]*')?)*)\\s*>`,"gi");e=e.replace(o,((e,o)=>{const n=[];if(o){const t=o.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()?w(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=RegExp(`</${t}>`,"gi");e=e.replace(n,`</${t}>`)}return e}function w(t){if(!t)return!1;if(t.startsWith("/")||t.startsWith("#")||t.startsWith("?"))return!0;try{const e=new URL(t,"https://example.com");return"http:"===e.protocol||"https:"===e.protocol}catch{return!1}}function x(t){return t.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}const v=e(class extends i{constructor(t){super(),!1!==t&&this.__registerHost(),this.__attachShadow(),this.formSubmit=o(this,"formSubmit"),this.buttonClick=o(this,"buttonClick"),this.linkClick=o(this,"linkClick"),this.navigate=o(this,"navigate"),this.flowComplete=o(this,"flowComplete"),this.flowError=o(this,"flowError"),this.screenChange=o(this,"screenChange")}get el(){return this}screen;apiUrl;baseUrl;state;screenId;watchScreenId(){this.updateDataScreenAttribute()}authParams;statePersistence="memory";storageKey="authhero_widget";branding;theme;loading=!1;autoSubmit=!1;autoNavigate;_screen;_authParams;_branding;_theme;formData={};listFilter="";conditionalMediationAbort;loadedFontUrl;formSubmit;buttonClick;linkClick;navigate;flowComplete;flowError;screenChange;watchScreen(t){if(this.conditionalMediationAbort?.abort(),this.conditionalMediationAbort=void 0,"string"==typeof t)try{this._screen=JSON.parse(t)}catch{console.error("Failed to parse screen JSON")}else this._screen=t;this._screen&&(this.formData={},this.listFilter="",this.initFormDataFromDefaults(this._screen),this.screenChange.emit(this._screen),this.updateDataScreenAttribute())}initFormDataFromDefaults(t){const e={};for(const i of t.components||[])if("config"in i&&i.config&&"default_value"in i.config&&i.config.default_value){const t=i.config.default_value;"string"==typeof t&&""!==t&&(e[i.id]=t)}Object.keys(e).length>0&&(this.formData={...e,...this.formData})}updateDataScreenAttribute(){const t=this._screen?.name||this.screenId;t?this.el.setAttribute("data-screen",t):this.el.removeAttribute("data-screen");const e=this.el.closest("[data-authhero-widget-container]");e&&(t?e.setAttribute("data-screen",t):e.removeAttribute("data-screen"))}watchBranding(t){if("string"==typeof t)try{this._branding=JSON.parse(t)}catch{console.error("Failed to parse branding JSON")}else this._branding=t;this.applyThemeStyles()}watchTheme(t){if("string"==typeof t)try{this._theme=JSON.parse(t)}catch{console.error("Failed to parse theme JSON")}else this._theme=t;this.applyThemeStyles()}watchAuthParams(t){if("string"==typeof t)try{this._authParams=JSON.parse(t)}catch{console.error("Failed to parse authParams JSON")}else this._authParams=t}applyThemeStyles(){const t=function(t,e){return{...p(t),...g(e)}}(this._branding,this._theme);!function(t,e){Object.entries(e).forEach((([e,i])=>{t.style.setProperty(e,i)}))}(this.el,t),this.loadCustomFont()}loadCustomFont(){if("undefined"==typeof document)return;const t=this._theme?.fonts?.font_url||this._branding?.font?.url;if(t===this.loadedFontUrl)return;for(const t of Array.from(document.head.querySelectorAll("link[data-authhero-font]")))t.remove();if(this.loadedFontUrl=void 0,!t)return;const e=document.createElement("link");e.rel="stylesheet",e.href=t,e.setAttribute("data-authhero-font",t),document.head.appendChild(e),this.loadedFontUrl=t}focusFirstInput(){requestAnimationFrame((()=>{const t=this.el.shadowRoot;if(!t)return;const e=t.querySelectorAll("authhero-node");for(const t of Array.from(e)){const e=t.shadowRoot;if(e){const t=e.querySelector('input:not([type="hidden"]):not([type="checkbox"]):not([disabled]), textarea:not([disabled])');if(t)return void t.focus()}}}))}pendingRenderResolvers=[];componentDidRender(){if(0===this.pendingRenderResolvers.length)return;const t=this.pendingRenderResolvers;this.pendingRenderResolvers=[],t.forEach((t=>t()))}nextRender(){return new Promise((t=>{let e=!1;const i=()=>{e||(e=!0,t())};this.pendingRenderResolvers.push(i),requestAnimationFrame((()=>requestAnimationFrame(i)))}))}async swapScreen(t){const e=this.el.shadowRoot?.querySelector(".widget-container"),i="function"==typeof window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches;if(!e||"function"!=typeof e.animate||i)return void t();const o=e.getBoundingClientRect().height;e.style.height=o+"px",e.style.overflow="hidden",t(),await this.nextRender();const n=()=>{e.style.height="",e.style.overflow=""};e.style.height="auto";const r=e.getBoundingClientRect().height;if(e.style.height=o+"px",e.getBoundingClientRect(),Math.abs(r-o)<1)return void n();const s=e.animate([{height:o+"px"},{height:r+"px"}],{duration:520,easing:"cubic-bezier(0.22, 1, 0.36, 1)"});try{await s.finished}catch{}finally{n()}}get shouldAutoNavigate(){return this.autoNavigate??this.autoSubmit}buildUrl(t){return this.baseUrl?""+new URL(t,this.baseUrl):t}loadPersistedState(){if("url"===this.statePersistence){const t=new URL(window.location.href).searchParams.get("state");t&&!this.state&&(this.state=t)}else if("session"===this.statePersistence)try{const t=sessionStorage.getItem(this.storageKey+"_state");t&&!this.state&&(this.state=t);const e=sessionStorage.getItem(this.storageKey+"_screenId");e&&!this.screenId&&(this.screenId=e)}catch{}}persistState(){if("url"===this.statePersistence){const t=new URL(window.location.href);this.state&&t.searchParams.set("state",this.state),this.screenId&&t.searchParams.set("screen",this.screenId),window.history.replaceState({},"",""+t)}else if("session"===this.statePersistence)try{this.state&&sessionStorage.setItem(this.storageKey+"_state",this.state),this.screenId&&sessionStorage.setItem(this.storageKey+"_screenId",this.screenId)}catch{}}handlePopState=t=>{if(!this.apiUrl)return;t.state?.state&&(this.state=t.state.state);const e=t.state?.screen??this.extractScreenIdFromHref(location.href);e&&this.fetchScreen(e)};connectedCallback(){window.addEventListener("popstate",this.handlePopState)}disconnectedCallback(){window.removeEventListener("popstate",this.handlePopState),this.conditionalMediationAbort?.abort(),this.conditionalMediationAbort=void 0}readJsonScript(t){if(!this.el)return;const e=this.el.querySelector(`script[type="application/json"][data-authhero="${t}"]`);return e?.textContent??void 0}async componentWillLoad(){if(!this._screen){const t=this.screen||this.readJsonScript("screen")||this.el?.getAttribute("screen");t&&this.watchScreen(t)}this._branding||this.watchBranding(this.branding??this.readJsonScript("branding")),this._theme||this.watchTheme(this.theme??this.readJsonScript("theme")),this._authParams||this.watchAuthParams(this.authParams??this.readJsonScript("auth-params")),this.loadPersistedState(),this.apiUrl&&!this._screen&&await this.fetchScreen(this.screenId)}async fetchScreen(t,e){if(!this.apiUrl)return!1;const i=t||this.screenId;let o=this.apiUrl;i&&o.includes("{screenId}")&&(o=o.replace("{screenId}",encodeURIComponent(i)));const n=new URL(o,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 this.listFilter="",i&&i!==this.screenId&&(this.screenId=i),this.initFormDataFromDefaults(this._screen),this.screenChange.emit(this._screen),this.updateDataScreenAttribute(),this.persistState(),this.focusFirstInput(),e.ceremony&&this.performWebAuthnCeremony(e.ceremony),!0}else{const e=await t.json().catch((()=>({message:"Failed to load screen"})));this.flowError.emit({message:e.message||"Failed to load screen"})}}catch(t){console.error("Failed to fetch screen:",t),this.flowError.emit({message:t instanceof Error?t.message:"Failed to fetch screen"})}finally{this.loading=!1}return!1}handleInputChange=(t,e)=>{this.formData={...this.formData,[t]:e}};handleSubmit=async(t,e)=>{if(t.preventDefault(),!this._screen||this.loading)return;let i={...this.formData,...e||{}};const o=this.el.shadowRoot?.querySelector("form");if(o&&o.querySelectorAll('input[type="hidden"]').forEach((t=>{t.name&&t.value&&(i[t.name]=t.value)})),this.formSubmit.emit({screen:this._screen,data:i}),this.autoSubmit)if(this._screen.method&&"GET"!==this._screen.method.toUpperCase()){this.loading=!0;try{const t=await fetch(this.buildUrl(this._screen.action),{method:this._screen.method,credentials:"include",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({data:i})}),e=t.headers.get("content-type");if(e?.includes("text/html")){const e=await t.text();return document.open(),document.write(e),void document.close()}if(e?.includes("application/json")){const e=await t.json();e.redirect?(this.flowComplete.emit({redirectUrl:e.redirect}),this.navigate.emit({url:e.redirect}),this.shouldAutoNavigate&&(window.location.href=e.redirect)):!t.ok&&e.screen?await this.swapScreen((()=>{this.loading=!1,this._screen=e.screen,this.listFilter="",this.initFormDataFromDefaults(e.screen),this.screenChange.emit(e.screen),this.updateDataScreenAttribute(),this.focusFirstInput()})):e.screen?await this.swapScreen((()=>{this.loading=!1,this._screen=e.screen,this.listFilter="",this.formData={},this.initFormDataFromDefaults(e.screen),this.screenChange.emit(e.screen),this.updateDataScreenAttribute(),e.screenId&&(this.screenId=e.screenId),this.persistState(),e.navigateUrl&&this.shouldAutoNavigate&&window.history.pushState({screen:e.screenId,state:this.state},"",e.navigateUrl),e.branding&&(this._branding=e.branding,this.applyThemeStyles()),e.state&&(this.state=e.state,this.persistState()),e.ceremony&&this.performWebAuthnCeremony(e.ceremony),this.focusFirstInput()})):e.complete?this.flowComplete.emit({}):!t.ok&&e.error&&(this._screen&&(this._screen={...this._screen,messages:[...this._screen.messages||[],{text:e.error,type:"error"}]}),this.flowError.emit({message:e.error}))}}catch(t){console.error("Form submission failed:",t),this.flowError.emit({message:t instanceof Error?t.message:"Form submission failed"})}finally{this.loading=!1}}else window.location.href=this.buildUrl(this._screen.action)};overrideFormSubmit(){const t=this.el.shadowRoot;if(!t)return;const e=t.querySelector("form");e&&(e.submit=()=>{const t=new FormData(e),i={};t.forEach(((t,e)=>{"string"==typeof t&&(i[e]=t)})),this.handleSubmit({preventDefault:()=>{}},i)})}performWebAuthnCeremony(t){this.isValidWebAuthnCeremony(t)?"webauthn-authentication-conditional"!==t.type?requestAnimationFrame((()=>{this.overrideFormSubmit(),"webauthn-authentication"===t.type?this.executeWebAuthnAuthentication(t):this.executeWebAuthnRegistration(t)})):this.executeWebAuthnConditionalMediation(t):console.error("Invalid WebAuthn ceremony payload",t)}isValidWebAuthnCeremony(t){if("object"!=typeof t||null===t)return!1;const e=t;if("string"!=typeof e.successAction)return!1;const i=e.options;if("object"!=typeof i||null===i)return!1;if("string"!=typeof i.challenge)return!1;if("webauthn-registration"===e.type){const t=i.rp;if("object"!=typeof t||null===t)return!1;if("string"!=typeof t.id||"string"!=typeof t.name)return!1;const e=i.user;return"object"==typeof e&&null!==e&&("string"==typeof e.id&&"string"==typeof e.name&&"string"==typeof e.displayName&&!!Array.isArray(i.pubKeyCredParams))}return"webauthn-authentication"===e.type||"webauthn-authentication-conditional"===e.type}async executeWebAuthnRegistration(t){const e=t.options,i=t=>{for(t=t.replace(/-/g,"+").replace(/_/g,"/");t.length%4;)t+="=";const e=atob(t),i=new Uint8Array(e.length);for(let t=0;t<e.length;t++)i[t]=e.charCodeAt(t);return i.buffer},o=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 s=await navigator.credentials.create({publicKey:r}),a=s.response,c={id:s.id,rawId:o(s.rawId),type:s.type,response:{attestationObject:o(a.attestationObject),clientDataJSON:o(a.clientDataJSON)},clientExtensionResults:s.getClientExtensionResults(),authenticatorAttachment:s.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()}}}async executeWebAuthnAuthentication(t){const e=t.options,i=t=>{for(t=t.replace(/-/g,"+").replace(/_/g,"/");t.length%4;)t+="=";const e=atob(t),i=new Uint8Array(e.length);for(let t=0;t<e.length;t++)i[t]=e.charCodeAt(t);return i.buffer},o=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),rpId:e.rpId,timeout:e.timeout,userVerification:e.userVerification||"preferred"};e.allowCredentials?.length&&(r.allowCredentials=e.allowCredentials.map((t=>({id:i(t.id),type:t.type,transports:t.transports||[]}))));const s=await navigator.credentials.get({publicKey:r}),a=s.response,c={id:s.id,rawId:o(s.rawId),type:s.type,response:{authenticatorData:o(a.authenticatorData),clientDataJSON:o(a.clientDataJSON),signature:o(a.signature)},clientExtensionResults:s.getClientExtensionResults(),authenticatorAttachment:s.authenticatorAttachment||void 0};a.userHandle&&(c.response.userHandle=o(a.userHandle));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 authentication error:",t);const e=n();if(e){const t=e.querySelector('[name="action-field"]')||e.querySelector("#action-field");t&&(t.value="error"),e.submit()}}}async executeWebAuthnConditionalMediation(t){if(!window.PublicKeyCredential||!PublicKeyCredential.isConditionalMediationAvailable)return;if(!await PublicKeyCredential.isConditionalMediationAvailable())return;this.conditionalMediationAbort?.abort();const e=new AbortController;this.conditionalMediationAbort=e;const i=t.options,o=t=>{for(t=t.replace(/-/g,"+").replace(/_/g,"/");t.length%4;)t+="=";const e=atob(t),i=new Uint8Array(e.length);for(let t=0;t<e.length;t++)i[t]=e.charCodeAt(t);return i.buffer},n=t=>{const e=new Uint8Array(t);let i="";for(let t=0;t<e.length;t++)i+=String.fromCharCode(e[t]);return btoa(i).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")};try{const r=await navigator.credentials.get({mediation:"conditional",signal:e.signal,publicKey:{challenge:o(i.challenge),rpId:i.rpId,timeout:i.timeout,userVerification:i.userVerification||"preferred"}}),s=r.response,a={id:r.id,rawId:n(r.rawId),type:r.type,response:{authenticatorData:n(s.authenticatorData),clientDataJSON:n(s.clientDataJSON),signature:n(s.signature)},clientExtensionResults:r.getClientExtensionResults(),authenticatorAttachment:r.authenticatorAttachment||void 0};s.userHandle&&(a.response.userHandle=n(s.userHandle)),this.formData["credential-field"]=JSON.stringify(a),this.formData["action-field"]=t.successAction,this.overrideFormSubmit();const c=this.el?.shadowRoot,h=c?.querySelector("form");if(h){const e=h.querySelector('[name="credential-field"]')||h.querySelector("#credential-field"),i=h.querySelector('[name="action-field"]')||h.querySelector("#action-field");e&&(e.value=JSON.stringify(a)),i&&(i.value=t.successAction),h.submit()}}catch(t){if("AbortError"===t?.name||"NotAllowedError"===t?.name)return;console.error("Conditional mediation error:",t)}}handleButtonClick=t=>{if("submit"!==t.type)if(this.buttonClick.emit(t),"SOCIAL"===t.type&&t.value&&this.shouldAutoNavigate){const e=this.getProviderHref(t.value);if(e){const t=this.extractScreenIdFromHref(e);return void(t&&this.apiUrl?this.navigateToScreen(t,e):window.location.href=e)}this.handleSocialLogin(t.value)}else"RESEND_BUTTON"===t.type&&this.shouldAutoNavigate&&this.handleResend();else{if((!this._screen?.method||"GET"===this._screen.method.toUpperCase())&&this._screen?.action)return void(window.location.href=this.buildUrl(this._screen.action));const e={...this.formData,[t.id]:"true"};this.formData=e,this.handleSubmit({preventDefault:()=>{}},e)}};handleSocialLogin(t){const e=this._authParams||{},i={connection:t};this.state?i.state=this.state:e.state&&(i.state=e.state),e.client_id&&(i.client_id=e.client_id),e.redirect_uri&&(i.redirect_uri=e.redirect_uri),e.scope&&(i.scope=e.scope),e.audience&&(i.audience=e.audience),e.nonce&&(i.nonce=e.nonce),e.response_type&&(i.response_type=e.response_type);const o=this.buildUrl("/authorize?"+new URLSearchParams(i));this.navigate.emit({url:o}),window.location.href=o}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 o=e.match(/\/u2\/([^/]+)$/);return o&&"login"!==o[1]&&"screen"!==o[1]?o[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}getChoiceButtonText(t){const e=t.config;return e?.text??""}render(){const t=this._screen;if(this.loading&&!t)return n("div",{class:"widget-container"},n("div",{class:"loading-spinner"}));if(!t)return n("div",{class:"widget-container"},n("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))||[],o=[...t.components??[]],r=o.filter((t=>!1!==t.visible)).sort(((t,e)=>(t.order??0)-(e.order??0))),s=o.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=c.filter((t=>"NEXT_BUTTON"===t.type)),u=f.length===c.length&&f.length>5,p=this.listFilter.trim().toLowerCase(),g=u&&p?f.filter((t=>this.getChoiceButtonText(t).toLowerCase().includes(p))):f,m=t=>{const e=t.config;return["social-buttons","button","button-secondary","button-social","button-social-content","button-social-text","button-social-subtitle","button-social-badge","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,"button-social-badge-"+e,"social-icon-"+e]}))].join(", ")},w=this._theme?.widget?.logo_url||this._branding?.logo_url;return n("div",{class:"widget-container",part:"container","data-authstack-container":!0},n("header",{class:"widget-header",part:"header"},w&&n("div",{class:"logo-wrapper",part:"logo-wrapper"},n("img",{class:"logo",part:"logo",src:w,alt:"Logo"})),t.title&&n("h1",{class:"title",part:"title",innerHTML:b(t.title)}),t.description&&n("p",{class:"description",part:"description",innerHTML:b(t.description)})),n("div",{class:"widget-body",part:"body"},e.map((t=>n("div",{class:"message message-error",part:"message message-error",key:t.id??t.text},t.text))),i.map((t=>n("div",{class:"message message-success",part:"message message-success",key:t.id??t.text},t.text))),n("form",{onSubmit:this.handleSubmit,action:t.action,method:t.method||"POST",part:"form"},s.map((t=>n("input",{type:"hidden",name:t.id,id:t.id,key:t.id,value:this.formData[t.id]||""}))),n("div",{class:"form-content"},a.length>0&&n("div",{class:"social-section",part:"social-section"},a.map((t=>n("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:m(t)})))),a.length>0&&c.length>0&&l&&n("div",{class:"divider",part:"divider"},n("span",{class:"divider-text"},d)),n("div",{class:"fields-section",part:"fields-section"},u&&n("input",{type:"text",class:"choice-list-search",part:"choice-list-search",placeholder:"Search","aria-label":"Search",autocomplete:"off",value:this.listFilter,onInput:t=>this.listFilter=t.target.value,onKeyDown:t=>{"Enter"===t.key&&t.preventDefault()}}),n("div",{class:u?"fields-list fields-list-scroll":"fields-list",part:u?"fields-list fields-list-scroll":"fields-list"},(u?g:c).map((t=>n("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}))),u&&0===g.length&&n("div",{class:"choice-list-empty",part:"choice-list-empty"},"No matches"))))),t.links&&t.links.length>0&&n("div",{class:"links",part:"links"},t.links.map((t=>n("span",{class:"link-wrapper",part:"link-wrapper",key:t.id??t.href},t.linkText?n("span",null,t.text," ",n("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)):n("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&&n("div",{class:"widget-footer",part:"footer",innerHTML:b(t.footer)})))}static get watchers(){return{screenId:[{watchScreenId:0}],screen:[{watchScreen:0}],branding:[{watchBranding:0}],theme:[{watchTheme:0}],authParams:[{watchAuthParams:0}]}}static get style(){return":host{display:block;font-family:var(--ah-font-family, 'ulp-font', -apple-system, BlinkMacSystemFont, Roboto, Helvetica, sans-serif);font-size:var(--ah-font-size-base, 16px);line-height:var(--ah-line-height-base, 1.5);color:var(--ah-color-text, #1e212a);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.widget-container{width:var(--ah-widget-max-width, 400px);margin:0 auto;background-color:var(--ah-color-bg, #ffffff);border-radius:var(--ah-widget-radius, 5px);border:var(--ah-widget-border-width, 0) solid var(--ah-widget-border-color, transparent);box-shadow:var(--ah-widget-shadow, 0 4px 22px 0 rgba(0, 0, 0, 0.11));box-sizing:border-box}.widget-header{padding:var(--ah-header-padding, 40px 48px 24px)}.widget-body{padding:var(--ah-body-padding, 0 48px 40px)}.logo-wrapper{display:var(--ah-logo-display, flex);justify-content:var(--ah-logo-align, center);margin-bottom:8px}.logo{display:block;height:var(--ah-logo-height, 52px);max-width:100%;width:auto;object-fit:contain}.title{font-size:var(--ah-font-size-title, 24px);font-weight:var(--ah-font-weight-title, 700);text-align:var(--ah-title-align, center);margin:var(--ah-title-margin, 24px 0 24px);color:var(--ah-color-text-header, var(--ah-color-header, #1e212a));line-height:1.2}.description{font-size:var(--ah-font-size-subtitle, 16px);font-weight:var(--ah-font-weight-subtitle, 400);text-align:var(--ah-title-align, center);margin:var(--ah-description-margin, 0 0 8px);color:var(--ah-color-text, #1e212a);line-height:1.5}.message{padding:12px 16px;border-radius:4px;margin-bottom:16px;font-size:14px;line-height:1.5}.message-error{background-color:var(--ah-color-error-bg, #ffeaea);color:var(--ah-color-error, #d03c38);border-left:3px solid var(--ah-color-error, #d03c38)}.message-success{background-color:var(--ah-color-success-bg, #e6f9f1);color:var(--ah-color-success, #13a769);border-left:3px solid var(--ah-color-success, #13a769)}form{display:flex;flex-direction:column}.form-content{display:flex;flex-direction:column}.social-section{display:flex;flex-direction:column;gap:8px;order:var(--ah-social-order, 2)}.fields-section{display:flex;flex-direction:column;order:var(--ah-fields-order, 0)}.fields-list{display:flex;flex-direction:column}.fields-list-scroll{max-height:var(--ah-choice-list-max-height, 320px);overflow-y:auto;gap:var(--ah-choice-list-gap, 8px);padding-right:4px}.choice-list-search{width:100%;padding:16px;margin-bottom:12px;font-size:16px;font-family:inherit;color:var(--ah-color-input-text, var(--ah-color-text, #1e212a));background-color:var(--ah-color-input-bg, #ffffff);border:var(--ah-input-border-width, 1px) solid var(--ah-color-border, #c9cace);border-radius:var(--ah-input-radius, 3px);outline:none;box-sizing:border-box;transition:border-color 0.15s ease-out, box-shadow 0.15s ease-out}.choice-list-search:hover{border-color:var(--ah-color-border-hover, #65676e)}.choice-list-search:focus{border-color:var(--ah-color-primary, var(--ah-color-link, #635dff))}.choice-list-empty{padding:16px;text-align:center;font-size:14px;color:var(--ah-color-text-muted, #65676e)}.divider{display:flex;align-items:center;text-align:center;margin:16px 0;order:var(--ah-divider-order, 1)}.divider::before,.divider::after{content:'';flex:1;border-bottom:1px solid var(--ah-color-border-muted, #c9cace)}.divider-text{padding:0 10px;font-size:12px;font-weight:400;color:var(--ah-color-text-muted, #65676e);text-transform:uppercase;letter-spacing:0}.links{display:flex;flex-direction:column;align-items:center;gap:8px;margin-top:16px}.link-wrapper{font-size:var(--ah-font-size-body, 14px);font-weight:var(--ah-font-weight-body, 400);color:var(--ah-color-text, #1e212a)}.link{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:var(--ah-font-size-link, 14px);font-weight:var(--ah-font-weight-link, 400);transition:color 150ms ease}.link:hover{text-decoration:underline}.link:focus-visible{outline:2px solid var(--ah-color-focus-ring, var(--ah-color-link, #635dff));outline-offset:2px;border-radius:2px}.widget-footer{margin-top:16px;text-align:center;font-size:12px;color:var(--ah-color-text-muted, #65676e)}.widget-footer a{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:12px;transition:color 150ms ease}.widget-footer a:hover{text-decoration:underline}.widget-footer a:focus-visible{outline:2px solid var(--ah-color-focus-ring, var(--ah-color-link, #635dff));outline-offset:2px;border-radius:2px}.loading-spinner{width:32px;height:32px;margin:24px auto;border:3px solid var(--ah-color-border-muted, #e0e1e3);border-top-color:var(--ah-color-primary, #635dff);border-radius:50%;animation:spin 0.8s linear infinite}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.error-message{text-align:center;color:var(--ah-color-error, #d03c38);padding:16px;font-size:14px}@media (max-width: 480px){:host{display:block;width:100%;min-height:100vh;background-color:var(--ah-color-bg, #ffffff)}.widget-container{box-shadow:none;border-radius:0;width:100%;margin:0}.widget-header{padding:24px 16px 16px}.widget-body{padding:0 16px 24px}}"}},[513,"authhero-widget",{screen:[1],apiUrl:[1,"api-url"],baseUrl:[1,"base-url"],state:[1025],screenId:[1025,"screen-id"],authParams:[1,"auth-params"],statePersistence:[1,"state-persistence"],storageKey:[1,"storage-key"],branding:[1],theme:[1],loading:[1028],autoSubmit:[4,"auto-submit"],autoNavigate:[4,"auto-navigate"],_screen:[32],_authParams:[32],_branding:[32],_theme:[32],formData:[32],listFilter:[32]},void 0,{screenId:[{watchScreenId:0}],screen:[{watchScreen:0}],branding:[{watchBranding:0}],theme:[{watchTheme:0}],authParams:[{watchAuthParams:0}]}]);function y(){"undefined"!=typeof customElements&&["authhero-widget","authhero-node"].forEach((e=>{switch(e){case"authhero-widget":customElements.get(t(e))||customElements.define(t(e),v);break;case"authhero-node":customElements.get(t(e))||r()}}))}y();const k=v,S=y;export{k as AuthheroWidget,S as defineCustomElement}
|
|
1
|
+
import{t,p as e,H as i,c as o,h as n}from"./p-cKZ5hFj1.js";import{d as r}from"./p-C9ZfIQiS.js";function s(t){const e=t.match(/^#([0-9a-f]{3})$/i)||t.match(/^#([0-9a-f]{6})$/i);if(!e)return null;let i=e[1];3===i.length&&(i=i[0]+i[0]+i[1]+i[1]+i[2]+i[2]);const o=parseInt(i,16);return[o>>16&255,o>>8&255,255&o]}function a(t){const e=s(t);if(!e)return NaN;const[i,o,n]=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*o+.0722*n}function c(t,e){const i=a(t),o=a(e);return isNaN(i)||isNaN(o)?NaN:(Math.max(i,o)+.05)/(Math.min(i,o)+.05)}function h(t,e="light"){const i=c(t,"#000000"),o=c(t,"#ffffff");return"light"===e?i>1.35*o?"#000000":"#ffffff":1.35*i>o?"#000000":"#ffffff"}function l(t,e){const i=s(t);if(!i)return t;const[o,n,r]=i,a=t=>Math.max(0,Math.round(t*(1-e))).toString(16).padStart(2,"0");return`#${a(o)}${a(n)}${a(r)}`}function d(t,e){const i=s(t);if(!i)return t;const[o,n,r]=i,a=t=>Math.min(255,Math.round(t+(255-t)*e)).toString(16).padStart(2,"0");return`#${a(o)}${a(n)}${a(r)}`}function f(t,e,i=4.5){if(c(t,e)>=i)return t;const o=a(e)>.5;let n=t;for(let r=1;r<=10;r++)if(n=o?l(t,.1*r):d(t,.1*r),c(n,e)>=i)return n;return o?"#000000":"#ffffff"}function u(t,e){if(void 0!==e)return e+"px";switch(t){case"pill":return"9999px";case"rounded":return"8px";case"sharp":return"0";default:return}}function p(t){if(!t)return{};const e={};if(t.colors?.primary&&(e["--ah-color-primary"]=t.colors.primary),t.colors?.page_background){const i=t.colors.page_background;"solid"===i.type&&i.start?e["--ah-page-bg"]=i.start:"gradient"===i.type&&i.start&&i.end&&(e["--ah-page-bg"]=`linear-gradient(${i.angle_deg??180}deg, ${i.start}, ${i.end})`)}return t.logo_url&&(e["--ah-logo-url"]=`url(${t.logo_url})`),t.font?.url&&(e["--ah-font-url"]=t.font.url),e}function g(t){if(!t)return{};const e={};if(t.borders){const i=t.borders;void 0!==i.widget_corner_radius&&(e["--ah-widget-radius"]=i.widget_corner_radius+"px"),void 0!==i.widget_border_weight&&(e["--ah-widget-border-width"]=i.widget_border_weight+"px"),!1===i.show_widget_shadow&&(e["--ah-widget-shadow"]="none");const o=u(i.buttons_style,i.button_border_radius);o&&(e["--ah-btn-radius"]=o),void 0!==i.button_border_weight&&(e["--ah-btn-border-width"]=i.button_border_weight+"px");const n=u(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,i.primary_button_label)e["--ah-color-text-on-primary"]=i.primary_button_label;else{e["--ah-color-text-on-primary"]=h(i.primary_button,"light");const t=h(i.primary_button,"dark");t!==e["--ah-color-text-on-primary"]&&(e["--ah-color-text-on-primary-dark"]=t)}else i.primary_button_label&&(e["--ah-color-text-on-primary"]=i.primary_button_label);i.secondary_button_border&&(e["--ah-btn-secondary-border"]=i.secondary_button_border),i.secondary_button_label&&(e["--ah-btn-secondary-text"]=i.secondary_button_label),i.body_text&&(e["--ah-color-text"]=i.body_text),i.header&&(e["--ah-color-text-header"]=i.header),i.input_labels_placeholders&&(e["--ah-color-text-label"]=i.input_labels_placeholders,e["--ah-color-text-muted"]=i.input_labels_placeholders),i.input_filled_text&&(e["--ah-color-input-text"]=i.input_filled_text),i.widget_background&&(e["--ah-color-bg"]=i.widget_background),i.input_background&&(e["--ah-color-input-bg"]=i.input_background),i.widget_border&&(e["--ah-widget-border-color"]=i.widget_border),i.input_border&&(e["--ah-color-border"]=i.input_border),i.links_focused_components&&(e["--ah-color-link"]=f(i.links_focused_components,i.widget_background||"#ffffff")),i.base_focus_color&&(e["--ah-color-focus-ring"]=i.base_focus_color),i.base_hover_color&&(e["--ah-color-primary-hover"]=i.base_hover_color),i.error&&(e["--ah-color-error"]=i.error),i.success&&(e["--ah-color-success"]=i.success),i.icons&&(e["--ah-color-icon"]=i.icons);const o=i.widget_background||"#ffffff",n=i.input_background||o,r=e["--ah-color-border"]||i.input_border||"#c9cace",s=c(r,o),a=c(r,n);Math.min(s,a)<3&&(e["--ah-color-border"]=f(r,s<a?o:n,3))}if(t.fonts){const i=t.fonts,o=i.reference_text_size||16,n=t=>t>=50?Math.round(t/100*o):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 m={br:[],em:[],i:[],strong:[],b:[],u:[],span:["class"],a:["href","class"]};function b(t){if(!t)return"";if(!t.includes("<"))return t;let e=t;e=e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'");for(const[t,i]of Object.entries(m)){if("br"===t){e=e.replace(/<br\s*\/?>/gi,"<br>");continue}const o=RegExp(`<${t}((?:\\s+[a-z-]+(?:="[^&]*"|='[^&]*')?)*)\\s*>`,"gi");e=e.replace(o,((e,o)=>{const n=[];if(o){const t=o.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()?w(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=RegExp(`</${t}>`,"gi");e=e.replace(n,`</${t}>`)}return e}function w(t){if(!t)return!1;if(t.startsWith("/")||t.startsWith("#")||t.startsWith("?"))return!0;try{const e=new URL(t,"https://example.com");return"http:"===e.protocol||"https:"===e.protocol}catch{return!1}}function x(t){return t.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}const v=new Set(["TEXT","EMAIL","CODE","PASSWORD","NUMBER","TEL","URL","DATE","BOOLEAN","LEGAL","COUNTRY","DROPDOWN","CHOICE"]),y=e(class extends i{constructor(t){super(),!1!==t&&this.__registerHost(),this.__attachShadow(),this.formSubmit=o(this,"formSubmit"),this.buttonClick=o(this,"buttonClick"),this.linkClick=o(this,"linkClick"),this.navigate=o(this,"navigate"),this.flowComplete=o(this,"flowComplete"),this.flowError=o(this,"flowError"),this.screenChange=o(this,"screenChange")}get el(){return this}screen;apiUrl;baseUrl;state;screenId;watchScreenId(){this.updateDataScreenAttribute()}authParams;statePersistence="memory";storageKey="authhero_widget";branding;theme;loading=!1;autoSubmit=!1;autoNavigate;locale;_screen;_authParams;_branding;_theme;formData={};listFilter="";conditionalMediationAbort;loadedFontUrl;formSubmit;buttonClick;linkClick;navigate;flowComplete;flowError;screenChange;watchScreen(t){if(this.conditionalMediationAbort?.abort(),this.conditionalMediationAbort=void 0,"string"==typeof t)try{this._screen=JSON.parse(t)}catch{console.error("Failed to parse screen JSON")}else this._screen=t;this._screen&&(this.formData={},this.listFilter="",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)continue;if(!("default_value"in i.config))continue;const t=i.config.default_value;"string"==typeof t&&""!==t?e[i.id]=t:"boolean"==typeof t&&(e[i.id]=t?"true":"false")}Object.keys(e).length>0&&(this.formData={...e,...this.formData})}updateDataScreenAttribute(){const t=this._screen?.name||this.screenId;t?this.el.setAttribute("data-screen",t):this.el.removeAttribute("data-screen");const e=this.el.closest("[data-authhero-widget-container]");e&&(t?e.setAttribute("data-screen",t):e.removeAttribute("data-screen"))}watchBranding(t){if("string"==typeof t)try{this._branding=JSON.parse(t)}catch{console.error("Failed to parse branding JSON")}else this._branding=t;this.applyThemeStyles()}watchTheme(t){if("string"==typeof t)try{this._theme=JSON.parse(t)}catch{console.error("Failed to parse theme JSON")}else this._theme=t;this.applyThemeStyles()}watchAuthParams(t){if("string"==typeof t)try{this._authParams=JSON.parse(t)}catch{console.error("Failed to parse authParams JSON")}else this._authParams=t}applyThemeStyles(){const t=function(t,e){return{...p(t),...g(e)}}(this._branding,this._theme);!function(t,e){Object.entries(e).forEach((([e,i])=>{t.style.setProperty(e,i)}))}(this.el,t),this.loadCustomFont()}loadCustomFont(){if("undefined"==typeof document)return;const t=this._theme?.fonts?.font_url||this._branding?.font?.url;if(t===this.loadedFontUrl)return;for(const t of Array.from(document.head.querySelectorAll("link[data-authhero-font]")))t.remove();if(this.loadedFontUrl=void 0,!t)return;const e=document.createElement("link");e.rel="stylesheet",e.href=t,e.setAttribute("data-authhero-font",t),document.head.appendChild(e),this.loadedFontUrl=t}focusFirstInput(){requestAnimationFrame((()=>{const t=this.el.shadowRoot;if(!t)return;const e=t.querySelectorAll("authhero-node");for(const t of Array.from(e)){const e=t.shadowRoot;if(e){const t=e.querySelector('input:not([type="hidden"]):not([type="checkbox"]):not([disabled]), textarea:not([disabled])');if(t)return void t.focus()}}}))}pendingRenderResolvers=[];componentDidRender(){if(0===this.pendingRenderResolvers.length)return;const t=this.pendingRenderResolvers;this.pendingRenderResolvers=[],t.forEach((t=>t()))}nextRender(){return new Promise((t=>{let e=!1;const i=()=>{e||(e=!0,t())};this.pendingRenderResolvers.push(i),requestAnimationFrame((()=>requestAnimationFrame(i)))}))}async swapScreen(t){const e=this.el.shadowRoot?.querySelector(".widget-container"),i="function"==typeof window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches;if(!e||"function"!=typeof e.animate||i)return void t();const o=e.getBoundingClientRect().height;e.style.height=o+"px",e.style.overflow="hidden",t(),await this.nextRender();const n=()=>{e.style.height="",e.style.overflow=""};e.style.height="auto";const r=e.getBoundingClientRect().height;if(e.style.height=o+"px",e.getBoundingClientRect(),Math.abs(r-o)<1)return void n();const s=e.animate([{height:o+"px"},{height:r+"px"}],{duration:520,easing:"cubic-bezier(0.22, 1, 0.36, 1)"});try{await s.finished}catch{}finally{n()}}get shouldAutoNavigate(){return this.autoNavigate??this.autoSubmit}buildUrl(t){return this.baseUrl?""+new URL(t,this.baseUrl):t}loadPersistedState(){if("url"===this.statePersistence){const t=new URL(window.location.href).searchParams.get("state");t&&!this.state&&(this.state=t)}else if("session"===this.statePersistence)try{const t=sessionStorage.getItem(this.storageKey+"_state");t&&!this.state&&(this.state=t);const e=sessionStorage.getItem(this.storageKey+"_screenId");e&&!this.screenId&&(this.screenId=e)}catch{}}persistState(){if("url"===this.statePersistence){const t=new URL(window.location.href);this.state&&t.searchParams.set("state",this.state),this.screenId&&t.searchParams.set("screen",this.screenId),window.history.replaceState({},"",""+t)}else if("session"===this.statePersistence)try{this.state&&sessionStorage.setItem(this.storageKey+"_state",this.state),this.screenId&&sessionStorage.setItem(this.storageKey+"_screenId",this.screenId)}catch{}}handlePopState=t=>{if(!this.apiUrl)return;t.state?.state&&(this.state=t.state.state);const e=t.state?.screen??this.extractScreenIdFromHref(location.href);e&&this.fetchScreen(e)};connectedCallback(){window.addEventListener("popstate",this.handlePopState)}disconnectedCallback(){window.removeEventListener("popstate",this.handlePopState),this.conditionalMediationAbort?.abort(),this.conditionalMediationAbort=void 0}readJsonScript(t){if(!this.el)return;const e=this.el.querySelector(`script[type="application/json"][data-authhero="${t}"]`);return e?.textContent??void 0}async componentWillLoad(){if(!this._screen){const t=this.screen||this.readJsonScript("screen")||this.el?.getAttribute("screen");t&&this.watchScreen(t)}this._branding||this.watchBranding(this.branding??this.readJsonScript("branding")),this._theme||this.watchTheme(this.theme??this.readJsonScript("theme")),this._authParams||this.watchAuthParams(this.authParams??this.readJsonScript("auth-params")),this.loadPersistedState(),this.apiUrl&&!this._screen&&await this.fetchScreen(this.screenId)}async fetchScreen(t,e){if(!this.apiUrl)return!1;const i=t||this.screenId;let o=this.apiUrl;i&&o.includes("{screenId}")&&(o=o.replace("{screenId}",encodeURIComponent(i)));const n=new URL(o,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 this.listFilter="",i&&i!==this.screenId&&(this.screenId=i),this.initFormDataFromDefaults(this._screen),this.screenChange.emit(this._screen),this.updateDataScreenAttribute(),this.persistState(),this.focusFirstInput(),e.ceremony&&this.performWebAuthnCeremony(e.ceremony),!0}else{const e=await t.json().catch((()=>({message:"Failed to load screen"})));this.flowError.emit({message:e.message||"Failed to load screen"})}}catch(t){console.error("Failed to fetch screen:",t),this.flowError.emit({message:t instanceof Error?t.message:"Failed to fetch screen"})}finally{this.loading=!1}return!1}handleInputChange=(t,e)=>{this.formData={...this.formData,[t]:e}};handleSubmit=async(t,e)=>{if(t.preventDefault(),!this._screen||this.loading)return;let i={...this.formData,...e||{}};const o=this.el.shadowRoot?.querySelector("form");if(o&&o.querySelectorAll('input[type="hidden"]').forEach((t=>{t.name&&t.value&&(i[t.name]=t.value)})),this.formSubmit.emit({screen:this._screen,data:i}),this.autoSubmit)if(this._screen.method&&"GET"!==this._screen.method.toUpperCase()){this.loading=!0;try{const t=await fetch(this.buildUrl(this._screen.action),{method:this._screen.method,credentials:"include",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({data:i})}),e=t.headers.get("content-type");if(e?.includes("text/html")){const e=await t.text();return document.open(),document.write(e),void document.close()}if(e?.includes("application/json")){const e=await t.json();e.redirect?(this.flowComplete.emit({redirectUrl:e.redirect}),this.navigate.emit({url:e.redirect}),this.shouldAutoNavigate&&(window.location.href=e.redirect)):!t.ok&&e.screen?await this.swapScreen((()=>{this.loading=!1,this._screen=e.screen,this.listFilter="",this.initFormDataFromDefaults(e.screen),this.screenChange.emit(e.screen),this.updateDataScreenAttribute(),this.focusFirstInput()})):e.screen?await this.swapScreen((()=>{this.loading=!1,this._screen=e.screen,this.listFilter="",this.formData={},this.initFormDataFromDefaults(e.screen),this.screenChange.emit(e.screen),this.updateDataScreenAttribute(),e.screenId&&(this.screenId=e.screenId),this.persistState(),e.navigateUrl&&this.shouldAutoNavigate&&window.history.pushState({screen:e.screenId,state:this.state},"",e.navigateUrl),e.branding&&(this._branding=e.branding,this.applyThemeStyles()),e.state&&(this.state=e.state,this.persistState()),e.ceremony&&this.performWebAuthnCeremony(e.ceremony),this.focusFirstInput()})):e.complete?this.flowComplete.emit({}):!t.ok&&e.error&&(this._screen&&(this._screen={...this._screen,messages:[...this._screen.messages||[],{text:e.error,type:"error"}]}),this.flowError.emit({message:e.error}))}}catch(t){console.error("Form submission failed:",t),this.flowError.emit({message:t instanceof Error?t.message:"Form submission failed"})}finally{this.loading=!1}}else window.location.href=this.buildUrl(this._screen.action)};overrideFormSubmit(){const t=this.el.shadowRoot;if(!t)return;const e=t.querySelector("form");e&&(e.submit=()=>{const t=new FormData(e),i={};t.forEach(((t,e)=>{"string"==typeof t&&(i[e]=t)})),this.handleSubmit({preventDefault:()=>{}},i)})}performWebAuthnCeremony(t){this.isValidWebAuthnCeremony(t)?"webauthn-authentication-conditional"!==t.type?requestAnimationFrame((()=>{this.overrideFormSubmit(),"webauthn-authentication"===t.type?this.executeWebAuthnAuthentication(t):this.executeWebAuthnRegistration(t)})):this.executeWebAuthnConditionalMediation(t):console.error("Invalid WebAuthn ceremony payload",t)}isValidWebAuthnCeremony(t){if("object"!=typeof t||null===t)return!1;const e=t;if("string"!=typeof e.successAction)return!1;const i=e.options;if("object"!=typeof i||null===i)return!1;if("string"!=typeof i.challenge)return!1;if("webauthn-registration"===e.type){const t=i.rp;if("object"!=typeof t||null===t)return!1;if("string"!=typeof t.id||"string"!=typeof t.name)return!1;const e=i.user;return"object"==typeof e&&null!==e&&("string"==typeof e.id&&"string"==typeof e.name&&"string"==typeof e.displayName&&!!Array.isArray(i.pubKeyCredParams))}return"webauthn-authentication"===e.type||"webauthn-authentication-conditional"===e.type}async executeWebAuthnRegistration(t){const e=t.options,i=t=>{for(t=t.replace(/-/g,"+").replace(/_/g,"/");t.length%4;)t+="=";const e=atob(t),i=new Uint8Array(e.length);for(let t=0;t<e.length;t++)i[t]=e.charCodeAt(t);return i.buffer},o=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 s=await navigator.credentials.create({publicKey:r}),a=s.response,c={id:s.id,rawId:o(s.rawId),type:s.type,response:{attestationObject:o(a.attestationObject),clientDataJSON:o(a.clientDataJSON)},clientExtensionResults:s.getClientExtensionResults(),authenticatorAttachment:s.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()}}}async executeWebAuthnAuthentication(t){const e=t.options,i=t=>{for(t=t.replace(/-/g,"+").replace(/_/g,"/");t.length%4;)t+="=";const e=atob(t),i=new Uint8Array(e.length);for(let t=0;t<e.length;t++)i[t]=e.charCodeAt(t);return i.buffer},o=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),rpId:e.rpId,timeout:e.timeout,userVerification:e.userVerification||"preferred"};e.allowCredentials?.length&&(r.allowCredentials=e.allowCredentials.map((t=>({id:i(t.id),type:t.type,transports:t.transports||[]}))));const s=await navigator.credentials.get({publicKey:r}),a=s.response,c={id:s.id,rawId:o(s.rawId),type:s.type,response:{authenticatorData:o(a.authenticatorData),clientDataJSON:o(a.clientDataJSON),signature:o(a.signature)},clientExtensionResults:s.getClientExtensionResults(),authenticatorAttachment:s.authenticatorAttachment||void 0};a.userHandle&&(c.response.userHandle=o(a.userHandle));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 authentication error:",t);const e=n();if(e){const t=e.querySelector('[name="action-field"]')||e.querySelector("#action-field");t&&(t.value="error"),e.submit()}}}async executeWebAuthnConditionalMediation(t){if(!window.PublicKeyCredential||!PublicKeyCredential.isConditionalMediationAvailable)return;if(!await PublicKeyCredential.isConditionalMediationAvailable())return;this.conditionalMediationAbort?.abort();const e=new AbortController;this.conditionalMediationAbort=e;const i=t.options,o=t=>{for(t=t.replace(/-/g,"+").replace(/_/g,"/");t.length%4;)t+="=";const e=atob(t),i=new Uint8Array(e.length);for(let t=0;t<e.length;t++)i[t]=e.charCodeAt(t);return i.buffer},n=t=>{const e=new Uint8Array(t);let i="";for(let t=0;t<e.length;t++)i+=String.fromCharCode(e[t]);return btoa(i).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")};try{const r=await navigator.credentials.get({mediation:"conditional",signal:e.signal,publicKey:{challenge:o(i.challenge),rpId:i.rpId,timeout:i.timeout,userVerification:i.userVerification||"preferred"}}),s=r.response,a={id:r.id,rawId:n(r.rawId),type:r.type,response:{authenticatorData:n(s.authenticatorData),clientDataJSON:n(s.clientDataJSON),signature:n(s.signature)},clientExtensionResults:r.getClientExtensionResults(),authenticatorAttachment:r.authenticatorAttachment||void 0};s.userHandle&&(a.response.userHandle=n(s.userHandle)),this.formData["credential-field"]=JSON.stringify(a),this.formData["action-field"]=t.successAction,this.overrideFormSubmit();const c=this.el?.shadowRoot,h=c?.querySelector("form");if(h){const e=h.querySelector('[name="credential-field"]')||h.querySelector("#credential-field"),i=h.querySelector('[name="action-field"]')||h.querySelector("#action-field");e&&(e.value=JSON.stringify(a)),i&&(i.value=t.successAction),h.submit()}}catch(t){if("AbortError"===t?.name||"NotAllowedError"===t?.name)return;console.error("Conditional mediation error:",t)}}handleButtonClick=t=>{if("submit"!==t.type)if(this.buttonClick.emit(t),"SOCIAL"===t.type&&t.value&&this.shouldAutoNavigate){const e=this.getProviderHref(t.value);if(e){const t=this.extractScreenIdFromHref(e);return void(t&&this.apiUrl?this.navigateToScreen(t,e):window.location.href=e)}this.handleSocialLogin(t.value)}else"RESEND_BUTTON"===t.type&&this.shouldAutoNavigate&&this.handleResend();else{if(this._screen&&this.hasUnfilledRequiredFields(this._screen))return;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 o=this.buildUrl("/authorize?"+new URLSearchParams(i));this.navigate.emit({url:o}),window.location.href=o}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 o=e.match(/\/u2\/([^/]+)$/);return o&&"login"!==o[1]&&"screen"!==o[1]?o[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}isRequiredFieldFilled(t){const e=this.formData[t.id];return"BOOLEAN"===t.type||"LEGAL"===t.type?"true"===e:"string"==typeof e&&""!==e.trim()}hasUnfilledRequiredFields(t){return(t.components??[]).some((t=>!1!==t.visible&&"required"in t&&!0===t.required&&v.has(t.type)&&!this.isRequiredFieldFilled(t)))}getChoiceButtonText(t){const e=t.config;return e?.text??""}render(){const t=this._screen;if(this.loading&&!t)return n("div",{class:"widget-container"},n("div",{class:"loading-spinner"}));if(!t)return n("div",{class:"widget-container"},n("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))||[],o=[...t.components??[]],r=o.filter((t=>!1!==t.visible)).sort(((t,e)=>(t.order??0)-(e.order??0))),s=o.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=c.filter((t=>"NEXT_BUTTON"===t.type)),u=f.length===c.length&&f.length>5,p=this.hasUnfilledRequiredFields(t),g=this.listFilter.trim().toLowerCase(),m=u&&g?f.filter((t=>this.getChoiceButtonText(t).toLowerCase().includes(g))):f,w=t=>{const e=t.config;return["social-buttons","button","button-secondary","button-social","button-social-content","button-social-text","button-social-subtitle","button-social-badge","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,"button-social-badge-"+e,"social-icon-"+e]}))].join(", ")},x=this._theme?.widget?.logo_url||this._branding?.logo_url;return n("div",{class:"widget-container",part:"container","data-authstack-container":!0},n("header",{class:"widget-header",part:"header"},x&&n("div",{class:"logo-wrapper",part:"logo-wrapper"},n("img",{class:"logo",part:"logo",src:x,alt:"Logo"})),t.title&&n("h1",{class:"title",part:"title",innerHTML:b(t.title)}),t.description&&n("p",{class:"description",part:"description",innerHTML:b(t.description)})),n("div",{class:"widget-body",part:"body"},e.map((t=>n("div",{class:"message message-error",part:"message message-error",key:t.id??t.text},t.text))),i.map((t=>n("div",{class:"message message-success",part:"message message-success",key:t.id??t.text},t.text))),n("form",{onSubmit:this.handleSubmit,action:t.action,method:t.method||"POST",part:"form"},s.map((t=>n("input",{type:"hidden",name:t.id,id:t.id,key:t.id,value:this.formData[t.id]||""}))),n("div",{class:"form-content"},a.length>0&&n("div",{class:"social-section",part:"social-section"},a.map((t=>n("authhero-node",{key:t.id,component:t,locale:this.locale,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:w(t)})))),a.length>0&&c.length>0&&l&&n("div",{class:"divider",part:"divider"},n("span",{class:"divider-text"},d)),n("div",{class:"fields-section",part:"fields-section"},u&&n("input",{type:"text",class:"choice-list-search",part:"choice-list-search",placeholder:"Search","aria-label":"Search",autocomplete:"off",value:this.listFilter,onInput:t=>this.listFilter=t.target.value,onKeyDown:t=>{"Enter"===t.key&&t.preventDefault()}}),n("div",{class:u?"fields-list fields-list-scroll":"fields-list",part:u?"fields-list fields-list-scroll":"fields-list"},(u?m:c).map((t=>n("authhero-node",{key:t.id,component:t,locale:this.locale,value:this.formData[t.id],onFieldChange:t=>this.handleInputChange(t.detail.id,t.detail.value),onButtonClick:t=>this.handleButtonClick(t.detail),disabled:this.loading||"NEXT_BUTTON"===t.type&&p}))),u&&0===m.length&&n("div",{class:"choice-list-empty",part:"choice-list-empty"},"No matches"))))),t.links&&t.links.length>0&&n("div",{class:"links",part:"links"},t.links.map((t=>n("span",{class:"link-wrapper",part:"link-wrapper",key:t.id??t.href},t.linkText?n("span",null,t.text," ",n("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)):n("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&&n("div",{class:"widget-footer",part:"footer",innerHTML:b(t.footer)})))}static get watchers(){return{screenId:[{watchScreenId:0}],screen:[{watchScreen:0}],branding:[{watchBranding:0}],theme:[{watchTheme:0}],authParams:[{watchAuthParams:0}]}}static get style(){return":host{display:block;font-family:var(--ah-font-family, 'ulp-font', -apple-system, BlinkMacSystemFont, Roboto, Helvetica, sans-serif);font-size:var(--ah-font-size-base, 16px);line-height:var(--ah-line-height-base, 1.5);color:var(--ah-color-text, #1e212a);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.widget-container{width:var(--ah-widget-max-width, 400px);margin:0 auto;background-color:var(--ah-color-bg, #ffffff);border-radius:var(--ah-widget-radius, 5px);border:var(--ah-widget-border-width, 0) solid var(--ah-widget-border-color, transparent);box-shadow:var(--ah-widget-shadow, 0 4px 22px 0 rgba(0, 0, 0, 0.11));box-sizing:border-box}.widget-header{padding:var(--ah-header-padding, 40px 48px 24px)}.widget-body{padding:var(--ah-body-padding, 0 48px 40px)}.logo-wrapper{display:var(--ah-logo-display, flex);justify-content:var(--ah-logo-align, center);margin-bottom:8px}.logo{display:block;height:var(--ah-logo-height, 52px);max-width:100%;width:auto;object-fit:contain}.title{font-size:var(--ah-font-size-title, 24px);font-weight:var(--ah-font-weight-title, 700);text-align:var(--ah-title-align, center);margin:var(--ah-title-margin, 24px 0 24px);color:var(--ah-color-text-header, var(--ah-color-header, #1e212a));line-height:1.2}.description{font-size:var(--ah-font-size-subtitle, 16px);font-weight:var(--ah-font-weight-subtitle, 400);text-align:var(--ah-title-align, center);margin:var(--ah-description-margin, 0 0 8px);color:var(--ah-color-text, #1e212a);line-height:1.5}.message{padding:12px 16px;border-radius:4px;margin-bottom:16px;font-size:14px;line-height:1.5}.message-error{background-color:var(--ah-color-error-bg, #ffeaea);color:var(--ah-color-error, #d03c38);border-left:3px solid var(--ah-color-error, #d03c38)}.message-success{background-color:var(--ah-color-success-bg, #e6f9f1);color:var(--ah-color-success, #13a769);border-left:3px solid var(--ah-color-success, #13a769)}form{display:flex;flex-direction:column}.form-content{display:flex;flex-direction:column}.social-section{display:flex;flex-direction:column;gap:8px;order:var(--ah-social-order, 2)}.fields-section{display:flex;flex-direction:column;order:var(--ah-fields-order, 0)}.fields-list{display:flex;flex-direction:column}.fields-list-scroll{max-height:var(--ah-choice-list-max-height, 320px);overflow-y:auto;gap:var(--ah-choice-list-gap, 8px);padding-right:4px}.choice-list-search{width:100%;padding:16px;margin-bottom:12px;font-size:16px;font-family:inherit;color:var(--ah-color-input-text, var(--ah-color-text, #1e212a));background-color:var(--ah-color-input-bg, #ffffff);border:var(--ah-input-border-width, 1px) solid var(--ah-color-border, #c9cace);border-radius:var(--ah-input-radius, 3px);outline:none;box-sizing:border-box;transition:border-color 0.15s ease-out, box-shadow 0.15s ease-out}.choice-list-search:hover{border-color:var(--ah-color-border-hover, #65676e)}.choice-list-search:focus{border-color:var(--ah-color-primary, var(--ah-color-link, #635dff))}.choice-list-empty{padding:16px;text-align:center;font-size:14px;color:var(--ah-color-text-muted, #65676e)}.divider{display:flex;align-items:center;text-align:center;margin:16px 0;order:var(--ah-divider-order, 1)}.divider::before,.divider::after{content:'';flex:1;border-bottom:1px solid var(--ah-color-border-muted, #c9cace)}.divider-text{padding:0 10px;font-size:12px;font-weight:400;color:var(--ah-color-text-muted, #65676e);text-transform:uppercase;letter-spacing:0}.links{display:flex;flex-direction:column;align-items:center;gap:8px;margin-top:16px}.link-wrapper{font-size:var(--ah-font-size-body, 14px);font-weight:var(--ah-font-weight-body, 400);color:var(--ah-color-text, #1e212a)}.link{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:var(--ah-font-size-link, 14px);font-weight:var(--ah-font-weight-link, 400);transition:color 150ms ease}.link:hover{text-decoration:underline}.link:focus-visible{outline:2px solid var(--ah-color-focus-ring, var(--ah-color-link, #635dff));outline-offset:2px;border-radius:2px}.widget-footer{margin-top:16px;text-align:center;font-size:12px;color:var(--ah-color-text-muted, #65676e)}.widget-footer a{color:var(--ah-color-link, #635dff);text-decoration:var(--ah-link-decoration, none);font-size:12px;transition:color 150ms ease}.widget-footer a:hover{text-decoration:underline}.widget-footer a:focus-visible{outline:2px solid var(--ah-color-focus-ring, var(--ah-color-link, #635dff));outline-offset:2px;border-radius:2px}.loading-spinner{width:32px;height:32px;margin:24px auto;border:3px solid var(--ah-color-border-muted, #e0e1e3);border-top-color:var(--ah-color-primary, #635dff);border-radius:50%;animation:spin 0.8s linear infinite}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.error-message{text-align:center;color:var(--ah-color-error, #d03c38);padding:16px;font-size:14px}@media (max-width: 480px){:host{display:block;width:100%;min-height:100vh;background-color:var(--ah-color-bg, #ffffff)}.widget-container{box-shadow:none;border-radius:0;width:100%;margin:0}.widget-header{padding:24px 16px 16px}.widget-body{padding:0 16px 24px}}"}},[513,"authhero-widget",{screen:[1],apiUrl:[1,"api-url"],baseUrl:[1,"base-url"],state:[1025],screenId:[1025,"screen-id"],authParams:[1,"auth-params"],statePersistence:[1,"state-persistence"],storageKey:[1,"storage-key"],branding:[1],theme:[1],loading:[1028],autoSubmit:[4,"auto-submit"],autoNavigate:[4,"auto-navigate"],locale:[1],_screen:[32],_authParams:[32],_branding:[32],_theme:[32],formData:[32],listFilter:[32]},void 0,{screenId:[{watchScreenId:0}],screen:[{watchScreen:0}],branding:[{watchBranding:0}],theme:[{watchTheme:0}],authParams:[{watchAuthParams:0}]}]);function S(){"undefined"!=typeof customElements&&["authhero-widget","authhero-node"].forEach((e=>{switch(e){case"authhero-widget":customElements.get(t(e))||customElements.define(t(e),y);break;case"authhero-node":customElements.get(t(e))||r()}}))}S();const k=y,A=S;export{k as AuthheroWidget,A as defineCustomElement}
|