@authon/react 0.3.2 → 0.7.16

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/index.cjs CHANGED
@@ -60,32 +60,35 @@ function AuthonProvider({ publishableKey, children, config }) {
60
60
  const [activeOrganization, setActiveOrganization] = (0, import_react.useState)(null);
61
61
  const clientRef = (0, import_react.useRef)(null);
62
62
  (0, import_react.useEffect)(() => {
63
+ let active = true;
64
+ let receivedSessionChange = false;
63
65
  const client = new import_js.Authon(publishableKey, config);
66
+ const sessionClient = client;
64
67
  clientRef.current = client;
65
- client.on("signedIn", (u) => {
66
- setUser(u);
68
+ const unsubscribeSession = sessionClient.onSessionChange((change) => {
69
+ if (!active) return;
70
+ receivedSessionChange = true;
71
+ setUser(change.user);
67
72
  setIsLoading(false);
68
- });
69
- client.on("signedOut", () => {
70
- setUser(null);
73
+ if (!change.user) setActiveOrganization(null);
71
74
  });
72
75
  client.on("error", () => {
73
76
  setIsLoading(false);
74
77
  });
75
- const existingUser = client.getUser();
76
- if (existingUser) {
77
- setUser(existingUser);
78
- }
79
- setIsLoading(false);
78
+ void sessionClient.waitUntilReady().then(() => {
79
+ if (!active) return;
80
+ if (!receivedSessionChange) setUser(client.getUser());
81
+ setIsLoading(false);
82
+ });
80
83
  return () => {
84
+ active = false;
85
+ unsubscribeSession();
81
86
  client.destroy();
82
87
  clientRef.current = null;
83
88
  };
84
89
  }, [publishableKey]);
85
90
  const signOut = (0, import_react.useCallback)(async () => {
86
91
  await clientRef.current?.signOut();
87
- setUser(null);
88
- setActiveOrganization(null);
89
92
  }, []);
90
93
  const openSignIn = (0, import_react.useCallback)(async () => {
91
94
  await clientRef.current?.openSignIn();
@@ -131,7 +134,7 @@ function useUser() {
131
134
  }
132
135
 
133
136
  // src/components/SignIn.tsx
134
- var import_react7 = require("react");
137
+ var import_react8 = require("react");
135
138
  var import_shared3 = require("@authon/shared");
136
139
  var import_js2 = require("@authon/js");
137
140
 
@@ -249,8 +252,10 @@ function Input({
249
252
  ...rest
250
253
  }) {
251
254
  const theme = useTheme();
255
+ const generatedId = (0, import_react5.useId)();
252
256
  const [focused, setFocused] = (0, import_react5.useState)(false);
253
257
  const resolvedStyle = inputStyle ?? theme.inputStyle;
258
+ const inputId = rest.id ?? generatedId;
254
259
  const wrapperStyle = {
255
260
  display: "flex",
256
261
  flexDirection: "column",
@@ -307,12 +312,13 @@ function Input({
307
312
  color: error ? "#ef4444" : theme.textMuted
308
313
  };
309
314
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: wrapperStyle, children: [
310
- label && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { style: labelStyle, children: label }),
315
+ label && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { htmlFor: inputId, style: labelStyle, children: label }),
311
316
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: inputContainerStyle, children: [
312
317
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
313
318
  "input",
314
319
  {
315
320
  ...rest,
321
+ id: inputId,
316
322
  style: { ...baseInputStyle, ...inputVariantStyle },
317
323
  onFocus: (e) => {
318
324
  setFocused(true);
@@ -460,19 +466,212 @@ function Divider({ label = "Or continue with" }) {
460
466
  ] });
461
467
  }
462
468
 
463
- // src/components/SignIn.tsx
469
+ // src/components/shared/AuthChallengeForms.tsx
470
+ var import_react7 = require("react");
464
471
  var import_jsx_runtime6 = require("react/jsx-runtime");
465
- function SignInCard({ afterSignInUrl, onSignIn, onNavigateSignUp }) {
472
+ function errorMessage(error, fallback) {
473
+ return error instanceof Error && error.message ? error.message : fallback;
474
+ }
475
+ function CodeForm({
476
+ title,
477
+ description,
478
+ label,
479
+ submitLabel,
480
+ backLabel,
481
+ onSubmit,
482
+ onBack,
483
+ onResend
484
+ }) {
485
+ const theme = useTheme();
486
+ const [code, setCode] = (0, import_react7.useState)("");
487
+ const [error, setError] = (0, import_react7.useState)("");
488
+ const [status, setStatus] = (0, import_react7.useState)("");
489
+ const [loading, setLoading] = (0, import_react7.useState)(false);
490
+ const [resending, setResending] = (0, import_react7.useState)(false);
491
+ const errorId = (0, import_react7.useId)();
492
+ const submitPending = (0, import_react7.useRef)(false);
493
+ const resendPending = (0, import_react7.useRef)(false);
494
+ const handleSubmit = async () => {
495
+ if (submitPending.current) return;
496
+ if (!code.trim()) {
497
+ setError(`${label} is required`);
498
+ return;
499
+ }
500
+ submitPending.current = true;
501
+ setLoading(true);
502
+ setError("");
503
+ setStatus("");
504
+ try {
505
+ await onSubmit(code.trim());
506
+ } catch (submitError) {
507
+ setError(errorMessage(submitError, "Verification failed"));
508
+ } finally {
509
+ submitPending.current = false;
510
+ setLoading(false);
511
+ }
512
+ };
513
+ const handleResend = async () => {
514
+ if (!onResend || resendPending.current) return;
515
+ resendPending.current = true;
516
+ setResending(true);
517
+ setError("");
518
+ setStatus("");
519
+ try {
520
+ await onResend();
521
+ setStatus("Verification code sent");
522
+ } catch (resendError) {
523
+ setError(errorMessage(resendError, "Could not resend verification code"));
524
+ } finally {
525
+ resendPending.current = false;
526
+ setResending(false);
527
+ }
528
+ };
529
+ const titleStyle = {
530
+ margin: 0,
531
+ fontSize: 24,
532
+ fontWeight: 700,
533
+ color: theme.text,
534
+ textAlign: "center",
535
+ letterSpacing: "-0.3px"
536
+ };
537
+ const descriptionStyle = {
538
+ margin: "-8px 0 0",
539
+ fontSize: 14,
540
+ lineHeight: 1.5,
541
+ color: theme.textMuted,
542
+ textAlign: "center"
543
+ };
544
+ const errorStyle = {
545
+ padding: "10px 14px",
546
+ borderRadius: theme.borderRadius,
547
+ background: "#fef2f2",
548
+ border: "1px solid #fecaca",
549
+ color: "#dc2626",
550
+ fontSize: 13
551
+ };
552
+ const statusStyle = {
553
+ padding: "10px 14px",
554
+ borderRadius: theme.borderRadius,
555
+ background: "#f0fdf4",
556
+ border: "1px solid #bbf7d0",
557
+ color: "#15803d",
558
+ fontSize: 13
559
+ };
560
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
561
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h1", { style: titleStyle, children: title }),
562
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { style: descriptionStyle, children: description }),
563
+ error && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { id: errorId, role: "alert", style: errorStyle, children: error }),
564
+ status && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { role: "status", "aria-live": "polite", style: statusStyle, children: status }),
565
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
566
+ Input,
567
+ {
568
+ label,
569
+ value: code,
570
+ onChange: setCode,
571
+ inputMode: "numeric",
572
+ autoComplete: "one-time-code",
573
+ disabled: loading,
574
+ "aria-invalid": !!error,
575
+ "aria-describedby": error ? errorId : void 0
576
+ }
577
+ ),
578
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
579
+ Button,
580
+ {
581
+ variant: "primary",
582
+ fullWidth: true,
583
+ loading,
584
+ disabled: resending,
585
+ onClick: handleSubmit,
586
+ children: submitLabel
587
+ }
588
+ ),
589
+ onResend && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
590
+ Button,
591
+ {
592
+ variant: "outline",
593
+ fullWidth: true,
594
+ loading: resending,
595
+ disabled: loading,
596
+ onClick: handleResend,
597
+ children: "Resend code"
598
+ }
599
+ ),
600
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
601
+ Button,
602
+ {
603
+ variant: "ghost",
604
+ fullWidth: true,
605
+ disabled: loading || resending,
606
+ onClick: onBack,
607
+ children: backLabel
608
+ }
609
+ )
610
+ ] });
611
+ }
612
+ function VerificationForm({
613
+ email,
614
+ backLabel,
615
+ onVerify,
616
+ onResend,
617
+ onBack
618
+ }) {
619
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
620
+ CodeForm,
621
+ {
622
+ title: "Verify your email",
623
+ description: `Enter the verification code sent to ${email}.`,
624
+ label: "Verification code",
625
+ submitLabel: "Verify email",
626
+ backLabel,
627
+ onSubmit: onVerify,
628
+ onResend,
629
+ onBack
630
+ }
631
+ );
632
+ }
633
+ function MfaForm({ onVerify, onBack }) {
634
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
635
+ CodeForm,
636
+ {
637
+ title: "Two-factor authentication",
638
+ description: "Enter the code from your authenticator app.",
639
+ label: "Authenticator code",
640
+ submitLabel: "Verify code",
641
+ backLabel: "Back to sign in",
642
+ onSubmit: onVerify,
643
+ onBack
644
+ }
645
+ );
646
+ }
647
+
648
+ // src/components/shared/navigation.ts
649
+ function navigateTo(url) {
650
+ window.location.assign(url);
651
+ }
652
+
653
+ // src/components/SignIn.tsx
654
+ var import_jsx_runtime7 = require("react/jsx-runtime");
655
+ function SignInCard({ afterSignInUrl, onSignIn, onForgotPassword, onNavigateSignUp }) {
466
656
  const theme = useTheme();
467
657
  const { client } = useAuthon();
468
658
  const { branding, providers, isLoaded } = useBranding();
469
- const [email, setEmail] = (0, import_react7.useState)("");
470
- const [password, setPassword] = (0, import_react7.useState)("");
471
- const [showPassword, setShowPassword] = (0, import_react7.useState)(false);
472
- const [loading, setLoading] = (0, import_react7.useState)(false);
473
- const [oauthLoading, setOauthLoading] = (0, import_react7.useState)(null);
474
- const [error, setError] = (0, import_react7.useState)("");
475
- const [fieldErrors, setFieldErrors] = (0, import_react7.useState)({});
659
+ const [email, setEmail] = (0, import_react8.useState)("");
660
+ const [password, setPassword] = (0, import_react8.useState)("");
661
+ const [showPassword, setShowPassword] = (0, import_react8.useState)(false);
662
+ const [loading, setLoading] = (0, import_react8.useState)(false);
663
+ const [oauthLoading, setOauthLoading] = (0, import_react8.useState)(null);
664
+ const [error, setError] = (0, import_react8.useState)("");
665
+ const [step, setStep] = (0, import_react8.useState)({ kind: "credentials" });
666
+ const [fieldErrors, setFieldErrors] = (0, import_react8.useState)({});
667
+ const authAttemptPending = (0, import_react8.useRef)(false);
668
+ const completed = (0, import_react8.useRef)(false);
669
+ const completeSignIn = () => {
670
+ if (completed.current) return;
671
+ completed.current = true;
672
+ if (afterSignInUrl) navigateTo(afterSignInUrl);
673
+ onSignIn?.();
674
+ };
476
675
  const validate = () => {
477
676
  const errs = {};
478
677
  if (!email.trim()) errs.email = "Email is required";
@@ -482,21 +681,35 @@ function SignInCard({ afterSignInUrl, onSignIn, onNavigateSignUp }) {
482
681
  return Object.keys(errs).length === 0;
483
682
  };
484
683
  const handleSubmit = async () => {
485
- if (!validate() || !client) return;
684
+ if (authAttemptPending.current || !validate() || !client) return;
685
+ authAttemptPending.current = true;
486
686
  setLoading(true);
487
687
  setError("");
488
688
  try {
489
- await client.signInWithEmail(email, password);
490
- if (afterSignInUrl) window.location.assign(afterSignInUrl);
491
- onSignIn?.();
492
- } catch (e) {
493
- setError(e?.message ?? "Sign in failed");
689
+ const result = await client.signInWithEmail(email, password);
690
+ if ("needsVerification" in result && result.needsVerification) {
691
+ setStep({ kind: "verification", email: result.email });
692
+ return;
693
+ }
694
+ completeSignIn();
695
+ } catch (submitError) {
696
+ if (submitError instanceof import_js2.AuthonMfaRequiredError) {
697
+ setStep({ kind: "mfa", mfaToken: submitError.mfaToken });
698
+ } else {
699
+ setError(submitError instanceof Error && submitError.message ? submitError.message : "Sign in failed");
700
+ }
494
701
  } finally {
702
+ authAttemptPending.current = false;
495
703
  setLoading(false);
496
704
  }
497
705
  };
706
+ const backToCredentials = () => {
707
+ setError("");
708
+ setStep({ kind: "credentials" });
709
+ };
498
710
  const handleOAuth = async (provider) => {
499
- if (!client) return;
711
+ if (!client || authAttemptPending.current) return;
712
+ authAttemptPending.current = true;
500
713
  setOauthLoading(provider);
501
714
  setError("");
502
715
  try {
@@ -504,6 +717,7 @@ function SignInCard({ afterSignInUrl, onSignIn, onNavigateSignUp }) {
504
717
  } catch (e) {
505
718
  setError(e?.message ?? "OAuth sign in failed");
506
719
  } finally {
720
+ authAttemptPending.current = false;
507
721
  setOauthLoading(null);
508
722
  }
509
723
  };
@@ -574,7 +788,7 @@ function SignInCard({ afterSignInUrl, onSignIn, onNavigateSignUp }) {
574
788
  (p) => !(branding.hiddenProviders ?? []).includes(p)
575
789
  );
576
790
  if (!isLoaded) {
577
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { ...cardStyle, alignItems: "center", justifyContent: "center", minHeight: 200 }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
791
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { ...cardStyle, alignItems: "center", justifyContent: "center", minHeight: 200 }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
578
792
  "span",
579
793
  {
580
794
  style: {
@@ -589,17 +803,49 @@ function SignInCard({ afterSignInUrl, onSignIn, onNavigateSignUp }) {
589
803
  }
590
804
  ) });
591
805
  }
592
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: cardStyle, children: [
593
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: logoStyle, children: [
594
- branding.logoDataUrl && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("img", { src: branding.logoDataUrl, alt: branding.brandName ?? "Logo", style: { height: 40, objectFit: "contain" } }),
595
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h1", { style: titleStyle, children: "Sign in" }),
596
- branding.brandName && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { style: subtitleStyle, children: [
806
+ if (step.kind === "verification") {
807
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: cardStyle, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
808
+ VerificationForm,
809
+ {
810
+ email: step.email,
811
+ backLabel: "Back to sign in",
812
+ onVerify: async (code) => {
813
+ if (!client) throw new Error("Sign in is unavailable");
814
+ await client.verifyEmail(step.email, code);
815
+ completeSignIn();
816
+ },
817
+ onResend: async () => {
818
+ if (!client) throw new Error("Sign in is unavailable");
819
+ await client.resendVerificationCode(step.email);
820
+ },
821
+ onBack: backToCredentials
822
+ }
823
+ ) });
824
+ }
825
+ if (step.kind === "mfa") {
826
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: cardStyle, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
827
+ MfaForm,
828
+ {
829
+ onVerify: async (code) => {
830
+ if (!client) throw new Error("Sign in is unavailable");
831
+ await client.verifyMfa(step.mfaToken, code);
832
+ completeSignIn();
833
+ },
834
+ onBack: backToCredentials
835
+ }
836
+ ) });
837
+ }
838
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: cardStyle, children: [
839
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: logoStyle, children: [
840
+ branding.logoDataUrl && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("img", { src: branding.logoDataUrl, alt: branding.brandName ?? "Logo", style: { height: 40, objectFit: "contain" } }),
841
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h1", { style: titleStyle, children: "Sign in" }),
842
+ branding.brandName && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { style: subtitleStyle, children: [
597
843
  "to ",
598
844
  branding.brandName
599
845
  ] })
600
846
  ] }),
