@tern-secure/nextjs 4.0.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/dist/cjs/app-router/client/TernSecureProvider.js +17 -2
  2. package/dist/cjs/app-router/client/TernSecureProvider.js.map +1 -1
  3. package/dist/cjs/app-router/client/actions.js +49 -49
  4. package/dist/cjs/app-router/client/actions.js.map +1 -1
  5. package/dist/cjs/app-router/route-handler/internal-route.js +17 -2
  6. package/dist/cjs/app-router/route-handler/internal-route.js.map +1 -1
  7. package/dist/cjs/boundary/TernSecureClientProvider.js +163 -40
  8. package/dist/cjs/boundary/TernSecureClientProvider.js.map +1 -1
  9. package/dist/cjs/boundary/TernSecureCtx.js.map +1 -1
  10. package/dist/cjs/boundary/hooks/useAuth.js +7 -8
  11. package/dist/cjs/boundary/hooks/useAuth.js.map +1 -1
  12. package/dist/cjs/components/sign-in.js +136 -45
  13. package/dist/cjs/components/sign-in.js.map +1 -1
  14. package/dist/cjs/components/sign-out-button.js +10 -1
  15. package/dist/cjs/components/sign-out-button.js.map +1 -1
  16. package/dist/cjs/components/sign-out.js +12 -3
  17. package/dist/cjs/components/sign-out.js.map +1 -1
  18. package/dist/cjs/components/sign-up.js +10 -5
  19. package/dist/cjs/components/sign-up.js.map +1 -1
  20. package/dist/cjs/errors.js +232 -5
  21. package/dist/cjs/errors.js.map +1 -1
  22. package/dist/cjs/index.js +0 -3
  23. package/dist/cjs/index.js.map +1 -1
  24. package/dist/cjs/types.js +14 -0
  25. package/dist/cjs/types.js.map +1 -1
  26. package/dist/cjs/utils/construct.js +50 -18
  27. package/dist/cjs/utils/construct.js.map +1 -1
  28. package/dist/cjs/utils/redirect.js +57 -0
  29. package/dist/cjs/utils/redirect.js.map +1 -0
  30. package/dist/esm/app-router/client/TernSecureProvider.js +17 -2
  31. package/dist/esm/app-router/client/TernSecureProvider.js.map +1 -1
  32. package/dist/esm/app-router/client/actions.js +59 -51
  33. package/dist/esm/app-router/client/actions.js.map +1 -1
  34. package/dist/esm/app-router/route-handler/internal-route.js +13 -1
  35. package/dist/esm/app-router/route-handler/internal-route.js.map +1 -1
  36. package/dist/esm/boundary/TernSecureClientProvider.js +164 -41
  37. package/dist/esm/boundary/TernSecureClientProvider.js.map +1 -1
  38. package/dist/esm/boundary/TernSecureCtx.js.map +1 -1
  39. package/dist/esm/boundary/hooks/useAuth.js +7 -8
  40. package/dist/esm/boundary/hooks/useAuth.js.map +1 -1
  41. package/dist/esm/components/sign-in.js +137 -46
  42. package/dist/esm/components/sign-in.js.map +1 -1
  43. package/dist/esm/components/sign-out-button.js +11 -2
  44. package/dist/esm/components/sign-out-button.js.map +1 -1
  45. package/dist/esm/components/sign-out.js +13 -4
  46. package/dist/esm/components/sign-out.js.map +1 -1
  47. package/dist/esm/components/sign-up.js +10 -5
  48. package/dist/esm/components/sign-up.js.map +1 -1
  49. package/dist/esm/errors.js +228 -4
  50. package/dist/esm/errors.js.map +1 -1
  51. package/dist/esm/index.js +0 -2
  52. package/dist/esm/index.js.map +1 -1
  53. package/dist/esm/types.js +6 -0
  54. package/dist/esm/types.js.map +1 -1
  55. package/dist/esm/utils/construct.js +46 -17
  56. package/dist/esm/utils/construct.js.map +1 -1
  57. package/dist/esm/utils/redirect.js +32 -0
  58. package/dist/esm/utils/redirect.js.map +1 -0
  59. package/dist/types/app-router/client/TernSecureProvider.d.ts +14 -3
  60. package/dist/types/app-router/client/TernSecureProvider.d.ts.map +1 -1
  61. package/dist/types/app-router/client/actions.d.ts +23 -21
  62. package/dist/types/app-router/client/actions.d.ts.map +1 -1
  63. package/dist/types/app-router/route-handler/internal-route.d.ts +3 -0
  64. package/dist/types/app-router/route-handler/internal-route.d.ts.map +1 -1
  65. package/dist/types/boundary/TernSecureClientProvider.d.ts +17 -1
  66. package/dist/types/boundary/TernSecureClientProvider.d.ts.map +1 -1
  67. package/dist/types/boundary/TernSecureCtx.d.ts +3 -1
  68. package/dist/types/boundary/TernSecureCtx.d.ts.map +1 -1
  69. package/dist/types/boundary/hooks/useAuth.d.ts +4 -1
  70. package/dist/types/boundary/hooks/useAuth.d.ts.map +1 -1
  71. package/dist/types/components/sign-in.d.ts +1 -2
  72. package/dist/types/components/sign-in.d.ts.map +1 -1
  73. package/dist/types/components/sign-out-button.d.ts +2 -1
  74. package/dist/types/components/sign-out-button.d.ts.map +1 -1
  75. package/dist/types/components/sign-out.d.ts +2 -1
  76. package/dist/types/components/sign-out.d.ts.map +1 -1
  77. package/dist/types/components/sign-up.d.ts.map +1 -1
  78. package/dist/types/components/ui/alert.d.ts +1 -1
  79. package/dist/types/components/ui/button.d.ts +1 -1
  80. package/dist/types/errors.d.ts +36 -2
  81. package/dist/types/errors.d.ts.map +1 -1
  82. package/dist/types/index.d.ts +0 -1
  83. package/dist/types/index.d.ts.map +1 -1
  84. package/dist/types/types.d.ts +35 -0
  85. package/dist/types/types.d.ts.map +1 -1
  86. package/dist/types/utils/construct.d.ts +20 -4
  87. package/dist/types/utils/construct.d.ts.map +1 -1
  88. package/dist/types/utils/redirect.d.ts +9 -0
  89. package/dist/types/utils/redirect.d.ts.map +1 -0
  90. package/package.json +6 -6
  91. package/dist/cjs/boundary/hooks/useUser.js +0 -44
  92. package/dist/cjs/boundary/hooks/useUser.js.map +0 -1
  93. package/dist/esm/boundary/hooks/useUser.js +0 -20
  94. package/dist/esm/boundary/hooks/useUser.js.map +0 -1
  95. package/dist/types/boundary/hooks/useUser.d.ts +0 -7
  96. package/dist/types/boundary/hooks/useUser.d.ts.map +0 -1
@@ -39,32 +39,79 @@ var import_client_init = require("../utils/client-init");
39
39
  var import_sessionTernSecure = require("../app-router/server/sessionTernSecure");
40
40
  var import_background = require("./background");
41
41
  var import_construct = require("../utils/construct");
42
- var import_errors = require("../errors");
43
42
  var import_internal_route = require("../app-router/route-handler/internal-route");
43
+ var import_useAuth = require("../boundary/hooks/useAuth");
44
+ var import_errors = require("../errors");
44
45
  const authDomain = process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN;
45
46
  const appName = process.env.NEXT_PUBLIC_FIREBASE_APP_NAME || "TernSecure";
46
47
  function SignIn({
47
48
  redirectUrl,
48
49
  onError,
49
50
  onSuccess,
50
- requiresVerification = true,
51
51
  className,
52
52
  customStyles = {}
53
53
  }) {
54
54
  const [loading, setLoading] = (0, import_react.useState)(false);
55
55
  const [checkingRedirect, setCheckingRedirect] = (0, import_react.useState)(true);
56
+ const [formError, setFormError] = (0, import_react.useState)(null);
56
57
  const [error, setError] = (0, import_react.useState)("");
57
58
  const [email, setEmail] = (0, import_react.useState)("");
58
59
  const [password, setPassword] = (0, import_react.useState)("");
60
+ const [showPassword, setShowPassword] = (0, import_react.useState)(false);
61
+ const [passwordFocused, setPasswordFocused] = (0, import_react.useState)(false);
59
62
  const [authResponse, setAuthResponse] = (0, import_react.useState)(null);
63
+ const [authErrorMessage, setAuthErrorMessage] = (0, import_react.useState)(null);
60
64
  const searchParams = (0, import_navigation.useSearchParams)();
61
65
  const isRedirectSignIn = searchParams.get("signInRedirect") === "true";
62
66
  const router = (0, import_navigation.useRouter)();
63
67
  const pathname = (0, import_navigation.usePathname)();
64
- const InternalComponent = (0, import_internal_route.handleInternalRoute)(pathname);
68
+ const InternalComponent = (0, import_internal_route.handleInternalRoute)(pathname || "");
69
+ const { requiresVerification, error: authError, status } = (0, import_useAuth.useAuth)();
70
+ const validRedirectUrl = (0, import_construct.getValidRedirectUrl)(searchParams, redirectUrl);
65
71
  if (InternalComponent) {
66
72
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InternalComponent, {});
67
73
  }
