@tern-secure/nextjs 3.4.3 → 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.
- package/dist/cjs/app-router/client/TernSecureProvider.js +17 -2
- package/dist/cjs/app-router/client/TernSecureProvider.js.map +1 -1
- package/dist/cjs/app-router/client/actions.js +55 -55
- package/dist/cjs/app-router/client/actions.js.map +1 -1
- package/dist/cjs/app-router/route-handler/internal-route.js +22 -3
- package/dist/cjs/app-router/route-handler/internal-route.js.map +1 -1
- package/dist/cjs/boundary/TernSecureClientProvider.js +167 -34
- package/dist/cjs/boundary/TernSecureClientProvider.js.map +1 -1
- package/dist/cjs/boundary/TernSecureCtx.js.map +1 -1
- package/dist/cjs/boundary/hooks/useAuth.js +15 -2
- package/dist/cjs/boundary/hooks/useAuth.js.map +1 -1
- package/dist/cjs/components/sign-in.js +158 -35
- package/dist/cjs/components/sign-in.js.map +1 -1
- package/dist/cjs/components/sign-out-button.js +84 -0
- package/dist/cjs/components/sign-out-button.js.map +1 -0
- package/dist/cjs/components/sign-out.js +39 -9
- package/dist/cjs/components/sign-out.js.map +1 -1
- package/dist/cjs/components/sign-up.js +10 -5
- package/dist/cjs/components/sign-up.js.map +1 -1
- package/dist/cjs/errors.js +233 -5
- package/dist/cjs/errors.js.map +1 -1
- package/dist/cjs/index.js +3 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types.js +14 -0
- package/dist/cjs/types.js.map +1 -1
- package/dist/cjs/utils/construct.js +50 -18
- package/dist/cjs/utils/construct.js.map +1 -1
- package/dist/cjs/utils/redirect.js +57 -0
- package/dist/cjs/utils/redirect.js.map +1 -0
- package/dist/esm/app-router/client/TernSecureProvider.js +17 -2
- package/dist/esm/app-router/client/TernSecureProvider.js.map +1 -1
- package/dist/esm/app-router/client/actions.js +64 -56
- package/dist/esm/app-router/client/actions.js.map +1 -1
- package/dist/esm/app-router/route-handler/internal-route.js +18 -2
- package/dist/esm/app-router/route-handler/internal-route.js.map +1 -1
- package/dist/esm/boundary/TernSecureClientProvider.js +168 -35
- package/dist/esm/boundary/TernSecureClientProvider.js.map +1 -1
- package/dist/esm/boundary/TernSecureCtx.js.map +1 -1
- package/dist/esm/boundary/hooks/useAuth.js +15 -2
- package/dist/esm/boundary/hooks/useAuth.js.map +1 -1
- package/dist/esm/components/sign-in.js +160 -37
- package/dist/esm/components/sign-in.js.map +1 -1
- package/dist/esm/components/sign-out-button.js +60 -0
- package/dist/esm/components/sign-out-button.js.map +1 -0
- package/dist/esm/components/sign-out.js +30 -10
- package/dist/esm/components/sign-out.js.map +1 -1
- package/dist/esm/components/sign-up.js +10 -5
- package/dist/esm/components/sign-up.js.map +1 -1
- package/dist/esm/errors.js +229 -4
- package/dist/esm/errors.js.map +1 -1
- package/dist/esm/index.js +2 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types.js +6 -0
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/utils/construct.js +46 -17
- package/dist/esm/utils/construct.js.map +1 -1
- package/dist/esm/utils/redirect.js +32 -0
- package/dist/esm/utils/redirect.js.map +1 -0
- package/dist/types/app-router/client/TernSecureProvider.d.ts +14 -3
- package/dist/types/app-router/client/TernSecureProvider.d.ts.map +1 -1
- package/dist/types/app-router/client/actions.d.ts +24 -18
- package/dist/types/app-router/client/actions.d.ts.map +1 -1
- package/dist/types/app-router/route-handler/internal-route.d.ts +8 -1
- package/dist/types/app-router/route-handler/internal-route.d.ts.map +1 -1
- package/dist/types/boundary/TernSecureClientProvider.d.ts +17 -1
- package/dist/types/boundary/TernSecureClientProvider.d.ts.map +1 -1
- package/dist/types/boundary/TernSecureCtx.d.ts +3 -8
- package/dist/types/boundary/TernSecureCtx.d.ts.map +1 -1
- package/dist/types/boundary/hooks/useAuth.d.ts +6 -1
- package/dist/types/boundary/hooks/useAuth.d.ts.map +1 -1
- package/dist/types/components/sign-in.d.ts.map +1 -1
- package/dist/types/components/sign-out-button.d.ts +14 -0
- package/dist/types/components/sign-out-button.d.ts.map +1 -0
- package/dist/types/components/sign-out.d.ts +7 -5
- package/dist/types/components/sign-out.d.ts.map +1 -1
- package/dist/types/components/sign-up.d.ts +4 -0
- package/dist/types/components/sign-up.d.ts.map +1 -1
- package/dist/types/components/ui/alert.d.ts +1 -1
- package/dist/types/components/ui/button.d.ts +1 -1
- package/dist/types/errors.d.ts +37 -2
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/types.d.ts +45 -0
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/utils/construct.d.ts +20 -4
- package/dist/types/utils/construct.d.ts.map +1 -1
- package/dist/types/utils/redirect.d.ts +9 -0
- package/dist/types/utils/redirect.d.ts.map +1 -0
- package/package.json +6 -6
- package/dist/cjs/boundary/hooks/useUser.js +0 -44
- package/dist/cjs/boundary/hooks/useUser.js.map +0 -1
- package/dist/esm/boundary/hooks/useUser.js +0 -20
- package/dist/esm/boundary/hooks/useUser.js.map +0 -1
- package/dist/types/boundary/hooks/useUser.d.ts +0 -7
- package/dist/types/boundary/hooks/useUser.d.ts.map +0 -1
|
@@ -39,6 +39,9 @@ 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_internal_route = require("../app-router/route-handler/internal-route");
|
|
43
|
+
var import_useAuth = require("../boundary/hooks/useAuth");
|
|
44
|
+
var import_errors = require("../errors");
|
|
42
45
|
const authDomain = process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN;
|
|
43
46
|
const appName = process.env.NEXT_PUBLIC_FIREBASE_APP_NAME || "TernSecure";
|
|
44
47
|
function SignIn({
|
|
@@ -50,11 +53,65 @@ function SignIn({
|
|
|
50
53
|
}) {
|
|
51
54
|
const [loading, setLoading] = (0, import_react.useState)(false);
|
|
52
55
|
const [checkingRedirect, setCheckingRedirect] = (0, import_react.useState)(true);
|
|
56
|
+
const [formError, setFormError] = (0, import_react.useState)(null);
|
|
53
57
|
const [error, setError] = (0, import_react.useState)("");
|
|
54
58
|
const [email, setEmail] = (0, import_react.useState)("");
|
|
55
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);
|
|
62
|
+
const [authResponse, setAuthResponse] = (0, import_react.useState)(null);
|
|
63
|
+
const [authErrorMessage, setAuthErrorMessage] = (0, import_react.useState)(null);
|
|
56
64
|
const searchParams = (0, import_navigation.useSearchParams)();
|
|
57
65
|
const isRedirectSignIn = searchParams.get("signInRedirect") === "true";
|
|
66
|
+
const router = (0, import_navigation.useRouter)();
|
|
67
|
+
const pathname = (0, import_navigation.usePathname)();
|
|
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);
|
|
71
|
+
if (InternalComponent) {
|
|
72
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InternalComponent, {});
|
|
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
|
+
);
|
|
58
115
|
const handleRedirectResult = (0, import_react.useCallback)(async () => {
|
|
59
116
|
if (!isRedirectSignIn) return false;
|
|
60
117
|
setCheckingRedirect(true);
|
|
@@ -75,15 +132,16 @@ function SignIn({
|
|
|
75
132
|
const storedRedirectUrl = sessionStorage.getItem("auth_return_url");
|
|
76
133
|
sessionStorage.removeItem("auth_redirect_url");
|
|
77
134
|
onSuccess == null ? void 0 : onSuccess();
|
|
78
|
-
window.location.href = storedRedirectUrl || (0, import_construct.getValidRedirectUrl)(
|
|
135
|
+
window.location.href = storedRedirectUrl || (0, import_construct.getValidRedirectUrl)(searchParams, redirectUrl);
|
|
79
136
|
return true;
|
|
80
137
|
}
|
|
81
138
|
setCheckingRedirect(false);
|
|
82
139
|
} catch (err) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
140
|
+
const errorMessage = err;
|
|
141
|
+
setFormError(errorMessage);
|
|
142
|
+
if (onError && err instanceof Error) {
|
|
143
|
+
onError(err);
|
|
144
|
+
}
|
|
87
145
|
sessionStorage.removeItem("auth_redirect_url");
|
|
88
146
|
return false;
|
|
89
147
|
}
|
|
@@ -92,21 +150,42 @@ function SignIn({
|
|
|
92
150
|
if (isRedirectSignIn) {
|
|
93
151
|
handleRedirectResult();
|
|
94
152
|
}
|
|
95
|
-
;
|
|
96
153
|
}, [handleRedirectResult, isRedirectSignIn]);
|
|
97
154
|
const handleSubmit = async (e) => {
|
|
98
155
|
e.preventDefault();
|
|
99
156
|
setLoading(true);
|
|
157
|
+
setFormError(null);
|
|
158
|
+
setAuthResponse(null);
|
|
100
159
|
try {
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
160
|
+
const response = await (0, import_actions.signInWithEmail)(email, password);
|
|
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
|
+
}
|
|
171
|
+
if (response.user) {
|
|
172
|
+
if (requiresVerification && !response.user.emailVerified) {
|
|
173
|
+
setFormError({
|
|
174
|
+
success: false,
|
|
175
|
+
message: "Email verification required",
|
|
176
|
+
error: "REQUIRES_VERIFICATION",
|
|
177
|
+
user: response.user
|
|
178
|
+
});
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
await handleSuccessfulAuth(response.user);
|
|
105
182
|
}
|
|
106
183
|
} catch (err) {
|
|
107
|
-
const errorMessage = err
|
|
108
|
-
|
|
109
|
-
onError
|
|
184
|
+
const errorMessage = err;
|
|
185
|
+
setFormError(errorMessage);
|
|
186
|
+
if (onError && err instanceof Error) {
|
|
187
|
+
onError(err);
|
|
188
|
+
}
|
|
110
189
|
} finally {
|
|
111
190
|
setLoading(false);
|
|
112
191
|
}
|
|
@@ -114,8 +193,8 @@ function SignIn({
|
|
|
114
193
|
const handleSocialSignIn = async (provider) => {
|
|
115
194
|
setLoading(true);
|
|
116
195
|
try {
|
|
117
|
-
const
|
|
118
|
-
sessionStorage.setItem("auth_redirect_url",
|
|
196
|
+
const validRedirectUrl2 = (0, import_construct.getValidRedirectUrl)(searchParams, redirectUrl);
|
|
197
|
+
sessionStorage.setItem("auth_redirect_url", validRedirectUrl2);
|
|
119
198
|
const currentUrl = new URL(window.location.href);
|
|
120
199
|
currentUrl.searchParams.set("signInRedirect", "true");
|
|
121
200
|
window.history.replaceState({}, "", currentUrl.toString());
|
|
@@ -124,29 +203,50 @@ function SignIn({
|
|
|
124
203
|
throw new Error(result.error);
|
|
125
204
|
}
|
|
126
205
|
} catch (err) {
|
|
127
|
-
const errorMessage = err
|
|
128
|
-
|
|
129
|
-
onError
|
|
206
|
+
const errorMessage = err;
|
|
207
|
+
setFormError(errorMessage);
|
|
208
|
+
if (onError && err instanceof Error) {
|
|
209
|
+
onError(err);
|
|
210
|
+
}
|
|
130
211
|
setLoading(false);
|
|
131
212
|
sessionStorage.removeItem("auth_redirect_url");
|
|
132
213
|
}
|
|
133
214
|
};
|
|
215
|
+
const handleVerificationRedirect = (e) => {
|
|
216
|
+
e.preventDefault();
|
|
217
|
+
router.push("/sign-in/verify");
|
|
218
|
+
};
|
|
134
219
|
if (checkingRedirect && isRedirectSignIn) {
|
|
135
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" }) }) });
|
|
136
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";
|
|
137
224
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative flex items-center justify-center", children: [
|
|
138
225
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_background.AuthBackground, {}),
|
|
139
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: [
|
|
140
227
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_card.CardHeader, { className: "space-y-1 text-center", children: [
|
|
141
228
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_card.CardTitle, { className: (0, import_utils.cn)("font-bold", customStyles.title), children: [
|
|
142
229
|
"Sign in to ",
|
|
143
|
-
`${appName}
|
|
230
|
+
`${appName}`,
|
|
231
|
+
" "
|
|
144
232
|
] }),
|
|
145
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" })
|
|
146
234
|
] }),
|
|
147
235
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_card.CardContent, { className: "space-y-4", children: [
|
|
148
236
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
|
|
149
|
-
|
|
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)(
|
|
240
|
+
import_button.Button,
|
|
241
|
+
{
|
|
242
|
+
type: "button",
|
|
243
|
+
variant: "link",
|
|
244
|
+
className: "p-0 h-auto font-normal text-sm hover:underline",
|
|
245
|
+
onClick: handleVerificationRedirect,
|
|
246
|
+
children: "Request new verification email \u2192"
|
|
247
|
+
}
|
|
248
|
+
)
|
|
249
|
+
] }) }),
|
|
150
250
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-2", children: [
|
|
151
251
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_label.Label, { htmlFor: "email", className: (0, import_utils.cn)(customStyles.label), children: "Email" }),
|
|
152
252
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -159,24 +259,47 @@ function SignIn({
|
|
|
159
259
|
onChange: (e) => setEmail(e.target.value),
|
|
160
260
|
disabled: loading,
|
|
161
261
|
className: (0, import_utils.cn)(customStyles.input),
|
|
162
|
-
required: true
|
|
262
|
+
required: true,
|
|
263
|
+
"aria-invalid": (activeError == null ? void 0 : activeError.error) === "INVALID_EMAIL",
|
|
264
|
+
"aria-describedby": activeError ? "error-message" : void 0
|
|
163
265
|
}
|
|
164
266
|
)
|
|
165
267
|
] }),
|
|
166
268
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-2", children: [
|
|
167
269
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_label.Label, { htmlFor: "password", className: (0, import_utils.cn)(customStyles.label), children: "Password" }),
|
|
168
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
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
|
+
] })
|
|
180
303
|
] }),
|
|
181
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: [
|
|
182
305
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
|
|
@@ -184,8 +307,8 @@ function SignIn({
|
|
|
184
307
|
] }) : "Sign in" })
|
|
185
308
|
] }),
|
|
186
309
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative", children: [
|
|
187
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
188
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "
|
|
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" }) })
|
|
189
312
|
] }),
|
|
190
313
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
191
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 } 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 } 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'\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\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 [error, setError] = useState('')\n const [email, setEmail] = useState('')\n const [password, setPassword] = useState('')\n const searchParams = useSearchParams()\n const isRedirectSignIn = searchParams.get('signInRedirect') === 'true'\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 try {\n const user = await signInWithEmail(email, password)\n if (user.success) {\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=\"destructive\">\n <AlertDescription>{error}</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'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'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"]}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
var sign_out_button_exports = {};
|
|
21
|
+
__export(sign_out_button_exports, {
|
|
22
|
+
SignOutButton: () => SignOutButton
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(sign_out_button_exports);
|
|
25
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
26
|
+
var import_react = require("react");
|
|
27
|
+
var import_navigation = require("next/navigation");
|
|
28
|
+
var import_auth = require("firebase/auth");
|
|
29
|
+
var import_button = require("./ui/button");
|
|
30
|
+
var import_client_init = require("../utils/client-init");
|
|
31
|
+
var import_sessionTernSecure = require("../app-router/server/sessionTernSecure");
|
|
32
|
+
var import_utils = require("../lib/utils");
|
|
33
|
+
var import_construct = require("../utils/construct");
|
|
34
|
+
function SignOutButton({
|
|
35
|
+
children = "Sign out",
|
|
36
|
+
onError,
|
|
37
|
+
onSignOutSuccess,
|
|
38
|
+
redirectPath,
|
|
39
|
+
className,
|
|
40
|
+
variant = "outline",
|
|
41
|
+
size = "default",
|
|
42
|
+
...buttonProps
|
|
43
|
+
}) {
|
|
44
|
+
const pathname = (0, import_navigation.usePathname)();
|
|
45
|
+
const router = (0, import_navigation.useRouter)();
|
|
46
|
+
const [isLoading, setIsLoading] = (0, import_react.useState)(false);
|
|
47
|
+
const loginPath = process.env.NEXT_PUBLIC_LOGIN_PATH || "/sign-in";
|
|
48
|
+
const handleSignOut = async () => {
|
|
49
|
+
setIsLoading(true);
|
|
50
|
+
try {
|
|
51
|
+
await (0, import_auth.signOut)(import_client_init.ternSecureAuth);
|
|
52
|
+
await (0, import_sessionTernSecure.clearSessionCookie)();
|
|
53
|
+
onSignOutSuccess == null ? void 0 : onSignOutSuccess();
|
|
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
|
+
}
|
|
60
|
+
} catch (error) {
|
|
61
|
+
console.error("Sign out error:", error);
|
|
62
|
+
onError == null ? void 0 : onError(error instanceof Error ? error : new Error("Failed to sign out"));
|
|
63
|
+
} finally {
|
|
64
|
+
setIsLoading(false);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
68
|
+
import_button.Button,
|
|
69
|
+
{
|
|
70
|
+
variant,
|
|
71
|
+
size,
|
|
72
|
+
onClick: handleSignOut,
|
|
73
|
+
disabled: isLoading,
|
|
74
|
+
className: (0, import_utils.cn)("", className),
|
|
75
|
+
...buttonProps,
|
|
76
|
+
children: isLoading ? "Signing out..." : children
|
|
77
|
+
}
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
81
|
+
0 && (module.exports = {
|
|
82
|
+
SignOutButton
|
|
83
|
+
});
|
|
84
|
+
//# sourceMappingURL=sign-out-button.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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":[]}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
"use client";
|
|
3
|
+
var __create = Object.create;
|
|
3
4
|
var __defProp = Object.defineProperty;
|
|
4
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
9
|
var __export = (target, all) => {
|
|
8
10
|
for (var name in all)
|
|
@@ -16,6 +18,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
18
|
}
|
|
17
19
|
return to;
|
|
18
20
|
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
19
29
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
30
|
var sign_out_exports = {};
|
|
21
31
|
__export(sign_out_exports, {
|
|
@@ -26,24 +36,38 @@ var import_jsx_runtime = require("react/jsx-runtime");
|
|
|
26
36
|
var import_react = require("react");
|
|
27
37
|
var import_navigation = require("next/navigation");
|
|
28
38
|
var import_auth = require("firebase/auth");
|
|
29
|
-
var import_button = require("./ui/button");
|
|
30
39
|
var import_client_init = require("../utils/client-init");
|
|
31
40
|
var import_sessionTernSecure = require("../app-router/server/sessionTernSecure");
|
|
41
|
+
var import_utils = require("../lib/utils");
|
|
42
|
+
var import_link = __toESM(require("next/link"));
|
|
43
|
+
var import_construct = require("../utils/construct");
|
|
32
44
|
function SignOut({
|
|
33
45
|
children = "Sign out",
|
|
34
46
|
onError,
|
|
35
47
|
onSignOutSuccess,
|
|
36
|
-
|
|
48
|
+
className,
|
|
49
|
+
activeClassName,
|
|
50
|
+
disabled = false,
|
|
51
|
+
redirectPath
|
|
37
52
|
}) {
|
|
38
|
-
const router = (0, import_navigation.useRouter)();
|
|
39
53
|
const [isLoading, setIsLoading] = (0, import_react.useState)(false);
|
|
40
|
-
const
|
|
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";
|
|
57
|
+
const handleSignOut = async (e) => {
|
|
58
|
+
e.preventDefault();
|
|
59
|
+
if (disabled || isLoading) return;
|
|
41
60
|
setIsLoading(true);
|
|
42
61
|
try {
|
|
43
62
|
await (0, import_auth.signOut)(import_client_init.ternSecureAuth);
|
|
44
63
|
await (0, import_sessionTernSecure.clearSessionCookie)();
|
|
45
64
|
onSignOutSuccess == null ? void 0 : onSignOutSuccess();
|
|
46
|
-
|
|
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
|
+
}
|
|
47
71
|
} catch (error) {
|
|
48
72
|
console.error("Sign out error:", error);
|
|
49
73
|
onError == null ? void 0 : onError(error instanceof Error ? error : new Error("Failed to sign out"));
|
|
@@ -52,12 +76,18 @@ function SignOut({
|
|
|
52
76
|
}
|
|
53
77
|
};
|
|
54
78
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
55
|
-
|
|
79
|
+
import_link.default,
|
|
56
80
|
{
|
|
57
|
-
|
|
81
|
+
href: "#",
|
|
58
82
|
onClick: handleSignOut,
|
|
59
|
-
|
|
60
|
-
|
|
83
|
+
className: (0, import_utils.cn)(
|
|
84
|
+
"text-sm font-medium transition-colors hover:text-primary",
|
|
85
|
+
disabled && "pointer-events-none opacity-50",
|
|
86
|
+
isLoading && "pointer-events-none",
|
|
87
|
+
className,
|
|
88
|
+
isLoading && activeClassName
|
|
89
|
+
),
|
|
90
|
+
"aria-disabled": disabled || isLoading,
|
|
61
91
|
children: isLoading ? "Signing out..." : children
|
|
62
92
|
}
|
|
63
93
|
);
|
|
@@ -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 {
|
|
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"]}
|