601
- error && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: errorBoxStyle, children: error }),
602
- providersToShow.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: providersToShow.length <= 3 ? providersToShow.map((provider) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
847
+ error && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { role: "alert", style: errorBoxStyle, children: error }),
848
+ providersToShow.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: providersToShow.length <= 3 ? providersToShow.map((provider) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
603
849
  OAuthButton,
604
850
  {
605
851
  provider,
@@ -609,7 +855,7 @@ function SignInCard({ afterSignInUrl, onSignIn, onNavigateSignUp }) {
609
855
  borderRadius: theme.borderRadius
610
856
  },
611
857
  provider
612
- )) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: 10, justifyContent: "center" }, children: providersToShow.map((provider) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
858
+ )) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: 10, justifyContent: "center" }, children: providersToShow.map((provider) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
613
859
  CompactOAuthButton,
614
860
  {
615
861
  provider,
@@ -620,9 +866,9 @@ function SignInCard({ afterSignInUrl, onSignIn, onNavigateSignUp }) {
620
866
  },
621
867
  provider
622
868
  )) }) }),
623
- showDivider && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Divider, {}),
624
- showEmailPw && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
625
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
869
+ showDivider && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Divider, {}),
870
+ showEmailPw && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
871
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
626
872
  Input,
627
873
  {
628
874
  label: "Email",
@@ -634,8 +880,8 @@ function SignInCard({ afterSignInUrl, onSignIn, onNavigateSignUp }) {
634
880
  autoComplete: "email"
635
881
  }
636
882
  ),
637
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: [
638
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
883
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: [
884
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
639
885
  Input,
640
886
  {
641
887
  label: "Password",
@@ -645,21 +891,21 @@ function SignInCard({ afterSignInUrl, onSignIn, onNavigateSignUp }) {
645
891
  onChange: setPassword,
646
892
  error: fieldErrors.password,
647
893
  autoComplete: "current-password",
648
- rightElement: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
894
+ rightElement: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
649
895
  "button",
650
896
  {
651
897
  type: "button",
652
898
  onClick: () => setShowPassword((v) => !v),
653
899
  style: { background: "none", border: "none", cursor: "pointer", padding: 0, display: "flex", color: theme.textMuted },
654
900
  "aria-label": showPassword ? "Hide password" : "Show password",
655
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: eyeIconPath }) })
901
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: eyeIconPath }) })
656
902
  }
657
903
  )
658
904
  }
659
905
  ),
660
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: forgotStyle, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", style: linkStyle, children: "Forgot password?" }) })
906
+ onForgotPassword && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: forgotStyle, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", style: linkStyle, onClick: onForgotPassword, children: "Forgot password?" }) })
661
907
  ] }),
662
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
908
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
663
909
  Button,
664
910
  {
665
911
  variant: "primary",
@@ -671,10 +917,10 @@ function SignInCard({ afterSignInUrl, onSignIn, onNavigateSignUp }) {
671
917
  }
672
918
  )
673
919
  ] }),
674
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: footerStyle, children: [
920
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: footerStyle, children: [
675
921
  "Don't have an account?",
676
922
  " ",
677
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
923
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
678
924
  "button",
679
925
  {
680
926
  type: "button",
@@ -684,16 +930,16 @@ function SignInCard({ afterSignInUrl, onSignIn, onNavigateSignUp }) {
684
930
  }
685
931
  )
686
932
  ] }),
687
- branding.showSecuredBy !== false && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SecuredByAuthon, { primaryStart: theme.primaryStart, textMuted: theme.textMuted }),
688
- branding.termsUrl || branding.privacyUrl ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { textAlign: "center", fontSize: 11, color: theme.textMuted, marginTop: -8 }, children: [
689
- branding.termsUrl && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("a", { href: branding.termsUrl, target: "_blank", rel: "noopener noreferrer", style: { color: theme.textMuted }, children: "Terms" }),
933
+ branding.showSecuredBy !== false && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SecuredByAuthon, { primaryStart: theme.primaryStart, textMuted: theme.textMuted }),
934
+ branding.termsUrl || branding.privacyUrl ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { textAlign: "center", fontSize: 11, color: theme.textMuted, marginTop: -8 }, children: [
935
+ branding.termsUrl && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("a", { href: branding.termsUrl, target: "_blank", rel: "noopener noreferrer", style: { color: theme.textMuted }, children: "Terms" }),
690
936
  branding.termsUrl && branding.privacyUrl && " \xB7 ",
691
- branding.privacyUrl && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("a", { href: branding.privacyUrl, target: "_blank", rel: "noopener noreferrer", style: { color: theme.textMuted }, children: "Privacy" })
937
+ branding.privacyUrl && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("a", { href: branding.privacyUrl, target: "_blank", rel: "noopener noreferrer", style: { color: theme.textMuted }, children: "Privacy" })
692
938
  ] }) : null
693
939
  ] });
694
940
  }
695
941
  function OAuthButton({ provider, loading, disabled, onClick, borderRadius }) {
696
- const [hovered, setHovered] = (0, import_react7.useState)(false);
942
+ const [hovered, setHovered] = (0, import_react8.useState)(false);
697
943
  const colors = import_shared3.PROVIDER_COLORS[provider] ?? { bg: "#333", text: "#fff" };
698
944
  const name = import_shared3.PROVIDER_DISPLAY_NAMES[provider] ?? provider;
699
945
  const config = (0, import_js2.getProviderButtonConfig)(provider);
@@ -719,7 +965,7 @@ function OAuthButton({ provider, loading, disabled, onClick, borderRadius }) {
719
965
  transition: "opacity 0.15s",
720
966
  boxSizing: "border-box"
721
967
  };
722
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
968
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
723
969
  "button",
724
970
  {
725
971
  type: "button",
@@ -729,9 +975,9 @@ function OAuthButton({ provider, loading, disabled, onClick, borderRadius }) {
729
975
  onMouseEnter: () => setHovered(true),
730
976
  onMouseLeave: () => setHovered(false),
731
977
  "aria-label": `Continue with ${name}`,
732
- children: loading ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: { width: 18, height: 18, border: `2px solid ${colors.text}`, borderTopColor: "transparent", borderRadius: "50%", display: "inline-block", animation: "authon-spin 0.6s linear infinite" } }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
733
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: { display: "flex", alignItems: "center" }, dangerouslySetInnerHTML: { __html: config.iconSvg } }),
734
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { children: [
978
+ children: loading ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { width: 18, height: 18, border: `2px solid ${colors.text}`, borderTopColor: "transparent", borderRadius: "50%", display: "inline-block", animation: "authon-spin 0.6s linear infinite" } }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
979
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { display: "flex", alignItems: "center" }, dangerouslySetInnerHTML: { __html: config.iconSvg } }),
980
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
735
981
  "Continue with ",
736
982
  name
737
983
  ] })
@@ -740,7 +986,7 @@ function OAuthButton({ provider, loading, disabled, onClick, borderRadius }) {
740
986
  );
741
987
  }
742
988
  function CompactOAuthButton({ provider, loading, disabled, onClick, borderRadius }) {
743
- const [hovered, setHovered] = (0, import_react7.useState)(false);
989
+ const [hovered, setHovered] = (0, import_react8.useState)(false);
744
990
  const colors = import_shared3.PROVIDER_COLORS[provider] ?? { bg: "#333", text: "#fff" };
745
991
  const name = import_shared3.PROVIDER_DISPLAY_NAMES[provider] ?? provider;
746
992
  const config = (0, import_js2.getProviderButtonConfig)(provider);
@@ -759,7 +1005,7 @@ function CompactOAuthButton({ provider, loading, disabled, onClick, borderRadius
759
1005
  transition: "opacity 0.15s",
760
1006
  padding: 0
761
1007
  };
762
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1008
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
763
1009
  "button",
764
1010
  {
765
1011
  type: "button",
@@ -769,33 +1015,34 @@ function CompactOAuthButton({ provider, loading, disabled, onClick, borderRadius
769
1015
  onMouseEnter: () => setHovered(true),
770
1016
  onMouseLeave: () => setHovered(false),
771
1017
  "aria-label": `Continue with ${name}`,
772
- children: loading ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: { width: 18, height: 18, border: `2px solid ${colors.text}`, borderTopColor: "transparent", borderRadius: "50%", display: "inline-block", animation: "authon-spin 0.6s linear infinite" } }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: { display: "flex" }, dangerouslySetInnerHTML: { __html: config.iconSvg } })
1018
+ children: loading ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { width: 18, height: 18, border: `2px solid ${colors.text}`, borderTopColor: "transparent", borderRadius: "50%", display: "inline-block", animation: "authon-spin 0.6s linear infinite" } }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { display: "flex" }, dangerouslySetInnerHTML: { __html: config.iconSvg } })
773
1019
  }