74
+ (0, import_react.useEffect)(() => {
75
+ if (authError && status !== "loading" && status !== "unauthenticated") {
76
+ const message = authError.message || "Authentication failed";
77
+ setAuthErrorMessage(message);
78
+ if (!authResponse || authResponse.message !== message) {
79
+ setAuthResponse(authError);
80
+ }
81
+ } else {
82
+ setAuthErrorMessage(null);
83
+ }
84
+ }, [authError, status, authResponse]);
85
+ const handleSuccessfulAuth = (0, import_react.useCallback)(
86
+ async (user) => {
87
+ try {
88
+ const idToken = await user.getIdToken();
89
+ const sessionResult = await (0, import_sessionTernSecure.createSessionCookie)(idToken);
90
+ if (!sessionResult.success) {
91
+ setFormError({
92
+ success: false,
93
+ message: sessionResult.message || "Failed to create session",
94
+ error: "INTERNAL_ERROR",
95
+ user: null
96
+ });
97
+ }
98
+ onSuccess == null ? void 0 : onSuccess();
99
+ if (process.env.NODE_ENV === "production") {
100
+ window.location.href = validRedirectUrl;
101
+ } else {
102
+ router.push(validRedirectUrl);
103
+ }
104
+ } catch (err) {
105
+ setFormError({
106
+ success: false,
107
+ message: "Failed to complete authentication",
108
+ error: "INTERNAL_ERROR",
109
+ user: null
110
+ });
111
+ }
112
+ },
113
+ [validRedirectUrl, router, onSuccess]
114
+ );
68
115
  const handleRedirectResult = (0, import_react.useCallback)(async () => {
69
116
  if (!isRedirectSignIn) return false;
70
117
  setCheckingRedirect(true);
@@ -85,15 +132,16 @@ function SignIn({
85
132
  const storedRedirectUrl = sessionStorage.getItem("auth_return_url");
86
133
  sessionStorage.removeItem("auth_redirect_url");
87
134
  onSuccess == null ? void 0 : onSuccess();
88
- window.location.href = storedRedirectUrl || (0, import_construct.getValidRedirectUrl)(redirectUrl, searchParams);
135
+ window.location.href = storedRedirectUrl || (0, import_construct.getValidRedirectUrl)(searchParams, redirectUrl);
89
136
  return true;
90
137
  }
91
138
  setCheckingRedirect(false);
92
139
  } catch (err) {
93
- console.error("Redirect result error:", err);
94
- const errorMessage = err instanceof Error ? err.message : "Authentication failed";
95
- setError(errorMessage);
96
- onError == null ? void 0 : onError(err instanceof Error ? err : new Error(errorMessage));
140
+ const errorMessage = err;
141
+ setFormError(errorMessage);
142
+ if (onError && err instanceof Error) {
143
+ onError(err);
144
+ }
97
145
  sessionStorage.removeItem("auth_redirect_url");
98
146
  return false;
99
147
  }
@@ -102,32 +150,42 @@ function SignIn({
102
150
  if (isRedirectSignIn) {
103
151
  handleRedirectResult();
104
152
  }
105
- ;
106
153
  }, [handleRedirectResult, isRedirectSignIn]);
107
154
  const handleSubmit = async (e) => {
108
155
  e.preventDefault();
109
156
  setLoading(true);
157
+ setFormError(null);
110
158
  setAuthResponse(null);
111
159
  try {
112
160
  const response = await (0, import_actions.signInWithEmail)(email, password);
113
161
  setAuthResponse(response);
162
+ if (!response.success) {
163
+ setFormError({
164
+ success: false,
165
+ message: response.message,
166
+ error: response.error,
167
+ user: null
168
+ });
169
+ return;
170
+ }
114
171
  if (response.user) {
115
172
  if (requiresVerification && !response.user.emailVerified) {
116
- setError("Email verification required");
173
+ setFormError({
174
+ success: false,
175
+ message: "Email verification required",
176
+ error: "REQUIRES_VERIFICATION",
177
+ user: response.user
178
+ });
117
179
  return;
118
180
  }
119
- const idToken = await response.user.getIdToken();
120
- const sessionResult = await (0, import_sessionTernSecure.createSessionCookie)(idToken);
121
- if (!sessionResult.success) {
122
- throw new Error(sessionResult.message || "Failed to create session");
123
- }
124
- onSuccess == null ? void 0 : onSuccess();
125
- window.location.href = (0, import_construct.getValidRedirectUrl)(redirectUrl, searchParams);
181
+ await handleSuccessfulAuth(response.user);
126
182
  }
127
183
  } catch (err) {
128
- const errorMessage = err instanceof Error ? err.message : "Failed to sign in";
129
- setError(errorMessage);
130
- onError == null ? void 0 : onError(err instanceof Error ? err : new Error("Failed to sign in"));
184
+ const errorMessage = err;
185
+ setFormError(errorMessage);
186
+ if (onError && err instanceof Error) {
187
+ onError(err);
188
+ }
131
189
  } finally {
132
190
  setLoading(false);
133
191
  }
@@ -135,8 +193,8 @@ function SignIn({
135
193
  const handleSocialSignIn = async (provider) => {
136
194
  setLoading(true);
137
195
  try {
138
- const validRedirectUrl = (0, import_construct.getValidRedirectUrl)(redirectUrl, searchParams);
139
- sessionStorage.setItem("auth_redirect_url", validRedirectUrl);
196
+ const validRedirectUrl2 = (0, import_construct.getValidRedirectUrl)(searchParams, redirectUrl);
197
+ sessionStorage.setItem("auth_redirect_url", validRedirectUrl2);
140
198
  const currentUrl = new URL(window.location.href);
141
199
  currentUrl.searchParams.set("signInRedirect", "true");
142
200
  window.history.replaceState({}, "", currentUrl.toString());
@@ -145,36 +203,46 @@ function SignIn({
145
203
  throw new Error(result.error);
146
204
  }
147
205
  } catch (err) {
148
- const errorMessage = err instanceof Error ? err.message : `Failed to sign in with ${provider}`;
149
- setError(errorMessage);
150
- onError == null ? void 0 : onError(err instanceof Error ? err : new Error(`Failed to sign in with ${provider}`));
206
+ const errorMessage = err;
207
+ setFormError(errorMessage);
208
+ if (onError && err instanceof Error) {
209
+ onError(err);
210
+ }
151
211
  setLoading(false);
152
212
  sessionStorage.removeItem("auth_redirect_url");
153
213
  }
154
214
  };
215
+ const handleVerificationRedirect = (e) => {
216
+ e.preventDefault();
217
+ router.push("/sign-in/verify");
218
+ };
155
219
  if (checkingRedirect && isRedirectSignIn) {
156
220
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex min-h-screen items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "text-center space-y-4", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "animate-spin rounded-full h-12 w-12 border-b-2 border-primary mx-auto" }) }) });
157
221
  }
222
+ const activeError = formError || authResponse;
223
+ const showEmailVerificationButton = (activeError == null ? void 0 : activeError.error) === "EMAIL_NOT_VERIFIED" || (activeError == null ? void 0 : activeError.error) === "REQUIRES_VERIFICATION";
158
224
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative flex items-center justify-center", children: [
159
225
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_background.AuthBackground, {}),
160
226
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_card.Card, { className: (0, import_utils.cn)("w-full max-w-md mx-auto mt-8", className, customStyles.card), children: [
161
227
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_card.CardHeader, { className: "space-y-1 text-center", children: [
162
228
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_card.CardTitle, { className: (0, import_utils.cn)("font-bold", customStyles.title), children: [
163
229
  "Sign in to ",
164
- `${appName}`
230
+ `${appName}`,
231
+ " "
165
232
  ] }),
166
233
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_card.CardDescription, { className: (0, import_utils.cn)("text-muted-foreground", customStyles.description), children: "Please sign in to continue" })
167
234
  ] }),
