@burdenoff/microfe-auth 2026.528.1 → 2026.528.3
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/auth/hooks/useMfaOperations.js.map +1 -1
- package/dist/auth/pages/LoginPage.js +124 -117
- package/dist/auth/pages/LoginPage.js.map +1 -1
- package/dist/auth/pages/MfaVerifyPage.js +10 -10
- package/dist/auth/pages/SsoConfigPage.js +59 -85
- package/dist/auth/pages/SsoConfigPage.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMfaOperations.js","names":[],"sources":["../../../src/auth/hooks/useMfaOperations.ts"],"sourcesContent":["import { useMutation } from \"@apollo/client/react\";\nimport { useEventBus } from \"@burdenoff/fe-libs/shared/events\";\nimport {\n loginProfile,\n type ProfileUser,\n} from \"@burdenoff/fe-libs/shared/providers/shell/ProfileStorageManager\";\nimport { useAuthStore } from \"../store/authStore\";\nimport { useAuth } from \"../providers/AuthProvider\";\nimport {\n SetupMfaDocument,\n EnableMfaDocument,\n VerifyMfaDocument,\n DisableMfaDocument,\n} from \"../../generated/global-operations\";\nimport type {\n MFAMethod,\n MFASetupResult,\n MFAVerifyInput,\n AuthResult,\n User,\n} from \"../types\";\n\nfunction toProfileUser(user: User): ProfileUser {\n return { ...user };\n}\n\nfunction setShellSsoCookie(userId: string): void {\n try {\n const hostname = window.location.hostname;\n const domain = hostname.endsWith(\".local.burdenoff.com\")\n ? \".local.burdenoff.com\"\n : undefined;\n const domainPart = domain ? `; domain=${domain}` : \"\";\n const securePart = window.location.protocol === \"https:\" ? \"; secure\" : \"\";\n const ssoValue = JSON.stringify({\n id: userId,\n origin: window.location.origin,\n });\n document.cookie = `bf-sso=${encodeURIComponent(ssoValue)}${domainPart}; path=/; samesite=lax${securePart}; max-age=86400`;\n document.cookie = `bf-sso-profile=${encodeURIComponent(ssoValue)}${domainPart}; path=/; samesite=lax${securePart}; max-age=86400`;\n } catch {\n // Best effort only.\n }\n}\n\n// =============================================================================\n// GRAPHQL RESPONSE INTERFACES\n// =============================================================================\n\ninterface SetupMFAResponse {\n setupMFA: MFASetupResult;\n}\n\ninterface SetupMFAVariables {\n method: MFAMethod;\n}\n\ninterface EnableMFAResponse {\n enableMFA: boolean;\n}\n\ninterface EnableMFAVariables {\n code: string;\n}\n\ninterface VerifyMFAResponse {\n verifyMFA: AuthResult;\n}\n\ninterface VerifyMFAVariables {\n input: MFAVerifyInput;\n}\n\ninterface DisableMFAResponse {\n disableMFA: boolean;\n}\n\n// GraphQL Operations\n\n/**\n * Hook for MFA operations\n */\nexport function useMfaOperations() {\n const store = useAuthStore();\n const context = useAuth();\n const eventBus = useEventBus();\n const [setupMfaMutation] = useMutation<SetupMFAResponse, SetupMFAVariables>(\n SetupMfaDocument,\n );\n const [enableMfaMutation] = useMutation<\n EnableMFAResponse,\n EnableMFAVariables\n >(EnableMfaDocument);\n const [verifyMfaMutation] = useMutation<\n VerifyMFAResponse,\n VerifyMFAVariables\n >(VerifyMfaDocument);\n const [disableMfaMutation] =\n useMutation<DisableMFAResponse>(DisableMfaDocument);\n\n /**\n * Setup MFA for the user\n */\n const setupMFA = async (method: MFAMethod): Promise<MFASetupResult> => {\n try {\n store.setLoading(true);\n\n const { data } = await setupMfaMutation({\n variables: { method },\n });\n\n return data!.setupMFA;\n } catch (error) {\n if (import.meta.env.DEV) {\n console.error(\"MFA setup failed:\", error);\n }\n throw error;\n } finally {\n store.setLoading(false);\n }\n };\n\n /**\n * Enable MFA after setup with verification code\n */\n const enableMFA = async (code: string): Promise<boolean> => {\n try {\n store.setLoading(true);\n\n const { data } = await enableMfaMutation({\n variables: { code },\n });\n\n if (data!.enableMFA && store.user) {\n store.setUser({ ...store.user, mfaEnabled: true });\n }\n\n return data!.enableMFA;\n } catch (error) {\n if (import.meta.env.DEV) {\n console.error(\"Failed to enable MFA:\", error);\n }\n throw error;\n } finally {\n store.setLoading(false);\n }\n };\n\n /**\n * Verify MFA code during login\n */\n const verifyMFA = async (input: MFAVerifyInput): Promise<AuthResult> => {\n try {\n store.setLoading(true);\n\n const { data, error } = await verifyMfaMutation({\n variables: { input },\n });\n\n const result = data?.verifyMFA;\n\n // Server returned no data (GraphQL errors, network failure, or null payload).\n // Surface a friendly message instead of letting `result.success` throw a\n // \"Cannot read properties of null\" error to the UI.\n if (!result) {\n return {\n success: false,\n error
|
|
1
|
+
{"version":3,"file":"useMfaOperations.js","names":[],"sources":["../../../src/auth/hooks/useMfaOperations.ts"],"sourcesContent":["import { useMutation } from \"@apollo/client/react\";\nimport { useEventBus } from \"@burdenoff/fe-libs/shared/events\";\nimport {\n loginProfile,\n type ProfileUser,\n} from \"@burdenoff/fe-libs/shared/providers/shell/ProfileStorageManager\";\nimport { useAuthStore } from \"../store/authStore\";\nimport { useAuth } from \"../providers/AuthProvider\";\nimport {\n SetupMfaDocument,\n EnableMfaDocument,\n VerifyMfaDocument,\n DisableMfaDocument,\n} from \"../../generated/global-operations\";\nimport type {\n MFAMethod,\n MFASetupResult,\n MFAVerifyInput,\n AuthResult,\n User,\n} from \"../types\";\n\nfunction toProfileUser(user: User): ProfileUser {\n return { ...user };\n}\n\nfunction setShellSsoCookie(userId: string): void {\n try {\n const hostname = window.location.hostname;\n const domain = hostname.endsWith(\".local.burdenoff.com\")\n ? \".local.burdenoff.com\"\n : undefined;\n const domainPart = domain ? `; domain=${domain}` : \"\";\n const securePart = window.location.protocol === \"https:\" ? \"; secure\" : \"\";\n const ssoValue = JSON.stringify({\n id: userId,\n origin: window.location.origin,\n });\n document.cookie = `bf-sso=${encodeURIComponent(ssoValue)}${domainPart}; path=/; samesite=lax${securePart}; max-age=86400`;\n document.cookie = `bf-sso-profile=${encodeURIComponent(ssoValue)}${domainPart}; path=/; samesite=lax${securePart}; max-age=86400`;\n } catch {\n // Best effort only.\n }\n}\n\n// =============================================================================\n// GRAPHQL RESPONSE INTERFACES\n// =============================================================================\n\ninterface SetupMFAResponse {\n setupMFA: MFASetupResult;\n}\n\ninterface SetupMFAVariables {\n method: MFAMethod;\n}\n\ninterface EnableMFAResponse {\n enableMFA: boolean;\n}\n\ninterface EnableMFAVariables {\n code: string;\n}\n\ninterface VerifyMFAResponse {\n verifyMFA: AuthResult;\n}\n\ninterface VerifyMFAVariables {\n input: MFAVerifyInput;\n}\n\ninterface DisableMFAResponse {\n disableMFA: boolean;\n}\n\n// GraphQL Operations\n\n/**\n * Hook for MFA operations\n */\nexport function useMfaOperations() {\n const store = useAuthStore();\n const context = useAuth();\n const eventBus = useEventBus();\n const [setupMfaMutation] = useMutation<SetupMFAResponse, SetupMFAVariables>(\n SetupMfaDocument,\n );\n const [enableMfaMutation] = useMutation<\n EnableMFAResponse,\n EnableMFAVariables\n >(EnableMfaDocument);\n const [verifyMfaMutation] = useMutation<\n VerifyMFAResponse,\n VerifyMFAVariables\n >(VerifyMfaDocument);\n const [disableMfaMutation] =\n useMutation<DisableMFAResponse>(DisableMfaDocument);\n\n /**\n * Setup MFA for the user\n */\n const setupMFA = async (method: MFAMethod): Promise<MFASetupResult> => {\n try {\n store.setLoading(true);\n\n const { data } = await setupMfaMutation({\n variables: { method },\n });\n\n return data!.setupMFA;\n } catch (error) {\n if (import.meta.env.DEV) {\n console.error(\"MFA setup failed:\", error);\n }\n throw error;\n } finally {\n store.setLoading(false);\n }\n };\n\n /**\n * Enable MFA after setup with verification code\n */\n const enableMFA = async (code: string): Promise<boolean> => {\n try {\n store.setLoading(true);\n\n const { data } = await enableMfaMutation({\n variables: { code },\n });\n\n if (data!.enableMFA && store.user) {\n store.setUser({ ...store.user, mfaEnabled: true });\n }\n\n return data!.enableMFA;\n } catch (error) {\n if (import.meta.env.DEV) {\n console.error(\"Failed to enable MFA:\", error);\n }\n throw error;\n } finally {\n store.setLoading(false);\n }\n };\n\n /**\n * Verify MFA code during login\n */\n const verifyMFA = async (input: MFAVerifyInput): Promise<AuthResult> => {\n try {\n store.setLoading(true);\n\n const { data, error } = await verifyMfaMutation({\n variables: { input },\n });\n\n const result = data?.verifyMFA;\n\n // Server returned no data (GraphQL errors, network failure, or null payload).\n // Surface a friendly message instead of letting `result.success` throw a\n // \"Cannot read properties of null\" error to the UI. Apollo Client v4\n // exposes a single `error` (ApolloError) on MutateResult, not an array.\n if (!result) {\n const gqlMessage = error?.message;\n return {\n success: false,\n error: gqlMessage || \"Invalid verification code. Please try again.\",\n } as AuthResult;\n }\n\n if (result.success && result.user && result.token) {\n store.setUser(result.user);\n store.setAuthTokens(result.token, result.refreshToken || \"\");\n store.setAuthenticated(true);\n store.setMfaRequired(false);\n\n const expiresAt = result.expiresIn\n ? Date.now() + result.expiresIn * 1000\n : undefined;\n loginProfile(toProfileUser(result.user), {\n accessToken: result.token,\n refreshToken: result.refreshToken || \"\",\n expiresAt,\n });\n setShellSsoCookie(result.user.id);\n\n eventBus.emit(\n \"auth.signed_in\",\n {\n userId: result.user.id,\n tenantId: result.user.tenantId,\n workspaceId: result.user.defaultWorkspaceId,\n mfaEnabled: result.user.mfaEnabled,\n emailVerified: result.user.emailVerified,\n },\n { component: \"useMfaOperations\" },\n );\n\n context.onAuthSuccess?.(result.user, result.token, result.refreshToken);\n } else {\n console.warn(\n \"[useMfaOperations] NOT saving tokens - condition failed:\",\n {\n success: result.success,\n hasUser: !!result.user,\n hasToken: !!result.token,\n },\n );\n }\n\n return result;\n } catch (error) {\n if (import.meta.env.DEV) {\n console.error(\"MFA verification failed:\", error);\n }\n throw error;\n } finally {\n store.setLoading(false);\n }\n };\n\n /**\n * Disable MFA\n */\n const disableMFA = async (): Promise<boolean> => {\n try {\n store.setLoading(true);\n\n const { data } = await disableMfaMutation();\n\n if (data!.disableMFA && store.user) {\n store.setUser({ ...store.user, mfaEnabled: false });\n }\n\n return data!.disableMFA;\n } catch (error) {\n if (import.meta.env.DEV) {\n console.error(\"Failed to disable MFA:\", error);\n }\n throw error;\n } finally {\n store.setLoading(false);\n }\n };\n\n // Legacy aliases\n const enableMfa = enableMFA;\n const verifyMfa = verifyMFA;\n const disableMfa = disableMFA;\n\n return {\n setupMFA,\n enableMFA,\n verifyMFA,\n disableMFA,\n // Legacy aliases\n enableMfa,\n verifyMfa,\n disableMfa,\n // State\n mfaRequired: store.mfaRequired,\n mfaChallengeId: store.mfaChallengeId,\n isLoading: store.isLoading,\n };\n}\n"],"mappings":"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"}
|
|
@@ -4,17 +4,18 @@ import { useAuthOperations as n } from "../hooks/useAuthOperations.js";
|
|
|
4
4
|
import { useMyWorkspaces as r } from "../hooks/useMyWorkspaces.js";
|
|
5
5
|
import { useOAuthOperations as i } from "../hooks/useOAuthOperations.js";
|
|
6
6
|
import { AuthLayout as a } from "../components/AuthLayout.js";
|
|
7
|
-
import { AlertIcon as o, EmailIcon as s, EyeIcon as
|
|
7
|
+
import { AlertIcon as o, EmailIcon as s, EyeIcon as ee, EyeOffIcon as te, GoogleIcon as c, LockIcon as l, MicrosoftIcon as ne, SpinnerIcon as u } from "../components/AuthIcons.js";
|
|
8
8
|
import { useCaptchaV3 as re } from "../hooks/useCaptchaV3.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
9
|
+
import { MFA_REDIRECT as ie } from "../constants/sessionKeys.js";
|
|
10
|
+
import { useCallback as d, useEffect as f, useRef as ae, useState as p } from "react";
|
|
11
|
+
import { SSORedirectSpinner as oe, getSSORedirectUrl as se } from "@burdenoff/fe-libs/shared/components";
|
|
12
|
+
import { useLocation as ce, useNavigate as le, useSearchParams as ue } from "react-router-dom";
|
|
13
|
+
import { useActiveContext as de, useI18n as fe } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
13
14
|
import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
14
|
-
import { resolveAuthBridgeConfig as
|
|
15
|
-
import { getProfileTokens as
|
|
15
|
+
import { resolveAuthBridgeConfig as pe } from "@burdenoff/fe-libs/shared/config";
|
|
16
|
+
import { getProfileTokens as me, getProfileUser as he, getProfileWorkspaceToken as ge, getProfiles as _, resolveActiveProfileId as _e } from "@burdenoff/fe-libs/shared/providers/shell/ProfileStorageManager";
|
|
16
17
|
//#region src/auth/pages/LoginPage.tsx
|
|
17
|
-
function
|
|
18
|
+
function v() {
|
|
18
19
|
if (typeof window > "u") return !1;
|
|
19
20
|
let e = window;
|
|
20
21
|
if (typeof e.Capacitor?.isNativePlatform == "function") try {
|
|
@@ -22,7 +23,7 @@ function ge() {
|
|
|
22
23
|
} catch {}
|
|
23
24
|
return !!(typeof navigator < "u" && /Electron/i.test(navigator.userAgent || ""));
|
|
24
25
|
}
|
|
25
|
-
function
|
|
26
|
+
function ve(e) {
|
|
26
27
|
if (typeof window > "u") return e;
|
|
27
28
|
try {
|
|
28
29
|
let t = new URL(e, window.location.origin);
|
|
@@ -31,7 +32,7 @@ function _e(e) {
|
|
|
31
32
|
return e;
|
|
32
33
|
}
|
|
33
34
|
}
|
|
34
|
-
function
|
|
35
|
+
function ye(e) {
|
|
35
36
|
try {
|
|
36
37
|
let t = e.split(".")[1].replace(/-/g, "+").replace(/_/g, "/"), n = t.padEnd(Math.ceil(t.length / 4) * 4, "="), r = JSON.parse(atob(n));
|
|
37
38
|
return typeof r.exp == "number" && r.exp > Date.now() / 1e3;
|
|
@@ -39,7 +40,7 @@ function ve(e) {
|
|
|
39
40
|
return !1;
|
|
40
41
|
}
|
|
41
42
|
}
|
|
42
|
-
function
|
|
43
|
+
function be(e) {
|
|
43
44
|
if (!e) return null;
|
|
44
45
|
try {
|
|
45
46
|
let t = new URL(decodeURIComponent(e), window.location.origin);
|
|
@@ -58,7 +59,7 @@ function y(e, t) {
|
|
|
58
59
|
let n = e.searchParams.toString();
|
|
59
60
|
return `${e.pathname}${n ? `?${n}` : ""}${e.hash}`;
|
|
60
61
|
}
|
|
61
|
-
function
|
|
62
|
+
function xe(e) {
|
|
62
63
|
try {
|
|
63
64
|
let t = new URL(decodeURIComponent(e), window.location.origin);
|
|
64
65
|
return y(t, { includeOrigin: t.origin !== window.location.origin });
|
|
@@ -67,73 +68,73 @@ function be(e) {
|
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
function b() {
|
|
70
|
-
let y =
|
|
71
|
-
let n =
|
|
71
|
+
let y = le(), b = ce(), [x] = ue(), { t: Se } = fe(), S = d((e, t) => {
|
|
72
|
+
let n = Se(e);
|
|
72
73
|
return n === e ? t : n;
|
|
73
|
-
}, [
|
|
74
|
-
if (typeof window > "u" ||
|
|
74
|
+
}, [Se]), { signIn: Ce, isLoading: C, error: w, errorCode: T, resendVerification: we } = n(), { completeAuthFlow: Te } = r(), { setWorkspace: E, setOrganization: D } = de(), { defaultPostLoginPath: O } = e(), { initiateGoogleOAuth: Ee, initiateMicrosoftOAuth: De, isProviderConfigured: k } = i(), A = t((e) => e.mfaRequired), { executeRecaptcha: Oe } = re(), [j, M] = p(!1), [ke, Ae] = p(!1), N = d((e) => {
|
|
75
|
+
if (typeof window > "u" || v()) return e;
|
|
75
76
|
try {
|
|
76
|
-
let t =
|
|
77
|
+
let t = pe(), n = new URL(t.url), r = window.location.origin;
|
|
77
78
|
if (n.origin === r) return e;
|
|
78
|
-
let i = new URL(e, r).href, a =
|
|
79
|
+
let i = new URL(e, r).href, a = _e();
|
|
79
80
|
if (!a) return e;
|
|
80
|
-
let o =
|
|
81
|
+
let o = me(a), s = he(a);
|
|
81
82
|
if (!o || !s) return e;
|
|
82
|
-
let
|
|
83
|
+
let ee = ge(a), te = {
|
|
83
84
|
profileId: a,
|
|
84
85
|
tokens: JSON.stringify({
|
|
85
86
|
...o,
|
|
86
|
-
workspaceToken:
|
|
87
|
+
workspaceToken: ee
|
|
87
88
|
}),
|
|
88
89
|
user: JSON.stringify(s),
|
|
89
90
|
profiles: JSON.stringify(_())
|
|
90
|
-
},
|
|
91
|
-
return
|
|
91
|
+
}, c = btoa(JSON.stringify(te)), l = new URL("/auth/sso-deposit", n.origin);
|
|
92
|
+
return l.searchParams.set("returnTo", i), `${l.href}#sso=${c}`;
|
|
92
93
|
} catch {
|
|
93
94
|
return e;
|
|
94
95
|
}
|
|
95
|
-
}, []),
|
|
96
|
+
}, []), P = d((e) => {
|
|
96
97
|
if (typeof window < "u") {
|
|
97
98
|
try {
|
|
98
99
|
sessionStorage.setItem("bf-post-login-return-to", e);
|
|
99
100
|
} catch {}
|
|
100
|
-
if (
|
|
101
|
-
y(
|
|
101
|
+
if (v()) {
|
|
102
|
+
y(ve(e));
|
|
102
103
|
return;
|
|
103
104
|
}
|
|
104
|
-
window.location.assign(
|
|
105
|
+
window.location.assign(N(e));
|
|
105
106
|
return;
|
|
106
107
|
}
|
|
107
108
|
y(e);
|
|
108
|
-
}, [y,
|
|
109
|
+
}, [y, N]), [F, je] = p(!1), [I, L] = p(!1), [Me, R] = p(!1), [Ne, z] = p(!1), [B, V] = p(!1), [H, U] = p(!1), [Pe, Fe] = p(!1), [Ie, W] = p(!1), [Le, G] = p(null), [Re, ze] = p(null), [K, q] = p({
|
|
109
110
|
email: "",
|
|
110
111
|
password: "",
|
|
111
112
|
rememberMe: !1
|
|
112
|
-
}), [
|
|
113
|
+
}), [J, Y] = p(null), [Be, X] = p(!1), Z = x.get("mode") === "add-account", Q = x.get("returnTo"), $ = ae(Q);
|
|
113
114
|
f(() => {
|
|
114
|
-
|
|
115
|
-
}, [
|
|
116
|
-
if (
|
|
117
|
-
let e =
|
|
115
|
+
!$.current && Q && ($.current = Q);
|
|
116
|
+
}, [Q]), f(() => {
|
|
117
|
+
if (Z || j) return;
|
|
118
|
+
let e = _e();
|
|
118
119
|
if (e) {
|
|
119
|
-
let n =
|
|
120
|
-
if (n?.accessToken && r &&
|
|
121
|
-
t.getState().loadFromProfile(e),
|
|
120
|
+
let n = me(e), r = he(e);
|
|
121
|
+
if (n?.accessToken && r && ye(n.accessToken)) {
|
|
122
|
+
t.getState().loadFromProfile(e), P(be(Q) ?? "/");
|
|
122
123
|
return;
|
|
123
124
|
}
|
|
124
125
|
}
|
|
125
|
-
let n =
|
|
126
|
+
let n = se();
|
|
126
127
|
n && (Ae(!0), window.location.replace(n));
|
|
127
128
|
}, [
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
129
|
+
Z,
|
|
130
|
+
j,
|
|
131
|
+
P,
|
|
132
|
+
Q
|
|
132
133
|
]), f(() => {
|
|
133
134
|
try {
|
|
134
135
|
localStorage.removeItem("remembered_password");
|
|
135
136
|
let e = localStorage.getItem("remembered_email");
|
|
136
|
-
e &&
|
|
137
|
+
e && q((t) => ({
|
|
137
138
|
...t,
|
|
138
139
|
email: e,
|
|
139
140
|
rememberMe: !0
|
|
@@ -143,7 +144,7 @@ function b() {
|
|
|
143
144
|
}
|
|
144
145
|
}, []), f(() => {
|
|
145
146
|
let e = b.state;
|
|
146
|
-
e?.message && ze(e.message), e?.email &&
|
|
147
|
+
e?.message && ze(e.message), e?.email && q((t) => ({
|
|
147
148
|
...t,
|
|
148
149
|
email: e.email
|
|
149
150
|
})), e && window.history.replaceState({}, document.title);
|
|
@@ -163,7 +164,7 @@ function b() {
|
|
|
163
164
|
};
|
|
164
165
|
f(() => {
|
|
165
166
|
let e = x.get("email");
|
|
166
|
-
if (e &&
|
|
167
|
+
if (e && q((t) => ({
|
|
167
168
|
...t,
|
|
168
169
|
email: e
|
|
169
170
|
})), x.get("expired") === "true") {
|
|
@@ -172,36 +173,42 @@ function b() {
|
|
|
172
173
|
window.history.replaceState({}, document.title, e);
|
|
173
174
|
}
|
|
174
175
|
}, [x, S]), f(() => {
|
|
175
|
-
|
|
176
|
-
}, [
|
|
176
|
+
A && y("/auth/mfa-verify");
|
|
177
|
+
}, [A, y]);
|
|
177
178
|
let He = async (e) => {
|
|
178
|
-
e.preventDefault(),
|
|
179
|
-
let n = (
|
|
179
|
+
e.preventDefault(), L(!1), R(!1), z(!1), V(!1), U(!1), X(!1), W(!1), Y(null);
|
|
180
|
+
let n = (K.email ?? "").trim();
|
|
180
181
|
if (!n) {
|
|
181
|
-
|
|
182
|
+
Y(S("auth.login.enterEmailOrUsername", "Please enter your email or username"));
|
|
182
183
|
return;
|
|
183
184
|
}
|
|
184
185
|
if (n.includes("@") && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(n)) {
|
|
185
|
-
|
|
186
|
+
Y(S("auth.login.invalidEmail", "Please enter a valid email address"));
|
|
186
187
|
return;
|
|
187
188
|
}
|
|
188
|
-
if (!
|
|
189
|
-
|
|
189
|
+
if (!K.password || K.password.length < 1) {
|
|
190
|
+
Y(S("auth.login.enterPassword", "Please enter your password"));
|
|
190
191
|
return;
|
|
191
192
|
}
|
|
192
|
-
if (
|
|
193
|
-
|
|
193
|
+
if (Z && _().some((e) => e.email.toLowerCase() === n.toLowerCase())) {
|
|
194
|
+
X(!0), Y(null);
|
|
194
195
|
return;
|
|
195
196
|
}
|
|
196
|
-
|
|
197
|
+
X(!1);
|
|
197
198
|
try {
|
|
198
|
-
let e = await Oe("login"), t = await
|
|
199
|
+
let e = await Oe("login"), t = await Ce({
|
|
199
200
|
email: n,
|
|
200
|
-
password:
|
|
201
|
-
rememberMe:
|
|
201
|
+
password: K.password,
|
|
202
|
+
rememberMe: K.rememberMe,
|
|
202
203
|
...e ? { recaptchaToken: e } : {}
|
|
203
204
|
});
|
|
204
|
-
if (t.requiresMFA)
|
|
205
|
+
if (t.requiresMFA) {
|
|
206
|
+
let e = xe($.current || Q || (O ?? "/dashboard"));
|
|
207
|
+
try {
|
|
208
|
+
sessionStorage.setItem(ie, e);
|
|
209
|
+
} catch {}
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
205
212
|
if (t.success) {
|
|
206
213
|
try {
|
|
207
214
|
let e = t.user?.id;
|
|
@@ -214,14 +221,14 @@ function b() {
|
|
|
214
221
|
}
|
|
215
222
|
} catch {}
|
|
216
223
|
try {
|
|
217
|
-
|
|
224
|
+
K.rememberMe ? localStorage.setItem("remembered_email", n) : localStorage.removeItem("remembered_email");
|
|
218
225
|
} catch (e) {
|
|
219
226
|
console.warn("[LoginPage] Failed to save/clear remembered email:", e);
|
|
220
227
|
}
|
|
221
|
-
|
|
222
|
-
let e =
|
|
228
|
+
M(!0);
|
|
229
|
+
let e = xe($.current || Q || (O ?? "/dashboard"));
|
|
223
230
|
try {
|
|
224
|
-
let n = await Promise.race([
|
|
231
|
+
let n = await Promise.race([Te(t.token), new Promise((e) => {
|
|
225
232
|
window.setTimeout(() => {
|
|
226
233
|
e({
|
|
227
234
|
success: !1,
|
|
@@ -229,63 +236,63 @@ function b() {
|
|
|
229
236
|
});
|
|
230
237
|
}, 5e3);
|
|
231
238
|
})]);
|
|
232
|
-
n.success ? (n.workspace && (E(n.workspace.id), n.workspace.organizationId && D(n.workspace.organizationId)),
|
|
239
|
+
n.success ? (n.workspace && (E(n.workspace.id), n.workspace.organizationId && D(n.workspace.organizationId)), P(e)) : n.error?.includes("No workspaces found") ? y("/onboarding/create-workspace") : (n.workspace && (E(n.workspace.id), n.workspace.organizationId && D(n.workspace.organizationId)), console.warn("Auth flow warning:", n.error), P(e));
|
|
233
240
|
} catch (t) {
|
|
234
|
-
console.error("Auth flow error (login succeeded):", t),
|
|
241
|
+
console.error("Auth flow error (login succeeded):", t), P(e);
|
|
235
242
|
} finally {
|
|
236
|
-
|
|
243
|
+
M(!1);
|
|
237
244
|
}
|
|
238
245
|
}
|
|
239
246
|
} catch (e) {
|
|
240
247
|
let n = e instanceof Error ? e.message : String(e);
|
|
241
|
-
n.includes("reCAPTCHA") &&
|
|
248
|
+
n.includes("reCAPTCHA") && Y(n);
|
|
242
249
|
let r = t.getState().errorCode, i = Ve(n, r);
|
|
243
|
-
i === "DELETED" ?
|
|
250
|
+
i === "DELETED" ? R(!0) : i === "SUSPENDED" ? z(!0) : i === "OAUTH_ONLY" ? V(!0) : i === "INACTIVE" ? L(!0) : i === "EMAIL_NOT_VERIFIED" && U(!0);
|
|
244
251
|
}
|
|
245
252
|
};
|
|
246
253
|
f(() => {
|
|
247
254
|
if (w) {
|
|
248
255
|
let e = Ve(w, T);
|
|
249
|
-
e === "DELETED" ?
|
|
256
|
+
e === "DELETED" ? R(!0) : e === "SUSPENDED" ? z(!0) : e === "OAUTH_ONLY" ? V(!0) : e === "INACTIVE" ? L(!0) : e === "EMAIL_NOT_VERIFIED" && U(!0);
|
|
250
257
|
}
|
|
251
258
|
}, [w, T]);
|
|
252
259
|
let Ue = () => {
|
|
253
|
-
|
|
260
|
+
G(null);
|
|
254
261
|
try {
|
|
255
262
|
Ee();
|
|
256
263
|
} catch (e) {
|
|
257
|
-
|
|
264
|
+
G(e instanceof Error ? e.message : S("auth.login.googleSignInFailed", "Failed to initiate Google sign in"));
|
|
258
265
|
}
|
|
259
266
|
}, We = () => {
|
|
260
|
-
|
|
267
|
+
G(null);
|
|
261
268
|
try {
|
|
262
269
|
De();
|
|
263
270
|
} catch (e) {
|
|
264
|
-
|
|
271
|
+
G(e instanceof Error ? e.message : S("auth.login.microsoftSignInFailed", "Failed to initiate Microsoft sign in"));
|
|
265
272
|
}
|
|
266
273
|
}, Ge = async () => {
|
|
267
|
-
Fe(!0),
|
|
274
|
+
Fe(!0), W(!1);
|
|
268
275
|
try {
|
|
269
|
-
(await
|
|
276
|
+
(await we((K.email ?? "").trim())).success ? W(!0) : Y(S("auth.login.resendFailed", "Failed to resend verification email. Please try again."));
|
|
270
277
|
} catch (e) {
|
|
271
|
-
console.error("Failed to resend verification email:", e),
|
|
278
|
+
console.error("Failed to resend verification email:", e), Y(e instanceof Error ? e.message : S("auth.login.resendFailed", "Failed to resend verification email. Please try again."));
|
|
272
279
|
} finally {
|
|
273
280
|
Fe(!1);
|
|
274
281
|
}
|
|
275
|
-
}, Ke =
|
|
282
|
+
}, Ke = k("google"), qe = k("microsoft"), Je = [{
|
|
276
283
|
name: "Google",
|
|
277
|
-
icon:
|
|
284
|
+
icon: c,
|
|
278
285
|
onClick: Ue,
|
|
279
286
|
disabled: !Ke,
|
|
280
287
|
tooltip: Ke ? void 0 : S("auth.login.googleNotConfigured", "Google sign in is not configured")
|
|
281
288
|
}, {
|
|
282
289
|
name: "Microsoft",
|
|
283
|
-
icon:
|
|
290
|
+
icon: ne,
|
|
284
291
|
onClick: We,
|
|
285
|
-
disabled:
|
|
286
|
-
tooltip:
|
|
292
|
+
disabled: !qe,
|
|
293
|
+
tooltip: qe ? void 0 : S("auth.login.microsoftNotConfigured", "Microsoft sign in is not configured")
|
|
287
294
|
}];
|
|
288
|
-
return ke ? /* @__PURE__ */ h(
|
|
295
|
+
return ke ? /* @__PURE__ */ h(oe, {}) : /* @__PURE__ */ g(a, {
|
|
289
296
|
title: S("auth.login.welcomeBack", "Welcome back"),
|
|
290
297
|
subtitle: S("auth.login.enterCredentials", "Enter your credentials to continue"),
|
|
291
298
|
children: [
|
|
@@ -311,11 +318,11 @@ function b() {
|
|
|
311
318
|
children: Re
|
|
312
319
|
})]
|
|
313
320
|
}),
|
|
314
|
-
|
|
321
|
+
J && /* @__PURE__ */ g("div", {
|
|
315
322
|
className: "flex items-start gap-3 p-4 rounded-xl border bg-status-warning-bg-subtle border-status-warning-border",
|
|
316
323
|
children: [/* @__PURE__ */ h(o, { className: "size-5 flex-shrink-0 mt-0.5 text-status-warning-text" }), /* @__PURE__ */ h("p", {
|
|
317
324
|
className: "text-sm text-status-warning-text",
|
|
318
|
-
children:
|
|
325
|
+
children: J
|
|
319
326
|
})]
|
|
320
327
|
}),
|
|
321
328
|
Be && /* @__PURE__ */ g("div", {
|
|
@@ -331,9 +338,9 @@ function b() {
|
|
|
331
338
|
className: "mt-1 text-sm text-status-warning-text/80",
|
|
332
339
|
children: S("auth.login.duplicateAccountHint", "Please use a different account, or go back and switch to this account from the profile menu.")
|
|
333
340
|
}),
|
|
334
|
-
(
|
|
341
|
+
($.current || Q) && /* @__PURE__ */ g("button", {
|
|
335
342
|
type: "button",
|
|
336
|
-
onClick: () => y(decodeURIComponent(
|
|
343
|
+
onClick: () => y(decodeURIComponent($.current || Q || "/dashboard")),
|
|
337
344
|
className: "mt-3 inline-flex items-center gap-2 px-4 py-2.5 rounded-xl border border-status-warning-border bg-bg-surface text-status-warning-text text-sm font-medium hover:bg-status-warning-bg-subtle hover:border-status-warning-border transition-all shadow-sm",
|
|
338
345
|
children: [/* @__PURE__ */ h("svg", {
|
|
339
346
|
className: "size-4",
|
|
@@ -351,22 +358,22 @@ function b() {
|
|
|
351
358
|
]
|
|
352
359
|
})]
|
|
353
360
|
}),
|
|
354
|
-
w && !
|
|
355
|
-
className: `flex items-start gap-3 p-4 rounded-xl border ${
|
|
356
|
-
children: [/* @__PURE__ */ h(o, { className: `size-5 flex-shrink-0 mt-0.5 ${
|
|
361
|
+
w && !J && !Be && /* @__PURE__ */ g("div", {
|
|
362
|
+
className: `flex items-start gap-3 p-4 rounded-xl border ${I || B || H ? "bg-status-warning-bg-subtle border-status-warning-border" : "bg-status-error-bg-subtle border-status-error-border"}`,
|
|
363
|
+
children: [/* @__PURE__ */ h(o, { className: `size-5 flex-shrink-0 mt-0.5 ${I || B || H ? "text-status-warning-text" : "text-status-error-text"}` }), /* @__PURE__ */ g("div", {
|
|
357
364
|
className: "flex-1",
|
|
358
365
|
children: [
|
|
359
366
|
/* @__PURE__ */ h("p", {
|
|
360
|
-
className: `text-sm ${
|
|
361
|
-
children: Me ? S("auth.login.accountDeleted", "This account has been permanently deleted and cannot be recovered.") : Ne ? S("auth.login.accountSuspended", "Your account has been suspended. Please contact support for assistance.") :
|
|
367
|
+
className: `text-sm ${I || B || H ? "text-status-warning-text" : "text-status-error-text"}`,
|
|
368
|
+
children: Me ? S("auth.login.accountDeleted", "This account has been permanently deleted and cannot be recovered.") : Ne ? S("auth.login.accountSuspended", "Your account has been suspended. Please contact support for assistance.") : I ? S("auth.login.accountDeactivated", "Your account has been deactivated.") : B ? S("auth.login.oauthOnly", "This account uses OAuth sign-in. Please use Google or Microsoft to sign in.") : H ? S("auth.login.emailNotVerified", "Please verify your email before signing in. Check your inbox for the verification link.") : w
|
|
362
369
|
}),
|
|
363
|
-
|
|
370
|
+
I && /* @__PURE__ */ h("button", {
|
|
364
371
|
type: "button",
|
|
365
|
-
onClick: () => y("/auth/reactivate", { state: { email:
|
|
372
|
+
onClick: () => y("/auth/reactivate", { state: { email: K.email } }),
|
|
366
373
|
className: "mt-2 text-sm font-semibold text-status-warning-text hover:text-status-warning-text underline underline-offset-2",
|
|
367
374
|
children: S("auth.login.clickReactivate", "Click here to reactivate your account")
|
|
368
375
|
}),
|
|
369
|
-
|
|
376
|
+
H && /* @__PURE__ */ h("div", {
|
|
370
377
|
className: "mt-3",
|
|
371
378
|
children: Ie ? /* @__PURE__ */ g("div", {
|
|
372
379
|
className: "flex items-center gap-2 text-sm text-status-success-text",
|
|
@@ -387,7 +394,7 @@ function b() {
|
|
|
387
394
|
onClick: Ge,
|
|
388
395
|
disabled: Pe,
|
|
389
396
|
className: "inline-flex items-center gap-2 px-4 py-2.5 rounded-xl border border-status-warning-border bg-bg-surface text-status-warning-text text-sm font-medium hover:bg-status-warning-bg-subtle hover:border-status-warning-border transition-all shadow-sm disabled:opacity-50 disabled:cursor-not-allowed",
|
|
390
|
-
children: Pe ? /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(
|
|
397
|
+
children: Pe ? /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(u, { className: "size-4 animate-spin" }), S("auth.login.sending", "Sending...")] }) : /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h("svg", {
|
|
391
398
|
className: "size-4",
|
|
392
399
|
fill: "none",
|
|
393
400
|
viewBox: "0 0 24 24",
|
|
@@ -401,18 +408,18 @@ function b() {
|
|
|
401
408
|
}), S("auth.login.resendVerification", "Resend verification email")] })
|
|
402
409
|
})
|
|
403
410
|
}),
|
|
404
|
-
|
|
411
|
+
B && /* @__PURE__ */ g("div", {
|
|
405
412
|
className: "mt-3 flex flex-col gap-2",
|
|
406
|
-
children: [
|
|
413
|
+
children: [k("google") && /* @__PURE__ */ g("button", {
|
|
407
414
|
type: "button",
|
|
408
415
|
onClick: Ue,
|
|
409
416
|
className: "inline-flex items-center justify-center gap-2 px-4 py-2.5 rounded-xl border border-border-default bg-bg-surface text-text-primary text-sm font-medium hover:bg-bg-canvas hover:border-border-default transition-all shadow-sm",
|
|
410
|
-
children: [/* @__PURE__ */ h(
|
|
411
|
-
}),
|
|
417
|
+
children: [/* @__PURE__ */ h(c, { className: "size-5" }), S("auth.login.signInWithGoogle", "Sign in with Google")]
|
|
418
|
+
}), k("microsoft") && /* @__PURE__ */ g("button", {
|
|
412
419
|
type: "button",
|
|
413
420
|
onClick: We,
|
|
414
421
|
className: "inline-flex items-center justify-center gap-2 px-4 py-2.5 rounded-xl border border-border-default bg-bg-surface text-text-primary text-sm font-medium hover:bg-bg-canvas hover:border-border-default transition-all shadow-sm",
|
|
415
|
-
children: [/* @__PURE__ */ h(
|
|
422
|
+
children: [/* @__PURE__ */ h(ne, { className: "size-5" }), S("auth.login.signInWithMicrosoft", "Sign in with Microsoft")]
|
|
416
423
|
})]
|
|
417
424
|
})
|
|
418
425
|
]
|
|
@@ -436,9 +443,9 @@ function b() {
|
|
|
436
443
|
required: !0,
|
|
437
444
|
"aria-required": "true",
|
|
438
445
|
"aria-label": S("auth.login.emailLabel", "Email"),
|
|
439
|
-
value:
|
|
440
|
-
onChange: (e) =>
|
|
441
|
-
...
|
|
446
|
+
value: K.email,
|
|
447
|
+
onChange: (e) => q({
|
|
448
|
+
...K,
|
|
442
449
|
email: e.target.value
|
|
443
450
|
}),
|
|
444
451
|
className: "block w-full pl-[3.5rem] pr-4 py-3 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] placeholder:text-[var(--color-text-tertiary)] focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all",
|
|
@@ -457,18 +464,18 @@ function b() {
|
|
|
457
464
|
children: [
|
|
458
465
|
/* @__PURE__ */ h("div", {
|
|
459
466
|
className: "absolute inset-y-0 left-0 pl-3.5 flex items-center pointer-events-none",
|
|
460
|
-
children: /* @__PURE__ */ h(
|
|
467
|
+
children: /* @__PURE__ */ h(l, { className: "size-5 text-[var(--color-text-tertiary)]" })
|
|
461
468
|
}),
|
|
462
469
|
/* @__PURE__ */ h("input", {
|
|
463
470
|
id: "password",
|
|
464
|
-
type:
|
|
471
|
+
type: F ? "text" : "password",
|
|
465
472
|
autoComplete: "current-password",
|
|
466
473
|
required: !0,
|
|
467
474
|
"aria-required": "true",
|
|
468
475
|
"aria-label": S("auth.login.passwordLabel", "Password"),
|
|
469
|
-
value:
|
|
470
|
-
onChange: (e) =>
|
|
471
|
-
...
|
|
476
|
+
value: K.password,
|
|
477
|
+
onChange: (e) => q({
|
|
478
|
+
...K,
|
|
472
479
|
password: e.target.value
|
|
473
480
|
}),
|
|
474
481
|
className: "block w-full pl-[3.5rem] pr-12 py-3 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] placeholder:text-[var(--color-text-tertiary)] focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all",
|
|
@@ -476,10 +483,10 @@ function b() {
|
|
|
476
483
|
}),
|
|
477
484
|
/* @__PURE__ */ h("button", {
|
|
478
485
|
type: "button",
|
|
479
|
-
onClick: () => je(!
|
|
480
|
-
"aria-label":
|
|
486
|
+
onClick: () => je(!F),
|
|
487
|
+
"aria-label": F ? "Hide password" : "Show password",
|
|
481
488
|
className: "absolute inset-y-0 right-0 pr-3.5 flex items-center text-[var(--color-text-tertiary)] hover:text-[var(--color-text-secondary)] transition-colors",
|
|
482
|
-
children: h(
|
|
489
|
+
children: h(F ? te : ee, { className: "size-5" })
|
|
483
490
|
})
|
|
484
491
|
]
|
|
485
492
|
})]
|
|
@@ -493,11 +500,11 @@ function b() {
|
|
|
493
500
|
children: [/* @__PURE__ */ h("input", {
|
|
494
501
|
type: "checkbox",
|
|
495
502
|
"aria-label": S("auth.login.rememberMe", "Remember me"),
|
|
496
|
-
checked:
|
|
503
|
+
checked: K.rememberMe,
|
|
497
504
|
onChange: (e) => {
|
|
498
505
|
let t = e.target.checked;
|
|
499
|
-
if (
|
|
500
|
-
...
|
|
506
|
+
if (q({
|
|
507
|
+
...K,
|
|
501
508
|
rememberMe: t
|
|
502
509
|
}), !t) try {
|
|
503
510
|
localStorage.removeItem("remembered_email");
|
|
@@ -534,9 +541,9 @@ function b() {
|
|
|
534
541
|
}),
|
|
535
542
|
/* @__PURE__ */ h("button", {
|
|
536
543
|
type: "submit",
|
|
537
|
-
disabled: C ||
|
|
544
|
+
disabled: C || j,
|
|
538
545
|
className: "auth-primary-button flex w-full items-center justify-center gap-2 px-4 py-3 font-semibold",
|
|
539
|
-
children: C ||
|
|
546
|
+
children: C || j ? /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(u, { className: "size-5 animate-spin" }), /* @__PURE__ */ h("span", { children: j ? S("auth.login.settingUpWorkspace", "Setting up workspace...") : S("auth.login.signingIn", "Signing in...") })] }) : S("auth.login.signIn", "Sign in")
|
|
540
547
|
})
|
|
541
548
|
]
|
|
542
549
|
}),
|
|
@@ -562,7 +569,7 @@ function b() {
|
|
|
562
569
|
}),
|
|
563
570
|
/* @__PURE__ */ h("div", {
|
|
564
571
|
className: "grid grid-cols-3 gap-3",
|
|
565
|
-
children:
|
|
572
|
+
children: Je.map((e) => /* @__PURE__ */ g("button", {
|
|
566
573
|
type: "button",
|
|
567
574
|
onClick: e.onClick,
|
|
568
575
|
disabled: e.disabled,
|