774
1020
  );
775
1021
  }
776
1022
  function SecuredByAuthon({ primaryStart, textMuted }) {
777
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: 5, marginTop: -8 }, children: [
778
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("svg", { width: "12", height: "14", viewBox: "0 0 12 14", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
779
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M6 0L0.5 2.5V6.5C0.5 9.7 2.9 12.7 6 13.5C9.1 12.7 11.5 9.7 11.5 6.5V2.5L6 0Z", fill: primaryStart, opacity: "0.85" }),
780
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M4 7L5.5 8.5L8.5 5.5", stroke: "white", strokeWidth: "1.2", strokeLinecap: "round", strokeLinejoin: "round" })
1023
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: 5, marginTop: -8 }, children: [
1024
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { width: "12", height: "14", viewBox: "0 0 12 14", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
1025
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M6 0L0.5 2.5V6.5C0.5 9.7 2.9 12.7 6 13.5C9.1 12.7 11.5 9.7 11.5 6.5V2.5L6 0Z", fill: primaryStart, opacity: "0.85" }),
1026
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M4 7L5.5 8.5L8.5 5.5", stroke: "white", strokeWidth: "1.2", strokeLinecap: "round", strokeLinejoin: "round" })
781
1027
  ] }),
782
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { style: { fontSize: 11, color: textMuted }, children: [
1028
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { style: { fontSize: 11, color: textMuted }, children: [
783
1029
  "Secured by",
784
1030
  " ",
785
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("a", { href: "https://authon.dev", target: "_blank", rel: "noopener noreferrer", style: { color: primaryStart, textDecoration: "none", fontWeight: 600 }, children: "Authon" })
1031
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("a", { href: "https://authon.dev", target: "_blank", rel: "noopener noreferrer", style: { color: primaryStart, textDecoration: "none", fontWeight: 600 }, children: "Authon" })
786
1032
  ] })
787
1033
  ] });
788
1034
  }
789
- function SignIn({ appearance, afterSignInUrl, onSignIn, onNavigateSignUp }) {
1035
+ function SignIn({ appearance, afterSignInUrl, onSignIn, onForgotPassword, onNavigateSignUp }) {
790
1036
  const { branding, isLoaded } = useBranding();
791
1037
  const effectiveBranding = isLoaded ? { ...branding, ...appearance?.variables ?? {} } : branding;
792
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(ThemeProvider, { branding: effectiveBranding, overrides: appearance?.variables, style: { display: "flex", justifyContent: "center" }, children: [
793
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("style", { children: `@keyframes authon-spin { to { transform: rotate(360deg); } }` }),
794
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1038
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(ThemeProvider, { branding: effectiveBranding, overrides: appearance?.variables, style: { display: "flex", justifyContent: "center" }, children: [
1039
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { children: `@keyframes authon-spin { to { transform: rotate(360deg); } }` }),
1040
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
795
1041
  SignInCard,
796
1042
  {
797
1043
  afterSignInUrl,
798
1044
  onSignIn,
1045
+ onForgotPassword,
799
1046
  onNavigateSignUp
800
1047
  }
801
1048
  )
@@ -803,23 +1050,32 @@ function SignIn({ appearance, afterSignInUrl, onSignIn, onNavigateSignUp }) {
803
1050
  }
804
1051
 
805
1052
  // src/components/SignUp.tsx
806
- var import_react8 = require("react");
1053
+ var import_react9 = require("react");
807
1054
  var import_shared4 = require("@authon/shared");
808
1055
  var import_js3 = require("@authon/js");
809
- var import_jsx_runtime7 = require("react/jsx-runtime");
1056
+ var import_jsx_runtime8 = require("react/jsx-runtime");
810
1057
  function SignUpCard({ afterSignUpUrl, onSignUp, onNavigateSignIn }) {
811
1058
  const theme = useTheme();
812
1059
  const { client } = useAuthon();
813
1060
  const { branding, providers, isLoaded } = useBranding();
814
- const [displayName, setDisplayName] = (0, import_react8.useState)("");
815
- const [email, setEmail] = (0, import_react8.useState)("");
816
- const [password, setPassword] = (0, import_react8.useState)("");
817
- const [confirmPassword, setConfirmPassword] = (0, import_react8.useState)("");
818
- const [showPassword, setShowPassword] = (0, import_react8.useState)(false);
819
- const [loading, setLoading] = (0, import_react8.useState)(false);
820
- const [oauthLoading, setOauthLoading] = (0, import_react8.useState)(null);
821
- const [error, setError] = (0, import_react8.useState)("");
822
- const [fieldErrors, setFieldErrors] = (0, import_react8.useState)({});
1061
+ const [displayName, setDisplayName] = (0, import_react9.useState)("");
1062
+ const [email, setEmail] = (0, import_react9.useState)("");
1063
+ const [password, setPassword] = (0, import_react9.useState)("");
1064
+ const [confirmPassword, setConfirmPassword] = (0, import_react9.useState)("");
1065
+ const [showPassword, setShowPassword] = (0, import_react9.useState)(false);
1066
+ const [loading, setLoading] = (0, import_react9.useState)(false);
1067
+ const [oauthLoading, setOauthLoading] = (0, import_react9.useState)(null);
1068
+ const [error, setError] = (0, import_react9.useState)("");
1069
+ const [verificationEmail, setVerificationEmail] = (0, import_react9.useState)(null);
1070
+ const [fieldErrors, setFieldErrors] = (0, import_react9.useState)({});
1071
+ const authAttemptPending = (0, import_react9.useRef)(false);
1072
+ const completed = (0, import_react9.useRef)(false);
1073
+ const completeSignUp = () => {
1074
+ if (completed.current) return;
1075
+ completed.current = true;
1076
+ if (afterSignUpUrl) navigateTo(afterSignUpUrl);
1077
+ onSignUp?.();
1078
+ };
823
1079
  const validate = () => {
824
1080
  const errs = {};
825
1081
  if (!email.trim()) errs.email = "Email is required";
@@ -831,21 +1087,27 @@ function SignUpCard({ afterSignUpUrl, onSignUp, onNavigateSignIn }) {
831
1087
  return Object.keys(errs).length === 0;
832
1088
  };
833
1089
  const handleSubmit = async () => {
834
- if (!validate() || !client) return;
1090
+ if (authAttemptPending.current || !validate() || !client) return;
1091
+ authAttemptPending.current = true;
835
1092
  setLoading(true);
836
1093
  setError("");
837
1094
  try {
838
- await client.signUpWithEmail(email, password, displayName ? { displayName } : void 0);
839
- if (afterSignUpUrl) window.location.assign(afterSignUpUrl);
840
- onSignUp?.();
841
- } catch (e) {
842
- setError(e?.message ?? "Sign up failed");
1095
+ const result = await client.signUpWithEmail(email, password, displayName ? { displayName } : void 0);
1096
+ if ("needsVerification" in result && result.needsVerification) {
1097
+ setVerificationEmail(result.email);
1098
+ return;
1099
+ }
1100
+ completeSignUp();
1101
+ } catch (submitError) {
1102
+ setError(submitError instanceof Error && submitError.message ? submitError.message : "Sign up failed");
843
1103
  } finally {
1104
+ authAttemptPending.current = false;
844
1105
  setLoading(false);
845
1106
  }
846
1107
  };
847
1108
  const handleOAuth = async (provider) => {
848
- if (!client) return;
1109
+ if (!client || authAttemptPending.current) return;
1110
+ authAttemptPending.current = true;
849
1111
  setOauthLoading(provider);
850
1112
  setError("");
851
1113
  try {
@@ -853,6 +1115,7 @@ function SignUpCard({ afterSignUpUrl, onSignUp, onNavigateSignIn }) {
853
1115
  } catch (e) {
854
1116
  setError(e?.message ?? "OAuth sign in failed");
855
1117
  } finally {
1118
+ authAttemptPending.current = false;
856
1119
  setOauthLoading(null);
857
1120
  }
858
1121
  };
@@ -918,7 +1181,7 @@ function SignUpCard({ afterSignUpUrl, onSignUp, onNavigateSignIn }) {
918
1181
  (p) => !(branding.hiddenProviders ?? []).includes(p)
919
1182
  );
920
1183
  if (!isLoaded) {
921
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { ...cardStyle, alignItems: "center", justifyContent: "center", minHeight: 200 }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1184
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { ...cardStyle, alignItems: "center", justifyContent: "center", minHeight: 200 }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
922
1185
  "span",
923
1186
  {
924
1187
  style: {
@@ -933,18 +1196,40 @@ function SignUpCard({ afterSignUpUrl, onSignUp, onNavigateSignIn }) {
933
1196
  }
934
1197
  ) });
935
1198
  }
1199
+ if (verificationEmail) {
1200
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: cardStyle, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1201
+ VerificationForm,
1202
+ {
1203
+ email: verificationEmail,
1204
+ backLabel: "Back to sign up",
1205
+ onVerify: async (code) => {
1206
+ if (!client) throw new Error("Sign up is unavailable");
1207
+ await client.verifyEmail(verificationEmail, code);
1208
+ completeSignUp();
1209
+ },
1210
+ onResend: async () => {
1211
+ if (!client) throw new Error("Sign up is unavailable");
1212
+ await client.resendVerificationCode(verificationEmail);
1213
+ },
1214
+ onBack: () => {
1215
+ setError("");
1216
+ setVerificationEmail(null);
1217
+ }
1218
+ }
1219
+ ) });
1220
+ }
936
1221
  const eyeIconPath = showPassword ? "M17.94 17.94A10.07 10.07 0 0112 20c-7 0-11-8-11-8a18.45 18.45 0 015.06-5.94M9.9 4.24A9.12 9.12 0 0112 4c7 0 11 8 11 8a18.5 18.5 0 01-2.16 3.19m-6.72-1.07a3 3 0 11-4.24-4.24 M1 1l22 22" : "M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z M12 9a3 3 0 100 6 3 3 0 000-6z";
937
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: cardStyle, children: [
938
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: logoStyle, children: [
939
- branding.logoDataUrl && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("img", { src: branding.logoDataUrl, alt: branding.brandName ?? "Logo", style: { height: 40, objectFit: "contain" } }),
940
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h1", { style: titleStyle, children: "Create account" }),
941
- branding.brandName && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { style: subtitleStyle, children: [
1222
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: cardStyle, children: [
1223
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: logoStyle, children: [
1224
+ branding.logoDataUrl && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("img", { src: branding.logoDataUrl, alt: branding.brandName ?? "Logo", style: { height: 40, objectFit: "contain" } }),
1225
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h1", { style: titleStyle, children: "Create account" }),
1226
+ branding.brandName && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("p", { style: subtitleStyle, children: [
942
1227
  "Join ",
943
1228
  branding.brandName
944
1229
  ] })
945
1230
  ] }),
946
- error && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: errorBoxStyle, children: error }),
947
- providersToShow.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: providersToShow.length <= 3 ? providersToShow.map((provider) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1231
+ error && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { role: "alert", style: errorBoxStyle, children: error }),
1232
+ providersToShow.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: providersToShow.length <= 3 ? providersToShow.map((provider) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
948
1233
  OAuthButtonFull,
949
1234
  {
950
1235
  provider,
@@ -954,7 +1239,7 @@ function SignUpCard({ afterSignUpUrl, onSignUp, onNavigateSignIn }) {
954
1239
  borderRadius: theme.borderRadius
955
1240
  },
956
1241
  provider
957
- )) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: 10, justifyContent: "center" }, children: providersToShow.map((provider) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1242
+ )) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: 10, justifyContent: "center" }, children: providersToShow.map((provider) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
958
1243
  CompactOAuthBtn,
959
1244
  {
960
1245
  provider,
@@ -965,9 +1250,9 @@ function SignUpCard({ afterSignUpUrl, onSignUp, onNavigateSignIn }) {
965
1250
  },
966
1251
  provider
967
1252
  )) }) }),
968
- showDivider && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Divider, {}),
969
- showEmailPw && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
970
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1253
+ showDivider && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Divider, {}),
1254
+ showEmailPw && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
1255
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
971
1256
  Input,
972
1257
  {
973
1258
  label: "Display name",
@@ -979,7 +1264,7 @@ function SignUpCard({ afterSignUpUrl, onSignUp, onNavigateSignIn }) {
979
1264
  autoComplete: "name"
980
1265
  }
981
1266
  ),
