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