168
235
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_card.CardContent, { className: "space-y-4", children: [
169
236
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
170
- error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_alert.Alert, { variant: (authResponse == null ? void 0 : authResponse.error) === import_errors.ERRORS.REQUIRES_VERIFICATION ? "destructive" : "destructive", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_alert.AlertDescription, { children: [
171
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: error }),
172
- (authResponse == null ? void 0 : authResponse.error) === import_errors.ERRORS.REQUIRES_VERIFICATION && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
237
+ activeError && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_alert.Alert, { variant: (0, import_errors.getErrorAlertVariant)(activeError), className: "animate-in fade-in-50", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_alert.AlertDescription, { children: [
238
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: activeError.message }),
239
+ showEmailVerificationButton && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
173
240
  import_button.Button,
174
241
  {
242
+ type: "button",
175
243
  variant: "link",
176
244
  className: "p-0 h-auto font-normal text-sm hover:underline",
177
- onClick: () => router.push(`/sign-in/verify`),
245
+ onClick: handleVerificationRedirect,
178
246
  children: "Request new verification email \u2192"
179
247
  }
180
248
  )
@@ -191,24 +259,47 @@ function SignIn({
191
259
  onChange: (e) => setEmail(e.target.value),
192
260
  disabled: loading,
193
261
  className: (0, import_utils.cn)(customStyles.input),
194
- required: true
262
+ required: true,
263
+ "aria-invalid": (activeError == null ? void 0 : activeError.error) === "INVALID_EMAIL",
264
+ "aria-describedby": activeError ? "error-message" : void 0
195
265
  }
196
266
  )
197
267
  ] }),
198
268
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-2", children: [
199
269
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_label.Label, { htmlFor: "password", className: (0, import_utils.cn)(customStyles.label), children: "Password" }),
200
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
201
- import_input.Input,
202
- {
203
- id: "password",
204
- type: "password",
205
- value: password,
206
- onChange: (e) => setPassword(e.target.value),
207
- disabled: loading,
208
- className: (0, import_utils.cn)(customStyles.input),
209
- required: true
210
- }
211
- )
270
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative", children: [
271
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
272
+ import_input.Input,
273
+ {
274
+ id: "password",
275
+ name: "password",
276
+ type: showPassword ? "text" : "password",
277
+ value: password,
278
+ onChange: (e) => setPassword(e.target.value),
279
+ onFocus: () => setPasswordFocused(true),
280
+ onBlur: () => setPasswordFocused(false),
281
+ disabled: loading,
282
+ className: (0, import_utils.cn)(customStyles.input),
283
+ required: true,
284
+ "aria-invalid": (activeError == null ? void 0 : activeError.error) === "INVALID_CREDENTIALS",
285
+ "aria-describedby": activeError ? "error-message" : void 0
286
+ }
287
+ ),
288
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
289
+ import_button.Button,
290
+ {
291
+ type: "button",
292
+ variant: "ghost",
293
+ size: "icon",
294
+ className: "absolute right-2 top-1/2 -translate-y-1/2 h-8 w-8 hover:bg-transparent",
295
+ onClick: () => setShowPassword(!showPassword),
296
+ children: [
297
+ showPassword ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.EyeOff, { className: "h-4 w-4 text-muted-foreground hover:text-foreground" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Eye, { className: "h-4 w-4 text-muted-foreground hover:text-foreground" }),
298
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "sr-only", children: showPassword ? "Hide password" : "Show password" })
299
+ ]
300
+ }
301
+ )
302
+ ] })
212
303
  ] }),
213
304
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_button.Button, { type: "submit", disabled: loading, className: (0, import_utils.cn)("w-full", customStyles.button), children: loading ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
214
305
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
@@ -216,8 +307,8 @@ function SignIn({
216
307
  ] }) : "Sign in" })
217
308
  ] }),
218
309
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative", children: [
219
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute inset-0 flex items-center", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_separator.Separator, { className: (0, import_utils.cn)(customStyles.separator) }) }),
220
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "relative flex justify-center text-xs uppercase", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "bg-background px-2 text-muted-foreground", children: "Or continue with" }) })
310
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_separator.Separator, { className: (0, import_utils.cn)(customStyles.separator) }),
311
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "bg-background px-2 text-muted-foreground text-sm", children: "Or continue with" }) })
221
312
  ] }),