982
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1267
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
983
1268
  Input,
984
1269
  {
985
1270
  label: "Email",
@@ -991,7 +1276,7 @@ function SignUpCard({ afterSignUpUrl, onSignUp, onNavigateSignIn }) {
991
1276
  autoComplete: "email"
992
1277
  }
993
1278
  ),
994
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1279
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
995
1280
  Input,
996
1281
  {
997
1282
  label: "Password",
@@ -1001,19 +1286,19 @@ function SignUpCard({ afterSignUpUrl, onSignUp, onNavigateSignIn }) {
1001
1286
  onChange: setPassword,
1002
1287
  error: fieldErrors.password,
1003
1288
  autoComplete: "new-password",
1004
- rightElement: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1289
+ rightElement: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1005
1290
  "button",
1006
1291
  {
1007
1292
  type: "button",
1008
1293
  onClick: () => setShowPassword((v) => !v),
1009
1294
  style: { background: "none", border: "none", cursor: "pointer", padding: 0, display: "flex", color: theme.textMuted },
1010
1295
  "aria-label": showPassword ? "Hide password" : "Show password",
1011
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: eyeIconPath }) })
1296
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: eyeIconPath }) })
1012
1297
  }
1013
1298
  )
1014
1299
  }
1015
1300
  ),
1016
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1301
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1017
1302
  Input,
1018
1303
  {
1019
1304
  label: "Confirm password",
@@ -1025,7 +1310,7 @@ function SignUpCard({ afterSignUpUrl, onSignUp, onNavigateSignIn }) {
1025
1310
  autoComplete: "new-password"
1026
1311
  }
1027
1312
  ),
1028
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1313
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1029
1314
  Button,
1030
1315
  {
1031
1316
  variant: "primary",
@@ -1037,23 +1322,23 @@ function SignUpCard({ afterSignUpUrl, onSignUp, onNavigateSignIn }) {
1037
1322
  }
1038
1323
  )
1039
1324
  ] }),
1040
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: footerStyle, children: [
1325
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: footerStyle, children: [
1041
1326
  "Already have an account?",
1042
1327
  " ",
1043
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", style: linkStyle, onClick: onNavigateSignIn, children: "Sign in" })
1328
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", style: linkStyle, onClick: onNavigateSignIn, children: "Sign in" })
1044
1329
  ] }),
1045
- branding.showSecuredBy !== false && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SecuredByAuthon2, { primaryStart: theme.primaryStart, textMuted: theme.textMuted }),
1046
- branding.termsUrl || branding.privacyUrl ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { textAlign: "center", fontSize: 11, color: theme.textMuted, marginTop: -8 }, children: [
1330
+ branding.showSecuredBy !== false && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SecuredByAuthon2, { primaryStart: theme.primaryStart, textMuted: theme.textMuted }),
1331
+ branding.termsUrl || branding.privacyUrl ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { textAlign: "center", fontSize: 11, color: theme.textMuted, marginTop: -8 }, children: [
1047
1332
  "By creating an account you agree to our",
1048
1333
  " ",
1049
- branding.termsUrl && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("a", { href: branding.termsUrl, target: "_blank", rel: "noopener noreferrer", style: { color: theme.primaryStart }, children: "Terms" }),
1334
+ branding.termsUrl && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("a", { href: branding.termsUrl, target: "_blank", rel: "noopener noreferrer", style: { color: theme.primaryStart }, children: "Terms" }),
1050
1335
  branding.termsUrl && branding.privacyUrl && " and ",
1051
- branding.privacyUrl && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("a", { href: branding.privacyUrl, target: "_blank", rel: "noopener noreferrer", style: { color: theme.primaryStart }, children: "Privacy Policy" })
1336
+ branding.privacyUrl && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("a", { href: branding.privacyUrl, target: "_blank", rel: "noopener noreferrer", style: { color: theme.primaryStart }, children: "Privacy Policy" })
1052
1337
  ] }) : null
1053
1338
  ] });
1054
1339
  }
1055
1340
  function OAuthButtonFull({ provider, loading, disabled, onClick, borderRadius }) {
1056
- const [hovered, setHovered] = (0, import_react8.useState)(false);
1341
+ const [hovered, setHovered] = (0, import_react9.useState)(false);
1057
1342
  const colors = import_shared4.PROVIDER_COLORS[provider] ?? { bg: "#333", text: "#fff" };
1058
1343
  const name = import_shared4.PROVIDER_DISPLAY_NAMES[provider] ?? provider;
1059
1344
  const config = (0, import_js3.getProviderButtonConfig)(provider);
@@ -1079,7 +1364,7 @@ function OAuthButtonFull({ provider, loading, disabled, onClick, borderRadius })
1079
1364
  transition: "opacity 0.15s",
1080
1365
  boxSizing: "border-box"
1081
1366
  };
1082
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1367
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1083
1368
  "button",
1084
1369
  {
1085
1370
  type: "button",
@@ -1089,9 +1374,9 @@ function OAuthButtonFull({ provider, loading, disabled, onClick, borderRadius })
1089
1374
  onMouseEnter: () => setHovered(true),
1090
1375
  onMouseLeave: () => setHovered(false),
1091
1376
  "aria-label": `Continue with ${name}`,
1092
- children: loading ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { width: 18, height: 18, border: `2px solid ${colors.text}`, borderTopColor: "transparent", borderRadius: "50%", display: "inline-block", animation: "authon-spin 0.6s linear infinite" } }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
1093
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { display: "flex", alignItems: "center" }, dangerouslySetInnerHTML: { __html: config.iconSvg } }),
1094
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
1377
+ children: loading ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { width: 18, height: 18, border: `2px solid ${colors.text}`, borderTopColor: "transparent", borderRadius: "50%", display: "inline-block", animation: "authon-spin 0.6s linear infinite" } }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
1378
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { display: "flex", alignItems: "center" }, dangerouslySetInnerHTML: { __html: config.iconSvg } }),
1379
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
1095
1380
  "Continue with ",
1096
1381
  name
1097
1382
  ] })
@@ -1100,7 +1385,7 @@ function OAuthButtonFull({ provider, loading, disabled, onClick, borderRadius })
1100
1385
  );
1101
1386
  }
1102
1387
  function CompactOAuthBtn({ provider, loading, disabled, onClick, borderRadius }) {
1103
- const [hovered, setHovered] = (0, import_react8.useState)(false);
1388
+ const [hovered, setHovered] = (0, import_react9.useState)(false);
1104
1389
  const colors = import_shared4.PROVIDER_COLORS[provider] ?? { bg: "#333", text: "#fff" };
1105
1390
  const name = import_shared4.PROVIDER_DISPLAY_NAMES[provider] ?? provider;
1106
1391
  const config = (0, import_js3.getProviderButtonConfig)(provider);
@@ -1119,7 +1404,7 @@ function CompactOAuthBtn({ provider, loading, disabled, onClick, borderRadius })
1119
1404
  transition: "opacity 0.15s",
1120
1405
  padding: 0
1121
1406
  };
1122
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1407
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1123
1408
  "button",
1124
1409
  {
1125
1410
  type: "button",
@@ -1129,29 +1414,29 @@ function CompactOAuthBtn({ provider, loading, disabled, onClick, borderRadius })
1129
1414
  onMouseEnter: () => setHovered(true),
1130
1415
  onMouseLeave: () => setHovered(false),
1131
1416
  "aria-label": `Continue with ${name}`,
1132
- children: loading ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { width: 18, height: 18, border: `2px solid ${colors.text}`, borderTopColor: "transparent", borderRadius: "50%", display: "inline-block", animation: "authon-spin 0.6s linear infinite" } }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { display: "flex" }, dangerouslySetInnerHTML: { __html: config.iconSvg } })
1417
+ children: loading ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { width: 18, height: 18, border: `2px solid ${colors.text}`, borderTopColor: "transparent", borderRadius: "50%", display: "inline-block", animation: "authon-spin 0.6s linear infinite" } }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { display: "flex" }, dangerouslySetInnerHTML: { __html: config.iconSvg } })
1133
1418
  }
1134
1419
  );
1135
1420
  }
1136
1421
  function SecuredByAuthon2({ primaryStart, textMuted }) {
1137
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: 5, marginTop: -8 }, children: [
1138
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { width: "12", height: "14", viewBox: "0 0 12 14", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
1139
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M6 0L0.5 2.5V6.5C0.5 9.7 2.9 12.7 6 13.5C9.1 12.7 11.5 9.7 11.5 6.5V2.5L6 0Z", fill: primaryStart, opacity: "0.85" }),
1140
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M4 7L5.5 8.5L8.5 5.5", stroke: "white", strokeWidth: "1.2", strokeLinecap: "round", strokeLinejoin: "round" })
1422
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: 5, marginTop: -8 }, children: [
1423
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { width: "12", height: "14", viewBox: "0 0 12 14", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
1424
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M6 0L0.5 2.5V6.5C0.5 9.7 2.9 12.7 6 13.5C9.1 12.7 11.5 9.7 11.5 6.5V2.5L6 0Z", fill: primaryStart, opacity: "0.85" }),
1425
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M4 7L5.5 8.5L8.5 5.5", stroke: "white", strokeWidth: "1.2", strokeLinecap: "round", strokeLinejoin: "round" })
1141
1426
  ] }),
1142
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { style: { fontSize: 11, color: textMuted }, children: [
1427
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { style: { fontSize: 11, color: textMuted }, children: [
1143
1428
  "Secured by",
1144
1429
  " ",
1145
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("a", { href: "https://authon.dev", target: "_blank", rel: "noopener noreferrer", style: { color: primaryStart, textDecoration: "none", fontWeight: 600 }, children: "Authon" })
1430
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("a", { href: "https://authon.dev", target: "_blank", rel: "noopener noreferrer", style: { color: primaryStart, textDecoration: "none", fontWeight: 600 }, children: "Authon" })
1146
1431
  ] })
1147
1432
  ] });
1148
1433
  }
