@insforge/react 0.4.0 → 0.4.6

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.
@@ -1,5 +1,6 @@
1
1
  import { createContext, useState, useRef, useEffect, useCallback, useContext } from 'react';
2
- import { createClient } from '@insforge/sdk';
2
+ import { useSearchParams } from 'react-router-dom';
3
+ import '@insforge/sdk';
3
4
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
4
5
  import { AlertTriangle, Check, EyeOff, Eye, Loader2, CircleCheck, LogOut } from 'lucide-react';
5
6
  import { z } from 'zod';
@@ -117,21 +118,12 @@ function AuthErrorBanner({ error }) {
117
118
  if (!error) {
118
119
  return null;
119
120
  }
120
- return /* @__PURE__ */ jsx("div", { className: "if-errorBanner if-internal-eb2m7k", children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
121
- /* @__PURE__ */ jsx(
122
- AlertTriangle,
123
- {
124
- style: { width: "1.5rem", height: "1.5rem", flexShrink: 0, color: "#dc2626" }
125
- }
126
- ),
121
+ return /* @__PURE__ */ jsx("div", { className: "if-errorBanner if-internal-eb2m7k", children: /* @__PURE__ */ jsxs("div", { className: "if-errorBanner-content", children: [
122
+ /* @__PURE__ */ jsx(AlertTriangle, { className: "if-errorBanner-icon" }),
127
123
  /* @__PURE__ */ jsx("span", { className: "if-errorBanner-text", children: error })
128
124
  ] }) });
129
125
  }
130
- function AuthFormField({
131
- label,
132
- id,
133
- ...props
134
- }) {
126
+ function AuthFormField({ label, id, ...props }) {
135
127
  return /* @__PURE__ */ jsxs("div", { className: "if-formField if-internal-f9n6p2", children: [
136
128
  /* @__PURE__ */ jsx("label", { htmlFor: id, className: "if-formField-label if-internal-l3k8m1", children: label }),
137
129
  /* @__PURE__ */ jsx("input", { id, className: "if-formField-input if-internal-i2v8k4", ...props })
@@ -258,14 +250,17 @@ function AuthSubmitButton({
258
250
  children,
259
251
  isLoading = false,
260
252
  confirmed = false,
261
- disabled = false
253
+ disabled = false,
254
+ type = "submit",
255
+ onClick
262
256
  }) {
263
257
  return /* @__PURE__ */ jsxs(
264
258
  "button",
265
259
  {
266
- type: "submit",
260
+ type,
267
261
  className: "if-submitButton if-internal-b8p3m4",
268
262
  disabled: disabled || isLoading || confirmed,
263
+ onClick,
269
264
  children: [
270
265
  isLoading && /* @__PURE__ */ jsx(Loader2, { className: "if-submitButton-icon if-submitButton-spinner", size: 20 }),
271
266
  confirmed && /* @__PURE__ */ jsx(CircleCheck, { className: "if-submitButton-icon", size: 20 }),
@@ -274,24 +269,16 @@ function AuthSubmitButton({
274
269
  }
275
270
  );
276
271
  }
277
- function AuthLink({
278
- text,
279
- linkText,
280
- href
281
- }) {
282
- const currentSearch = typeof window !== "undefined" ? window.location.search : "";
272
+ function AuthLink({ text, linkText, href }) {
273
+ const [searchParams] = useSearchParams();
274
+ const currentSearch = searchParams.toString();
283
275
  const finalHref = (() => {
284
276
  if (!currentSearch) {
285
277
  return href;
286
278
  }
287
279
  try {
288
280
  const url = new URL(href, window.location.origin);
289
- const currentParams = new URLSearchParams(currentSearch);
290
- currentParams.forEach((value, key) => {
291
- if (!url.searchParams.has(key)) {
292
- url.searchParams.set(key, value);
293
- }
294
- });
281
+ url.search = currentSearch;
295
282
  return url.pathname + url.search;
296
283
  } catch {
297
284
  return href;
@@ -648,28 +635,26 @@ function AuthVerificationCodeInput({
648
635
  }
649
636
  function AuthEmailVerificationStep({
650
637
  email,
651
- description,
652
638
  method = "code",
653
639
  onVerifyCode
654
640
  }) {
655
- const { baseUrl } = useInsforge();
656
- const [insforge] = useState(() => createClient({ baseUrl }));
641
+ const { sendVerificationEmail } = useInsforge();
657
642
  const [resendDisabled, setResendDisabled] = useState(true);
658
643
  const [resendCountdown, setResendCountdown] = useState(60);
659
644
  const [isSending, setIsSending] = useState(false);
660
645
  const [verificationCode, setVerificationCode] = useState("");
661
646
  const [isVerifying, setIsVerifying] = useState(false);
662
- const [verificationError, setVerificationError] = useState("");
663
647
  const defaultDescription = method === "code" ? "We've sent a 6-digit verification code to {email}. Please enter it below to verify your account. The code will expire in 10 minutes." : "We've sent a verification link to {email}. Please check your email and click the link to verify your account. The link will expire in 10 minutes.";
664
648
  useEffect(() => {
665
649
  const sendInitialEmail = async () => {
666
650
  try {
667
- await insforge.auth.sendVerificationEmail({ email });
668
- } catch {
651
+ await sendVerificationEmail(email);
652
+ } catch (error) {
653
+ console.error("Failed to send verification email:", error);
669
654
  }
670
655
  };
671
656
  void sendInitialEmail();
672
- }, [email, method, insforge.auth]);
657
+ }, [email, sendVerificationEmail]);
673
658
  useEffect(() => {
674
659
  if (resendCountdown > 0) {
675
660
  const timer = setInterval(() => {
@@ -688,9 +673,8 @@ function AuthEmailVerificationStep({
688
673
  setResendDisabled(true);
689
674
  setResendCountdown(60);
690
675
  setIsSending(true);
691
- setVerificationError("");
692
676
  try {
693
- await insforge.auth.sendVerificationEmail({ email });
677
+ await sendVerificationEmail(email);
694
678
  } catch {
695
679
  setResendDisabled(false);
696
680
  setResendCountdown(0);
@@ -698,123 +682,157 @@ function AuthEmailVerificationStep({
698
682
  setIsSending(false);
699
683
  }
700
684
  };
701
- const handleVerifyCode = async (code) => {
702
- if (!onVerifyCode) {
685
+ const handleSubmit = async () => {
686
+ if (!onVerifyCode || verificationCode.length !== 6) {
703
687
  return;
704
688
  }
705
689
  setIsVerifying(true);
706
- setVerificationError("");
707
690
  try {
708
- await onVerifyCode(code);
709
- } catch (error) {
710
- setVerificationError(
711
- error instanceof Error ? error.message : "Invalid verification code. Please try again."
712
- );
713
- setVerificationCode("");
691
+ await onVerifyCode(verificationCode);
714
692
  } finally {
715
693
  setIsVerifying(false);
694
+ setVerificationCode("");
716
695
  }
717
696
  };
718
- const displayDescription = description || defaultDescription;
719
- return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1.5rem", alignItems: "stretch" }, children: [
720
- /* @__PURE__ */ jsx("p", { className: "if-verificationCode-description", children: displayDescription.split("{email}").map((part, index, array) => /* @__PURE__ */ jsxs("span", { children: [
697
+ const displayDescription = defaultDescription;
698
+ const isLinkMethod = method === "link";
699
+ return /* @__PURE__ */ jsxs("div", { className: "if-verificationStep", children: [
700
+ /* @__PURE__ */ jsx("p", { className: "if-verificationStep-description", children: displayDescription.split("{email}").map((part, index, array) => /* @__PURE__ */ jsxs("span", { children: [
721
701
  part,
722
702
  index < array.length - 1 && /* @__PURE__ */ jsx("span", { className: "if-verificationCode-email", children: email })
723
703
  ] }, index)) }),
724
- verificationError && /* @__PURE__ */ jsx("div", { className: "if-errorBanner if-internal-eb2m7k", children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
704
+ !isLinkMethod && /* @__PURE__ */ jsxs("div", { className: "if-verificationStep-codeContainer", children: [
705
+ /* @__PURE__ */ jsx("div", { className: "if-verificationStep-codeInputWrapper", children: /* @__PURE__ */ jsx(
706
+ AuthVerificationCodeInput,
707
+ {
708
+ value: verificationCode,
709
+ onChange: setVerificationCode,
710
+ email,
711
+ disabled: isVerifying
712
+ }
713
+ ) }),
725
714
  /* @__PURE__ */ jsx(
726
- "svg",
715
+ AuthSubmitButton,
727
716
  {
728
- style: { width: "1.5rem", height: "1.5rem", flexShrink: 0, color: "#DC2626" },
729
- fill: "none",
730
- strokeLinecap: "round",
731
- strokeLinejoin: "round",
732
- strokeWidth: "2",
733
- viewBox: "0 0 24 24",
734
- stroke: "currentColor",
735
- children: /* @__PURE__ */ jsx("path", { d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" })
717
+ type: "button",
718
+ isLoading: isVerifying,
719
+ disabled: isVerifying || verificationCode.length !== 6,
720
+ onClick: () => {
721
+ void handleSubmit();
722
+ },
723
+ children: isVerifying ? "Verifying..." : "Verify Code"
736
724
  }
737
- ),
738
- /* @__PURE__ */ jsx("p", { className: "if-errorBanner-text", children: verificationError })
739
- ] }) }),
740
- method === "code" && /* @__PURE__ */ jsxs(
741
- "div",
742
- {
743
- style: {
744
- width: "100%",
745
- backgroundColor: "#F5F5F5",
746
- borderRadius: "0.5rem",
747
- padding: "1rem 1rem 1.5rem",
748
- display: "flex",
749
- flexDirection: "column",
750
- gap: "1rem"
751
- },
752
- children: [
753
- /* @__PURE__ */ jsx(
754
- AuthVerificationCodeInput,
755
- {
756
- value: verificationCode,
757
- onChange: setVerificationCode,
758
- email,
759
- disabled: isVerifying,
760
- onComplete: (code) => {
761
- void handleVerifyCode(code);
762
- }
763
- }
764
- ),
765
- isVerifying && /* @__PURE__ */ jsx(
766
- "p",
767
- {
768
- style: {
769
- fontSize: "0.875rem",
770
- color: "#828282",
771
- textAlign: "center",
772
- fontFamily: "var(--if-font-family)"
773
- },
774
- children: "Verifying..."
775
- }
776
- )
777
- ]
778
- }
779
- ),
780
- /* @__PURE__ */ jsxs(
781
- "div",
782
- {
783
- style: {
784
- width: "100%",
785
- fontSize: "0.875rem",
786
- textAlign: "center",
787
- color: "#828282",
788
- fontFamily: "var(--if-font-family)"
789
- },
790
- children: [
791
- "Didn't receive the email?",
792
- " ",
793
- /* @__PURE__ */ jsx(
794
- "button",
795
- {
796
- onClick: () => {
797
- void handleResend();
798
- },
799
- disabled: resendDisabled || isSending,
800
- style: {
801
- color: "#000",
802
- fontWeight: 500,
803
- transition: "all 0.2s",
804
- cursor: resendDisabled || isSending ? "not-allowed" : "pointer",
805
- background: "none",
806
- border: "none",
807
- padding: 0,
808
- textDecoration: resendDisabled || isSending ? "none" : "underline",
809
- opacity: resendDisabled || isSending ? 0.5 : 1,
810
- fontFamily: "var(--if-font-family)"
811
- },
812
- children: isSending ? "Sending..." : resendDisabled ? `Retry in (${resendCountdown}s)` : "Click to resend"
813
- }
814
- )
815
- ]
816
- }
817
- )
725
+ )
726
+ ] }),
727
+ /* @__PURE__ */ jsxs("div", { className: "if-verificationStep-resendContainer", children: [
728
+ "Didn't receive the email?",
729
+ " ",
730
+ /* @__PURE__ */ jsx(
731
+ "button",
732
+ {
733
+ onClick: () => {
734
+ void handleResend();
735
+ },
736
+ disabled: resendDisabled || isSending,
737
+ className: "if-verificationStep-resendButton",
738
+ children: isSending ? "Sending..." : resendDisabled ? `Retry in (${resendCountdown}s)` : "Click to resend"
739
+ }
740
+ )
741
+ ] })
742
+ ] });
743
+ }
744
+ function AuthResetPasswordVerificationStep({
745
+ email,
746
+ method,
747
+ onVerifyCode,
748
+ onResendEmail
749
+ }) {
750
+ const [resendDisabled, setResendDisabled] = useState(true);
751
+ const [resendCountdown, setResendCountdown] = useState(60);
752
+ const [isSending, setIsSending] = useState(false);
753
+ const [verificationCode, setVerificationCode] = useState("");
754
+ const [isVerifying, setIsVerifying] = useState(false);
755
+ useEffect(() => {
756
+ if (resendCountdown > 0) {
757
+ const timer = setInterval(() => {
758
+ setResendCountdown((prev) => {
759
+ if (prev <= 1) {
760
+ setResendDisabled(false);
761
+ return 0;
762
+ }
763
+ return prev - 1;
764
+ });
765
+ }, 1e3);
766
+ return () => clearInterval(timer);
767
+ }
768
+ }, [resendCountdown]);
769
+ const handleResend = useCallback(async () => {
770
+ setResendDisabled(true);
771
+ setResendCountdown(60);
772
+ setIsSending(true);
773
+ try {
774
+ await onResendEmail();
775
+ } catch {
776
+ setResendDisabled(false);
777
+ setResendCountdown(0);
778
+ } finally {
779
+ setIsSending(false);
780
+ }
781
+ }, [onResendEmail]);
782
+ const handleSubmit = async () => {
783
+ if (!onVerifyCode || verificationCode.length !== 6) {
784
+ return;
785
+ }
786
+ setIsVerifying(true);
787
+ try {
788
+ await onVerifyCode(verificationCode);
789
+ } finally {
790
+ setIsVerifying(false);
791
+ setVerificationCode("");
792
+ }
793
+ };
794
+ const isLinkMethod = method === "link";
795
+ const description = isLinkMethod ? `We've sent a password reset link to ${email}. Please check your email and click the link to reset your password. The link will expire in 10 minutes.` : `We've sent a 6-digit verification code to ${email}. Please enter it below to reset your password. The code will expire in 10 minutes.`;
796
+ return /* @__PURE__ */ jsxs("div", { className: "if-verificationStep", children: [
797
+ /* @__PURE__ */ jsx("p", { className: "if-verificationStep-description", children: description }),
798
+ !isLinkMethod && /* @__PURE__ */ jsxs("div", { className: "if-verificationStep-codeContainer", children: [
799
+ /* @__PURE__ */ jsx("div", { className: "if-verificationStep-codeInputWrapper", children: /* @__PURE__ */ jsx(
800
+ AuthVerificationCodeInput,
801
+ {
802
+ value: verificationCode,
803
+ onChange: setVerificationCode,
804
+ email,
805
+ disabled: isVerifying
806
+ }
807
+ ) }),
808
+ /* @__PURE__ */ jsx(
809
+ AuthSubmitButton,
810
+ {
811
+ type: "button",
812
+ isLoading: isVerifying,
813
+ disabled: isVerifying || verificationCode.length !== 6,
814
+ onClick: () => {
815
+ void handleSubmit();
816
+ },
817
+ children: isVerifying ? "Verifying..." : "Continue"
818
+ }
819
+ )
820
+ ] }),
821
+ /* @__PURE__ */ jsxs("div", { className: "if-verificationStep-resendContainer", children: [
822
+ "Didn't receive the email?",
823
+ " ",
824
+ /* @__PURE__ */ jsx(
825
+ "button",
826
+ {
827
+ onClick: () => {
828
+ void handleResend();
829
+ },
830
+ disabled: resendDisabled || isSending,
831
+ className: "if-verificationStep-resendButton",
832
+ children: isSending ? "Sending..." : resendDisabled ? `Retry in (${resendCountdown}s)` : "Click to resend"
833
+ }
834
+ )
835
+ ] })
818
836
  ] });
819
837
  }
820
838
  function SignInForm({
@@ -844,8 +862,7 @@ function SignInForm({
844
862
  signUpUrl = "/sign-up",
845
863
  dividerText = "or",
846
864
  showVerificationStep = false,
847
- onVerifyCode,
848
- verificationDescription
865
+ onVerifyCode
849
866
  }) {
850
867
  return /* @__PURE__ */ jsxs(AuthContainer, { children: [
851
868
  /* @__PURE__ */ jsx(
@@ -856,14 +873,7 @@ function SignInForm({
856
873
  }
857
874
  ),
858
875
  /* @__PURE__ */ jsx(AuthErrorBanner, { error: error || "" }),
859
- showVerificationStep ? /* @__PURE__ */ jsx(
860
- AuthEmailVerificationStep,
861
- {
862
- email,
863
- description: verificationDescription,
864
- onVerifyCode
865
- }
866
- ) : /* @__PURE__ */ jsxs("form", { onSubmit, noValidate: true, className: "if-form if-internal-fm9k2p", children: [
876
+ showVerificationStep ? /* @__PURE__ */ jsx(AuthEmailVerificationStep, { email, onVerifyCode }) : /* @__PURE__ */ jsxs("form", { onSubmit, noValidate: true, className: "if-form if-internal-fm9k2p", children: [
867
877
  /* @__PURE__ */ jsx(
868
878
  AuthFormField,
869
879
  {
@@ -913,16 +923,17 @@ function SignInForm({
913
923
  ] })
914
924
  ] });
915
925
  }
916
- function SignIn({ afterSignInUrl, onSuccess, onError, ...uiProps }) {
917
- const { signIn, baseUrl } = useInsforge();
926
+ function SignIn({ onError, ...uiProps }) {
927
+ const { signIn, verifyEmail, loginWithOAuth } = useInsforge();
918
928
  const { authConfig } = usePublicAuthConfig();
919
929
  const [email, setEmail] = useState("");
920
930
  const [password, setPassword] = useState("");
921
931
  const [error, setError] = useState("");
922
932
  const [loading, setLoading] = useState(false);
923
933
  const [step, setStep] = useState("form");
924
- const [oauthLoading, setOauthLoading] = useState(null);
925
- const [insforge] = useState(() => createClient({ baseUrl }));
934
+ const [oauthLoading] = useState(null);
935
+ const [searchParams] = useSearchParams();
936
+ const redirectUrl = searchParams.get("redirect");
926
937
  async function handleSubmit(e) {
927
938
  e.preventDefault();
928
939
  setLoading(true);
@@ -938,10 +949,13 @@ function SignIn({ afterSignInUrl, onSuccess, onError, ...uiProps }) {
938
949
  throw new Error(result.error);
939
950
  }
940
951
  const { user, accessToken, redirectTo } = result;
941
- if (onSuccess) {
942
- if (user) {
943
- onSuccess(user, accessToken || "", redirectTo);
944
- }
952
+ if (user) {
953
+ const finalUrl = new URL(redirectTo || redirectUrl || "", window.location.origin);
954
+ finalUrl.searchParams.set("access_token", accessToken);
955
+ finalUrl.searchParams.set("user_id", user.id);
956
+ finalUrl.searchParams.set("email", user.email);
957
+ finalUrl.searchParams.set("name", user.name);
958
+ window.location.href = finalUrl.toString();
945
959
  }
946
960
  } catch (err) {
947
961
  const errorMessage = err instanceof Error ? err.message : "Sign in failed";
@@ -954,38 +968,28 @@ function SignIn({ afterSignInUrl, onSuccess, onError, ...uiProps }) {
954
968
  }
955
969
  }
956
970
  async function handleVerifyCode(code) {
971
+ setError("");
957
972
  try {
958
- const result = await insforge.auth.verifyEmail({ email, otp: code });
959
- if (result.error) {
973
+ const result = await verifyEmail(email, code);
974
+ if (result?.error) {
960
975
  throw new Error(result.error.message || "Verification failed");
961
976
  }
962
- if (result.data?.accessToken) {
963
- if (onSuccess && result.data.user) {
964
- onSuccess(result.data.user, result.data.accessToken);
965
- }
977
+ if (result?.user) {
978
+ const finalUrl = new URL(result.redirectTo || redirectUrl || "", window.location.origin);
979
+ finalUrl.searchParams.set("access_token", result.accessToken);
980
+ finalUrl.searchParams.set("user_id", result.user.id);
981
+ finalUrl.searchParams.set("email", result.user.email);
982
+ finalUrl.searchParams.set("name", result.user.name);
983
+ window.location.href = finalUrl.toString();
966
984
  }
967
985
  } catch (err) {
968
986
  const errorMessage = err instanceof Error ? err.message : "Invalid verification code";
969
- throw new Error(errorMessage);
970
- }
971
- }
972
- async function handleOAuth(provider) {
973
- try {
974
- setOauthLoading(provider);
975
- setError("");
976
- await insforge.auth.signInWithOAuth({
977
- provider,
978
- redirectTo: afterSignInUrl
979
- });
980
- } catch (err) {
981
- const errorMessage = err instanceof Error ? err.message : `${provider} sign in failed`;
982
987
  setError(errorMessage);
983
- if (onError) {
984
- onError(new Error(errorMessage));
985
- }
986
- setOauthLoading(null);
987
988
  }
988
989
  }
990
+ function handleOAuth(provider) {
991
+ loginWithOAuth(provider, redirectUrl || "");
992
+ }
989
993
  if (!authConfig) {
990
994
  return null;
991
995
  }
@@ -1034,8 +1038,7 @@ function SignUpForm({
1034
1038
  signInUrl = "/sign-in",
1035
1039
  dividerText = "or",
1036
1040
  showVerificationStep = false,
1037
- onVerifyCode,
1038
- verificationDescription
1041
+ onVerifyCode
1039
1042
  }) {
1040
1043
  return /* @__PURE__ */ jsxs(AuthContainer, { children: [
1041
1044
  /* @__PURE__ */ jsx(
@@ -1046,14 +1049,7 @@ function SignUpForm({
1046
1049
  }
1047
1050
  ),
1048
1051
  /* @__PURE__ */ jsx(AuthErrorBanner, { error: error || "" }),
1049
- showVerificationStep ? /* @__PURE__ */ jsx(
1050
- AuthEmailVerificationStep,
1051
- {
1052
- email,
1053
- description: verificationDescription,
1054
- onVerifyCode
1055
- }
1056
- ) : /* @__PURE__ */ jsxs("form", { onSubmit, noValidate: true, className: "if-form if-internal-fm9k2p", children: [
1052
+ showVerificationStep ? /* @__PURE__ */ jsx(AuthEmailVerificationStep, { email, onVerifyCode }) : /* @__PURE__ */ jsxs("form", { onSubmit, noValidate: true, className: "if-form if-internal-fm9k2p", children: [
1057
1053
  /* @__PURE__ */ jsx(
1058
1054
  AuthFormField,
1059
1055
  {
@@ -1129,16 +1125,17 @@ function createPasswordSchema(options) {
1129
1125
  return schema;
1130
1126
  }
1131
1127
  createPasswordSchema();
1132
- function SignUp({ afterSignUpUrl, onSuccess, onError, ...uiProps }) {
1133
- const { signUp, baseUrl } = useInsforge();
1128
+ function SignUp({ onError, ...uiProps }) {
1129
+ const { signUp, verifyEmail, loginWithOAuth } = useInsforge();
1134
1130
  const { authConfig } = usePublicAuthConfig();
1135
1131
  const [email, setEmail] = useState("");
1136
1132
  const [password, setPassword] = useState("");
1137
1133
  const [error, setError] = useState("");
1138
1134
  const [loading, setLoading] = useState(false);
1139
1135
  const [step, setStep] = useState("form");
1140
- const [oauthLoading, setOauthLoading] = useState(null);
1141
- const [insforge] = useState(() => createClient({ baseUrl }));
1136
+ const [oauthLoading] = useState(null);
1137
+ const [searchParams] = useSearchParams();
1138
+ const redirectUrl = searchParams.get("redirect");
1142
1139
  async function handleSubmit(e) {
1143
1140
  e.preventDefault();
1144
1141
  setLoading(true);
@@ -1180,9 +1177,12 @@ function SignUp({ afterSignUpUrl, onSuccess, onError, ...uiProps }) {
1180
1177
  return;
1181
1178
  }
1182
1179
  if (result.accessToken && result.user) {
1183
- if (onSuccess) {
1184
- onSuccess(result.user, result.accessToken, result.redirectTo);
1185
- }
1180
+ const finalUrl = new URL(result.redirectTo || redirectUrl || "", window.location.origin);
1181
+ finalUrl.searchParams.set("access_token", result.accessToken);
1182
+ finalUrl.searchParams.set("user_id", result.user.id);
1183
+ finalUrl.searchParams.set("email", result.user.email);
1184
+ finalUrl.searchParams.set("name", result.user.name);
1185
+ window.location.href = finalUrl.toString();
1186
1186
  }
1187
1187
  } catch (err) {
1188
1188
  const errorMessage = err instanceof Error ? err.message : "Sign up failed";
@@ -1195,38 +1195,28 @@ function SignUp({ afterSignUpUrl, onSuccess, onError, ...uiProps }) {
1195
1195
  }
1196
1196
  }
1197
1197
  async function handleVerifyCode(code) {
1198
+ setError("");
1198
1199
  try {
1199
- const result = await insforge.auth.verifyEmail({ email, otp: code });
1200
- if (result.error) {
1200
+ const result = await verifyEmail(email, code);
1201
+ if (result?.error) {
1201
1202
  throw new Error(result.error.message || "Verification failed");
1202
1203
  }
1203
- if (result.data?.accessToken) {
1204
- if (onSuccess && result.data.user) {
1205
- onSuccess(result.data.user, result.data.accessToken);
1206
- }
1204
+ if (result?.user) {
1205
+ const finalUrl = new URL(result.redirectTo || redirectUrl || "", window.location.origin);
1206
+ finalUrl.searchParams.set("access_token", result.accessToken);
1207
+ finalUrl.searchParams.set("user_id", result.user.id);
1208
+ finalUrl.searchParams.set("email", result.user.email);
1209
+ finalUrl.searchParams.set("name", result.user.name);
1210
+ window.location.href = finalUrl.toString();
1207
1211
  }
1208
1212
  } catch (err) {
1209
1213
  const errorMessage = err instanceof Error ? err.message : "Invalid verification code";
1210
- throw new Error(errorMessage);
1211
- }
1212
- }
1213
- async function handleOAuth(provider) {
1214
- try {
1215
- setOauthLoading(provider);
1216
- setError("");
1217
- await insforge.auth.signInWithOAuth({
1218
- provider,
1219
- redirectTo: afterSignUpUrl
1220
- });
1221
- } catch (err) {
1222
- const errorMessage = err instanceof Error ? err.message : `${provider} sign up failed`;
1223
1214
  setError(errorMessage);
1224
- if (onError) {
1225
- onError(new Error(errorMessage));
1226
- }
1227
- setOauthLoading(null);
1228
1215
  }
1229
1216
  }
1217
+ function handleOAuth(provider) {
1218
+ loginWithOAuth(provider, redirectUrl || "");
1219
+ }
1230
1220
  if (!authConfig) {
1231
1221
  return null;
1232
1222
  }
@@ -1256,7 +1246,6 @@ function ForgotPasswordForm({
1256
1246
  onSubmit,
1257
1247
  error,
1258
1248
  loading = false,
1259
- success = false,
1260
1249
  title = "Forgot Password?",
1261
1250
  subtitle = "Enter your email address and we'll send you a code to reset your password.",
1262
1251
  emailLabel = "Email",
@@ -1265,53 +1254,30 @@ function ForgotPasswordForm({
1265
1254
  loadingButtonText = "Sending...",
1266
1255
  backToSignInText = "Remember your password?",
1267
1256
  backToSignInUrl = "/sign-in",
1268
- successTitle = "Check Your Email",
1269
- successMessage
1257
+ showVerificationStep = false,
1258
+ resetPasswordMethod = "code",
1259
+ onVerifyCode,
1260
+ onResendEmail
1270
1261
  }) {
1271
- if (success) {
1272
- return /* @__PURE__ */ jsx(AuthContainer, { children: /* @__PURE__ */ jsxs(
1273
- "div",
1262
+ return /* @__PURE__ */ jsxs(AuthContainer, { children: [
1263
+ /* @__PURE__ */ jsx(
1264
+ AuthHeader,
1274
1265
  {
1275
- style: { display: "flex", flexDirection: "column", alignItems: "center", gap: "1rem" },
1276
- children: [
1277
- /* @__PURE__ */ jsx(
1278
- "div",
1279
- {
1280
- style: {
1281
- width: "4rem",
1282
- height: "4rem",
1283
- borderRadius: "50%",
1284
- backgroundColor: "#D1FAE5",
1285
- display: "flex",
1286
- alignItems: "center",
1287
- justifyContent: "center"
1288
- },
1289
- children: /* @__PURE__ */ jsx(
1290
- "svg",
1291
- {
1292
- style: { width: "2rem", height: "2rem", color: "#059669" },
1293
- fill: "none",
1294
- strokeLinecap: "round",
1295
- strokeLinejoin: "round",
1296
- strokeWidth: "2",
1297
- viewBox: "0 0 24 24",
1298
- stroke: "currentColor",
1299
- children: /* @__PURE__ */ jsx("path", { d: "M5 13l4 4L19 7" })
1300
- }
1301
- )
1302
- }
1303
- ),
1304
- /* @__PURE__ */ jsx("h2", { className: "if-authHeader-title", style: { textAlign: "center" }, children: successTitle }),
1305
- /* @__PURE__ */ jsx("p", { className: "if-authHeader-subtitle", style: { textAlign: "center" }, children: successMessage || `We've sent a password reset link to ${email}. Please check your email and follow the instructions.` }),
1306
- /* @__PURE__ */ jsx("a", { href: backToSignInUrl, className: "if-authLink-link", style: { marginTop: "1rem" }, children: "Back to Sign In" })
1307
- ]
1266
+ title: showVerificationStep ? resetPasswordMethod === "link" ? "Check Your Email" : "Enter Reset Code" : title,
1267
+ subtitle: showVerificationStep ? "" : subtitle
1308
1268
  }
1309
- ) });
1310
- }
1311
- return /* @__PURE__ */ jsxs(AuthContainer, { children: [
1312
- /* @__PURE__ */ jsx(AuthHeader, { title, subtitle }),
1269
+ ),
1313
1270
  /* @__PURE__ */ jsx(AuthErrorBanner, { error: error || "" }),
1314
- /* @__PURE__ */ jsxs("form", { onSubmit, noValidate: true, className: "if-form if-internal-fm9k2p", children: [
1271
+ showVerificationStep ? /* @__PURE__ */ jsx(
1272
+ AuthResetPasswordVerificationStep,
1273
+ {
1274
+ email,
1275
+ method: resetPasswordMethod,
1276
+ onVerifyCode,
1277
+ onResendEmail: onResendEmail || (async () => {
1278
+ })
1279
+ }
1280
+ ) : /* @__PURE__ */ jsxs("form", { onSubmit, noValidate: true, className: "if-form if-internal-fm9k2p", children: [
1315
1281
  /* @__PURE__ */ jsx(
1316
1282
  AuthFormField,
1317
1283
  {
@@ -1327,7 +1293,7 @@ function ForgotPasswordForm({
1327
1293
  ),
1328
1294
  /* @__PURE__ */ jsx(AuthSubmitButton, { isLoading: loading, disabled: loading, children: loading ? loadingButtonText : submitButtonText })
1329
1295
  ] }),
1330
- /* @__PURE__ */ jsx(AuthLink, { text: backToSignInText, linkText: "Back to Sign In", href: backToSignInUrl })
1296
+ !showVerificationStep && /* @__PURE__ */ jsx(AuthLink, { text: backToSignInText, linkText: "Back to Sign In", href: backToSignInUrl })
1331
1297
  ] });
1332
1298
  }
1333
1299
  function ResetPasswordForm({
@@ -1348,11 +1314,12 @@ function ResetPasswordForm({
1348
1314
  confirmPasswordPlaceholder = "\u2022\u2022\u2022\u2022\u2022\u2022",
1349
1315
  submitButtonText = "Reset Password",
1350
1316
  loadingButtonText = "Resetting...",
1351
- backToSignInText = "",
1352
- backToSignInUrl = "/sign-in",
1353
- successTitle = "Password Reset Successful!",
1354
- successMessage = "Your password has been successfully reset. You can now sign in with your new password."
1317
+ successTitle = "Password Reset Successful!"
1355
1318
  }) {
1319
+ let successMessage = "Your password has been successfully reset. You can close this page and sign in with your new password.";
1320
+ if (authConfig && authConfig.verifyEmailMethod === "code") {
1321
+ successMessage = "Your password has been successfully reset. You can wait for redirect to sign in with your new password.";
1322
+ }
1356
1323
  if (success) {
1357
1324
  return /* @__PURE__ */ jsx(AuthContainer, { children: /* @__PURE__ */ jsxs(
1358
1325
  "div",
@@ -1387,8 +1354,7 @@ function ResetPasswordForm({
1387
1354
  }
1388
1355
  ),
1389
1356
  /* @__PURE__ */ jsx("h2", { className: "if-authHeader-title", style: { textAlign: "center" }, children: successTitle }),
1390
- /* @__PURE__ */ jsx("p", { className: "if-authHeader-subtitle", style: { textAlign: "center" }, children: successMessage }),
1391
- /* @__PURE__ */ jsx("a", { href: backToSignInUrl, className: "if-authLink-link", style: { marginTop: "1rem" }, children: "Back to Sign In" })
1357
+ /* @__PURE__ */ jsx("p", { className: "if-authHeader-subtitle", style: { textAlign: "center" }, children: successMessage })
1392
1358
  ]
1393
1359
  }
1394
1360
  ) });
@@ -1425,64 +1391,115 @@ function ResetPasswordForm({
1425
1391
  }
1426
1392
  ),
1427
1393
  /* @__PURE__ */ jsx(AuthSubmitButton, { isLoading: loading, disabled: loading, children: loading ? loadingButtonText : submitButtonText })
1428
- ] }),
1429
- /* @__PURE__ */ jsx(AuthLink, { text: backToSignInText, linkText: "Back to Sign In", href: backToSignInUrl })
1394
+ ] })
1430
1395
  ] });
1431
1396
  }
1432
- function ResetPassword({
1433
- token,
1434
- backToSignInUrl = "/sign-in",
1435
- onSuccess,
1436
- onError,
1437
- ...uiProps
1438
- }) {
1439
- const { resetPassword } = useInsforge();
1397
+ function ForgotPassword({ onError, ...uiProps }) {
1398
+ const { sendResetPasswordEmail, exchangeResetPasswordToken, resetPassword } = useInsforge();
1440
1399
  const { authConfig } = usePublicAuthConfig();
1400
+ const [searchParams] = useSearchParams();
1401
+ const [step, setStep] = useState("email");
1402
+ const [email, setEmail] = useState("");
1403
+ const [resetToken, setResetToken] = useState("");
1441
1404
  const [newPassword, setNewPassword] = useState("");
1442
1405
  const [confirmPassword, setConfirmPassword] = useState("");
1443
1406
  const [error, setError] = useState("");
1444
1407
  const [loading, setLoading] = useState(false);
1445
1408
  const [success, setSuccess] = useState(false);
1446
- async function handleSubmit(e) {
1409
+ const [showVerificationStep, setShowVerificationStep] = useState(false);
1410
+ async function handleEmailSubmit(e) {
1447
1411
  e.preventDefault();
1448
1412
  setLoading(true);
1449
1413
  setError("");
1450
- if (!authConfig) {
1451
- setError("Configuration not loaded. Please refresh the page.");
1452
- setLoading(false);
1453
- return;
1454
- }
1455
- if (newPassword !== confirmPassword) {
1456
- setError("Passwords do not match");
1457
- setLoading(false);
1458
- return;
1459
- }
1460
- if (!token) {
1461
- setError("Reset token is missing");
1462
- setLoading(false);
1463
- return;
1464
- }
1465
- const passwordZodSchema = createPasswordSchema({
1466
- minLength: authConfig.passwordMinLength,
1467
- requireUppercase: authConfig.requireUppercase,
1468
- requireLowercase: authConfig.requireLowercase,
1469
- requireNumber: authConfig.requireNumber,
1470
- requireSpecialChar: authConfig.requireSpecialChar
1471
- });
1472
- const passwordValidation = passwordZodSchema.safeParse(newPassword);
1473
- if (!passwordValidation.success) {
1474
- const firstError = passwordValidation.error.issues[0];
1414
+ const emailValidation = emailSchema.safeParse(email);
1415
+ if (!emailValidation.success) {
1416
+ const firstError = emailValidation.error.issues[0];
1475
1417
  setError(firstError.message);
1476
1418
  setLoading(false);
1477
1419
  return;
1478
1420
  }
1479
1421
  try {
1480
- const result = await resetPassword(token, newPassword);
1422
+ const result = await sendResetPasswordEmail(emailValidation.data);
1423
+ if (result?.success) {
1424
+ setShowVerificationStep(true);
1425
+ } else {
1426
+ const errorMessage = result?.message || "Failed to send reset email";
1427
+ setError(errorMessage);
1428
+ if (onError) {
1429
+ onError(new Error(errorMessage));
1430
+ }
1431
+ }
1432
+ } catch (err) {
1433
+ const errorMessage = err instanceof Error ? err.message : "Failed to send reset email";
1434
+ setError(errorMessage);
1435
+ if (onError) {
1436
+ onError(new Error(errorMessage));
1437
+ }
1438
+ } finally {
1439
+ setLoading(false);
1440
+ }
1441
+ }
1442
+ async function handleVerifyCode(code) {
1443
+ setError("");
1444
+ try {
1445
+ const result = await exchangeResetPasswordToken(email, code);
1446
+ if ("error" in result) {
1447
+ throw new Error(result.error.message || "Failed to verify code");
1448
+ }
1449
+ if (result.token) {
1450
+ setResetToken(result.token);
1451
+ setStep("password");
1452
+ }
1453
+ } catch (err) {
1454
+ const errorMessage = err instanceof Error ? err.message : "Invalid verification code";
1455
+ setError(errorMessage);
1456
+ if (onError) {
1457
+ onError(new Error(errorMessage));
1458
+ }
1459
+ }
1460
+ }
1461
+ async function handleResendEmail() {
1462
+ await sendResetPasswordEmail(email);
1463
+ }
1464
+ async function handleResetPasswordSubmit(e) {
1465
+ e.preventDefault();
1466
+ setLoading(true);
1467
+ setError("");
1468
+ if (newPassword !== confirmPassword) {
1469
+ setError("Passwords do not match");
1470
+ setLoading(false);
1471
+ return;
1472
+ }
1473
+ if (!authConfig) {
1474
+ setError("Configuration not loaded");
1475
+ setLoading(false);
1476
+ return;
1477
+ }
1478
+ const passwordZodSchema = createPasswordSchema({
1479
+ minLength: authConfig.passwordMinLength,
1480
+ requireUppercase: authConfig.requireUppercase,
1481
+ requireLowercase: authConfig.requireLowercase,
1482
+ requireNumber: authConfig.requireNumber,
1483
+ requireSpecialChar: authConfig.requireSpecialChar
1484
+ });
1485
+ const passwordValidation = passwordZodSchema.safeParse(newPassword);
1486
+ if (!passwordValidation.success) {
1487
+ const firstError = passwordValidation.error.issues[0];
1488
+ setError(firstError.message);
1489
+ setLoading(false);
1490
+ return;
1491
+ }
1492
+ try {
1493
+ const result = await resetPassword(resetToken, newPassword);
1481
1494
  if (result?.message) {
1482
1495
  setSuccess(true);
1483
- if (onSuccess) {
1484
- onSuccess();
1485
- }
1496
+ const signInUrl = new URL("/sign-in", window.location.origin);
1497
+ searchParams.forEach((value, key) => {
1498
+ signInUrl.searchParams.set(key, value);
1499
+ });
1500
+ setTimeout(() => {
1501
+ window.location.href = signInUrl.toString();
1502
+ }, 2e3);
1486
1503
  } else {
1487
1504
  const errorMessage = "Failed to reset password";
1488
1505
  setError(errorMessage);
@@ -1503,6 +1520,25 @@ function ResetPassword({
1503
1520
  if (!authConfig) {
1504
1521
  return null;
1505
1522
  }
1523
+ if (step === "email") {
1524
+ return /* @__PURE__ */ jsx(
1525
+ ForgotPasswordForm,
1526
+ {
1527
+ email,
1528
+ onEmailChange: setEmail,
1529
+ onSubmit: (e) => {
1530
+ void handleEmailSubmit(e);
1531
+ },
1532
+ error,
1533
+ loading,
1534
+ showVerificationStep,
1535
+ resetPasswordMethod: authConfig.resetPasswordMethod,
1536
+ onVerifyCode: handleVerifyCode,
1537
+ onResendEmail: handleResendEmail,
1538
+ ...uiProps
1539
+ }
1540
+ );
1541
+ }
1506
1542
  return /* @__PURE__ */ jsx(
1507
1543
  ResetPasswordForm,
1508
1544
  {
@@ -1510,83 +1546,71 @@ function ResetPassword({
1510
1546
  confirmPassword,
1511
1547
  onNewPasswordChange: setNewPassword,
1512
1548
  onConfirmPasswordChange: setConfirmPassword,
1513
- onSubmit: handleSubmit,
1549
+ onSubmit: handleResetPasswordSubmit,
1514
1550
  error,
1515
1551
  loading,
1516
1552
  success,
1517
1553
  authConfig,
1518
- backToSignInUrl,
1519
1554
  ...uiProps
1520
1555
  }
1521
1556
  );
1522
1557
  }
1523
- function ForgotPassword({
1524
- backToSignInUrl = "/sign-in",
1525
- onSuccess,
1526
- onError,
1527
- ...uiProps
1528
- }) {
1529
- const { sendResetPasswordEmail, baseUrl } = useInsforge();
1558
+ function ResetPassword({ onError, ...uiProps }) {
1559
+ const [searchParams] = useSearchParams();
1560
+ const token = searchParams.get("token");
1561
+ const { resetPassword } = useInsforge();
1530
1562
  const { authConfig } = usePublicAuthConfig();
1531
- const [insforge] = useState(() => createClient({ baseUrl }));
1532
- const [step, setStep] = useState("email");
1533
- const [email, setEmail] = useState("");
1534
- const [verificationCode, setVerificationCode] = useState("");
1535
- const [resetToken, setResetToken] = useState("");
1563
+ const [newPassword, setNewPassword] = useState("");
1564
+ const [confirmPassword, setConfirmPassword] = useState("");
1536
1565
  const [error, setError] = useState("");
1537
1566
  const [loading, setLoading] = useState(false);
1538
1567
  const [success, setSuccess] = useState(false);
1539
- const [resendDisabled, setResendDisabled] = useState(true);
1540
- const [resendCountdown, setResendCountdown] = useState(60);
1541
- const [isSendingCode, setIsSendingCode] = useState(false);
1542
- const [isVerifyingCode, setIsVerifyingCode] = useState(false);
1543
- useEffect(() => {
1544
- if (resendCountdown > 0 && step === "code") {
1545
- const timer = setInterval(() => {
1546
- setResendCountdown((prev) => {
1547
- if (prev <= 1) {
1548
- setResendDisabled(false);
1549
- return 0;
1550
- }
1551
- return prev - 1;
1552
- });
1553
- }, 1e3);
1554
- return () => clearInterval(timer);
1555
- }
1556
- }, [resendCountdown, step]);
1557
- async function handleEmailSubmit(e) {
1568
+ async function handleSubmit(e) {
1558
1569
  e.preventDefault();
1559
1570
  setLoading(true);
1560
1571
  setError("");
1561
- const emailValidation = emailSchema.safeParse(email);
1562
- if (!emailValidation.success) {
1563
- const firstError = emailValidation.error.issues[0];
1572
+ if (!authConfig) {
1573
+ setError("Configuration not loaded. Please refresh the page.");
1574
+ setLoading(false);
1575
+ return;
1576
+ }
1577
+ if (newPassword !== confirmPassword) {
1578
+ setError("Passwords do not match");
1579
+ setLoading(false);
1580
+ return;
1581
+ }
1582
+ if (!token) {
1583
+ setError("Reset token is missing");
1584
+ setLoading(false);
1585
+ return;
1586
+ }
1587
+ const passwordZodSchema = createPasswordSchema({
1588
+ minLength: authConfig.passwordMinLength,
1589
+ requireUppercase: authConfig.requireUppercase,
1590
+ requireLowercase: authConfig.requireLowercase,
1591
+ requireNumber: authConfig.requireNumber,
1592
+ requireSpecialChar: authConfig.requireSpecialChar
1593
+ });
1594
+ const passwordValidation = passwordZodSchema.safeParse(newPassword);
1595
+ if (!passwordValidation.success) {
1596
+ const firstError = passwordValidation.error.issues[0];
1564
1597
  setError(firstError.message);
1565
1598
  setLoading(false);
1566
1599
  return;
1567
1600
  }
1568
1601
  try {
1569
- const result = await sendResetPasswordEmail(emailValidation.data);
1570
- if (result?.success) {
1571
- if (authConfig?.resetPasswordMethod === "link") {
1572
- setSuccess(true);
1573
- if (onSuccess) {
1574
- onSuccess();
1575
- }
1576
- } else {
1577
- setStep("code");
1578
- setResendDisabled(true);
1579
- setResendCountdown(60);
1580
- }
1602
+ const result = await resetPassword(token, newPassword);
1603
+ if (result?.message) {
1604
+ setSuccess(true);
1581
1605
  } else {
1582
- const errorMessage = result?.message || "Failed to send reset code";
1606
+ const errorMessage = "Failed to reset password";
1583
1607
  setError(errorMessage);
1584
1608
  if (onError) {
1585
1609
  onError(new Error(errorMessage));
1586
1610
  }
1587
1611
  }
1588
1612
  } catch (err) {
1589
- const errorMessage = err instanceof Error ? err.message : "Failed to send reset code";
1613
+ const errorMessage = err instanceof Error ? err.message : "Failed to reset password";
1590
1614
  setError(errorMessage);
1591
1615
  if (onError) {
1592
1616
  onError(new Error(errorMessage));
@@ -1595,297 +1619,157 @@ function ForgotPassword({
1595
1619
  setLoading(false);
1596
1620
  }
1597
1621
  }
1598
- async function handleVerifyCode(code) {
1599
- setIsVerifyingCode(true);
1600
- setError("");
1601
- setVerificationCode(code);
1602
- try {
1603
- const result = await insforge.auth.exchangeResetPasswordToken({ email, code });
1604
- if (result.error) {
1605
- throw new Error(result.error.message || "Failed to verify code");
1606
- }
1607
- if (result.data) {
1608
- setResetToken(result.data.token);
1609
- setStep("password");
1610
- }
1611
- } catch (err) {
1612
- const errorMessage = err instanceof Error ? err.message : "Invalid verification code";
1613
- setError(errorMessage);
1614
- setVerificationCode("");
1615
- } finally {
1616
- setIsVerifyingCode(false);
1617
- }
1618
- }
1619
- const handleResendCode = useCallback(async () => {
1620
- setResendDisabled(true);
1621
- setResendCountdown(60);
1622
- setIsSendingCode(true);
1623
- setError("");
1624
- try {
1625
- await sendResetPasswordEmail(email);
1626
- } catch (err) {
1627
- const errorMessage = err instanceof Error ? err.message : "Failed to resend code";
1628
- setError(errorMessage);
1629
- setResendDisabled(false);
1630
- setResendCountdown(0);
1631
- } finally {
1632
- setIsSendingCode(false);
1633
- }
1634
- }, [email, sendResetPasswordEmail]);
1635
- function handlePasswordResetSuccess(redirectTo) {
1636
- const targetUrl = redirectTo || backToSignInUrl;
1637
- if (onSuccess) {
1638
- onSuccess();
1639
- }
1640
- setTimeout(() => {
1641
- window.location.href = targetUrl;
1642
- }, 1500);
1643
- }
1644
1622
  if (!authConfig) {
1645
1623
  return null;
1646
1624
  }
1647
- if (step === "email") {
1648
- return /* @__PURE__ */ jsx(
1649
- ForgotPasswordForm,
1650
- {
1651
- email,
1652
- onEmailChange: setEmail,
1653
- onSubmit: (e) => {
1654
- void handleEmailSubmit(e);
1655
- },
1656
- error,
1657
- loading,
1658
- success,
1659
- backToSignInUrl,
1660
- ...uiProps
1661
- }
1662
- );
1663
- }
1664
- if (step === "code") {
1625
+ if (!token) {
1665
1626
  return /* @__PURE__ */ jsxs(AuthContainer, { children: [
1627
+ /* @__PURE__ */ jsx(AuthHeader, { title: "Invalid Reset Link", subtitle: "" }),
1666
1628
  /* @__PURE__ */ jsx(
1667
- AuthHeader,
1668
- {
1669
- title: "Enter Reset Code",
1670
- subtitle: `We've sent a 6-digit verification code to ${email}. Please enter it below to reset your password. The code will expire in 10 minutes.`
1671
- }
1672
- ),
1673
- /* @__PURE__ */ jsx(AuthErrorBanner, { error }),
1674
- /* @__PURE__ */ jsxs(
1675
1629
  "div",
1676
1630
  {
1677
1631
  style: {
1678
- width: "100%",
1679
- display: "flex",
1680
- flexDirection: "column",
1681
- gap: "1.5rem",
1682
- alignItems: "center"
1632
+ padding: "1.5rem",
1633
+ backgroundColor: "#FEE2E2",
1634
+ borderRadius: "0.5rem",
1635
+ border: "1px solid #DC2626"
1683
1636
  },
1684
- children: [
1685
- /* @__PURE__ */ jsx(
1686
- "div",
1687
- {
1688
- style: {
1689
- width: "100%",
1690
- backgroundColor: "#F5F5F5",
1691
- borderRadius: "0.5rem",
1692
- padding: "1rem 1rem 1.5rem",
1693
- display: "flex",
1694
- flexDirection: "column",
1695
- gap: "1rem"
1696
- },
1697
- children: /* @__PURE__ */ jsxs(
1698
- "div",
1699
- {
1700
- style: {
1701
- display: "flex",
1702
- flexDirection: "column",
1703
- gap: "0.75rem",
1704
- marginTop: "0.5rem"
1705
- },
1706
- children: [
1707
- /* @__PURE__ */ jsx(
1708
- AuthVerificationCodeInput,
1709
- {
1710
- value: verificationCode,
1711
- onChange: setVerificationCode,
1712
- email,
1713
- disabled: isVerifyingCode,
1714
- onComplete: (code) => {
1715
- void handleVerifyCode(code);
1716
- }
1717
- }
1718
- ),
1719
- isVerifyingCode && /* @__PURE__ */ jsx("p", { className: "if-authHeader-subtitle", style: { textAlign: "center" }, children: "Verifying..." })
1720
- ]
1721
- }
1722
- )
1723
- }
1724
- ),
1725
- /* @__PURE__ */ jsxs(
1726
- "div",
1727
- {
1728
- style: {
1729
- width: "100%",
1730
- fontSize: "0.875rem",
1731
- textAlign: "center",
1732
- color: "#828282",
1733
- fontFamily: "var(--if-font-family)"
1734
- },
1735
- children: [
1736
- "Didn't receive the email?",
1737
- " ",
1738
- /* @__PURE__ */ jsx(
1739
- "button",
1740
- {
1741
- onClick: () => {
1742
- void handleResendCode();
1743
- },
1744
- disabled: resendDisabled || isSendingCode,
1745
- style: {
1746
- color: "#000",
1747
- fontWeight: 500,
1748
- transition: "all 0.2s",
1749
- cursor: resendDisabled || isSendingCode ? "not-allowed" : "pointer",
1750
- background: "none",
1751
- border: "none",
1752
- padding: 0,
1753
- textDecoration: resendDisabled || isSendingCode ? "none" : "underline",
1754
- opacity: resendDisabled || isSendingCode ? 0.5 : 1,
1755
- fontFamily: "var(--if-font-family)"
1756
- },
1757
- children: isSendingCode ? "Sending..." : resendDisabled ? `Retry in (${resendCountdown}s)` : "Click to resend"
1758
- }
1759
- )
1760
- ]
1761
- }
1762
- )
1763
- ]
1637
+ children: /* @__PURE__ */ jsx(
1638
+ "p",
1639
+ {
1640
+ style: {
1641
+ fontSize: "0.875rem",
1642
+ color: "#DC2626",
1643
+ margin: 0,
1644
+ fontFamily: "var(--if-font-family)"
1645
+ },
1646
+ children: "The password reset link is missing or invalid. Please request a new password reset link."
1647
+ }
1648
+ )
1764
1649
  }
1765
- ),
1766
- /* @__PURE__ */ jsx("p", { className: "if-authHeader-subtitle", style: { textAlign: "center" }, children: /* @__PURE__ */ jsx("a", { href: backToSignInUrl, className: "if-authLink-link", children: "Back to Sign In" }) })
1650
+ )
1767
1651
  ] });
1768
1652
  }
1769
- return /* @__PURE__ */ jsx(
1770
- ResetPassword,
1771
- {
1772
- token: resetToken,
1773
- backToSignInUrl,
1774
- onSuccess: handlePasswordResetSuccess,
1775
- onError
1776
- }
1777
- );
1778
- }
1779
- function VerifyEmailStatus({
1780
- status,
1781
- error,
1782
- verifyingTitle = "Verifying your email...",
1783
- successTitle = "Email Verified!",
1784
- successMessage = "Your email has been verified successfully. You can close this page and return to your app.",
1785
- errorTitle = "Verification Failed"
1786
- }) {
1787
- if (status === "verifying") {
1653
+ if (success) {
1788
1654
  return /* @__PURE__ */ jsx(AuthContainer, { children: /* @__PURE__ */ jsxs(
1789
1655
  "div",
1790
1656
  {
1791
- style: {
1792
- width: "100%",
1793
- display: "flex",
1794
- flexDirection: "column",
1795
- alignItems: "center",
1796
- justifyContent: "center",
1797
- gap: "1.5rem"
1798
- },
1657
+ style: { display: "flex", flexDirection: "column", alignItems: "center", gap: "1rem" },
1799
1658
  children: [
1800
- /* @__PURE__ */ jsx("h2", { className: "if-authHeader-title", children: verifyingTitle }),
1801
1659
  /* @__PURE__ */ jsx(
1802
1660
  "div",
1803
1661
  {
1804
- className: "if-submitButton-spinner",
1805
1662
  style: {
1663
+ width: "4rem",
1664
+ height: "4rem",
1806
1665
  borderRadius: "50%",
1807
- height: "3rem",
1808
- width: "3rem",
1809
- borderBottom: "2px solid black"
1810
- }
1666
+ backgroundColor: "#D1FAE5",
1667
+ display: "flex",
1668
+ alignItems: "center",
1669
+ justifyContent: "center"
1670
+ },
1671
+ children: /* @__PURE__ */ jsx(
1672
+ "svg",
1673
+ {
1674
+ style: { width: "2rem", height: "2rem", color: "#059669" },
1675
+ fill: "none",
1676
+ strokeLinecap: "round",
1677
+ strokeLinejoin: "round",
1678
+ strokeWidth: "2",
1679
+ viewBox: "0 0 24 24",
1680
+ stroke: "currentColor",
1681
+ children: /* @__PURE__ */ jsx("path", { d: "M5 13l4 4L19 7" })
1682
+ }
1683
+ )
1684
+ }
1685
+ ),
1686
+ /* @__PURE__ */ jsx(
1687
+ "h2",
1688
+ {
1689
+ style: {
1690
+ fontSize: "1.5rem",
1691
+ fontWeight: 600,
1692
+ color: "#000",
1693
+ margin: 0,
1694
+ textAlign: "center",
1695
+ fontFamily: "var(--if-font-family)"
1696
+ },
1697
+ children: "Password Reset Successfully"
1698
+ }
1699
+ ),
1700
+ /* @__PURE__ */ jsx(
1701
+ "p",
1702
+ {
1703
+ style: {
1704
+ fontSize: "0.875rem",
1705
+ color: "#828282",
1706
+ textAlign: "center",
1707
+ margin: 0,
1708
+ fontFamily: "var(--if-font-family)"
1709
+ },
1710
+ children: "Your password has been reset successfully. You can now close this page and return to the login page in your original tab."
1811
1711
  }
1812
1712
  )
1813
1713
  ]
1814
1714
  }
1815
1715
  ) });
1816
1716
  }
1717
+ return /* @__PURE__ */ jsx(
1718
+ ResetPasswordForm,
1719
+ {
1720
+ newPassword,
1721
+ confirmPassword,
1722
+ onNewPasswordChange: setNewPassword,
1723
+ onConfirmPasswordChange: setConfirmPassword,
1724
+ onSubmit: handleSubmit,
1725
+ error,
1726
+ loading,
1727
+ success: false,
1728
+ authConfig,
1729
+ ...uiProps
1730
+ }
1731
+ );
1732
+ }
1733
+ function VerifyEmailStatus({
1734
+ status,
1735
+ error,
1736
+ verifyingTitle = "Verifying your email...",
1737
+ successTitle = "Email Verified!",
1738
+ successMessage = "Your email has been verified successfully. You can close this page and sign in to your app.",
1739
+ errorTitle = "Verification Failed"
1740
+ }) {
1741
+ if (status === "verifying") {
1742
+ return /* @__PURE__ */ jsx(AuthContainer, { children: /* @__PURE__ */ jsxs("div", { className: "if-verifyStatus-container", children: [
1743
+ /* @__PURE__ */ jsx("h2", { className: "if-authHeader-title", children: verifyingTitle }),
1744
+ /* @__PURE__ */ jsx("div", { className: "if-submitButton-spinner if-verifyStatus-spinner" })
1745
+ ] }) });
1746
+ }
1817
1747
  if (status === "error") {
1818
- return /* @__PURE__ */ jsx(AuthContainer, { children: /* @__PURE__ */ jsx(
1819
- "div",
1748
+ return /* @__PURE__ */ jsx(AuthContainer, { children: /* @__PURE__ */ jsx("div", { className: "if-verifyStatus-container-stretch", children: /* @__PURE__ */ jsxs("div", { className: "if-authHeader if-internal-h3m7w5", children: [
1749
+ /* @__PURE__ */ jsx("h1", { className: "if-authHeader-title if-internal-t4p1k9", children: errorTitle }),
1750
+ /* @__PURE__ */ jsxs("p", { className: "if-authHeader-subtitle if-internal-s7q2m3", children: [
1751
+ error || "The verification link is invalid or has expired.",
1752
+ " Please try again or contact support if the problem persists. You can close this page and return to your app."
1753
+ ] })
1754
+ ] }) }) });
1755
+ }
1756
+ return /* @__PURE__ */ jsx(AuthContainer, { children: /* @__PURE__ */ jsx("div", { className: "if-verifyStatus-container-stretch", children: /* @__PURE__ */ jsxs("div", { className: "if-verifyStatus-successContent", children: [
1757
+ /* @__PURE__ */ jsx("div", { className: "if-verifyStatus-successIcon", children: /* @__PURE__ */ jsx(
1758
+ "svg",
1820
1759
  {
1821
- style: {
1822
- width: "100%",
1823
- display: "flex",
1824
- flexDirection: "column",
1825
- alignItems: "stretch",
1826
- justifyContent: "center",
1827
- gap: "1.5rem"
1828
- },
1829
- children: /* @__PURE__ */ jsxs("div", { className: "if-authHeader if-internal-h3m7w5", children: [
1830
- /* @__PURE__ */ jsx("h1", { className: "if-authHeader-title if-internal-t4p1k9", children: errorTitle }),
1831
- /* @__PURE__ */ jsxs("p", { className: "if-authHeader-subtitle if-internal-s7q2m3", style: { lineHeight: "1.5" }, children: [
1832
- error || "The verification link is invalid or has expired.",
1833
- " Please try again or contact support if the problem persists. You can close this page and return to your app."
1834
- ] })
1835
- ] })
1760
+ className: "if-verifyStatus-successIconSvg",
1761
+ fill: "none",
1762
+ strokeLinecap: "round",
1763
+ strokeLinejoin: "round",
1764
+ strokeWidth: "2",
1765
+ viewBox: "0 0 24 24",
1766
+ stroke: "currentColor",
1767
+ children: /* @__PURE__ */ jsx("path", { d: "M5 13l4 4L19 7" })
1836
1768
  }
1837
- ) });
1838
- }
1839
- return /* @__PURE__ */ jsx(AuthContainer, { children: /* @__PURE__ */ jsx(
1840
- "div",
1841
- {
1842
- style: {
1843
- width: "100%",
1844
- display: "flex",
1845
- flexDirection: "column",
1846
- alignItems: "stretch",
1847
- justifyContent: "center",
1848
- gap: "1.5rem"
1849
- },
1850
- children: /* @__PURE__ */ jsxs(
1851
- "div",
1852
- {
1853
- style: { display: "flex", flexDirection: "column", alignItems: "center", gap: "1rem" },
1854
- children: [
1855
- /* @__PURE__ */ jsx(
1856
- "div",
1857
- {
1858
- style: {
1859
- width: "4rem",
1860
- height: "4rem",
1861
- borderRadius: "50%",
1862
- backgroundColor: "#D1FAE5",
1863
- display: "flex",
1864
- alignItems: "center",
1865
- justifyContent: "center"
1866
- },
1867
- children: /* @__PURE__ */ jsx(
1868
- "svg",
1869
- {
1870
- style: { width: "2rem", height: "2rem", color: "#059669" },
1871
- fill: "none",
1872
- strokeLinecap: "round",
1873
- strokeLinejoin: "round",
1874
- strokeWidth: "2",
1875
- viewBox: "0 0 24 24",
1876
- stroke: "currentColor",
1877
- children: /* @__PURE__ */ jsx("path", { d: "M5 13l4 4L19 7" })
1878
- }
1879
- )
1880
- }
1881
- ),
1882
- /* @__PURE__ */ jsx("h2", { className: "if-authHeader-title", style: { textAlign: "center" }, children: successTitle }),
1883
- /* @__PURE__ */ jsx("p", { className: "if-authHeader-subtitle", style: { textAlign: "center" }, children: successMessage })
1884
- ]
1885
- }
1886
- )
1887
- }
1888
- ) });
1769
+ ) }),
1770
+ /* @__PURE__ */ jsx("h2", { className: "if-authHeader-title if-verifyStatus-textCenter", children: successTitle }),
1771
+ /* @__PURE__ */ jsx("p", { className: "if-authHeader-subtitle if-verifyStatus-textCenter", children: successMessage })
1772
+ ] }) }) });
1889
1773
  }
1890
1774
  function VerifyEmail({ token, onSuccess, onError, ...uiProps }) {
1891
1775
  const { verifyEmail } = useInsforge();
@@ -1986,93 +1870,43 @@ function UserButton({ afterSignOutUrl = "/", mode = "detailed" }) {
1986
1870
  }
1987
1871
  const initials = user.name ? user.name.charAt(0).toUpperCase() : user.email.split("@")[0].slice(0, 2).toUpperCase();
1988
1872
  const buttonClassName = mode === "detailed" ? "if-userButton if-userButton-detailed" : "if-userButton";
1989
- return /* @__PURE__ */ jsxs(
1990
- "div",
1991
- {
1992
- className: "if-userButton if-internal-ub3k8p",
1993
- style: { position: "relative", display: "inline-block" },
1994
- ref: dropdownRef,
1995
- children: [
1996
- /* @__PURE__ */ jsxs(
1997
- "button",
1998
- {
1999
- className: buttonClassName,
2000
- style: {
2001
- display: "flex",
2002
- alignItems: "center",
2003
- justifyContent: "center",
2004
- gap: "0.5rem",
2005
- ...mode === "detailed" ? { borderRadius: "0.5rem", padding: "0.5rem" } : {}
2006
- },
2007
- onClick: () => setIsOpen(!isOpen),
2008
- "aria-expanded": isOpen,
2009
- "aria-haspopup": "true",
2010
- children: [
2011
- /* @__PURE__ */ jsx("div", { className: "if-userButton-avatar", children: user.avatarUrl && !imageError ? /* @__PURE__ */ jsx(
2012
- "img",
2013
- {
2014
- src: user.avatarUrl,
2015
- alt: user.email,
2016
- onError: () => setImageError(true),
2017
- style: { borderRadius: "50%", objectFit: "cover", width: "100%", height: "100%" }
2018
- }
2019
- ) : /* @__PURE__ */ jsx("span", { style: { color: "white", fontWeight: 600, fontSize: "0.875rem" }, children: initials }) }),
2020
- mode === "detailed" && /* @__PURE__ */ jsxs(
2021
- "div",
2022
- {
2023
- style: {
2024
- display: "flex",
2025
- flexDirection: "column",
2026
- alignItems: "flex-start",
2027
- gap: "0.125rem"
2028
- },
2029
- children: [
2030
- user.name && /* @__PURE__ */ jsx(
2031
- "div",
2032
- {
2033
- style: {
2034
- fontSize: "0.875rem",
2035
- fontWeight: 600,
2036
- color: "#1f1f1f",
2037
- lineHeight: "1.25rem",
2038
- textAlign: "left"
2039
- },
2040
- children: user.name
2041
- }
2042
- ),
2043
- /* @__PURE__ */ jsx(
2044
- "div",
2045
- {
2046
- style: {
2047
- fontSize: "0.75rem",
2048
- color: "#828282",
2049
- lineHeight: "1rem",
2050
- textAlign: "left"
2051
- },
2052
- children: user.email
2053
- }
2054
- )
2055
- ]
2056
- }
2057
- )
2058
- ]
2059
- }
2060
- ),
2061
- isOpen && /* @__PURE__ */ jsx("div", { className: "if-userButton-menu", children: /* @__PURE__ */ jsxs(
2062
- "button",
2063
- {
2064
- onClick: handleSignOut,
2065
- className: "if-userButton-menuItem",
2066
- style: { color: "#DC2626" },
2067
- children: [
2068
- /* @__PURE__ */ jsx(LogOut, { style: { width: "1.25rem", height: "1.25rem" } }),
2069
- "Sign out"
2070
- ]
2071
- }
2072
- ) })
2073
- ]
2074
- }
2075
- );
1873
+ return /* @__PURE__ */ jsxs("div", { className: "if-userButton-container if-internal-ub3k8p", ref: dropdownRef, children: [
1874
+ /* @__PURE__ */ jsxs(
1875
+ "button",
1876
+ {
1877
+ className: buttonClassName,
1878
+ onClick: () => setIsOpen(!isOpen),
1879
+ "aria-expanded": isOpen,
1880
+ "aria-haspopup": "true",
1881
+ children: [
1882
+ /* @__PURE__ */ jsx("div", { className: "if-userButton-avatar", children: user.avatarUrl && !imageError ? /* @__PURE__ */ jsx(
1883
+ "img",
1884
+ {
1885
+ src: user.avatarUrl,
1886
+ alt: user.email,
1887
+ onError: () => setImageError(true),
1888
+ className: "if-userButton-avatarImage"
1889
+ }
1890
+ ) : /* @__PURE__ */ jsx("span", { className: "if-userButton-avatarInitials", children: initials }) }),
1891
+ mode === "detailed" && /* @__PURE__ */ jsxs("div", { className: "if-userButton-info", children: [
1892
+ user.name && /* @__PURE__ */ jsx("div", { className: "if-userButton-name", children: user.name }),
1893
+ /* @__PURE__ */ jsx("div", { className: "if-userButton-email", children: user.email })
1894
+ ] })
1895
+ ]
1896
+ }
1897
+ ),
1898
+ isOpen && /* @__PURE__ */ jsx("div", { className: "if-userButton-menu", children: /* @__PURE__ */ jsxs(
1899
+ "button",
1900
+ {
1901
+ onClick: handleSignOut,
1902
+ className: "if-userButton-menuItem if-userButton-menuItem-signout",
1903
+ children: [
1904
+ /* @__PURE__ */ jsx(LogOut, { className: "if-userButton-menuItem-icon" }),
1905
+ "Sign out"
1906
+ ]
1907
+ }
1908
+ ) })
1909
+ ] });
2076
1910
  }
2077
1911
  function Protect({
2078
1912
  children,
@@ -2130,95 +1964,7 @@ function SignedOut({ children }) {
2130
1964
  }
2131
1965
  return /* @__PURE__ */ jsx(Fragment, { children });
2132
1966
  }
2133
- function InsforgeCallback({
2134
- redirectTo = "/",
2135
- onSuccess,
2136
- onError,
2137
- loadingComponent,
2138
- onRedirect
2139
- }) {
2140
- const isProcessingRef = useRef(false);
2141
- const { isLoaded, isSignedIn } = useInsforge();
2142
- useEffect(() => {
2143
- if (!isLoaded) {
2144
- return;
2145
- }
2146
- if (isProcessingRef.current) {
2147
- return;
2148
- }
2149
- isProcessingRef.current = true;
2150
- const processCallback = () => {
2151
- const searchParams = new URLSearchParams(window.location.search);
2152
- const error = searchParams.get("error");
2153
- if (error) {
2154
- if (onError) {
2155
- onError(error);
2156
- } else {
2157
- const errorUrl = "/?error=" + encodeURIComponent(error);
2158
- if (onRedirect) {
2159
- onRedirect(errorUrl);
2160
- } else {
2161
- window.location.href = errorUrl;
2162
- }
2163
- }
2164
- return;
2165
- }
2166
- if (!isSignedIn) {
2167
- const errorMsg = "authentication_failed";
2168
- if (onError) {
2169
- onError(errorMsg);
2170
- } else {
2171
- const errorUrl = "/?error=" + encodeURIComponent(errorMsg);
2172
- if (onRedirect) {
2173
- onRedirect(errorUrl);
2174
- } else {
2175
- window.location.href = errorUrl;
2176
- }
2177
- }
2178
- return;
2179
- }
2180
- window.history.replaceState({}, "", window.location.pathname);
2181
- if (onSuccess) {
2182
- onSuccess();
2183
- }
2184
- if (onRedirect) {
2185
- onRedirect(redirectTo);
2186
- } else {
2187
- window.location.href = redirectTo;
2188
- }
2189
- };
2190
- processCallback();
2191
- }, [isLoaded, isSignedIn, redirectTo, onSuccess, onError, onRedirect]);
2192
- const defaultLoading = /* @__PURE__ */ jsx(
2193
- "div",
2194
- {
2195
- style: {
2196
- display: "flex",
2197
- alignItems: "center",
2198
- justifyContent: "center",
2199
- minHeight: "100vh"
2200
- },
2201
- children: /* @__PURE__ */ jsxs("div", { style: { textAlign: "center" }, children: [
2202
- /* @__PURE__ */ jsx("h2", { className: "if-authHeader-title", style: { marginBottom: "1rem" }, children: "Completing authentication..." }),
2203
- /* @__PURE__ */ jsx(
2204
- "div",
2205
- {
2206
- className: "if-submitButton-spinner",
2207
- style: {
2208
- borderRadius: "50%",
2209
- height: "3rem",
2210
- width: "3rem",
2211
- borderBottom: "2px solid #2563EB",
2212
- margin: "0 auto"
2213
- }
2214
- }
2215
- )
2216
- ] })
2217
- }
2218
- );
2219
- return loadingComponent || defaultLoading;
2220
- }
2221
1967
 
2222
- export { AuthBranding, AuthContainer, AuthDivider, AuthEmailVerificationStep, AuthErrorBanner, AuthFormField, AuthHeader, AuthLink, AuthOAuthButton, AuthOAuthProviders, AuthPasswordField, AuthPasswordStrengthIndicator, AuthSubmitButton, AuthVerificationCodeInput, ForgotPassword, ForgotPasswordForm, InsforgeCallback, Protect, ResetPassword, ResetPasswordForm, SignIn, SignInForm, SignUp, SignUpForm, SignedIn, SignedOut, UserButton, VerifyEmail, VerifyEmailStatus };
1968
+ export { AuthBranding, AuthContainer, AuthDivider, AuthEmailVerificationStep, AuthErrorBanner, AuthFormField, AuthHeader, AuthLink, AuthOAuthButton, AuthOAuthProviders, AuthPasswordField, AuthPasswordStrengthIndicator, AuthResetPasswordVerificationStep, AuthSubmitButton, AuthVerificationCodeInput, ForgotPassword, ForgotPasswordForm, Protect, ResetPassword, ResetPasswordForm, SignIn, SignInForm, SignUp, SignUpForm, SignedIn, SignedOut, UserButton, VerifyEmail, VerifyEmailStatus };
2223
1969
  //# sourceMappingURL=components.js.map
2224
1970
  //# sourceMappingURL=components.js.map