222
313
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "grid grid-cols-2 gap-4", children: [
223
314
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/sign-in.tsx"],"sourcesContent":["'use client'\n\nimport React, { useState, useCallback, useEffect } from 'react'\nimport { useSearchParams, useRouter, usePathname} from 'next/navigation'\nimport { signInWithEmail, signInWithRedirectGoogle, signInWithMicrosoft, type SignInResponse } from '../app-router/client/actions'\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from \"./ui/card\"\nimport { Input } from \"./ui/input\"\nimport { Label } from \"./ui/label\"\nimport { Button } from \"./ui/button\"\nimport { Alert, AlertDescription } from \"./ui/alert\"\nimport { Separator } from \"./ui/separator\"\nimport { cn } from \"../lib/utils\"\nimport { Loader2 } from 'lucide-react'\nimport { getRedirectResult } from 'firebase/auth'\nimport { ternSecureAuth } from '../utils/client-init'\nimport { createSessionCookie } from '../app-router/server/sessionTernSecure'\nimport { AuthBackground } from './background'\nimport { getValidRedirectUrl } from '../utils/construct'\nimport { ERRORS } from '../errors'\nimport { handleInternalRoute } from '../app-router/route-handler/internal-route'\n\n\nconst authDomain = process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN;\nconst appName = process.env.NEXT_PUBLIC_FIREBASE_APP_NAME || 'TernSecure';\n\n\nexport interface SignInProps {\n redirectUrl?: string\n onError?: (error: Error) => void\n onSuccess?: () => void\n requiresVerification?: boolean\n className?: string\n customStyles?: {\n card?: string\n input?: string\n button?: string\n label?: string\n separator?: string\n title?: string\n description?: string\n socialButton?: string\n }\n}\n\nexport function SignIn({\n redirectUrl,\n onError,\n onSuccess,\n requiresVerification = true,\n className,\n customStyles = {}\n}: SignInProps) {\n const [loading, setLoading] = useState(false)\n const [checkingRedirect, setCheckingRedirect] = useState(true)\n const [error, setError] = useState('')\n const [email, setEmail] = useState('')\n const [password, setPassword] = useState('')\n const [authResponse, setAuthResponse] = useState<SignInResponse | null>(null)\n const searchParams = useSearchParams()\n const isRedirectSignIn = searchParams.get('signInRedirect') === 'true'\n const router = useRouter()\n const pathname = usePathname()\n const InternalComponent = handleInternalRoute(pathname)\n\n if (InternalComponent) {\n return <InternalComponent />\n }\n\n\n const handleRedirectResult = useCallback(async () => {\n if (!isRedirectSignIn) return false\n setCheckingRedirect(true)\n try {\n console.log('Checking redirect result...');\n console.log('Current hostname:', window.location.hostname);\n console.log('Auth domain hostname:', authDomain);\n\n const isOnAuth = authDomain && \n window.location.hostname === authDomain.replace(/https?:\\/\\//, '');\n console.log('Is on AuthDomain:', isOnAuth);\n\n\n const result = await getRedirectResult(ternSecureAuth)\n console.log('Redirect result:', result);\n if (result) {\n const idToken = await result.user.getIdToken()\n const sessionResult = await createSessionCookie(idToken)\n if (!sessionResult.success) {\n throw new Error('Failed to create session')\n }\n const storedRedirectUrl = sessionStorage.getItem('auth_return_url')\n sessionStorage.removeItem('auth_redirect_url') \n onSuccess?.()\n window.location.href = storedRedirectUrl || getValidRedirectUrl(redirectUrl, searchParams)\n return true\n }\n setCheckingRedirect(false)\n } catch (err) {\n console.error('Redirect result error:', err)\n const errorMessage = err instanceof Error ? err.message : 'Authentication failed'\n setError(errorMessage)\n onError?.(err instanceof Error ? err : new Error(errorMessage))\n sessionStorage.removeItem('auth_redirect_url')\n return false\n }\n }, [isRedirectSignIn, redirectUrl, searchParams, onSuccess, onError])\n\n ///const REDIRECT_TIMEOUT = 5000;\n\n useEffect(() => {\n //let timeoutId: NodeJS.Timeout;\n\n if (isRedirectSignIn) {\n handleRedirectResult();\n\n /*timeoutId = setTimeout(() => {\n console.warn('Redirect check timed out');\n setCheckingRedirect(false);\n setError('Sign in took too long. Please try again.');\n \n }, REDIRECT_TIMEOUT);\n }\n\n return () => {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }*/\n };\n }, [handleRedirectResult, isRedirectSignIn])\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault()\n setLoading(true)\n setAuthResponse(null)\n try {\n const response = await signInWithEmail(email, password)\n setAuthResponse(response)\n\n // if (response.error === ERRORS.REQUIRES_VERIFICATION) {\n // if (requiresVerification) {\n // setError(response.message || 'Email verification required')\n // return\n // }\n // }\n\n if (response.user) {\n if (requiresVerification && !response.user.emailVerified) {\n setError('Email verification required')\n return\n }\n\n const idToken = await response.user.getIdToken()\n const sessionResult = await createSessionCookie(idToken)\n\n if(!sessionResult.success) {\n throw new Error(sessionResult.message || 'Failed to create session')\n }\n\n onSuccess?.()\n window.location.href = getValidRedirectUrl(redirectUrl, searchParams)\n }\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Failed to sign in'\n setError(errorMessage)\n onError?.(err instanceof Error ? err : new Error('Failed to sign in'))\n } finally {\n setLoading(false)\n }\n }\n\n const handleSocialSignIn = async (provider: 'google' | 'microsoft') => {\n setLoading(true)\n try {\n\n const validRedirectUrl = getValidRedirectUrl(redirectUrl, searchParams)\n sessionStorage.setItem('auth_redirect_url', validRedirectUrl)\n\n const currentUrl = new URL(window.location.href)\n currentUrl.searchParams.set('signInRedirect', 'true')\n window.history.replaceState({}, '', currentUrl.toString())\n\n const result = provider === 'google' ? await signInWithRedirectGoogle() : await signInWithMicrosoft()\n if (!result.success) {\n throw new Error(result.error)\n }\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : `Failed to sign in with ${provider}`\n setError(errorMessage)\n onError?.(err instanceof Error ? err : new Error(`Failed to sign in with ${provider}`))\n setLoading(false)\n sessionStorage.removeItem('auth_redirect_url')\n }\n }\n\n if (checkingRedirect && isRedirectSignIn) {\n return (\n <div className=\"flex min-h-screen items-center justify-center\">\n <div className=\"text-center space-y-4\">\n <div className=\"animate-spin rounded-full h-12 w-12 border-b-2 border-primary mx-auto\" />\n \n </div>\n </div>\n )\n }\n\n return (\n <div className=\"relative flex items-center justify-center\">\n <AuthBackground />\n <Card className={cn(\"w-full max-w-md mx-auto mt-8\", className, customStyles.card)}>\n <CardHeader className=\"space-y-1 text-center\">\n <CardTitle className={cn(\"font-bold\", customStyles.title)}>Sign in to {`${appName}`}</CardTitle>\n <CardDescription className={cn(\"text-muted-foreground\", customStyles.description)}>\n Please sign in to continue\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n {error && (\n <Alert variant={authResponse?.error === ERRORS.REQUIRES_VERIFICATION ? \"destructive\" : \"destructive\"}>\n <AlertDescription>\n <span>{error}</span>\n {authResponse?.error === ERRORS.REQUIRES_VERIFICATION && (\n <Button\n variant=\"link\"\n className=\"p-0 h-auto font-normal text-sm hover:underline\"\n onClick={() => router.push(`/sign-in/verify`)}\n >\n Request new verification email →\n </Button>\n )}\n </AlertDescription>\n </Alert>\n )}\n <div className=\"space-y-2\">\n <Label htmlFor=\"email\" className={cn(customStyles.label)}>Email</Label>\n <Input\n id=\"email\"\n type=\"email\"\n placeholder=\"m@example.com\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n disabled={loading}\n className={cn(customStyles.input)}\n required\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"password\" className={cn(customStyles.label)}>Password</Label>\n <Input\n id=\"password\"\n type=\"password\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n disabled={loading}\n className={cn(customStyles.input)}\n required\n />\n </div>\n <Button type=\"submit\" disabled={loading} className={cn(\"w-full\", customStyles.button)}>\n {loading ? (\n <>\n <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n Signing in...\n </>\n ) : (\n 'Sign in'\n )}\n </Button>\n </form>\n <div className=\"relative\">\n <div className=\"absolute inset-0 flex items-center\">\n <Separator className={cn(customStyles.separator)} />\n </div>\n <div className=\"relative flex justify-center text-xs uppercase\">\n <span className=\"bg-background px-2 text-muted-foreground\">Or continue with</span>\n </div>\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <Button \n variant=\"outline\" \n disabled={loading} \n onClick={() => handleSocialSignIn('google')} \n className={cn(\"flex items-center justify-center\", customStyles.socialButton)}\n >\n <svg className=\"w-5 h-5 mr-2\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z\" fill=\"#4285F4\"/>\n <path d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\" fill=\"#34A853\"/>\n <path d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z\" fill=\"#FBBC05\"/>\n <path d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\" fill=\"#EA4335\"/>\n </svg>\n Google\n </Button>\n <Button \n variant=\"outline\" \n disabled={loading} \n onClick={() => handleSocialSignIn('microsoft')} \n className={cn(\"flex items-center justify-center\", customStyles.socialButton)}\n >\n <svg className=\"w-5 h-5 mr-2\" viewBox=\"0 0 23 23\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill=\"#f3f3f3\" d=\"M0 0h23v23H0z\"/>\n <path fill=\"#f35325\" d=\"M1 1h10v10H1z\"/>\n <path fill=\"#81bc06\" d=\"M12 1h10v10H12z\"/>\n <path fill=\"#05a6f0\" d=\"M1 12h10v10H1z\"/>\n <path fill=\"#ffba08\" d=\"M12 12h10v10H12z\"/>\n </svg>\n Microsoft\n </Button>\n </div>\n </CardContent>\n <CardFooter className=\"flex justify-center\">\n <p className=\"text-sm text-muted-foreground\">\n Don&apos;t have an account?{' '}\n <a href=\"/sign-up\" className=\"text-primary hover:underline\">\n Sign up\n </a>\n </p>\n </CardFooter>\n </Card>\n </div>\n )\n}\n\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components/sign-in.tsx"],"sourcesContent":["'use client'\n\nimport React, { useState, useCallback, useEffect } from 'react'\nimport { useSearchParams, useRouter, usePathname} from 'next/navigation'\nimport { signInWithEmail, signInWithRedirectGoogle, signInWithMicrosoft } from '../app-router/client/actions'\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from \"./ui/card\"\nimport { Input } from \"./ui/input\"\nimport { Label } from \"./ui/label\"\nimport { Button } from \"./ui/button\"\nimport { Alert, AlertDescription } from \"./ui/alert\"\nimport { Separator } from \"./ui/separator\"\nimport { cn } from \"../lib/utils\"\nimport { Loader2, Eye, EyeOff } from 'lucide-react'\nimport { getRedirectResult, User } from 'firebase/auth'\nimport { ternSecureAuth } from '../utils/client-init'\nimport { createSessionCookie } from '../app-router/server/sessionTernSecure'\nimport { AuthBackground } from './background'\nimport { getValidRedirectUrl } from '../utils/construct'\nimport { handleInternalRoute } from '../app-router/route-handler/internal-route'\nimport type { SignInResponse } from '../types'\nimport { useAuth } from '../boundary/hooks/useAuth'\nimport { getErrorAlertVariant, ErrorCode } from '../errors'\n\n\n\nconst authDomain = process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN;\nconst appName = process.env.NEXT_PUBLIC_FIREBASE_APP_NAME || 'TernSecure';\n\n\nexport interface SignInProps {\n redirectUrl?: string\n onError?: (error: Error) => void\n onSuccess?: () => void\n className?: string\n customStyles?: {\n card?: string\n input?: string\n button?: string\n label?: string\n separator?: string\n title?: string\n description?: string\n socialButton?: string\n }\n}\n\n\nexport function SignIn({\n redirectUrl,\n onError,\n onSuccess,\n className,\n customStyles = {}\n}: SignInProps) {\n const [loading, setLoading] = useState(false)\n const [checkingRedirect, setCheckingRedirect] = useState(true)\n const [formError, setFormError] = useState<SignInResponse | null>(null)\n const [error, setError] = useState('')\n const [email, setEmail] = useState('')\n const [password, setPassword] = useState('')\n const [showPassword, setShowPassword] = useState(false)\n const [passwordFocused, setPasswordFocused] = useState(false)\n const [authResponse, setAuthResponse] = useState<SignInResponse | null>(null)\n const [authErrorMessage, setAuthErrorMessage] = useState<string | null>(null)\n const searchParams = useSearchParams()\n const isRedirectSignIn = searchParams.get('signInRedirect') === 'true'\n const router = useRouter()\n const pathname = usePathname()\n const InternalComponent = handleInternalRoute(pathname || \"\")\n const { requiresVerification, error: authError, status } = useAuth()\n const validRedirectUrl = getValidRedirectUrl(searchParams, redirectUrl)\n\n\n if (InternalComponent) {\n return <InternalComponent />\n }\n\n useEffect(() => {\n if (authError && status !== \"loading\" && status !== \"unauthenticated\") {\n\n const message = authError.message || \"Authentication failed\"\n setAuthErrorMessage(message)\n\n if(!authResponse || authResponse.message !== message) {\n setAuthResponse(authError as SignInResponse)\n }\n } else {\n setAuthErrorMessage(null)\n }\n }, [authError, status, authResponse])\n\n const handleSuccessfulAuth = useCallback(\n async (user: User) => {\n try {\n const idToken = await user.getIdToken()\n const sessionResult = await createSessionCookie(idToken)\n\n if (!sessionResult.success) {\n setFormError({\n success: false, \n message: sessionResult.message || \"Failed to create session\", \n error: 'INTERNAL_ERROR', \n user: null\n })\n }\n\n onSuccess?.()\n\n // Use the finalRedirectUrl for navigation\n if (process.env.NODE_ENV === \"production\") {\n // Use window.location.href in production for a full page reload\n window.location.href = validRedirectUrl\n } else {\n // Use router.push in development\n router.push(validRedirectUrl)\n }\n } catch (err) {\n setFormError({\n success: false, \n message: \"Failed to complete authentication\", \n error: 'INTERNAL_ERROR', \n user: null\n })\n }\n },\n [validRedirectUrl, router, onSuccess],\n )\n\n\n const handleRedirectResult = useCallback(async () => {\n if (!isRedirectSignIn) return false\n setCheckingRedirect(true)\n try {\n console.log('Checking redirect result...');\n console.log('Current hostname:', window.location.hostname);\n console.log('Auth domain hostname:', authDomain);\n\n const isOnAuth = authDomain && \n window.location.hostname === authDomain.replace(/https?:\\/\\//, '');\n console.log('Is on AuthDomain:', isOnAuth);\n\n\n const result = await getRedirectResult(ternSecureAuth)\n console.log('Redirect result:', result);\n if (result) {\n const idToken = await result.user.getIdToken()\n const sessionResult = await createSessionCookie(idToken)\n if (!sessionResult.success) {\n throw new Error('Failed to create session')\n }\n const storedRedirectUrl = sessionStorage.getItem('auth_return_url')\n sessionStorage.removeItem('auth_redirect_url') \n onSuccess?.()\n window.location.href = storedRedirectUrl || getValidRedirectUrl(searchParams, redirectUrl)\n return true\n }\n setCheckingRedirect(false)\n } catch (err) { \n const errorMessage = err as SignInResponse\n setFormError(errorMessage)\n if (onError && err instanceof Error) {\n onError(err)\n }\n sessionStorage.removeItem('auth_redirect_url')\n return false\n }\n }, [isRedirectSignIn, redirectUrl, searchParams, onSuccess, onError])\n\n //const REDIRECT_TIMEOUT = 5000;\n\n useEffect(() => {\n if (isRedirectSignIn) {\n handleRedirectResult()\n }\n }, [handleRedirectResult, isRedirectSignIn])\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault()\n setLoading(true)\n setFormError(null)\n setAuthResponse(null)\n\n try {\n const response= await signInWithEmail(email, password)\n setAuthResponse(response)\n\n if (!response.success) {\n setFormError({\n success: false, \n message: response.message, \n error: response.error, \n user: null\n })\n return\n }\n\n if (response.user) {\n if(requiresVerification && !response.user.emailVerified) {\n setFormError({\n success: false, \n message: 'Email verification required', \n error: 'REQUIRES_VERIFICATION', \n user: response.user\n })\n return\n }\n\n await handleSuccessfulAuth(response.user)\n }\n } catch (err) {\n const errorMessage = err as SignInResponse\n setFormError(errorMessage)\n if (onError && err instanceof Error) {\n onError(err)\n }\n } finally {\n setLoading(false)\n }\n }\n\n const handleSocialSignIn = async (provider: 'google' | 'microsoft') => {\n setLoading(true)\n try {\n\n const validRedirectUrl = getValidRedirectUrl(searchParams, redirectUrl)\n sessionStorage.setItem('auth_redirect_url', validRedirectUrl)\n\n const currentUrl = new URL(window.location.href)\n currentUrl.searchParams.set('signInRedirect', 'true')\n window.history.replaceState({}, '', currentUrl.toString())\n\n const result = provider === 'google' ? await signInWithRedirectGoogle() : await signInWithMicrosoft()\n if (!result.success) {\n throw new Error(result.error)\n }\n } catch (err) {\n const errorMessage = err as SignInResponse\n setFormError(errorMessage)\n if (onError && err instanceof Error) {\n onError(err)\n }\n setLoading(false)\n sessionStorage.removeItem('auth_redirect_url')\n }\n }\n\n const handleVerificationRedirect = (e: React.MouseEvent) => {\n e.preventDefault()\n router.push(\"/sign-in/verify\")\n }\n\n\n if (checkingRedirect && isRedirectSignIn) {\n return (\n <div className=\"flex min-h-screen items-center justify-center\">\n <div className=\"text-center space-y-4\">\n <div className=\"animate-spin rounded-full h-12 w-12 border-b-2 border-primary mx-auto\" />\n \n </div>\n </div>\n )\n }\n\n\nconst activeError = formError || authResponse\nconst showEmailVerificationButton =\n activeError?.error === \"EMAIL_NOT_VERIFIED\" || activeError?.error === \"REQUIRES_VERIFICATION\"\n\n return (\n <div className=\"relative flex items-center justify-center\">\n <AuthBackground />\n <Card className={cn(\"w-full max-w-md mx-auto mt-8\", className, customStyles.card)}>\n <CardHeader className=\"space-y-1 text-center\">\n <CardTitle className={cn(\"font-bold\", customStyles.title)}>Sign in to {`${appName}`} </CardTitle>\n <CardDescription className={cn(\"text-muted-foreground\", customStyles.description)}>\n Please sign in to continue\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n {activeError && (\n <Alert variant={getErrorAlertVariant(activeError)} className=\"animate-in fade-in-50\">\n <AlertDescription>\n <span>{activeError.message}</span>\n {showEmailVerificationButton && (\n <Button\n type='button'\n variant=\"link\"\n className=\"p-0 h-auto font-normal text-sm hover:underline\"\n onClick={handleVerificationRedirect}\n >\n Request new verification email →\n </Button>\n )}\n </AlertDescription>\n </Alert>\n )}\n <div className=\"space-y-2\">\n <Label htmlFor=\"email\" className={cn(customStyles.label)}>Email</Label>\n <Input\n id=\"email\"\n type=\"email\"\n placeholder=\"m@example.com\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n disabled={loading}\n className={cn(customStyles.input)}\n required\n aria-invalid={activeError?.error === \"INVALID_EMAIL\"}\n aria-describedby={activeError ? \"error-message\" : undefined}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"password\" className={cn(customStyles.label)}>Password</Label>\n <div className=\"relative\">\n <Input\n id=\"password\"\n name=\"password\"\n type={showPassword ? \"text\" : \"password\"}\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n onFocus={() => setPasswordFocused(true)}\n onBlur={() => setPasswordFocused(false)}\n disabled={loading}\n className={cn(customStyles.input)}\n required\n aria-invalid={activeError?.error === \"INVALID_CREDENTIALS\"}\n aria-describedby={activeError ? \"error-message\" : undefined}\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"absolute right-2 top-1/2 -translate-y-1/2 h-8 w-8 hover:bg-transparent\"\n onClick={() => setShowPassword(!showPassword)}\n >\n {showPassword ? (\n <EyeOff className=\"h-4 w-4 text-muted-foreground hover:text-foreground\" />\n ) : (\n <Eye className=\"h-4 w-4 text-muted-foreground hover:text-foreground\" />\n )}\n <span className=\"sr-only\">{showPassword ? \"Hide password\" : \"Show password\"}</span>\n </Button>\n </div>\n </div>\n <Button type=\"submit\" disabled={loading} className={cn(\"w-full\", customStyles.button)}>\n {loading ? (\n <>\n <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n Signing in...\n </>\n ) : (\n 'Sign in'\n )}\n </Button>\n </form>\n <div className=\"relative\">\n <Separator className={cn(customStyles.separator)} />\n <div className=\"absolute inset-0 flex items-center justify-center\">\n <span className=\"bg-background px-2 text-muted-foreground text-sm\">Or continue with</span>\n </div>\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <Button \n variant=\"outline\" \n disabled={loading} \n onClick={() => handleSocialSignIn('google')} \n className={cn(\"flex items-center justify-center\", customStyles.socialButton)}\n >\n <svg className=\"w-5 h-5 mr-2\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z\" fill=\"#4285F4\"/>\n <path d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\" fill=\"#34A853\"/>\n <path d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z\" fill=\"#FBBC05\"/>\n <path d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\" fill=\"#EA4335\"/>\n </svg>\n Google\n </Button>\n <Button \n variant=\"outline\" \n disabled={loading} \n onClick={() => handleSocialSignIn('microsoft')} \n className={cn(\"flex items-center justify-center\", customStyles.socialButton)}\n >\n <svg className=\"w-5 h-5 mr-2\" viewBox=\"0 0 23 23\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill=\"#f3f3f3\" d=\"M0 0h23v23H0z\"/>\n <path fill=\"#f35325\" d=\"M1 1h10v10H1z\"/>\n <path fill=\"#81bc06\" d=\"M12 1h10v10H12z\"/>\n <path fill=\"#05a6f0\" d=\"M1 12h10v10H1z\"/>\n <path fill=\"#ffba08\" d=\"M12 12h10v10H12z\"/>\n </svg>\n Microsoft\n </Button>\n </div>\n </CardContent>\n <CardFooter className=\"flex justify-center\">\n <p className=\"text-sm text-muted-foreground\">\n Don&apos;t have an account?{' '}\n <a href=\"/sign-up\" className=\"text-primary hover:underline\">\n Sign up\n </a>\n </p>\n </CardFooter>\n </Card>\n </div>\n )\n}\n\n"],"mappings":"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","names":["validRedirectUrl"]}
@@ -30,24 +30,33 @@ var import_button = require("./ui/button");
30
30
  var import_client_init = require("../utils/client-init");