1149
1434
  function SignUp({ appearance, afterSignUpUrl, onSignUp, onNavigateSignIn }) {
1150
1435
  const { branding, isLoaded } = useBranding();
1151
1436
  const effectiveBranding = isLoaded ? { ...branding, ...appearance?.variables ?? {} } : branding;
1152
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(ThemeProvider, { branding: effectiveBranding, overrides: appearance?.variables, style: { display: "flex", justifyContent: "center" }, children: [
1153
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { children: `@keyframes authon-spin { to { transform: rotate(360deg); } }` }),
1154
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1437
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(ThemeProvider, { branding: effectiveBranding, overrides: appearance?.variables, style: { display: "flex", justifyContent: "center" }, children: [
1438
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("style", { children: `@keyframes authon-spin { to { transform: rotate(360deg); } }` }),
1439
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1155
1440
  SignUpCard,
1156
1441
  {
1157
1442
  afterSignUpUrl,
@@ -1163,8 +1448,8 @@ function SignUp({ appearance, afterSignUpUrl, onSignUp, onNavigateSignIn }) {
1163
1448
  }
1164
1449
 
1165
1450
  // src/components/UserButton.tsx
1166
- var import_react9 = require("react");
1167
- var import_jsx_runtime8 = require("react/jsx-runtime");
1451
+ var import_react10 = require("react");
1452
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1168
1453
  function UserAvatar({
1169
1454
  avatarUrl,
1170
1455
  displayName,
@@ -1188,24 +1473,24 @@ function UserAvatar({
1188
1473
  fontWeight: 700,
1189
1474
  userSelect: "none"
1190
1475
  };
1191
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: avatarStyle, children: avatarUrl ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("img", { src: avatarUrl, alt: displayName ?? "avatar", style: { width: "100%", height: "100%", objectFit: "cover" } }) : initials });
1476
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: avatarStyle, children: avatarUrl ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("img", { src: avatarUrl, alt: displayName ?? "avatar", style: { width: "100%", height: "100%", objectFit: "cover" } }) : initials });
1192
1477
  }
1193
1478
  function UserButtonInner({ afterSignOutUrl, userProfileUrl }) {
1194
1479
  const theme = useTheme();
1195
1480
  const { user, signOut, openSignIn, isSignedIn, activeOrganization, client } = useAuthon();
1196
- const [open, setOpen] = (0, import_react9.useState)(false);
1197
- const dropdownRef = (0, import_react9.useRef)(null);
1198
- const handleClickOutside = (0, import_react9.useCallback)((e) => {
1481
+ const [open, setOpen] = (0, import_react10.useState)(false);
1482
+ const dropdownRef = (0, import_react10.useRef)(null);
1483
+ const handleClickOutside = (0, import_react10.useCallback)((e) => {
1199
1484
  if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
1200
1485
  setOpen(false);
1201
1486
  }
1202
1487
  }, []);
1203
- (0, import_react9.useEffect)(() => {
1488
+ (0, import_react10.useEffect)(() => {
1204
1489
  if (open) document.addEventListener("mousedown", handleClickOutside);
1205
1490
  return () => document.removeEventListener("mousedown", handleClickOutside);
1206
1491
  }, [open, handleClickOutside]);
1207
1492
  if (!isSignedIn) {
1208
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1493
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1209
1494
  "button",
1210
1495
  {
1211
1496
  type: "button",
@@ -1274,8 +1559,8 @@ function UserButtonInner({ afterSignOutUrl, userProfileUrl }) {
1274
1559
  fontFamily: theme.fontFamily,
1275
1560
  boxSizing: "border-box"
1276
1561
  });
1277
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { ref: dropdownRef, style: { position: "relative", display: "inline-block" }, children: [
1278
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", style: triggerStyle, onClick: () => setOpen((v) => !v), "aria-label": "User menu", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1562
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { ref: dropdownRef, style: { position: "relative", display: "inline-block" }, children: [
1563
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", style: triggerStyle, onClick: () => setOpen((v) => !v), "aria-label": "User menu", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1279
1564
  UserAvatar,
1280
1565
  {
1281
1566
  avatarUrl: user?.avatarUrl,
@@ -1286,9 +1571,9 @@ function UserButtonInner({ afterSignOutUrl, userProfileUrl }) {
1286
1571
  primaryEnd: theme.primaryEnd
1287
1572
  }
1288
1573
  ) }),
1289
- open && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: dropdownStyle, children: [
1290
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: headerStyle, children: [
1291
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1574
+ open && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: dropdownStyle, children: [
1575
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: headerStyle, children: [
1576
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1292
1577
  UserAvatar,
1293
1578
  {
1294
1579
  avatarUrl: user?.avatarUrl,
@@ -1299,12 +1584,12 @@ function UserButtonInner({ afterSignOutUrl, userProfileUrl }) {
1299
1584
  primaryEnd: theme.primaryEnd
1300
1585
  }
1301
1586
  ),
1302
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
1303
- user?.displayName && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { fontSize: 14, fontWeight: 600, color: theme.text, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: user.displayName }),
1304
- user?.email && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { fontSize: 12, color: theme.textMuted, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", marginTop: 1 }, children: user.email })
1587
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
1588
+ user?.displayName && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { fontSize: 14, fontWeight: 600, color: theme.text, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: user.displayName }),
1589
+ user?.email && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { fontSize: 12, color: theme.textMuted, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", marginTop: 1 }, children: user.email })
1305
1590
  ] })
1306
1591
  ] }),
1307
- activeOrganization && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1592
+ activeOrganization && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1308
1593
  OrgSwitcherRow,
1309
1594
  {
1310
1595
  org: activeOrganization,
@@ -1313,7 +1598,7 @@ function UserButtonInner({ afterSignOutUrl, userProfileUrl }) {
1313
1598
  client
1314
1599
  }
1315
1600
  ),
1316
- userProfileUrl && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1601
+ userProfileUrl && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1317
1602
  MenuButton,
1318
1603
  {
1319
1604
  style: menuItemStyle(),
@@ -1321,14 +1606,14 @@ function UserButtonInner({ afterSignOutUrl, userProfileUrl }) {
1321
1606
  setOpen(false);
1322
1607
  window.location.assign(userProfileUrl);
1323
1608
  },
1324
- icon: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1325
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M20 21v-2a4 4 0 00-4-4H8a4 4 0 00-4 4v2" }),
1326
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("circle", { cx: "12", cy: "7", r: "4" })
1609
+ icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1610
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M20 21v-2a4 4 0 00-4-4H8a4 4 0 00-4 4v2" }),
1611
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("circle", { cx: "12", cy: "7", r: "4" })
1327
1612
  ] }),
1328
1613
  children: "Manage account"
1329
1614
  }
1330
1615
  ),
1331
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { borderTop: `1px solid ${theme.border}` }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1616
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { borderTop: `1px solid ${theme.border}` }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1332
1617
  MenuButton,
1333
1618
  {
1334
1619
  style: menuItemStyle(true),
@@ -1337,10 +1622,10 @@ function UserButtonInner({ afterSignOutUrl, userProfileUrl }) {
1337
1622
  await signOut();
1338
1623
  if (afterSignOutUrl) window.location.assign(afterSignOutUrl);
1339
1624
  },
1340
- icon: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1341
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4" }),
1342
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("polyline", { points: "16 17 21 12 16 7" }),
1343
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("line", { x1: "21", y1: "12", x2: "9", y2: "12" })
1625
+ icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1626
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4" }),
1627
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("polyline", { points: "16 17 21 12 16 7" }),
1628
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "21", y1: "12", x2: "9", y2: "12" })
1344
1629
  ] }),
1345
1630
  children: "Sign out"
1346
1631
  }
@@ -1354,8 +1639,8 @@ function MenuButton({
1354
1639
  icon,
1355
1640
  children
1356
1641
  }) {
1357
- const [hovered, setHovered] = (0, import_react9.useState)(false);
1358
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1642
+ const [hovered, setHovered] = (0, import_react10.useState)(false);
1643
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1359
1644
  "button",
1360
1645
  {
1361
1646
  type: "button",
@@ -1379,7 +1664,7 @@ function OrgSwitcherRow({
1379
1664
  theme,
1380
1665
  client
1381
1666
  }) {
1382
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1667
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1383
1668
  "div",
1384
1669
  {
1385
1670
  style: {
@@ -1390,7 +1675,7 @@ function OrgSwitcherRow({
1390
1675
  gap: 10
1391
1676
  },
1392
1677
  children: [
1393
- org.logoUrl ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("img", { src: org.logoUrl, alt: org.name, style: { width: 24, height: 24, borderRadius: 6, objectFit: "cover" } }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1678
+ org.logoUrl ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("img", { src: org.logoUrl, alt: org.name, style: { width: 24, height: 24, borderRadius: 6, objectFit: "cover" } }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1394
1679
  "div",
1395
1680
  {
1396
1681
  style: {
@@ -1408,9 +1693,9 @@ function OrgSwitcherRow({
1408
1693
  children: org.name[0]?.toUpperCase()
1409
1694
  }
1410
1695
  ),
1411
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
1412
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { fontSize: 12, color: theme.textMuted }, children: "Organization" }),
1413
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { fontSize: 13, fontWeight: 600, color: theme.text, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: org.name })
1696
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
1697
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { fontSize: 12, color: theme.textMuted }, children: "Organization" }),
1698
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { fontSize: 13, fontWeight: 600, color: theme.text, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: org.name })
1414
1699
  ] })
1415
1700
  ]
1416
1701
  }
@@ -1419,39 +1704,39 @@ function OrgSwitcherRow({
1419
1704
  function UserButton({ appearance, afterSignOutUrl, userProfileUrl }) {
1420
1705
  const { branding } = useBranding();
1421
1706
  const effectiveBranding = { ...branding, ...appearance?.variables ?? {} };
1422
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ThemeProvider, { branding: effectiveBranding, style: { display: "inline-block" }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(UserButtonInner, { afterSignOutUrl, userProfileUrl }) });
1707
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ThemeProvider, { branding: effectiveBranding, style: { display: "inline-block" }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(UserButtonInner, { afterSignOutUrl, userProfileUrl }) });
1423
1708
  }
1424
1709
 
1425
1710
  // src/SignedIn.tsx
1426
- var import_jsx_runtime9 = require("react/jsx-runtime");
1711
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1427
1712
  function SignedIn({ children }) {
1428
1713
  const { isSignedIn, isLoading } = useAuthon();
1429
1714
  if (isLoading || !isSignedIn) return null;
1430
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_jsx_runtime9.Fragment, { children });
1715
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children });
1431
1716
  }
1432
1717
 
1433
1718
  // src/SignedOut.tsx
1434
- var import_jsx_runtime10 = require("react/jsx-runtime");
1719
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1435
1720
  function SignedOut({ children }) {
1436
1721
  const { isSignedIn, isLoading } = useAuthon();
1437
1722
  if (isLoading || isSignedIn) return null;
1438
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children });
1723
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_jsx_runtime11.Fragment, { children });
1439
1724
  }
1440
1725
 
1441
1726
  // src/Protect.tsx
1442
- var import_jsx_runtime11 = require("react/jsx-runtime");
1727
+ var import_jsx_runtime12 = require("react/jsx-runtime");
1443
1728
  function Protect({ children, fallback = null, condition }) {
1444
1729
  const { isSignedIn, isLoading, user } = useAuthon();
1445
1730
  if (isLoading) return null;
1446
- if (!isSignedIn || !user) return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_jsx_runtime11.Fragment, { children: fallback });
1447
- if (condition && !condition(user)) return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_jsx_runtime11.Fragment, { children: fallback });
1448
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_jsx_runtime11.Fragment, { children });
1731
+ if (!isSignedIn || !user) return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_jsx_runtime12.Fragment, { children: fallback });
1732
+ if (condition && !condition(user)) return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_jsx_runtime12.Fragment, { children: fallback });
1733
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_jsx_runtime12.Fragment, { children });
1449
1734
  }
1450
1735
 
1451
1736
  // src/SocialButton.tsx
1452
1737
  var import_shared5 = require("@authon/shared");
1453
1738
  var import_js4 = require("@authon/js");
1454
- var import_jsx_runtime12 = require("react/jsx-runtime");
1739
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1455
1740
  var baseStyle = {
1456
1741
  display: "flex",
1457
1742
  alignItems: "center",
@@ -1497,7 +1782,7 @@ function SocialButton({
1497
1782
  const iconSvg = config.iconSvg.replace(/width="\d+"/, `width="${resolvedIconSize}"`).replace(/height="\d+"/, `height="${resolvedIconSize}"`);
1498
1783
  const borderProps = needsBorder ? { border: "1px solid #dadce0" } : {};
1499
1784
  if (compact) {
1500
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1785
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1501
1786
  "button",
1502
1787
  {
1503
1788
  className,
@@ -1513,7 +1798,7 @@ function SocialButton({
1513
1798
  onClick: () => onClick(provider),
1514
1799
  disabled: disabled || loading,
1515
1800
  "aria-label": `Sign in with ${displayName}`,
1516
- children: loading ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1801
+ children: loading ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1517
1802
  "span",
1518
1803
  {
1519
1804
  style: {
@@ -1526,7 +1811,7 @@ function SocialButton({
1526
1811
  animation: "authon-spin 0.6s linear infinite"
1527
1812
  }
1528
1813
  }
1529
- ) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1814
+ ) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1530
1815
  "span",
1531
1816
  {
1532
1817
  style: { display: "flex", alignItems: "center", flexShrink: 0 },
@@ -1536,7 +1821,7 @@ function SocialButton({
1536
1821
  }
1537
1822
  );
1538
1823
  }
1539
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1824
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1540
1825
  "button",
1541
1826
  {
1542
1827
  className,
@@ -1552,7 +1837,7 @@ function SocialButton({
1552
1837
  onClick: () => onClick(provider),
1553
1838
  disabled: disabled || loading,
1554
1839
  "aria-label": `Sign in with ${displayName}`,
1555
- children: loading ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1840
+ children: loading ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1556
1841
  "span",
1557
1842
  {
1558
1843
  style: {
@@ -1565,23 +1850,23 @@ function SocialButton({
1565
1850
  animation: "authon-spin 0.6s linear infinite"
1566
1851
  }
1567
1852
  }
1568
- ) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1569
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1853
+ ) : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
1854
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1570
1855
  "span",
1571
1856
  {
1572
1857
  style: { display: "flex", alignItems: "center", flexShrink: 0 },
1573
1858
  dangerouslySetInnerHTML: { __html: iconSvg }
1574
1859
  }
1575
1860
  ),
1576
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: { fontSize: 15, fontWeight: 600, whiteSpace: "nowrap" }, children: buttonLabel })
1861
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: { fontSize: 15, fontWeight: 600, whiteSpace: "nowrap" }, children: buttonLabel })
1577
1862
  ] })
1578
1863
  }
1579
1864
  );
