@authhero/widget 0.7.1 → 0.8.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/README.md +118 -66
- package/dist/authhero-widget/authhero-widget.esm.js +1 -1
- package/dist/authhero-widget/index.esm.js +1 -1
- package/dist/authhero-widget/{p-29e844e0.entry.js → p-188ffffd.entry.js} +1 -1
- package/dist/authhero-widget/p-6e32b31d.entry.js +1 -0
- package/dist/authhero-widget/p-BzFenraS.js +2 -0
- package/dist/cjs/authhero-node.cjs.entry.js +1 -1
- package/dist/cjs/authhero-widget.cjs.entry.js +312 -33
- package/dist/cjs/authhero-widget.cjs.js +3 -3
- package/dist/cjs/{index-CFDpaA1R.js → index-xXst3JOw.js} +132 -1830
- package/dist/cjs/index.cjs.js +1 -1
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/collection/collection-manifest.json +1 -1
- package/dist/collection/components/authhero-widget/authhero-widget.js +470 -34
- 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-7EkYyes4.js +1 -0
- package/dist/components/{p-uGYnrdy5.js → p-DnNvVt9e.js} +1 -1
- package/dist/esm/authhero-node.entry.js +1 -1
- package/dist/esm/authhero-widget.entry.js +312 -33
- package/dist/esm/authhero-widget.js +4 -4
- package/dist/esm/{index-DKg5ozw7.js → index-BzFenraS.js} +132 -1830
- package/dist/esm/index.js +1 -1
- package/dist/esm/loader.js +3 -3
- package/dist/types/components/authhero-widget/authhero-widget.d.ts +96 -4
- package/dist/types/components.d.ts +66 -4
- package/hydrate/index.js +4114 -3849
- package/hydrate/index.mjs +4114 -3849
- package/package.json +2 -2
- package/dist/authhero-widget/p-553c2cbe.entry.js +0 -1
- package/dist/authhero-widget/p-DKg5ozw7.js +0 -2
- package/dist/components/p-JzMtjMQb.js +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as registerInstance, c as createEvent, g as getElement, h } from './index-
|
|
1
|
+
import { r as registerInstance, c as createEvent, g as getElement, h } from './index-BzFenraS.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* AuthHero Widget - Branding Utilities
|
|
@@ -311,8 +311,43 @@ const AuthheroWidget = class {
|
|
|
311
311
|
/**
|
|
312
312
|
* API endpoint to fetch the initial screen from.
|
|
313
313
|
* If provided, the widget will fetch the screen on load.
|
|
314
|
+
* Can include {screenId} placeholder which will be replaced with the current screen.
|
|
315
|
+
* Example: "/u2/screen/{screenId}" or "https://auth.example.com/u2/screen/{screenId}"
|
|
314
316
|
*/
|
|
315
317
|
apiUrl;
|
|
318
|
+
/**
|
|
319
|
+
* Base URL for all API calls. Used when widget is embedded on a different domain.
|
|
320
|
+
* If not provided, relative URLs are used.
|
|
321
|
+
* Example: "https://auth.example.com"
|
|
322
|
+
*/
|
|
323
|
+
baseUrl;
|
|
324
|
+
/**
|
|
325
|
+
* Login session state token. Required for social login and maintaining session.
|
|
326
|
+
*/
|
|
327
|
+
state;
|
|
328
|
+
/**
|
|
329
|
+
* Current screen ID. Used with apiUrl to fetch screen configuration.
|
|
330
|
+
* When statePersistence is 'url', this is synced with the URL.
|
|
331
|
+
*/
|
|
332
|
+
screenId;
|
|
333
|
+
/**
|
|
334
|
+
* OAuth/OIDC parameters for social login redirects.
|
|
335
|
+
* Can be passed as a JSON string or object.
|
|
336
|
+
*/
|
|
337
|
+
authParams;
|
|
338
|
+
/**
|
|
339
|
+
* Where to persist state and screen ID.
|
|
340
|
+
* - 'url': Updates URL path/query (default for standalone pages)
|
|
341
|
+
* - 'session': Uses sessionStorage (for embedded widgets)
|
|
342
|
+
* - 'memory': No persistence, state only in memory
|
|
343
|
+
* @default 'memory'
|
|
344
|
+
*/
|
|
345
|
+
statePersistence = "memory";
|
|
346
|
+
/**
|
|
347
|
+
* Storage key prefix for session/local storage persistence.
|
|
348
|
+
* @default 'authhero_widget'
|
|
349
|
+
*/
|
|
350
|
+
storageKey = "authhero_widget";
|
|
316
351
|
/**
|
|
317
352
|
* Branding configuration from AuthHero API.
|
|
318
353
|
* Controls logo, primary color, and page background.
|
|
@@ -337,10 +372,21 @@ const AuthheroWidget = class {
|
|
|
337
372
|
* @default false
|
|
338
373
|
*/
|
|
339
374
|
autoSubmit = false;
|
|
375
|
+
/**
|
|
376
|
+
* Whether the widget should handle navigation automatically.
|
|
377
|
+
* When true, social login buttons redirect, links navigate, etc.
|
|
378
|
+
* When false, only events are emitted.
|
|
379
|
+
* @default false (same as autoSubmit when not specified)
|
|
380
|
+
*/
|
|
381
|
+
autoNavigate;
|
|
340
382
|
/**
|
|
341
383
|
* Internal parsed screen state.
|
|
342
384
|
*/
|
|
343
385
|
_screen;
|
|
386
|
+
/**
|
|
387
|
+
* Internal parsed auth params state.
|
|
388
|
+
*/
|
|
389
|
+
_authParams;
|
|
344
390
|
/**
|
|
345
391
|
* Internal parsed branding state.
|
|
346
392
|
*/
|
|
@@ -387,12 +433,12 @@ const AuthheroWidget = class {
|
|
|
387
433
|
*/
|
|
388
434
|
screenChange;
|
|
389
435
|
watchScreen(newValue) {
|
|
390
|
-
if (typeof newValue ===
|
|
436
|
+
if (typeof newValue === "string") {
|
|
391
437
|
try {
|
|
392
438
|
this._screen = JSON.parse(newValue);
|
|
393
439
|
}
|
|
394
440
|
catch {
|
|
395
|
-
console.error(
|
|
441
|
+
console.error("Failed to parse screen JSON");
|
|
396
442
|
}
|
|
397
443
|
}
|
|
398
444
|
else {
|
|
@@ -403,12 +449,12 @@ const AuthheroWidget = class {
|
|
|
403
449
|
}
|
|
404
450
|
}
|
|
405
451
|
watchBranding(newValue) {
|
|
406
|
-
if (typeof newValue ===
|
|
452
|
+
if (typeof newValue === "string") {
|
|
407
453
|
try {
|
|
408
454
|
this._branding = JSON.parse(newValue);
|
|
409
455
|
}
|
|
410
456
|
catch {
|
|
411
|
-
console.error(
|
|
457
|
+
console.error("Failed to parse branding JSON");
|
|
412
458
|
}
|
|
413
459
|
}
|
|
414
460
|
else {
|
|
@@ -417,12 +463,12 @@ const AuthheroWidget = class {
|
|
|
417
463
|
this.applyThemeStyles();
|
|
418
464
|
}
|
|
419
465
|
watchTheme(newValue) {
|
|
420
|
-
if (typeof newValue ===
|
|
466
|
+
if (typeof newValue === "string") {
|
|
421
467
|
try {
|
|
422
468
|
this._theme = JSON.parse(newValue);
|
|
423
469
|
}
|
|
424
470
|
catch {
|
|
425
|
-
console.error(
|
|
471
|
+
console.error("Failed to parse theme JSON");
|
|
426
472
|
}
|
|
427
473
|
}
|
|
428
474
|
else {
|
|
@@ -430,6 +476,19 @@ const AuthheroWidget = class {
|
|
|
430
476
|
}
|
|
431
477
|
this.applyThemeStyles();
|
|
432
478
|
}
|
|
479
|
+
watchAuthParams(newValue) {
|
|
480
|
+
if (typeof newValue === "string") {
|
|
481
|
+
try {
|
|
482
|
+
this._authParams = JSON.parse(newValue);
|
|
483
|
+
}
|
|
484
|
+
catch {
|
|
485
|
+
console.error("Failed to parse authParams JSON");
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
else {
|
|
489
|
+
this._authParams = newValue;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
433
492
|
/**
|
|
434
493
|
* Apply branding and theme as CSS custom properties
|
|
435
494
|
*/
|
|
@@ -437,36 +496,164 @@ const AuthheroWidget = class {
|
|
|
437
496
|
const vars = mergeThemeVars(this._branding, this._theme);
|
|
438
497
|
applyCssVars(this.el, vars);
|
|
439
498
|
}
|
|
499
|
+
/**
|
|
500
|
+
* Get the effective autoNavigate value (defaults to autoSubmit if not set)
|
|
501
|
+
*/
|
|
502
|
+
get shouldAutoNavigate() {
|
|
503
|
+
return this.autoNavigate ?? this.autoSubmit;
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Build the full URL for API calls
|
|
507
|
+
*/
|
|
508
|
+
buildUrl(path) {
|
|
509
|
+
if (this.baseUrl) {
|
|
510
|
+
return new URL(path, this.baseUrl).toString();
|
|
511
|
+
}
|
|
512
|
+
return path;
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Load state from URL or storage based on statePersistence setting
|
|
516
|
+
*/
|
|
517
|
+
loadPersistedState() {
|
|
518
|
+
if (this.statePersistence === "url") {
|
|
519
|
+
const url = new URL(window.location.href);
|
|
520
|
+
const stateParam = url.searchParams.get("state");
|
|
521
|
+
if (stateParam && !this.state) {
|
|
522
|
+
this.state = stateParam;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
else if (this.statePersistence === "session") {
|
|
526
|
+
try {
|
|
527
|
+
const stored = sessionStorage.getItem(`${this.storageKey}_state`);
|
|
528
|
+
if (stored && !this.state) {
|
|
529
|
+
this.state = stored;
|
|
530
|
+
}
|
|
531
|
+
const storedScreenId = sessionStorage.getItem(`${this.storageKey}_screenId`);
|
|
532
|
+
if (storedScreenId && !this.screenId) {
|
|
533
|
+
this.screenId = storedScreenId;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
catch {
|
|
537
|
+
// sessionStorage not available
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Save state to URL or storage based on statePersistence setting
|
|
543
|
+
*/
|
|
544
|
+
persistState() {
|
|
545
|
+
if (this.statePersistence === "url") {
|
|
546
|
+
const url = new URL(window.location.href);
|
|
547
|
+
if (this.state) {
|
|
548
|
+
url.searchParams.set("state", this.state);
|
|
549
|
+
}
|
|
550
|
+
if (this.screenId) {
|
|
551
|
+
url.searchParams.set("screen", this.screenId);
|
|
552
|
+
}
|
|
553
|
+
window.history.replaceState({}, "", url.toString());
|
|
554
|
+
}
|
|
555
|
+
else if (this.statePersistence === "session") {
|
|
556
|
+
try {
|
|
557
|
+
if (this.state) {
|
|
558
|
+
sessionStorage.setItem(`${this.storageKey}_state`, this.state);
|
|
559
|
+
}
|
|
560
|
+
if (this.screenId) {
|
|
561
|
+
sessionStorage.setItem(`${this.storageKey}_screenId`, this.screenId);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
catch {
|
|
565
|
+
// sessionStorage not available
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
440
569
|
async componentWillLoad() {
|
|
441
570
|
// Parse initial props
|
|
442
571
|
this.watchScreen(this.screen);
|
|
443
572
|
this.watchBranding(this.branding);
|
|
444
573
|
this.watchTheme(this.theme);
|
|
574
|
+
this.watchAuthParams(this.authParams);
|
|
575
|
+
// Load persisted state if available
|
|
576
|
+
this.loadPersistedState();
|
|
445
577
|
// Fetch screen from API if URL provided and no screen prop
|
|
446
578
|
if (this.apiUrl && !this._screen) {
|
|
447
|
-
await this.fetchScreen();
|
|
579
|
+
await this.fetchScreen(this.screenId);
|
|
448
580
|
}
|
|
449
581
|
}
|
|
450
|
-
|
|
582
|
+
/**
|
|
583
|
+
* Fetch screen configuration from the API
|
|
584
|
+
* @param screenIdOverride Optional screen ID to fetch (overrides this.screenId)
|
|
585
|
+
* @param nodeId Optional node ID for flow navigation
|
|
586
|
+
*/
|
|
587
|
+
async fetchScreen(screenIdOverride, nodeId) {
|
|
451
588
|
if (!this.apiUrl)
|
|
452
589
|
return;
|
|
590
|
+
const currentScreenId = screenIdOverride || this.screenId;
|
|
591
|
+
// Build the API URL, replacing {screenId} placeholder if present
|
|
592
|
+
let url = this.apiUrl;
|
|
593
|
+
if (currentScreenId && url.includes("{screenId}")) {
|
|
594
|
+
url = url.replace("{screenId}", encodeURIComponent(currentScreenId));
|
|
595
|
+
}
|
|
596
|
+
// Add state and nodeId as query params
|
|
597
|
+
const urlObj = new URL(url, this.baseUrl || window.location.origin);
|
|
598
|
+
if (this.state) {
|
|
599
|
+
urlObj.searchParams.set("state", this.state);
|
|
600
|
+
}
|
|
601
|
+
if (nodeId) {
|
|
602
|
+
urlObj.searchParams.set("nodeId", nodeId);
|
|
603
|
+
}
|
|
453
604
|
this.loading = true;
|
|
454
605
|
try {
|
|
455
|
-
const response = await fetch(this.
|
|
456
|
-
credentials:
|
|
606
|
+
const response = await fetch(this.buildUrl(urlObj.pathname + urlObj.search), {
|
|
607
|
+
credentials: "include",
|
|
457
608
|
headers: {
|
|
458
|
-
Accept:
|
|
609
|
+
Accept: "application/json",
|
|
459
610
|
},
|
|
460
611
|
});
|
|
461
612
|
if (response.ok) {
|
|
462
|
-
|
|
613
|
+
const data = await response.json();
|
|
614
|
+
// Handle different response formats
|
|
615
|
+
if (data.screen) {
|
|
616
|
+
this._screen = data.screen;
|
|
617
|
+
if (data.branding) {
|
|
618
|
+
this._branding = data.branding;
|
|
619
|
+
this.applyThemeStyles();
|
|
620
|
+
}
|
|
621
|
+
// Update state if returned
|
|
622
|
+
if (data.state) {
|
|
623
|
+
this.state = data.state;
|
|
624
|
+
}
|
|
625
|
+
// Update screenId if returned in response
|
|
626
|
+
if (data.screenId) {
|
|
627
|
+
this.screenId = data.screenId;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
else {
|
|
631
|
+
// Response is the screen itself
|
|
632
|
+
this._screen = data;
|
|
633
|
+
}
|
|
463
634
|
if (this._screen) {
|
|
635
|
+
// If we fetched with a screenId override, update our stored screenId
|
|
636
|
+
if (currentScreenId && currentScreenId !== this.screenId) {
|
|
637
|
+
this.screenId = currentScreenId;
|
|
638
|
+
}
|
|
464
639
|
this.screenChange.emit(this._screen);
|
|
640
|
+
this.persistState();
|
|
465
641
|
}
|
|
466
642
|
}
|
|
643
|
+
else {
|
|
644
|
+
const error = await response
|
|
645
|
+
.json()
|
|
646
|
+
.catch(() => ({ message: "Failed to load screen" }));
|
|
647
|
+
this.flowError.emit({
|
|
648
|
+
message: error.message || "Failed to load screen",
|
|
649
|
+
});
|
|
650
|
+
}
|
|
467
651
|
}
|
|
468
652
|
catch (error) {
|
|
469
|
-
console.error(
|
|
653
|
+
console.error("Failed to fetch screen:", error);
|
|
654
|
+
this.flowError.emit({
|
|
655
|
+
message: error instanceof Error ? error.message : "Failed to fetch screen",
|
|
656
|
+
});
|
|
470
657
|
}
|
|
471
658
|
finally {
|
|
472
659
|
this.loading = false;
|
|
@@ -494,17 +681,17 @@ const AuthheroWidget = class {
|
|
|
494
681
|
// Submit to the server
|
|
495
682
|
this.loading = true;
|
|
496
683
|
try {
|
|
497
|
-
const response = await fetch(this._screen.action, {
|
|
684
|
+
const response = await fetch(this.buildUrl(this._screen.action), {
|
|
498
685
|
method: this._screen.method,
|
|
499
|
-
credentials:
|
|
686
|
+
credentials: "include",
|
|
500
687
|
headers: {
|
|
501
|
-
|
|
502
|
-
Accept:
|
|
688
|
+
"Content-Type": "application/json",
|
|
689
|
+
Accept: "application/json",
|
|
503
690
|
},
|
|
504
691
|
body: JSON.stringify({ data: this.formData }),
|
|
505
692
|
});
|
|
506
|
-
const contentType = response.headers.get(
|
|
507
|
-
if (contentType?.includes(
|
|
693
|
+
const contentType = response.headers.get("content-type");
|
|
694
|
+
if (contentType?.includes("application/json")) {
|
|
508
695
|
const result = await response.json();
|
|
509
696
|
// Handle different response types
|
|
510
697
|
if (result.redirect) {
|
|
@@ -512,17 +699,31 @@ const AuthheroWidget = class {
|
|
|
512
699
|
this.flowComplete.emit({ redirectUrl: result.redirect });
|
|
513
700
|
// Also emit navigate for backwards compatibility
|
|
514
701
|
this.navigate.emit({ url: result.redirect });
|
|
702
|
+
// Auto-navigate if enabled
|
|
703
|
+
if (this.shouldAutoNavigate) {
|
|
704
|
+
window.location.href = result.redirect;
|
|
705
|
+
}
|
|
515
706
|
}
|
|
516
707
|
else if (result.screen) {
|
|
517
708
|
// Next screen
|
|
518
709
|
this._screen = result.screen;
|
|
519
710
|
this.formData = {};
|
|
520
711
|
this.screenChange.emit(result.screen);
|
|
712
|
+
// Update screenId if returned in response
|
|
713
|
+
if (result.screenId) {
|
|
714
|
+
this.screenId = result.screenId;
|
|
715
|
+
}
|
|
716
|
+
this.persistState();
|
|
521
717
|
// Apply branding if included
|
|
522
718
|
if (result.branding) {
|
|
523
719
|
this._branding = result.branding;
|
|
524
720
|
this.applyThemeStyles();
|
|
525
721
|
}
|
|
722
|
+
// Update state if returned
|
|
723
|
+
if (result.state) {
|
|
724
|
+
this.state = result.state;
|
|
725
|
+
this.persistState();
|
|
726
|
+
}
|
|
526
727
|
}
|
|
527
728
|
else if (result.complete) {
|
|
528
729
|
// Flow complete without redirect
|
|
@@ -536,9 +737,9 @@ const AuthheroWidget = class {
|
|
|
536
737
|
}
|
|
537
738
|
}
|
|
538
739
|
catch (err) {
|
|
539
|
-
console.error(
|
|
740
|
+
console.error("Form submission failed:", err);
|
|
540
741
|
this.flowError.emit({
|
|
541
|
-
message: err instanceof Error ? err.message :
|
|
742
|
+
message: err instanceof Error ? err.message : "Form submission failed",
|
|
542
743
|
});
|
|
543
744
|
}
|
|
544
745
|
finally {
|
|
@@ -547,14 +748,79 @@ const AuthheroWidget = class {
|
|
|
547
748
|
};
|
|
548
749
|
handleButtonClick = (detail) => {
|
|
549
750
|
// If this is a submit button click, trigger form submission
|
|
550
|
-
if (detail.type ===
|
|
751
|
+
if (detail.type === "submit") {
|
|
551
752
|
// Create a synthetic submit event and call handleSubmit
|
|
552
753
|
const syntheticEvent = { preventDefault: () => { } };
|
|
553
754
|
this.handleSubmit(syntheticEvent);
|
|
554
755
|
return;
|
|
555
756
|
}
|
|
757
|
+
// Always emit the event
|
|
556
758
|
this.buttonClick.emit(detail);
|
|
759
|
+
// Handle social login if autoNavigate is enabled
|
|
760
|
+
if (detail.type === "SOCIAL" && detail.value && this.shouldAutoNavigate) {
|
|
761
|
+
this.handleSocialLogin(detail.value);
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
// Handle resend button
|
|
765
|
+
if (detail.type === "RESEND_BUTTON" && this.shouldAutoNavigate) {
|
|
766
|
+
this.handleResend();
|
|
767
|
+
return;
|
|
768
|
+
}
|
|
557
769
|
};
|
|
770
|
+
/**
|
|
771
|
+
* Handle social login redirect
|
|
772
|
+
*/
|
|
773
|
+
handleSocialLogin(connection) {
|
|
774
|
+
const params = this._authParams || {};
|
|
775
|
+
const queryParams = {
|
|
776
|
+
connection,
|
|
777
|
+
};
|
|
778
|
+
// Add state
|
|
779
|
+
if (this.state) {
|
|
780
|
+
queryParams.state = this.state;
|
|
781
|
+
}
|
|
782
|
+
else if (params.state) {
|
|
783
|
+
queryParams.state = params.state;
|
|
784
|
+
}
|
|
785
|
+
// Add client_id
|
|
786
|
+
if (params.client_id) {
|
|
787
|
+
queryParams.client_id = params.client_id;
|
|
788
|
+
}
|
|
789
|
+
// Add optional params
|
|
790
|
+
if (params.redirect_uri)
|
|
791
|
+
queryParams.redirect_uri = params.redirect_uri;
|
|
792
|
+
if (params.scope)
|
|
793
|
+
queryParams.scope = params.scope;
|
|
794
|
+
if (params.audience)
|
|
795
|
+
queryParams.audience = params.audience;
|
|
796
|
+
if (params.nonce)
|
|
797
|
+
queryParams.nonce = params.nonce;
|
|
798
|
+
if (params.response_type)
|
|
799
|
+
queryParams.response_type = params.response_type;
|
|
800
|
+
const socialUrl = this.buildUrl("/authorize?" + new URLSearchParams(queryParams).toString());
|
|
801
|
+
// Emit navigate event and redirect
|
|
802
|
+
this.navigate.emit({ url: socialUrl });
|
|
803
|
+
window.location.href = socialUrl;
|
|
804
|
+
}
|
|
805
|
+
/**
|
|
806
|
+
* Handle resend button click (e.g., resend OTP code)
|
|
807
|
+
*/
|
|
808
|
+
async handleResend() {
|
|
809
|
+
if (!this._screen?.action)
|
|
810
|
+
return;
|
|
811
|
+
try {
|
|
812
|
+
const url = this._screen.action +
|
|
813
|
+
(this._screen.action.includes("?") ? "&" : "?") +
|
|
814
|
+
"action=resend";
|
|
815
|
+
await fetch(this.buildUrl(url), {
|
|
816
|
+
method: "POST",
|
|
817
|
+
credentials: "include",
|
|
818
|
+
});
|
|
819
|
+
}
|
|
820
|
+
catch (error) {
|
|
821
|
+
console.error("Resend failed:", error);
|
|
822
|
+
}
|
|
823
|
+
}
|
|
558
824
|
handleLinkClick = (e, link) => {
|
|
559
825
|
// Emit the event so the consuming app can handle it
|
|
560
826
|
this.linkClick.emit({
|
|
@@ -562,9 +828,9 @@ const AuthheroWidget = class {
|
|
|
562
828
|
href: link.href,
|
|
563
829
|
text: link.text,
|
|
564
830
|
});
|
|
565
|
-
// If
|
|
831
|
+
// If autoNavigate is enabled, let the browser handle the navigation
|
|
566
832
|
// Otherwise, prevent default and let the app decide
|
|
567
|
-
if (!this.
|
|
833
|
+
if (!this.shouldAutoNavigate) {
|
|
568
834
|
e.preventDefault();
|
|
569
835
|
}
|
|
570
836
|
};
|
|
@@ -572,13 +838,13 @@ const AuthheroWidget = class {
|
|
|
572
838
|
* Get error messages from the screen-level messages array.
|
|
573
839
|
*/
|
|
574
840
|
getScreenErrors() {
|
|
575
|
-
return this._screen?.messages?.filter((m) => m.type ===
|
|
841
|
+
return this._screen?.messages?.filter((m) => m.type === "error") || [];
|
|
576
842
|
}
|
|
577
843
|
/**
|
|
578
844
|
* Get success messages from the screen-level messages array.
|
|
579
845
|
*/
|
|
580
846
|
getScreenSuccesses() {
|
|
581
|
-
return this._screen?.messages?.filter((m) => m.type ===
|
|
847
|
+
return this._screen?.messages?.filter((m) => m.type === "success") || [];
|
|
582
848
|
}
|
|
583
849
|
/**
|
|
584
850
|
* Sort components by order.
|
|
@@ -596,13 +862,13 @@ const AuthheroWidget = class {
|
|
|
596
862
|
isSocialComponent(component) {
|
|
597
863
|
// Check the type property directly - FormComponent has a 'type' field
|
|
598
864
|
// SocialField has type 'SOCIAL'
|
|
599
|
-
return component.type ===
|
|
865
|
+
return component.type === "SOCIAL";
|
|
600
866
|
}
|
|
601
867
|
/**
|
|
602
868
|
* Check if a component is a divider.
|
|
603
869
|
*/
|
|
604
870
|
isDividerComponent(component) {
|
|
605
|
-
return component.type ===
|
|
871
|
+
return component.type === "DIVIDER";
|
|
606
872
|
}
|
|
607
873
|
render() {
|
|
608
874
|
if (this.loading && !this._screen) {
|
|
@@ -615,12 +881,22 @@ const AuthheroWidget = class {
|
|
|
615
881
|
const screenSuccesses = this.getScreenSuccesses();
|
|
616
882
|
const components = this.getOrderedComponents();
|
|
617
883
|
// Separate social, divider, and field components for layout ordering
|
|
618
|
-
const socialComponents = components.filter(c => this.isSocialComponent(c));
|
|
619
|
-
const fieldComponents = components.filter(c => !this.isSocialComponent(c) && !this.isDividerComponent(c));
|
|
620
|
-
const hasDivider = components.some(c => this.isDividerComponent(c));
|
|
884
|
+
const socialComponents = components.filter((c) => this.isSocialComponent(c));
|
|
885
|
+
const fieldComponents = components.filter((c) => !this.isSocialComponent(c) && !this.isDividerComponent(c));
|
|
886
|
+
const hasDivider = components.some((c) => this.isDividerComponent(c));
|
|
621
887
|
// Get logo URL from theme.widget (takes precedence) or branding
|
|
622
888
|
const logoUrl = this._theme?.widget?.logo_url || this._branding?.logo_url;
|
|
623
|
-
return (h("div", { class: "widget-container", part: "container" }, 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" }))), this._screen.title && (h("h1", { class: "title", part: "title" }, this._screen.title)), this._screen.description && (h("p", { class: "description", part: "description" }, this._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, part: "form" }, 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 }))))), socialComponents.length > 0 &&
|
|
889
|
+
return (h("div", { class: "widget-container", part: "container" }, 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" }))), this._screen.title && (h("h1", { class: "title", part: "title" }, this._screen.title)), this._screen.description && (h("p", { class: "description", part: "description" }, this._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, part: "form" }, 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 }))))), socialComponents.length > 0 &&
|
|
890
|
+
fieldComponents.length > 0 &&
|
|
891
|
+
hasDivider && (h("div", { class: "divider", part: "divider" }, h("span", { class: "divider-text" }, "Or"))), h("div", { class: "fields-section", part: "fields-section" }, 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 })))))), this._screen.links && this._screen.links.length > 0 && (h("div", { class: "links", part: "links" }, this._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, {
|
|
892
|
+
id: link.id,
|
|
893
|
+
href: link.href,
|
|
894
|
+
text: link.linkText || link.text,
|
|
895
|
+
}) }, link.linkText))) : (h("a", { href: link.href, class: "link", part: "link", onClick: (e) => this.handleLinkClick(e, {
|
|
896
|
+
id: link.id,
|
|
897
|
+
href: link.href,
|
|
898
|
+
text: link.text,
|
|
899
|
+
}) }, link.text))))))))));
|
|
624
900
|
}
|
|
625
901
|
static get watchers() { return {
|
|
626
902
|
"screen": [{
|
|
@@ -631,6 +907,9 @@ const AuthheroWidget = class {
|
|
|
631
907
|
}],
|
|
632
908
|
"theme": [{
|
|
633
909
|
"watchTheme": 0
|
|
910
|
+
}],
|
|
911
|
+
"authParams": [{
|
|
912
|
+
"watchAuthParams": 0
|
|
634
913
|
}]
|
|
635
914
|
}; }
|
|
636
915
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { p as promiseResolve, b as bootstrapLazy } from './index-
|
|
2
|
-
export { s as setNonce } from './index-
|
|
1
|
+
import { p as promiseResolve, b as bootstrapLazy } from './index-BzFenraS.js';
|
|
2
|
+
export { s as setNonce } from './index-BzFenraS.js';
|
|
3
3
|
import { g as globalScripts } from './app-globals-DQuL1Twl.js';
|
|
4
4
|
|
|
5
5
|
/*
|
|
6
|
-
Stencil Client Patch Browser v4.41.
|
|
6
|
+
Stencil Client Patch Browser v4.41.3 | MIT Licensed | https://stenciljs.com
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
var patchBrowser = () => {
|
|
@@ -17,5 +17,5 @@ var patchBrowser = () => {
|
|
|
17
17
|
|
|
18
18
|
patchBrowser().then(async (options) => {
|
|
19
19
|
await globalScripts();
|
|
20
|
-
return bootstrapLazy([["authhero-node",[[513,"authhero-node",{"component":[16],"value":[1],"disabled":[4],"passwordVisible":[32]}]]],["authhero-widget",[[513,"authhero-widget",{"screen":[1],"apiUrl":[1,"api-url"],"branding":[1],"theme":[1],"loading":[1028],"autoSubmit":[4,"auto-submit"],"_screen":[32],"_branding":[32],"_theme":[32],"formData":[32]},null,{"screen":[{"watchScreen":0}],"branding":[{"watchBranding":0}],"theme":[{"watchTheme":0}]}]]]], options);
|
|
20
|
+
return bootstrapLazy([["authhero-node",[[513,"authhero-node",{"component":[16],"value":[1],"disabled":[4],"passwordVisible":[32]}]]],["authhero-widget",[[513,"authhero-widget",{"screen":[1],"apiUrl":[1,"api-url"],"baseUrl":[1,"base-url"],"state":[1025],"screenId":[1025,"screen-id"],"authParams":[1,"auth-params"],"statePersistence":[1,"state-persistence"],"storageKey":[1,"storage-key"],"branding":[1],"theme":[1],"loading":[1028],"autoSubmit":[4,"auto-submit"],"autoNavigate":[4,"auto-navigate"],"_screen":[32],"_authParams":[32],"_branding":[32],"_theme":[32],"formData":[32]},null,{"screen":[{"watchScreen":0}],"branding":[{"watchBranding":0}],"theme":[{"watchTheme":0}],"authParams":[{"watchAuthParams":0}]}]]]], options);
|
|
21
21
|
});
|