31
31
  var import_sessionTernSecure = require("../app-router/server/sessionTernSecure");
32
32
  var import_utils = require("../lib/utils");
33
+ var import_construct = require("../utils/construct");
33
34
  function SignOutButton({
34
35
  children = "Sign out",
35
36
  onError,
36
37
  onSignOutSuccess,
38
+ redirectPath,
37
39
  className,
38
40
  variant = "outline",
39
41
  size = "default",
40
42
  ...buttonProps
41
43
  }) {
44
+ const pathname = (0, import_navigation.usePathname)();
42
45
  const router = (0, import_navigation.useRouter)();
43
46
  const [isLoading, setIsLoading] = (0, import_react.useState)(false);
47
+ const loginPath = process.env.NEXT_PUBLIC_LOGIN_PATH || "/sign-in";
44
48
  const handleSignOut = async () => {
45
49
  setIsLoading(true);
46
50
  try {
47
51
  await (0, import_auth.signOut)(import_client_init.ternSecureAuth);
48
52
  await (0, import_sessionTernSecure.clearSessionCookie)();
49
53
  onSignOutSuccess == null ? void 0 : onSignOutSuccess();
50
- router.push("/sign-in");
54
+ const loginUrl = (0, import_construct.constructUrlWithRedirect)(loginPath, pathname);
55
+ if (process.env.NODE_ENV === "production") {
56
+ window.location.href = loginUrl;
57
+ } else {
58
+ router.push(loginUrl);
59
+ }
51
60
  } catch (error) {
52
61
  console.error("Sign out error:", error);
53
62
  onError == null ? void 0 : onError(error instanceof Error ? error : new Error("Failed to sign out"));
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/sign-out-button.tsx"],"sourcesContent":["'use client'\n\nimport { useState } from 'react'\nimport { useRouter } from 'next/navigation'\nimport { signOut } from 'firebase/auth'\nimport { Button, type ButtonProps } from './ui/button'\nimport { ternSecureAuth } from '../utils/client-init'\nimport { clearSessionCookie } from '../app-router/server/sessionTernSecure'\nimport { cn } from '../lib/utils'\n\ntype SignOutCustomProps = {\n children?: React.ReactNode\n onError?: (error: Error) => void\n onSignOutSuccess?: () => void\n className?: string\n variant?: ButtonProps['variant']\n size?: ButtonProps['size']\n}\n\ntype SignOutProps = Omit<ButtonProps, 'onClick'> & SignOutCustomProps\n\nexport function SignOutButton({ \n children = 'Sign out', \n onError,\n onSignOutSuccess,\n className,\n variant = 'outline',\n size = 'default',\n ...buttonProps \n}: SignOutProps) {\n const router = useRouter()\n const [isLoading, setIsLoading] = useState(false)\n\n const handleSignOut = async () => {\n setIsLoading(true)\n try {\n // Sign out from Firebase\n await signOut(ternSecureAuth)\n \n await clearSessionCookie()\n \n // Call success callback if provided\n onSignOutSuccess?.()\n \n // Redirect to sign-in page\n router.push('/sign-in') //todo: singout and include a redirect URl\n } catch (error) {\n console.error('Sign out error:', error)\n onError?.(error instanceof Error ? error : new Error('Failed to sign out'))\n } finally {\n setIsLoading(false)\n }\n }\n\n return (\n <Button\n variant={variant}\n size={size}\n onClick={handleSignOut}\n disabled={isLoading}\n className={cn(\"\", className)}\n {...buttonProps}\n >\n {isLoading ? 'Signing out...' : children}\n </Button>\n )\n}\n\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAuDI;AArDJ,mBAAyB;AACzB,wBAA0B;AAC1B,kBAAwB;AACxB,oBAAyC;AACzC,yBAA+B;AAC/B,+BAAmC;AACnC,mBAAmB;AAaZ,SAAS,cAAc;AAAA,EAC5B,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,OAAO;AAAA,EACP,GAAG;AACL,GAAiB;AACf,QAAM,aAAS,6BAAU;AACzB,QAAM,CAAC,WAAW,YAAY,QAAI,uBAAS,KAAK;AAEhD,QAAM,gBAAgB,YAAY;AAChC,iBAAa,IAAI;AACjB,QAAI;AAEF,gBAAM,qBAAQ,iCAAc;AAE5B,gBAAM,6CAAmB;AAGzB;AAGA,aAAO,KAAK,UAAU;AAAA,IACxB,SAAS,OAAO;AACd,cAAQ,MAAM,mBAAmB,KAAK;AACtC,yCAAU,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,oBAAoB;AAAA,IAC3E,UAAE;AACA,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,SAAS;AAAA,MACT,UAAU;AAAA,MACV,eAAW,iBAAG,IAAI,SAAS;AAAA,MAC1B,GAAG;AAAA,MAEH,sBAAY,mBAAmB;AAAA;AAAA,EAClC;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/sign-out-button.tsx"],"sourcesContent":["'use client'\n\nimport { useState } from 'react'\nimport { usePathname, useRouter } from 'next/navigation'\nimport { signOut } from 'firebase/auth'\nimport { Button, type ButtonProps } from './ui/button'\nimport { ternSecureAuth } from '../utils/client-init'\nimport { clearSessionCookie } from '../app-router/server/sessionTernSecure'\nimport { cn } from '../lib/utils'\nimport { constructUrlWithRedirect } from '../utils/construct'\n\n\ntype SignOutCustomProps = {\n children?: React.ReactNode\n onError?: (error: Error) => void\n onSignOutSuccess?: () => void\n redirectPath?: string\n className?: string\n variant?: ButtonProps['variant']\n size?: ButtonProps['size']\n}\n\ntype SignOutProps = Omit<ButtonProps, 'onClick'> & SignOutCustomProps\n\nexport function SignOutButton({ \n children = 'Sign out', \n onError,\n onSignOutSuccess,\n redirectPath,\n className,\n variant = 'outline',\n size = 'default',\n ...buttonProps \n}: SignOutProps) {\n const pathname = usePathname()\n const router = useRouter()\n const [isLoading, setIsLoading] = useState(false)\n const loginPath = process.env.NEXT_PUBLIC_LOGIN_PATH || '/sign-in'\n\n const handleSignOut = async () => {\n setIsLoading(true)\n try {\n // Sign out from Firebase\n await signOut(ternSecureAuth)\n \n await clearSessionCookie()\n \n // Call success callback if provided\n onSignOutSuccess?.()\n\n // Construct login URL with redirect parameter\n const loginUrl = constructUrlWithRedirect(loginPath, pathname)\n\n // Use router for development and window.location for production\n if (process.env.NODE_ENV === \"production\") {\n window.location.href = loginUrl\n } else {\n router.push(loginUrl)\n }\n } catch (error) {\n console.error('Sign out error:', error)\n onError?.(error instanceof Error ? error : new Error('Failed to sign out'))\n } finally {\n setIsLoading(false)\n }\n }\n\n return (\n <Button\n variant={variant}\n size={size}\n onClick={handleSignOut}\n disabled={isLoading}\n className={cn(\"\", className)}\n {...buttonProps}\n >\n {isLoading ? 'Signing out...' : children}\n </Button>\n )\n}\n\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAoEI;AAlEJ,mBAAyB;AACzB,wBAAuC;AACvC,kBAAwB;AACxB,oBAAyC;AACzC,yBAA+B;AAC/B,+BAAmC;AACnC,mBAAmB;AACnB,uBAAyC;AAelC,SAAS,cAAc;AAAA,EAC5B,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,OAAO;AAAA,EACP,GAAG;AACL,GAAiB;AACf,QAAM,eAAW,+BAAY;AAC7B,QAAM,aAAS,6BAAU;AACzB,QAAM,CAAC,WAAW,YAAY,QAAI,uBAAS,KAAK;AAChD,QAAM,YAAY,QAAQ,IAAI,0BAA0B;AAExD,QAAM,gBAAgB,YAAY;AAChC,iBAAa,IAAI;AACjB,QAAI;AAEF,gBAAM,qBAAQ,iCAAc;AAE5B,gBAAM,6CAAmB;AAGzB;AAGA,YAAM,eAAW,2CAAyB,WAAW,QAAQ;AAG7D,UAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,eAAO,SAAS,OAAO;AAAA,MACzB,OAAO;AACL,eAAO,KAAK,QAAQ;AAAA,MACtB;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,mBAAmB,KAAK;AACtC,yCAAU,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,oBAAoB;AAAA,IAC3E,UAAE;AACA,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,SAAS;AAAA,MACT,UAAU;AAAA,MACV,eAAW,iBAAG,IAAI,SAAS;AAAA,MAC1B,GAAG;AAAA,MAEH,sBAAY,mBAAmB;AAAA;AAAA,EAClC;AAEJ;","names":[]}
@@ -40,16 +40,20 @@ var import_client_init = require("../utils/client-init");
40
40
  var import_sessionTernSecure = require("../app-router/server/sessionTernSecure");
41
41
  var import_utils = require("../lib/utils");
42
42
  var import_link = __toESM(require("next/link"));
43
+ var import_construct = require("../utils/construct");
43
44
  function SignOut({
44
45
  children = "Sign out",
45
46
  onError,
46
47
  onSignOutSuccess,
47
48
  className,
48
49
  activeClassName,
49
- disabled = false
50
+ disabled = false,
51
+ redirectPath
50
52
  }) {
51
- const router = (0, import_navigation.useRouter)();
52
53
  const [isLoading, setIsLoading] = (0, import_react.useState)(false);
54
+ const pathname = (0, import_navigation.usePathname)();
55
+ const router = (0, import_navigation.useRouter)();
56
+ const loginPath = process.env.NEXT_PUBLIC_LOGIN_PATH || "/sign-in";
53
57
  const handleSignOut = async (e) => {
54
58
  e.preventDefault();
55
59
  if (disabled || isLoading) return;
@@ -58,7 +62,12 @@ function SignOut({
58
62
  await (0, import_auth.signOut)(import_client_init.ternSecureAuth);
59
63
  await (0, import_sessionTernSecure.clearSessionCookie)();
60
64
  onSignOutSuccess == null ? void 0 : onSignOutSuccess();
61
- router.push("/sign-in");
65
+ const loginUrl = (0, import_construct.constructUrlWithRedirect)(loginPath, pathname);
66
+ if (process.env.NODE_ENV === "production") {
67
+ window.location.href = loginUrl;
68
+ } else {
69
+ router.push(loginUrl);
70
+ }
62
71
  } catch (error) {
63
72
  console.error("Sign out error:", error);
64
73
  onError == null ? void 0 : onError(error instanceof Error ? error : new Error("Failed to sign out"));
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/sign-out.tsx"],"sourcesContent":["'use client'\n\nimport { useState } from 'react'\nimport { useRouter } from 'next/navigation'\nimport { signOut } from 'firebase/auth'\nimport { ternSecureAuth } from '../utils/client-init'\nimport { clearSessionCookie } from '../app-router/server/sessionTernSecure'\nimport { cn } from '../lib/utils'\nimport Link from 'next/link'\n\ninterface SignOutLinkProps {\n children?: React.ReactNode\n onError?: (error: Error) => void\n onSignOutSuccess?: () => void\n className?: string\n activeClassName?: string\n disabled?: boolean\n}\n\nexport function SignOut({\n children = 'Sign out',\n onError,\n onSignOutSuccess,\n className,\n activeClassName,\n disabled = false,\n}: SignOutLinkProps) {\n const router = useRouter()\n const [isLoading, setIsLoading] = useState(false)\n\n const handleSignOut = async (e: React.MouseEvent<HTMLAnchorElement>) => {\n e.preventDefault()\n if (disabled || isLoading) return\n\n setIsLoading(true)\n try {\n await signOut(ternSecureAuth)\n await clearSessionCookie()\n onSignOutSuccess?.()\n router.push('/sign-in')\n } catch (error) {\n console.error('Sign out error:', error)\n onError?.(error instanceof Error ? error : new Error('Failed to sign out'))\n } finally {\n setIsLoading(false)\n }\n }\n\n return (\n <Link\n href=\"#\"\n onClick={handleSignOut}\n className={cn(\n 'text-sm font-medium transition-colors hover:text-primary',\n disabled && 'pointer-events-none opacity-50',\n isLoading && 'pointer-events-none',\n className,\n isLoading && activeClassName\n )}\n aria-disabled={disabled || isLoading}\n >\n {isLoading ? 'Signing out...' : children}\n </Link>\n )\n}"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAiDI;AA/CJ,mBAAyB;AACzB,wBAA0B;AAC1B,kBAAwB;AACxB,yBAA+B;AAC/B,+BAAmC;AACnC,mBAAmB;AACnB,kBAAiB;AAWV,SAAS,QAAQ;AAAA,EACtB,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AACb,GAAqB;AACnB,QAAM,aAAS,6BAAU;AACzB,QAAM,CAAC,WAAW,YAAY,QAAI,uBAAS,KAAK;AAEhD,QAAM,gBAAgB,OAAO,MAA2C;AACtE,MAAE,eAAe;AACjB,QAAI,YAAY,UAAW;AAE3B,iBAAa,IAAI;AACjB,QAAI;AACF,gBAAM,qBAAQ,iCAAc;AAC5B,gBAAM,6CAAmB;AACzB;AACA,aAAO,KAAK,UAAU;AAAA,IACxB,SAAS,OAAO;AACd,cAAQ,MAAM,mBAAmB,KAAK;AACtC,yCAAU,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,oBAAoB;AAAA,IAC3E,UAAE;AACA,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF;AAEA,SACE;AAAA,IAAC,YAAAA;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,SAAS;AAAA,MACT,eAAW;AAAA,QACT;AAAA,QACA,YAAY;AAAA,QACZ,aAAa;AAAA,QACb;AAAA,QACA,aAAa;AAAA,MACf;AAAA,MACA,iBAAe,YAAY;AAAA,MAE1B,sBAAY,mBAAmB;AAAA;AAAA,EAClC;AAEJ;","names":["Link"]}
1
+ {"version":3,"sources":["../../../src/components/sign-out.tsx"],"sourcesContent":["'use client'\n\nimport { useState } from 'react'\nimport { usePathname, useRouter } from 'next/navigation'\nimport { signOut } from 'firebase/auth'\nimport { ternSecureAuth } from '../utils/client-init'\nimport { clearSessionCookie } from '../app-router/server/sessionTernSecure'\nimport { cn } from '../lib/utils'\nimport Link from 'next/link'\nimport { constructUrlWithRedirect } from '../utils/construct'\n\n\ninterface SignOutLinkProps {\n children?: React.ReactNode\n onError?: (error: Error) => void\n onSignOutSuccess?: () => void\n className?: string\n activeClassName?: string\n disabled?: boolean\n redirectPath?: string\n}\n\nexport function SignOut({\n children = 'Sign out',\n onError,\n onSignOutSuccess,\n className,\n activeClassName,\n disabled = false,\n redirectPath,\n}: SignOutLinkProps) {\n const [isLoading, setIsLoading] = useState(false)\n const pathname = usePathname()\n const router = useRouter()\n const loginPath = process.env.NEXT_PUBLIC_LOGIN_PATH || \"/sign-in\"\n\n const handleSignOut = async (e: React.MouseEvent<HTMLAnchorElement>) => {\n e.preventDefault()\n if (disabled || isLoading) return\n\n setIsLoading(true)\n try {\n // Sign out from Firebase\n await signOut(ternSecureAuth)\n\n // Clear the session cookie\n await clearSessionCookie()\n\n // Call success callback if provided\n onSignOutSuccess?.()\n\n // Construct login URL with redirect parameter\n const loginUrl = constructUrlWithRedirect(loginPath, pathname)\n\n // Use router for development and window.location for production\n if (process.env.NODE_ENV === \"production\") {\n window.location.href = loginUrl\n } else {\n router.push(loginUrl)\n }\n } catch (error) {\n console.error('Sign out error:', error)\n onError?.(error instanceof Error ? error : new Error('Failed to sign out'))\n } finally {\n setIsLoading(false)\n }\n }\n\n return (\n <Link\n href=\"#\"\n onClick={handleSignOut}\n className={cn(\n 'text-sm font-medium transition-colors hover:text-primary',\n disabled && 'pointer-events-none opacity-50',\n isLoading && 'pointer-events-none',\n className,\n isLoading && activeClassName\n )}\n aria-disabled={disabled || isLoading}\n >\n {isLoading ? 'Signing out...' : children}\n </Link>\n )\n}"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAqEI;AAnEJ,mBAAyB;AACzB,wBAAuC;AACvC,kBAAwB;AACxB,yBAA+B;AAC/B,+BAAmC;AACnC,mBAAmB;AACnB,kBAAiB;AACjB,uBAAyC;AAalC,SAAS,QAAQ;AAAA,EACtB,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AACF,GAAqB;AACnB,QAAM,CAAC,WAAW,YAAY,QAAI,uBAAS,KAAK;AAChD,QAAM,eAAW,+BAAY;AAC7B,QAAM,aAAS,6BAAU;AACzB,QAAM,YAAY,QAAQ,IAAI,0BAA0B;AAExD,QAAM,gBAAgB,OAAO,MAA2C;AACtE,MAAE,eAAe;AACjB,QAAI,YAAY,UAAW;AAE3B,iBAAa,IAAI;AACjB,QAAI;AAEF,gBAAM,qBAAQ,iCAAc;AAG5B,gBAAM,6CAAmB;AAGzB;AAGA,YAAM,eAAW,2CAAyB,WAAW,QAAQ;AAG7D,UAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,eAAO,SAAS,OAAO;AAAA,MACzB,OAAO;AACL,eAAO,KAAK,QAAQ;AAAA,MACtB;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,mBAAmB,KAAK;AACtC,yCAAU,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,oBAAoB;AAAA,IAC3E,UAAE;AACA,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF;AAEA,SACE;AAAA,IAAC,YAAAA;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,SAAS;AAAA,MACT,eAAW;AAAA,QACT;AAAA,QACA,YAAY;AAAA,QACZ,aAAa;AAAA,QACb;AAAA,QACA,aAAa;AAAA,MACf;AAAA,MACA,iBAAe,YAAY;AAAA,MAE1B,sBAAY,mBAAmB;AAAA;AAAA,EAClC;AAEJ;","names":["Link"]}
@@ -48,6 +48,7 @@ var import_separator = require("./ui/separator");
48
48
  var import_actions = require("../app-router/client/actions");
49
49
  var import_useSignUp = require("../boundary/hooks/useSignUp");
50
50
  var import_internal_route = require("../app-router/route-handler/internal-route");
51
+ var import_errors = require("../errors");
51
52
  function SignUp({
52
53
  redirectUrl,
53
54
  onError,
@@ -55,10 +56,10 @@ function SignUp({
55
56
  }) {
56
57
  const pathname = (0, import_navigation.usePathname)();
57
58
  const InternalComponent = (0, import_internal_route.handleInternalRoute)(pathname);
59
+ const { setEmail: setContextEmail } = (0, import_useSignUp.useSignUp)();
58
60
  if (InternalComponent) {
59
61
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InternalComponent, {});
60
62
  }
61
- const { setEmail: setContextEmail } = (0, import_useSignUp.useSignUp)();
62
63
  const [formData, setFormData] = (0, import_react.useState)({
63
64
  email: "",
64
65
  password: "",
@@ -67,7 +68,7 @@ function SignUp({
67
68
  const [showPassword, setShowPassword] = (0, import_react.useState)(false);
68
69
  const [showConfirmPassword, setShowConfirmPassword] = (0, import_react.useState)(false);
69
70
  const [isLoading, setLoading] = (0, import_react.useState)(false);
70
- const [error, setError] = (0, import_react.useState)("");
71
+ const [error, setError] = (0, import_react.useState)(null);
71
72
  const [passwordFocused, setPasswordFocused] = (0, import_react.useState)(false);
72
73
  const router = (0, import_navigation.useRouter)();
73
74
  const passwordRequirements = [
@@ -102,6 +103,7 @@ function SignUp({
102
103
  ...prev,
103
104
  [name]: value
104
105
  }));
106
+ setError(null);
105
107
  };
106
108
  const isFormValid = () => {
107
109
  return formData.email.length > 0 && passwordRequirements.every((req) => req.satisfied);
@@ -110,15 +112,18 @@ function SignUp({
110
112
  e.preventDefault();
111
113
  if (!isFormValid()) return;
112
114
  setLoading(true);
115
+ setError(null);
113
116
  try {
114
117
  const result = await (0, import_actions.createUser)(formData.email, formData.password);
115
118
  if (result.success) {
116
119
  setContextEmail(formData.email);
117
120
  onSuccess == null ? void 0 : onSuccess();
118
121
  router.push(`sign-up/verify`);
122
+ } else {
123
+ setError(result);
119
124
  }
120
125
  } catch (error2) {
121
- const errorMessage = error2 instanceof Error ? error2.message : "Failed to sign in";
126
+ const errorMessage = error2;
122
127
  setError(errorMessage);
123
128
  onError == null ? void 0 : onError(error2 instanceof Error ? error2 : new Error("Failed to create account"));
124
129
  } finally {
@@ -136,7 +141,7 @@ function SignUp({
136
141
  throw new Error(result.error);
137
142
  }
138
143
  } catch (err) {
139
- const errorMessage = err instanceof Error ? err.message : `Failed to sign in with ${provider}`;
144
+ const errorMessage = err;
140
145
  setError(errorMessage);
141
146
  const newUrl = new URL(window.location.href);
142
147
  newUrl.searchParams.delete("signInRedirect");
@@ -152,7 +157,7 @@ function SignUp({
152
157
  ] }),
153
158
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { onSubmit: handleSubmit, children: [
154
159
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_card.CardContent, { className: "space-y-4", children: [
155
- error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_alert.Alert, { variant: "destructive", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_alert.AlertDescription, { children: error }) }),
160
+ error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_alert.Alert, { variant: (0, import_errors.getErrorAlertVariant)(error), className: "animate-in fade-in-50", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_alert.AlertDescription, { children: error.message }) }),
156
161
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-2", children: [
157
162
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_label.Label, { htmlFor: "email", children: "Email" }),
158
163
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(