1580
1865
  }
1581
1866
 
1582
1867
  // src/SocialButtons.tsx
1583
- var import_react10 = require("react");
1584
- var import_jsx_runtime13 = require("react/jsx-runtime");
1868
+ var import_react11 = require("react");
1869
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1585
1870
  function SocialButtons({
1586
1871
  onSuccess,
1587
1872
  onError,
@@ -1593,9 +1878,9 @@ function SocialButtons({
1593
1878
  buttonProps
1594
1879
  }) {
1595
1880
  const { client } = useAuthon();
1596
- const [providers, setProviders] = (0, import_react10.useState)([]);
1597
- const [loadingProvider, setLoadingProvider] = (0, import_react10.useState)(null);
1598
- (0, import_react10.useEffect)(() => {
1881
+ const [providers, setProviders] = (0, import_react11.useState)([]);
1882
+ const [loadingProvider, setLoadingProvider] = (0, import_react11.useState)(null);
1883
+ (0, import_react11.useEffect)(() => {
1599
1884
  if (!client) return;
1600
1885
  client.getProviders().then((p) => setProviders(p));
1601
1886
  }, [client]);
@@ -1615,7 +1900,7 @@ function SocialButtons({
1615
1900
  }
1616
1901
  };
1617
1902
  const containerStyle = compact ? { display: "flex", flexDirection: "row", flexWrap: "wrap", justifyContent: "center", gap: resolvedGap, ...userStyle } : { display: "flex", flexDirection: "column", gap: resolvedGap, ...userStyle };
1618
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className, style: containerStyle, children: providers.map((provider) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1903
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className, style: containerStyle, children: providers.map((provider) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1619
1904
  SocialButton,
1620
1905
  {
1621
1906
  provider,
@@ -1631,13 +1916,13 @@ function SocialButtons({
1631
1916
  }
1632
1917
 
1633
1918
  // src/useAuthonMfa.ts
1634
- var import_react11 = require("react");
1919
+ var import_react12 = require("react");
1635
1920
  function useAuthonMfa() {
1636
- const ctx = (0, import_react11.useContext)(AuthonContext);
1921
+ const ctx = (0, import_react12.useContext)(AuthonContext);
1637
1922
  if (!ctx) throw new Error("useAuthonMfa must be used within <AuthonProvider>");
1638
- const [isLoading, setIsLoading] = (0, import_react11.useState)(false);
1639
- const [error, setError] = (0, import_react11.useState)(null);
1640
- const wrap = (0, import_react11.useCallback)(
1923
+ const [isLoading, setIsLoading] = (0, import_react12.useState)(false);
1924
+ const [error, setError] = (0, import_react12.useState)(null);
1925
+ const wrap = (0, import_react12.useCallback)(
1641
1926
  async (fn) => {
1642
1927
  setIsLoading(true);
1643
1928
  setError(null);
@@ -1653,34 +1938,34 @@ function useAuthonMfa() {
1653
1938
  },
1654
1939
  []
1655
1940
  );
1656
- const setupMfa = (0, import_react11.useCallback)(async () => {
1941
+ const setupMfa = (0, import_react12.useCallback)(async () => {
1657
1942
  return wrap(() => ctx.client.setupMfa());
1658
1943
  }, [ctx.client, wrap]);
1659
- const verifyMfaSetup = (0, import_react11.useCallback)(
1944
+ const verifyMfaSetup = (0, import_react12.useCallback)(
1660
1945
  async (code) => {
1661
1946
  const result = await wrap(() => ctx.client.verifyMfaSetup(code));
1662
1947
  return result !== null;
1663
1948
  },
1664
1949
  [ctx.client, wrap]
1665
1950
  );
1666
- const verifyMfa = (0, import_react11.useCallback)(
1951
+ const verifyMfa = (0, import_react12.useCallback)(
1667
1952
  async (mfaToken, code) => {
1668
1953
  const result = await wrap(() => ctx.client.verifyMfa(mfaToken, code));
1669
1954
  return result !== null;
1670
1955
  },
1671
1956
  [ctx.client, wrap]
1672
1957
  );
1673
- const disableMfa = (0, import_react11.useCallback)(
1958
+ const disableMfa = (0, import_react12.useCallback)(
1674
1959
  async (code) => {
1675
1960
  const result = await wrap(() => ctx.client.disableMfa(code));
1676
1961
  return result !== null;
1677
1962
  },
1678
1963
  [ctx.client, wrap]
1679
1964
  );
1680
- const getMfaStatus = (0, import_react11.useCallback)(async () => {
1965
+ const getMfaStatus = (0, import_react12.useCallback)(async () => {
1681
1966
  return wrap(() => ctx.client.getMfaStatus());
1682
1967
  }, [ctx.client, wrap]);
1683
- const regenerateBackupCodes = (0, import_react11.useCallback)(
1968
+ const regenerateBackupCodes = (0, import_react12.useCallback)(
1684
1969
  async (code) => {
1685
1970
  return wrap(() => ctx.client.regenerateBackupCodes(code));
1686
1971
  },
@@ -1699,13 +1984,13 @@ function useAuthonMfa() {
1699
1984
  }
1700
1985
 
1701
1986
  // src/useAuthonPasskeys.ts
1702
- var import_react12 = require("react");
1987
+ var import_react13 = require("react");
1703
1988
  function useAuthonPasskeys() {
1704
- const ctx = (0, import_react12.useContext)(AuthonContext);
1989
+ const ctx = (0, import_react13.useContext)(AuthonContext);
1705
1990
  if (!ctx) throw new Error("useAuthonPasskeys must be used within <AuthonProvider>");
1706
- const [isLoading, setIsLoading] = (0, import_react12.useState)(false);
1707
- const [error, setError] = (0, import_react12.useState)(null);
1708
- const wrap = (0, import_react12.useCallback)(
1991
+ const [isLoading, setIsLoading] = (0, import_react13.useState)(false);
1992
+ const [error, setError] = (0, import_react13.useState)(null);
1993
+ const wrap = (0, import_react13.useCallback)(
1709
1994
  async (fn) => {
1710
1995
  setIsLoading(true);
1711
1996
  setError(null);
@@ -1720,26 +2005,26 @@ function useAuthonPasskeys() {
1720
2005
  },
1721
2006
  []
1722
2007
  );
1723
- const registerPasskey = (0, import_react12.useCallback)(
2008
+ const registerPasskey = (0, import_react13.useCallback)(
1724
2009
  (name) => wrap(() => ctx.client.registerPasskey(name)),
1725
2010
  [ctx.client, wrap]
1726
2011
  );
1727
- const authenticateWithPasskey = (0, import_react12.useCallback)(
2012
+ const authenticateWithPasskey = (0, import_react13.useCallback)(
1728
2013
  async (email) => {
1729
2014
  const result = await wrap(() => ctx.client.authenticateWithPasskey(email));
1730
2015
  return result !== null;
1731
2016
  },
1732
2017
  [ctx.client, wrap]
1733
2018
  );
1734
- const listPasskeys = (0, import_react12.useCallback)(
2019
+ const listPasskeys = (0, import_react13.useCallback)(
1735
2020
  () => wrap(() => ctx.client.listPasskeys()),
1736
2021
  [ctx.client, wrap]
1737
2022
  );
1738
- const renamePasskey = (0, import_react12.useCallback)(
2023
+ const renamePasskey = (0, import_react13.useCallback)(
1739
2024
  (id, name) => wrap(() => ctx.client.renamePasskey(id, name)),
1740
2025
  [ctx.client, wrap]
1741
2026
  );
1742
- const revokePasskey = (0, import_react12.useCallback)(
2027
+ const revokePasskey = (0, import_react13.useCallback)(
1743
2028
  async (id) => {
1744
2029
  const result = await wrap(() => ctx.client.revokePasskey(id));
1745
2030
  return result !== null;
@@ -1758,13 +2043,13 @@ function useAuthonPasskeys() {
1758
2043
  }
1759
2044
 
1760
2045
  // src/useAuthonPasswordless.ts
1761
- var import_react13 = require("react");
2046
+ var import_react14 = require("react");
1762
2047
  function useAuthonPasswordless() {
1763
- const ctx = (0, import_react13.useContext)(AuthonContext);
2048
+ const ctx = (0, import_react14.useContext)(AuthonContext);
1764
2049
  if (!ctx) throw new Error("useAuthonPasswordless must be used within <AuthonProvider>");
1765
- const [isLoading, setIsLoading] = (0, import_react13.useState)(false);
1766
- const [error, setError] = (0, import_react13.useState)(null);
1767
- const wrap = (0, import_react13.useCallback)(
2050
+ const [isLoading, setIsLoading] = (0, import_react14.useState)(false);
2051
+ const [error, setError] = (0, import_react14.useState)(null);
2052
+ const wrap = (0, import_react14.useCallback)(
1768
2053
  async (fn) => {
1769
2054
  setIsLoading(true);
1770
2055
  setError(null);
@@ -1779,21 +2064,21 @@ function useAuthonPasswordless() {
1779
2064
  },
1780
2065
  []
1781
2066
  );
1782
- const sendMagicLink = (0, import_react13.useCallback)(
2067
+ const sendMagicLink = (0, import_react14.useCallback)(
1783
2068
  async (email) => {
1784
2069
  const result = await wrap(() => ctx.client.sendMagicLink(email));
1785
2070
  return result !== null;
1786
2071
  },
1787
2072
  [ctx.client, wrap]
1788
2073
  );
1789
- const sendEmailOtp = (0, import_react13.useCallback)(
2074
+ const sendEmailOtp = (0, import_react14.useCallback)(
1790
2075
  async (email) => {
1791
2076
  const result = await wrap(() => ctx.client.sendEmailOtp(email));
1792
2077
  return result !== null;
1793
2078
  },
1794
2079
  [ctx.client, wrap]
1795
2080
  );
1796
- const verifyPasswordless = (0, import_react13.useCallback)(
2081
+ const verifyPasswordless = (0, import_react14.useCallback)(
1797
2082
  async (opts) => {
1798
2083
  const result = await wrap(() => ctx.client.verifyPasswordless(opts));
1799
2084
  return result !== null;
@@ -1810,13 +2095,13 @@ function useAuthonPasswordless() {
1810
2095
  }
1811
2096
 
1812
2097
  // src/useAuthonWeb3.ts
1813
- var import_react14 = require("react");
2098
+ var import_react15 = require("react");
1814
2099
  function useAuthonWeb3() {
1815
- const ctx = (0, import_react14.useContext)(AuthonContext);
2100
+ const ctx = (0, import_react15.useContext)(AuthonContext);
1816
2101
  if (!ctx) throw new Error("useAuthonWeb3 must be used within <AuthonProvider>");
1817
- const [isLoading, setIsLoading] = (0, import_react14.useState)(false);
1818
- const [error, setError] = (0, import_react14.useState)(null);
1819
- const wrap = (0, import_react14.useCallback)(
2102
+ const [isLoading, setIsLoading] = (0, import_react15.useState)(false);
2103
+ const [error, setError] = (0, import_react15.useState)(null);
2104
+ const wrap = (0, import_react15.useCallback)(
1820
2105
  async (fn) => {
1821
2106
  setIsLoading(true);
1822
2107
  setError(null);
@@ -1831,11 +2116,11 @@ function useAuthonWeb3() {
1831
2116
  },
1832
2117
  []
1833
2118
  );
1834
- const getNonce = (0, import_react14.useCallback)(
2119
+ const getNonce = (0, import_react15.useCallback)(
1835
2120
  (address, chain, walletType, chainId) => wrap(() => ctx.client.web3GetNonce(address, chain, walletType, chainId)),
1836
2121
  [ctx.client, wrap]
1837
2122
  );
1838
- const verify = (0, import_react14.useCallback)(
2123
+ const verify = (0, import_react15.useCallback)(
1839
2124
  async (message, signature, address, chain, walletType) => {
1840
2125
  const result = await wrap(
1841
2126
  () => ctx.client.web3Verify(message, signature, address, chain, walletType)
@@ -1844,15 +2129,15 @@ function useAuthonWeb3() {
1844
2129
  },
1845
2130
  [ctx.client, wrap]
1846
2131
  );
1847
- const listWallets = (0, import_react14.useCallback)(
2132
+ const listWallets = (0, import_react15.useCallback)(
1848
2133
  () => wrap(() => ctx.client.listWallets()),
1849
2134
  [ctx.client, wrap]
1850
2135
  );
1851
- const linkWallet = (0, import_react14.useCallback)(
2136
+ const linkWallet = (0, import_react15.useCallback)(
1852
2137
  (params) => wrap(() => ctx.client.linkWallet(params)),
1853
2138
  [ctx.client, wrap]
1854
2139
  );
1855
- const unlinkWallet = (0, import_react14.useCallback)(
2140
+ const unlinkWallet = (0, import_react15.useCallback)(
1856
2141
  async (walletId) => {
1857
2142
  const result = await wrap(() => ctx.client.unlinkWallet(walletId));
1858
2143
  return result !== null;
@@ -1871,13 +2156,13 @@ function useAuthonWeb3() {
1871
2156
  }
1872
2157
 
1873
2158
  // src/useAuthonSessions.ts
1874
- var import_react15 = require("react");
2159
+ var import_react16 = require("react");
1875
2160
  function useAuthonSessions() {
1876
- const ctx = (0, import_react15.useContext)(AuthonContext);
2161
+ const ctx = (0, import_react16.useContext)(AuthonContext);
1877
2162
  if (!ctx) throw new Error("useAuthonSessions must be used within <AuthonProvider>");
1878
- const [isLoading, setIsLoading] = (0, import_react15.useState)(false);
1879
- const [error, setError] = (0, import_react15.useState)(null);
1880
- const wrap = (0, import_react15.useCallback)(
2163
+ const [isLoading, setIsLoading] = (0, import_react16.useState)(false);
2164
+ const [error, setError] = (0, import_react16.useState)(null);
2165
+ const wrap = (0, import_react16.useCallback)(
1881
2166
  async (fn) => {
1882
2167
  setIsLoading(true);
1883
2168
  setError(null);
@@ -1892,11 +2177,11 @@ function useAuthonSessions() {
1892
2177
  },
1893
2178
  []
1894
2179
  );
1895
- const listSessions = (0, import_react15.useCallback)(
2180
+ const listSessions = (0, import_react16.useCallback)(
1896
2181
  () => wrap(() => ctx.client.listSessions()),
1897
2182
  [ctx.client, wrap]
1898
2183
  );
1899
- const revokeSession = (0, import_react15.useCallback)(
2184
+ const revokeSession = (0, import_react16.useCallback)(
1900
2185
  async (sessionId) => {
1901
2186
  const result = await wrap(() => ctx.client.revokeSession(sessionId));
1902
2187
  return result !== null;
@@ -1912,14 +2197,14 @@ function useAuthonSessions() {
1912
2197
  }
1913
2198
 
1914
2199
  // src/useOrganization.ts
1915
- var import_react16 = require("react");
2200
+ var import_react17 = require("react");
1916
2201
  function useOrganization() {
1917
- const ctx = (0, import_react16.useContext)(AuthonContext);
2202
+ const ctx = (0, import_react17.useContext)(AuthonContext);
1918
2203
  if (!ctx) throw new Error("useOrganization must be used within <AuthonProvider>");
1919
- const [members, setMembers] = (0, import_react16.useState)([]);
1920
- const [isLoaded, setIsLoaded] = (0, import_react16.useState)(false);
2204
+ const [members, setMembers] = (0, import_react17.useState)([]);
2205
+ const [isLoaded, setIsLoaded] = (0, import_react17.useState)(false);
1921
2206
  const organization = ctx.activeOrganization;
1922
- (0, import_react16.useEffect)(() => {
2207
+ (0, import_react17.useEffect)(() => {
1923
2208
  if (!organization || !ctx.client) {
1924
2209
  setMembers([]);
1925
2210
  setIsLoaded(!organization);
@@ -1942,13 +2227,13 @@ function useOrganization() {
1942
2227
  }
1943
2228
 
1944
2229
  // src/useOrganizationList.ts
1945
- var import_react17 = require("react");
2230
+ var import_react18 = require("react");
1946
2231
  function useOrganizationList() {
1947
- const ctx = (0, import_react17.useContext)(AuthonContext);
2232
+ const ctx = (0, import_react18.useContext)(AuthonContext);
1948
2233
  if (!ctx) throw new Error("useOrganizationList must be used within <AuthonProvider>");
1949
- const [organizations, setOrganizations] = (0, import_react17.useState)([]);
1950
- const [isLoaded, setIsLoaded] = (0, import_react17.useState)(false);
1951
- (0, import_react17.useEffect)(() => {
2234
+ const [organizations, setOrganizations] = (0, import_react18.useState)([]);
2235
+ const [isLoaded, setIsLoaded] = (0, import_react18.useState)(false);
2236
+ (0, import_react18.useEffect)(() => {
1952
2237
  if (!ctx.client || !ctx.isSignedIn) {
1953
2238
  setOrganizations([]);
1954
2239
  setIsLoaded(!ctx.isSignedIn);
@@ -1963,7 +2248,7 @@ function useOrganizationList() {
1963
2248
  setIsLoaded(true);
1964
2249
  });
1965
2250
  }, [ctx.client, ctx.isSignedIn]);
1966
- const createOrganization = (0, import_react17.useCallback)(
2251
+ const createOrganization = (0, import_react18.useCallback)(
1967
2252
  async (params) => {
1968
2253
  if (!ctx.client) return null;
1969
2254
  try {
@@ -1976,7 +2261,7 @@ function useOrganizationList() {
1976
2261
  },
1977
2262
  [ctx.client]
1978
2263
  );
1979
- const setActive = (0, import_react17.useCallback)(
2264
+ const setActive = (0, import_react18.useCallback)(
1980
2265
  (org) => {
1981
2266
  ctx.setActiveOrganization(org);
1982
2267
  },
@@ -1991,16 +2276,16 @@ function useOrganizationList() {
1991
2276
  }
1992
2277
 
1993
2278
  // src/components/UserProfile.tsx
1994
- var import_react18 = require("react");
1995
- var import_jsx_runtime14 = require("react/jsx-runtime");
2279
+ var import_react19 = require("react");
2280
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1996
2281
  function ProfileTab() {
1997
2282
  const theme = useTheme();
1998
2283
  const { user, client } = useAuthon();
1999
- const [displayName, setDisplayName] = (0, import_react18.useState)(user?.displayName ?? "");
2000
- const [phone, setPhone] = (0, import_react18.useState)(user?.phone ?? "");
2001
- const [loading, setLoading] = (0, import_react18.useState)(false);
2002
- const [success, setSuccess] = (0, import_react18.useState)("");
2003
- const [error, setError] = (0, import_react18.useState)("");
2284
+ const [displayName, setDisplayName] = (0, import_react19.useState)(user?.displayName ?? "");
2285
+ const [phone, setPhone] = (0, import_react19.useState)(user?.phone ?? "");
2286
+ const [loading, setLoading] = (0, import_react19.useState)(false);
2287
+ const [success, setSuccess] = (0, import_react19.useState)("");
2288
+ const [error, setError] = (0, import_react19.useState)("");
2004
2289
  const handleSave = async () => {
2005
2290
  if (!client) return;
2006
2291
  setLoading(true);
@@ -2016,9 +2301,9 @@ function ProfileTab() {
2016
2301
  }
2017
2302
  };
2018
2303
  const initials = user?.displayName ? user.displayName.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2) : (user?.email?.[0] ?? "?").toUpperCase();
2019
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 24 }, children: [
2020
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 16 }, children: [
2021
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2304
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 24 }, children: [
2305
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 16 }, children: [
2306
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2022
2307
  "div",
2023
2308
  {
2024
2309
  style: {
@@ -2035,37 +2320,37 @@ function ProfileTab() {
2035
2320
  overflow: "hidden",
2036
2321
  flexShrink: 0
2037
2322
  },
2038
- children: user?.avatarUrl ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("img", { src: user.avatarUrl, alt: "avatar", style: { width: "100%", height: "100%", objectFit: "cover" } }) : initials
2323
+ children: user?.avatarUrl ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("img", { src: user.avatarUrl, alt: "avatar", style: { width: "100%", height: "100%", objectFit: "cover" } }) : initials
2039
2324
  }
2040
2325
  ),
2041
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
2042
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { fontSize: 16, fontWeight: 600, color: theme.text }, children: user?.displayName ?? "User" }),
2043
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { fontSize: 13, color: theme.textMuted }, children: user?.email }),
2044
- !user?.emailVerified && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { style: { fontSize: 11, color: "#d97706", background: "#fef3c7", padding: "2px 8px", borderRadius: 99, fontWeight: 500, marginTop: 4, display: "inline-block" }, children: "Email not verified" })
2326
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { children: [
2327
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { fontSize: 16, fontWeight: 600, color: theme.text }, children: user?.displayName ?? "User" }),
2328
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { fontSize: 13, color: theme.textMuted }, children: user?.email }),
2329
+ !user?.emailVerified && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { style: { fontSize: 11, color: "#d97706", background: "#fef3c7", padding: "2px 8px", borderRadius: 99, fontWeight: 500, marginTop: 4, display: "inline-block" }, children: "Email not verified" })
2045
2330
  ] })
2046
2331
  ] }),
2047
- success && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { padding: "10px 14px", borderRadius: theme.borderRadius, background: "#f0fdf4", border: "1px solid #bbf7d0", color: "#166534", fontSize: 13 }, children: success }),
2048
- error && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { padding: "10px 14px", borderRadius: theme.borderRadius, background: "#fef2f2", border: "1px solid #fecaca", color: "#dc2626", fontSize: 13 }, children: error }),
2049
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 16 }, children: [
2050
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Input, { label: "Display name", value: displayName, onChange: setDisplayName, placeholder: "Your name" }),
2051
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Input, { label: "Email", type: "email", value: user?.email ?? "", disabled: true, placeholder: "Email" }),
2052
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Input, { label: "Phone", type: "tel", value: phone, onChange: setPhone, placeholder: "+1 (555) 000-0000" })
2332
+ success && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { padding: "10px 14px", borderRadius: theme.borderRadius, background: "#f0fdf4", border: "1px solid #bbf7d0", color: "#166534", fontSize: 13 }, children: success }),
2333
+ error && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { padding: "10px 14px", borderRadius: theme.borderRadius, background: "#fef2f2", border: "1px solid #fecaca", color: "#dc2626", fontSize: 13 }, children: error }),
2334
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 16 }, children: [
2335
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Input, { label: "Display name", value: displayName, onChange: setDisplayName, placeholder: "Your name" }),
2336
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Input, { label: "Email", type: "email", value: user?.email ?? "", disabled: true, placeholder: "Email" }),
2337
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Input, { label: "Phone", type: "tel", value: phone, onChange: setPhone, placeholder: "+1 (555) 000-0000" })
2053
2338
  ] }),
2054
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Button, { variant: "primary", onClick: handleSave, loading, style: { alignSelf: "flex-start", minWidth: 120 }, children: "Save changes" })
2339
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { variant: "primary", onClick: handleSave, loading, style: { alignSelf: "flex-start", minWidth: 120 }, children: "Save changes" })
2055
2340
  ] });
2056
2341
  }
2057
2342
  function SecurityTab() {
2058
2343
  const theme = useTheme();
2059
2344
  const { client } = useAuthon();
2060
- const [currentPw, setCurrentPw] = (0, import_react18.useState)("");
2061
- const [newPw, setNewPw] = (0, import_react18.useState)("");
2062
- const [confirmPw, setConfirmPw] = (0, import_react18.useState)("");
2063
- const [pwLoading, setPwLoading] = (0, import_react18.useState)(false);
2064
- const [pwError, setPwError] = (0, import_react18.useState)("");
2065
- const [pwSuccess, setPwSuccess] = (0, import_react18.useState)("");
2066
- const [mfaStatus, setMfaStatus] = (0, import_react18.useState)(null);
2067
- const [mfaLoading, setMfaLoading] = (0, import_react18.useState)(false);
2068
- (0, import_react18.useEffect)(() => {
2345
+ const [currentPw, setCurrentPw] = (0, import_react19.useState)("");
2346
+ const [newPw, setNewPw] = (0, import_react19.useState)("");
2347
+ const [confirmPw, setConfirmPw] = (0, import_react19.useState)("");
2348
+ const [pwLoading, setPwLoading] = (0, import_react19.useState)(false);
2349
+ const [pwError, setPwError] = (0, import_react19.useState)("");
2350
+ const [pwSuccess, setPwSuccess] = (0, import_react19.useState)("");
2351
+ const [mfaStatus, setMfaStatus] = (0, import_react19.useState)(null);
2352
+ const [mfaLoading, setMfaLoading] = (0, import_react19.useState)(false);
2353
+ (0, import_react19.useEffect)(() => {
2069
2354
  if (!client) return;
2070
2355
  client.getMfaStatus().then(setMfaStatus).catch(() => null);
2071
2356
  }, [client]);
@@ -2102,26 +2387,26 @@ function SecurityTab() {
2102
2387
  paddingBottom: 10,
2103
2388
  borderBottom: `1px solid ${theme.border}`
2104
2389
  };
2105
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 32 }, children: [
2106
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
2107
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: sectionTitle, children: "Change password" }),
2108
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 16 }, children: [
2109
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Input, { label: "Current password", type: "password", value: currentPw, onChange: setCurrentPw, placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", autoComplete: "current-password" }),
2110
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Input, { label: "New password", type: "password", value: newPw, onChange: setNewPw, placeholder: "Minimum 8 characters", autoComplete: "new-password" }),
2111
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Input, { label: "Confirm new password", type: "password", value: confirmPw, onChange: setConfirmPw, placeholder: "Repeat new password", autoComplete: "new-password" }),
2112
- pwError && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { color: "#dc2626", fontSize: 13 }, children: pwError }),
2113
- pwSuccess && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { color: "#166534", fontSize: 13 }, children: pwSuccess }),
2114
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Button, { variant: "primary", onClick: handlePasswordChange, loading: pwLoading, style: { alignSelf: "flex-start", minWidth: 160 }, children: "Update password" })
2390
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 32 }, children: [
2391
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { children: [
2392
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: sectionTitle, children: "Change password" }),
2393
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 16 }, children: [
2394
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Input, { label: "Current password", type: "password", value: currentPw, onChange: setCurrentPw, placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", autoComplete: "current-password" }),
2395
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Input, { label: "New password", type: "password", value: newPw, onChange: setNewPw, placeholder: "Minimum 8 characters", autoComplete: "new-password" }),
2396
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Input, { label: "Confirm new password", type: "password", value: confirmPw, onChange: setConfirmPw, placeholder: "Repeat new password", autoComplete: "new-password" }),
2397
+ pwError && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { color: "#dc2626", fontSize: 13 }, children: pwError }),
2398
+ pwSuccess && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { color: "#166534", fontSize: 13 }, children: pwSuccess }),
2399
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { variant: "primary", onClick: handlePasswordChange, loading: pwLoading, style: { alignSelf: "flex-start", minWidth: 160 }, children: "Update password" })
2115
2400
  ] })
2116
2401
  ] }),
2117
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
2118
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: sectionTitle, children: "Two-factor authentication" }),
2119
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", padding: "14px 0" }, children: [
2120
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
2121
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { fontSize: 14, fontWeight: 500, color: theme.text }, children: "Authenticator app" }),
2122
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { fontSize: 13, color: theme.textMuted, marginTop: 2 }, children: mfaStatus?.enabled ? `Enabled \xB7 ${mfaStatus.backupCodesRemaining} backup codes remaining` : "Add extra security to your account" })
2402
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { children: [
2403
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: sectionTitle, children: "Two-factor authentication" }),
2404
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", padding: "14px 0" }, children: [
2405
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { children: [
2406
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { fontSize: 14, fontWeight: 500, color: theme.text }, children: "Authenticator app" }),
2407
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { fontSize: 13, color: theme.textMuted, marginTop: 2 }, children: mfaStatus?.enabled ? `Enabled \xB7 ${mfaStatus.backupCodesRemaining} backup codes remaining` : "Add extra security to your account" })
2123
2408
  ] }),
2124
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
2409
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2125
2410
  "span",
2126
2411
  {
2127
2412
  style: {
@@ -2136,7 +2421,7 @@ function SecurityTab() {
2136
2421
  color: mfaStatus?.enabled ? "#166534" : theme.textMuted
2137
2422
  },
2138
2423
  children: [
2139
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { style: { width: 6, height: 6, borderRadius: "50%", background: mfaStatus?.enabled ? "#22c55e" : "#9ca3af", display: "inline-block" } }),
2424
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { style: { width: 6, height: 6, borderRadius: "50%", background: mfaStatus?.enabled ? "#22c55e" : "#9ca3af", display: "inline-block" } }),
2140
2425
  mfaStatus?.enabled ? "Enabled" : "Disabled"
2141
2426
  ]
2142
2427
  }
@@ -2148,10 +2433,10 @@ function SecurityTab() {
2148
2433
  function SessionsTab() {
2149
2434
  const theme = useTheme();
2150
2435
  const { client } = useAuthon();
2151
- const [sessions, setSessions] = (0, import_react18.useState)([]);
2152
- const [loading, setLoading] = (0, import_react18.useState)(true);
2153
- const [revoking, setRevoking] = (0, import_react18.useState)(null);
2154
- const loadSessions = (0, import_react18.useCallback)(async () => {
2436
+ const [sessions, setSessions] = (0, import_react19.useState)([]);
2437
+ const [loading, setLoading] = (0, import_react19.useState)(true);
2438
+ const [revoking, setRevoking] = (0, import_react19.useState)(null);
2439
+ const loadSessions = (0, import_react19.useCallback)(async () => {
2155
2440
  if (!client) return;
2156
2441
  setLoading(true);
2157
2442
  try {
@@ -2162,7 +2447,7 @@ function SessionsTab() {
2162
2447
  setLoading(false);
2163
2448
  }
2164
2449
  }, [client]);
2165
- (0, import_react18.useEffect)(() => {
2450
+ (0, import_react19.useEffect)(() => {
2166
2451
  loadSessions();
2167
2452
  }, [loadSessions]);
2168
2453
  const handleRevoke = async (sessionId) => {
@@ -2185,11 +2470,11 @@ function SessionsTab() {
2185
2470
  borderBottom: `1px solid ${theme.border}`
2186
2471
  };
2187
2472
  if (loading) {
2188
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { display: "flex", justifyContent: "center", padding: 40 }, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { style: { width: 24, height: 24, border: `3px solid ${theme.primaryStart}33`, borderTopColor: theme.primaryStart, borderRadius: "50%", display: "inline-block", animation: "authon-spin 0.7s linear infinite" } }) });
2473
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { display: "flex", justifyContent: "center", padding: 40 }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { style: { width: 24, height: 24, border: `3px solid ${theme.primaryStart}33`, borderTopColor: theme.primaryStart, borderRadius: "50%", display: "inline-block", animation: "authon-spin 0.7s linear infinite" } }) });
2189
2474
  }
2190
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
2191
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: sectionTitle, children: "Active sessions" }),
2192
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: sessions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { color: theme.textMuted, fontSize: 14, textAlign: "center", padding: "24px 0" }, children: "No active sessions" }) : sessions.map((session) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
2475
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { children: [
2476
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: sectionTitle, children: "Active sessions" }),
2477
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: sessions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { color: theme.textMuted, fontSize: 14, textAlign: "center", padding: "24px 0" }, children: "No active sessions" }) : sessions.map((session) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2193
2478
  "div",
2194
2479
  {
2195
2480
  style: {
@@ -2202,24 +2487,24 @@ function SessionsTab() {
2202
2487
  gap: 12
2203
2488
  },
2204
2489
  children: [
2205
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 12, flex: 1, minWidth: 0 }, children: [
2206
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { width: 36, height: 36, borderRadius: "50%", background: `${theme.primaryStart}18`, color: theme.primaryStart, display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2207
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("rect", { x: "2", y: "3", width: "20", height: "14", rx: "2", ry: "2" }),
2208
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("line", { x1: "8", y1: "21", x2: "16", y2: "21" }),
2209
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("line", { x1: "12", y1: "17", x2: "12", y2: "21" })
2490
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 12, flex: 1, minWidth: 0 }, children: [
2491
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { width: 36, height: 36, borderRadius: "50%", background: `${theme.primaryStart}18`, color: theme.primaryStart, display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2492
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("rect", { x: "2", y: "3", width: "20", height: "14", rx: "2", ry: "2" }),
2493
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("line", { x1: "8", y1: "21", x2: "16", y2: "21" }),
2494
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("line", { x1: "12", y1: "17", x2: "12", y2: "21" })
2210
2495
  ] }) }),
2211
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { minWidth: 0 }, children: [
2212
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { fontSize: 13, fontWeight: 500, color: theme.text, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: session.userAgent ? session.userAgent.length > 50 ? session.userAgent.slice(0, 50) + "\u2026" : session.userAgent : "Unknown device" }),
2213
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { fontSize: 12, color: theme.textMuted, marginTop: 2 }, children: [
2496
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { minWidth: 0 }, children: [
2497
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { fontSize: 13, fontWeight: 500, color: theme.text, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: session.userAgent ? session.userAgent.length > 50 ? session.userAgent.slice(0, 50) + "\u2026" : session.userAgent : "Unknown device" }),
2498
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { fontSize: 12, color: theme.textMuted, marginTop: 2 }, children: [
2214
2499
  session.ipAddress ?? "Unknown IP",
2215
- session.lastActiveAt && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
2500
+ session.lastActiveAt && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
2216
2501
  " \xB7 ",
2217
2502
  formatRelative(session.lastActiveAt)
2218
2503
  ] })
2219
2504
  ] })
2220
2505
  ] })
2221
2506
  ] }),
2222
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2507
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2223
2508
  Button,
2224
2509
  {
2225
2510
  variant: "outline",
@@ -2247,7 +2532,7 @@ function formatRelative(dateStr) {
2247
2532
  }
2248
2533
  function UserProfilePanel() {
2249
2534
  const theme = useTheme();
2250
- const [tab, setTab] = (0, import_react18.useState)("profile");
2535
+ const [tab, setTab] = (0, import_react19.useState)("profile");
2251
2536
  const panelStyle = {
2252
2537
  width: "100%",
2253
2538
  maxWidth: 640,
@@ -2282,9 +2567,9 @@ function UserProfilePanel() {
2282
2567
  { key: "security", label: "Security" },
2283
2568
  { key: "sessions", label: "Sessions" }
2284
2569
  ];
2285
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: panelStyle, children: [
2286
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("style", { children: `@keyframes authon-spin { to { transform: rotate(360deg); } }` }),
2287
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: tabBarStyle, children: tabs.map(({ key, label }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2570
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: panelStyle, children: [
2571
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("style", { children: `@keyframes authon-spin { to { transform: rotate(360deg); } }` }),
2572
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: tabBarStyle, children: tabs.map(({ key, label }) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2288
2573
  "button",
2289
2574
  {
2290
2575
  type: "button",
@@ -2294,26 +2579,26 @@ function UserProfilePanel() {
2294
2579
  },
2295
2580
  key
2296
2581
  )) }),
2297
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: contentStyle, children: [
2298
- tab === "profile" && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ProfileTab, {}),
2299
- tab === "security" && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SecurityTab, {}),
2300
- tab === "sessions" && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SessionsTab, {})
2582
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: contentStyle, children: [
2583
+ tab === "profile" && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ProfileTab, {}),
2584
+ tab === "security" && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SecurityTab, {}),
2585
+ tab === "sessions" && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SessionsTab, {})
2301
2586
  ] })
2302
2587
  ] });
2303
2588
  }
2304
2589
  function UserProfile({ appearance }) {
2305
2590
  const { branding } = useBranding();
2306
2591
  const effectiveBranding = { ...branding, ...appearance?.variables ?? {} };
2307
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ThemeProvider, { branding: effectiveBranding, style: { display: "flex", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(UserProfilePanel, {}) });
2592
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ThemeProvider, { branding: effectiveBranding, style: { display: "flex", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(UserProfilePanel, {}) });
2308
2593
  }
2309
2594
 
2310
2595
  // src/components/shared/ProviderIcon.tsx
2311
2596
  var import_js5 = require("@authon/js");
2312
- var import_jsx_runtime15 = require("react/jsx-runtime");
2597
+ var import_jsx_runtime16 = require("react/jsx-runtime");
2313
2598
  function ProviderIcon({ provider, size = 20 }) {
2314
2599
  const config = (0, import_js5.getProviderButtonConfig)(provider);
2315
2600
  const svg = config.iconSvg.replace(/width="\d+"/, `width="${size}"`).replace(/height="\d+"/, `height="${size}"`);
2316
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2601
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2317
2602
  "span",
2318
2603
  {
2319
2604
  style: { display: "flex", alignItems: "center", flexShrink: 0 },