@cedros/login-react 0.0.18 → 0.0.19
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/{GoogleLoginButton-CwKEUISj.js → GoogleLoginButton-B6qnNMZp.js} +46 -44
- package/dist/GoogleLoginButton-B6qnNMZp.js.map +1 -0
- package/dist/GoogleLoginButton-D7CoMXLq.cjs +1 -0
- package/dist/GoogleLoginButton-D7CoMXLq.cjs.map +1 -0
- package/dist/email-only.d.ts +1 -1
- package/dist/google-only.cjs +1 -1
- package/dist/google-only.d.ts +5 -1
- package/dist/google-only.js +1 -1
- package/dist/index.cjs +12 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +1241 -1238
- package/dist/index.js.map +1 -1
- package/dist/solana-only.d.ts +1 -1
- package/package.json +1 -1
- package/dist/GoogleLoginButton-CwKEUISj.js.map +0 -1
- package/dist/GoogleLoginButton-oM5fMYPB.cjs +0 -1
- package/dist/GoogleLoginButton-oM5fMYPB.cjs.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import { useState as
|
|
3
|
-
import { u as
|
|
4
|
-
import { L as
|
|
5
|
-
const
|
|
1
|
+
import { jsxs as k, jsx as g } from "react/jsx-runtime";
|
|
2
|
+
import { useState as m, useRef as w, useMemo as y, useEffect as C, useCallback as R } from "react";
|
|
3
|
+
import { u as v, A as G, h as _ } from "./useCedrosLogin-_94MmGGq.js";
|
|
4
|
+
import { L as z } from "./LoadingSpinner-6vml-zwr.js";
|
|
5
|
+
const O = {
|
|
6
6
|
loading: !1,
|
|
7
7
|
loaded: !1,
|
|
8
8
|
error: null,
|
|
@@ -25,7 +25,7 @@ const L = {
|
|
|
25
25
|
}, s.onerror = () => {
|
|
26
26
|
this.loading = !1, s.remove();
|
|
27
27
|
const t = new Error("Failed to load Google Sign-In script");
|
|
28
|
-
this.callbacks.forEach((
|
|
28
|
+
this.callbacks.forEach((f) => f.reject(t)), this.callbacks = [];
|
|
29
29
|
}, document.head.appendChild(s);
|
|
30
30
|
}));
|
|
31
31
|
},
|
|
@@ -37,49 +37,49 @@ const L = {
|
|
|
37
37
|
this.loading = !1, this.loaded = !1, this.error = null, this.callbacks = [];
|
|
38
38
|
}
|
|
39
39
|
};
|
|
40
|
-
function
|
|
41
|
-
const { config: e, _internal: c } =
|
|
42
|
-
() => new
|
|
40
|
+
function M() {
|
|
41
|
+
const { config: e, _internal: c } = v(), [d, s] = m(!1), [t, f] = m(!1), [E, n] = m(null), [I, h] = m(null), a = w(null), b = w(e), u = y(
|
|
42
|
+
() => new G({
|
|
43
43
|
baseUrl: e.serverUrl,
|
|
44
44
|
timeoutMs: e.requestTimeout,
|
|
45
45
|
retryAttempts: e.retryAttempts
|
|
46
46
|
}),
|
|
47
47
|
[e.serverUrl, e.requestTimeout, e.retryAttempts]
|
|
48
48
|
);
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
C(() => {
|
|
50
|
+
b.current = e;
|
|
51
51
|
}, [e]);
|
|
52
|
-
const
|
|
52
|
+
const p = R(
|
|
53
53
|
async (o) => {
|
|
54
54
|
const i = a.current;
|
|
55
55
|
if (i)
|
|
56
56
|
try {
|
|
57
|
-
const r = await
|
|
57
|
+
const r = await u.post("/google", {
|
|
58
58
|
idToken: o.credential
|
|
59
59
|
});
|
|
60
|
-
|
|
60
|
+
b.current.callbacks?.onLoginSuccess?.(r.user, "google"), c?.handleLoginSuccess(r.user, r.tokens), s(!1), i.resolve(r);
|
|
61
61
|
} catch (r) {
|
|
62
|
-
const l =
|
|
63
|
-
n(l), s(!1), i.reject(l);
|
|
62
|
+
const l = _(r, "Google sign-in failed");
|
|
63
|
+
l.code === "ACCOUNT_LINK_REQUIRED" && h(o.credential), n(l), s(!1), i.reject(l);
|
|
64
64
|
} finally {
|
|
65
65
|
a.current = null;
|
|
66
66
|
}
|
|
67
67
|
},
|
|
68
|
-
[
|
|
68
|
+
[u, c]
|
|
69
69
|
);
|
|
70
|
-
|
|
70
|
+
C(() => {
|
|
71
71
|
if (!e.googleClientId)
|
|
72
72
|
return;
|
|
73
73
|
let o = !0;
|
|
74
74
|
const i = () => {
|
|
75
75
|
o && (window.google?.accounts?.id?.initialize({
|
|
76
76
|
client_id: e.googleClientId,
|
|
77
|
-
callback:
|
|
77
|
+
callback: p,
|
|
78
78
|
auto_select: !1,
|
|
79
79
|
cancel_on_tap_outside: !0
|
|
80
|
-
}), o &&
|
|
80
|
+
}), o && f(!0));
|
|
81
81
|
};
|
|
82
|
-
return
|
|
82
|
+
return O.load().then(() => {
|
|
83
83
|
o && i();
|
|
84
84
|
}).catch(() => {
|
|
85
85
|
o && n({
|
|
@@ -89,8 +89,8 @@ function _() {
|
|
|
89
89
|
}), () => {
|
|
90
90
|
o = !1;
|
|
91
91
|
};
|
|
92
|
-
}, [e.googleClientId,
|
|
93
|
-
const
|
|
92
|
+
}, [e.googleClientId, p]);
|
|
93
|
+
const S = R(async () => {
|
|
94
94
|
if (!e.googleClientId) {
|
|
95
95
|
const o = {
|
|
96
96
|
code: "VALIDATION_ERROR",
|
|
@@ -135,13 +135,15 @@ function _() {
|
|
|
135
135
|
}
|
|
136
136
|
});
|
|
137
137
|
});
|
|
138
|
-
}, [e.googleClientId, t]),
|
|
138
|
+
}, [e.googleClientId, t]), A = R(() => n(null), []), L = R(() => h(null), []);
|
|
139
139
|
return {
|
|
140
|
-
signIn:
|
|
140
|
+
signIn: S,
|
|
141
141
|
isLoading: d,
|
|
142
142
|
isInitialized: t,
|
|
143
|
-
error:
|
|
144
|
-
clearError:
|
|
143
|
+
error: E,
|
|
144
|
+
clearError: A,
|
|
145
|
+
pendingLinkIdToken: I,
|
|
146
|
+
clearPendingLink: L
|
|
145
147
|
};
|
|
146
148
|
}
|
|
147
149
|
function D({
|
|
@@ -150,33 +152,33 @@ function D({
|
|
|
150
152
|
className: d = "",
|
|
151
153
|
variant: s = "default",
|
|
152
154
|
size: t = "md",
|
|
153
|
-
disabled:
|
|
155
|
+
disabled: f = !1
|
|
154
156
|
}) {
|
|
155
|
-
const { signIn:
|
|
157
|
+
const { signIn: E, isLoading: n, isInitialized: I } = M(), h = async () => {
|
|
156
158
|
try {
|
|
157
|
-
await
|
|
158
|
-
} catch (
|
|
159
|
-
const
|
|
160
|
-
c?.(
|
|
159
|
+
await E(), e?.();
|
|
160
|
+
} catch (u) {
|
|
161
|
+
const p = u instanceof Error ? u : new Error(String(u));
|
|
162
|
+
c?.(p);
|
|
161
163
|
}
|
|
162
|
-
},
|
|
164
|
+
}, a = {
|
|
163
165
|
sm: "cedros-button-sm",
|
|
164
166
|
md: "cedros-button-md",
|
|
165
167
|
lg: "cedros-button-lg"
|
|
166
168
|
};
|
|
167
|
-
return /* @__PURE__ */
|
|
169
|
+
return /* @__PURE__ */ k(
|
|
168
170
|
"button",
|
|
169
171
|
{
|
|
170
172
|
type: "button",
|
|
171
173
|
className: `cedros-button ${{
|
|
172
174
|
default: "cedros-button-social",
|
|
173
175
|
outline: "cedros-button-social-outline"
|
|
174
|
-
}[s]} ${
|
|
176
|
+
}[s]} ${a[t]} ${d}`,
|
|
175
177
|
onClick: h,
|
|
176
|
-
disabled:
|
|
178
|
+
disabled: f || !I || n,
|
|
177
179
|
"aria-label": "Sign in with Google",
|
|
178
180
|
children: [
|
|
179
|
-
n ? /* @__PURE__ */
|
|
181
|
+
n ? /* @__PURE__ */ g(z, { size: "sm" }) : /* @__PURE__ */ k(
|
|
180
182
|
"svg",
|
|
181
183
|
{
|
|
182
184
|
className: "cedros-button-icon",
|
|
@@ -186,28 +188,28 @@ function D({
|
|
|
186
188
|
fill: "none",
|
|
187
189
|
"aria-hidden": "true",
|
|
188
190
|
children: [
|
|
189
|
-
/* @__PURE__ */
|
|
191
|
+
/* @__PURE__ */ g(
|
|
190
192
|
"path",
|
|
191
193
|
{
|
|
192
194
|
d: "M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844c-.209 1.125-.843 2.078-1.796 2.717v2.258h2.908c1.702-1.567 2.684-3.874 2.684-6.615z",
|
|
193
195
|
fill: "#4285F4"
|
|
194
196
|
}
|
|
195
197
|
),
|
|
196
|
-
/* @__PURE__ */
|
|
198
|
+
/* @__PURE__ */ g(
|
|
197
199
|
"path",
|
|
198
200
|
{
|
|
199
201
|
d: "M9.003 18c2.43 0 4.467-.806 5.956-2.18l-2.909-2.26c-.806.54-1.836.86-3.047.86-2.344 0-4.328-1.584-5.036-3.711H.96v2.332A8.997 8.997 0 0 0 9.003 18z",
|
|
200
202
|
fill: "#34A853"
|
|
201
203
|
}
|
|
202
204
|
),
|
|
203
|
-
/* @__PURE__ */
|
|
205
|
+
/* @__PURE__ */ g(
|
|
204
206
|
"path",
|
|
205
207
|
{
|
|
206
208
|
d: "M3.964 10.712A5.41 5.41 0 0 1 3.682 9c0-.593.102-1.17.282-1.71V4.958H.96A8.996 8.996 0 0 0 0 9c0 1.452.348 2.827.96 4.042l3.004-2.33z",
|
|
207
209
|
fill: "#FBBC05"
|
|
208
210
|
}
|
|
209
211
|
),
|
|
210
|
-
/* @__PURE__ */
|
|
212
|
+
/* @__PURE__ */ g(
|
|
211
213
|
"path",
|
|
212
214
|
{
|
|
213
215
|
d: "M9.003 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.464.891 11.428 0 9.002 0A8.997 8.997 0 0 0 .96 4.958l3.005 2.332c.708-2.127 2.692-3.71 5.036-3.71z",
|
|
@@ -217,12 +219,12 @@ function D({
|
|
|
217
219
|
]
|
|
218
220
|
}
|
|
219
221
|
),
|
|
220
|
-
/* @__PURE__ */
|
|
222
|
+
/* @__PURE__ */ g("span", { children: "Continue with Google" })
|
|
221
223
|
]
|
|
222
224
|
}
|
|
223
225
|
);
|
|
224
226
|
}
|
|
225
227
|
export {
|
|
226
228
|
D as G,
|
|
227
|
-
|
|
229
|
+
M as u
|
|
228
230
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GoogleLoginButton-B6qnNMZp.js","sources":["../src/hooks/useGoogleAuth.ts","../src/components/google/GoogleLoginButton.tsx"],"sourcesContent":["import { useState, useCallback, useEffect, useRef, useMemo } from 'react';\nimport { useCedrosLogin } from '../context/useCedrosLogin';\nimport { ApiClient, handleApiError } from '../utils/apiClient';\nimport type { AuthResponse, AuthError } from '../types';\n\n/**\n * Module-level singleton for Google script loading (P-01)\n *\n * Prevents race conditions when multiple components mount simultaneously.\n * Uses a promise queue pattern to ensure the script is only loaded once.\n *\n * ## SSR Limitations (F-08)\n *\n * This singleton persists across the module lifecycle. In SSR environments:\n * - Module state persists between requests (potential cross-request leakage)\n * - Google Sign-In requires browser APIs (document, window)\n * - The hook guards against SSR with `googleClientId` checks\n *\n * For SSR frameworks (Next.js, Remix), ensure this hook is only used\n * in client-side components.\n *\n * ## Test Isolation\n *\n * For test isolation, call `scriptLoader._reset()` in test setup/teardown.\n *\n * @internal\n */\nconst scriptLoader = {\n loading: false,\n loaded: false,\n error: null as Error | null,\n callbacks: [] as Array<{ resolve: () => void; reject: (err: Error) => void }>,\n\n load(): Promise<void> {\n // SSR guard: avoid touching browser globals when running in Node/SSR.\n if (typeof window === 'undefined' || typeof document === 'undefined') {\n return Promise.reject(new Error('Google Sign-In script loader cannot run in SSR'));\n }\n\n // Already loaded\n if (this.loaded) {\n return Promise.resolve();\n }\n\n // Loading in progress - queue callback\n if (this.loading) {\n return new Promise((resolve, reject) => {\n this.callbacks.push({ resolve, reject });\n });\n }\n\n // Start loading\n this.loading = true;\n return new Promise((resolve, reject) => {\n this.callbacks.push({ resolve, reject });\n\n // Check if script already exists (from previous session or SSR)\n const existingScript = document.getElementById('google-gsi-script');\n if (existingScript) {\n if (window.google?.accounts?.id) {\n this.loaded = true;\n this.loading = false;\n this.callbacks.forEach((cb) => cb.resolve());\n this.callbacks = [];\n } else {\n existingScript.addEventListener('load', () => {\n this.loaded = true;\n this.loading = false;\n this.callbacks.forEach((cb) => cb.resolve());\n this.callbacks = [];\n });\n }\n return;\n }\n\n const script = document.createElement('script');\n script.src = 'https://accounts.google.com/gsi/client';\n script.async = true;\n script.defer = true;\n script.id = 'google-gsi-script';\n\n script.onload = () => {\n this.loaded = true;\n this.loading = false;\n this.callbacks.forEach((cb) => cb.resolve());\n this.callbacks = [];\n };\n\n script.onerror = () => {\n this.loading = false;\n // M-02: Remove failed script from DOM to allow retry on next load() call.\n // Without removal, retry finds existingScript and waits for a load event\n // that will never fire on an already-failed script.\n script.remove();\n const error = new Error('Failed to load Google Sign-In script');\n this.callbacks.forEach((cb) => cb.reject(error));\n this.callbacks = [];\n };\n\n document.head.appendChild(script);\n });\n },\n\n /**\n * Reset singleton state for test isolation (F-08)\n * @internal - Only use in test setup/teardown\n */\n _reset(): void {\n this.loading = false;\n this.loaded = false;\n this.error = null;\n this.callbacks = [];\n },\n};\n\n/** @internal */\nexport const _internalGoogleScriptLoader = scriptLoader;\n\nexport interface UseGoogleAuthReturn {\n signIn: () => Promise<AuthResponse>;\n isLoading: boolean;\n isInitialized: boolean;\n error: AuthError | null;\n clearError: () => void;\n /** ID token saved when ACCOUNT_LINK_REQUIRED is returned. Pass to POST /auth/link-oauth with the user's password. */\n pendingLinkIdToken: string | null;\n /** Clear the pending link state */\n clearPendingLink: () => void;\n}\n\ninterface PromiseCallbacks {\n resolve: (value: AuthResponse) => void;\n reject: (error: AuthError) => void;\n}\n\n/**\n * Hook for Google OAuth authentication.\n *\n * @example\n * ```tsx\n * function GoogleButton() {\n * const { signIn, isLoading, isInitialized, error } = useGoogleAuth();\n *\n * return (\n * <button onClick={signIn} disabled={!isInitialized || isLoading}>\n * {isLoading ? 'Signing in...' : 'Sign in with Google'}\n * </button>\n * );\n * }\n * ```\n */\nexport function useGoogleAuth(): UseGoogleAuthReturn {\n const { config, _internal } = useCedrosLogin();\n const [isLoading, setIsLoading] = useState(false);\n const [isInitialized, setIsInitialized] = useState(false);\n const [error, setError] = useState<AuthError | null>(null);\n\n const [pendingLinkIdToken, setPendingLinkIdToken] = useState<string | null>(null);\n\n const promiseCallbacksRef = useRef<PromiseCallbacks | null>(null);\n const configRef = useRef(config);\n\n const apiClient = useMemo(\n () =>\n new ApiClient({\n baseUrl: config.serverUrl,\n timeoutMs: config.requestTimeout,\n retryAttempts: config.retryAttempts,\n }),\n [config.serverUrl, config.requestTimeout, config.retryAttempts]\n );\n\n // Keep config ref in sync\n useEffect(() => {\n configRef.current = config;\n }, [config]);\n\n // Handle credential response from Google\n const handleCredentialResponse = useCallback(\n async (response: { credential: string }) => {\n const callbacks = promiseCallbacksRef.current;\n if (!callbacks) return;\n\n try {\n const data = await apiClient.post<AuthResponse>('/google', {\n idToken: response.credential,\n });\n configRef.current.callbacks?.onLoginSuccess?.(data.user, 'google');\n _internal?.handleLoginSuccess(data.user, data.tokens);\n setIsLoading(false);\n callbacks.resolve(data);\n } catch (err) {\n const authError = handleApiError(err, 'Google sign-in failed');\n if (authError.code === 'ACCOUNT_LINK_REQUIRED') {\n setPendingLinkIdToken(response.credential);\n }\n setError(authError);\n setIsLoading(false);\n callbacks.reject(authError);\n } finally {\n promiseCallbacksRef.current = null;\n }\n },\n [apiClient, _internal]\n );\n\n // P-01: Initialize Google Sign-In SDK using singleton loader\n useEffect(() => {\n // Early return if Google auth is not enabled\n if (!config.googleClientId) {\n return;\n }\n\n // Track mounted state to prevent state updates after unmount\n let isMounted = true;\n\n const initializeGoogleSignIn = () => {\n if (!isMounted) return;\n\n window.google?.accounts?.id?.initialize({\n client_id: config.googleClientId!,\n callback: handleCredentialResponse,\n auto_select: false,\n cancel_on_tap_outside: true,\n });\n\n if (isMounted) {\n setIsInitialized(true);\n }\n };\n\n // Use singleton loader to handle script loading\n scriptLoader\n .load()\n .then(() => {\n if (isMounted) {\n initializeGoogleSignIn();\n }\n })\n .catch(() => {\n if (isMounted) {\n setError({\n code: 'SERVER_ERROR',\n message: 'Failed to load Google Sign-In',\n });\n }\n });\n\n return () => {\n isMounted = false;\n };\n }, [config.googleClientId, handleCredentialResponse]);\n\n const signIn = useCallback(async (): Promise<AuthResponse> => {\n if (!config.googleClientId) {\n const err: AuthError = {\n code: 'VALIDATION_ERROR',\n message: 'Google Client ID not configured',\n };\n setError(err);\n throw err;\n }\n\n if (!isInitialized) {\n const err: AuthError = {\n code: 'VALIDATION_ERROR',\n message: 'Google Sign-In not initialized',\n };\n setError(err);\n throw err;\n }\n\n if (promiseCallbacksRef.current) {\n const err: AuthError = {\n code: 'VALIDATION_ERROR',\n message: 'Google Sign-In already in progress',\n };\n setError(err);\n throw err;\n }\n\n setIsLoading(true);\n setError(null);\n\n return new Promise<AuthResponse>((resolve, reject) => {\n promiseCallbacksRef.current = { resolve, reject };\n\n // Show Google One Tap prompt\n window.google?.accounts?.id?.prompt((notification) => {\n if (notification.isNotDisplayed()) {\n const err: AuthError = {\n code: 'SERVER_ERROR',\n message: 'Google Sign-In popup was blocked. Please allow popups or try again.',\n };\n setError(err);\n setIsLoading(false);\n promiseCallbacksRef.current = null;\n reject(err);\n } else if (notification.isSkippedMoment()) {\n const err: AuthError = {\n code: 'SERVER_ERROR',\n message: 'Google Sign-In was cancelled',\n };\n setError(err);\n setIsLoading(false);\n promiseCallbacksRef.current = null;\n reject(err);\n } else if (notification.isDismissedMoment()) {\n const err: AuthError = {\n code: 'SERVER_ERROR',\n message: 'Google Sign-In was cancelled',\n };\n setError(err);\n setIsLoading(false);\n promiseCallbacksRef.current = null;\n reject(err);\n }\n });\n });\n }, [config.googleClientId, isInitialized]);\n\n const clearError = useCallback(() => setError(null), []);\n const clearPendingLink = useCallback(() => setPendingLinkIdToken(null), []);\n\n return {\n signIn,\n isLoading,\n isInitialized,\n error,\n clearError,\n pendingLinkIdToken,\n clearPendingLink,\n };\n}\n\n// Type declaration for Google Identity Services\ndeclare global {\n interface Window {\n google?: {\n accounts?: {\n id?: {\n initialize: (config: {\n client_id: string;\n callback: (response: { credential: string }) => void;\n auto_select?: boolean;\n cancel_on_tap_outside?: boolean;\n }) => void;\n prompt: (\n callback: (notification: {\n isNotDisplayed: () => boolean;\n isSkippedMoment: () => boolean;\n isDismissedMoment: () => boolean;\n getMomentType: () => string;\n }) => void\n ) => void;\n renderButton: (element: HTMLElement, config: object) => void;\n disableAutoSelect: () => void;\n };\n };\n };\n }\n}\n","import { useGoogleAuth } from '../../hooks/useGoogleAuth';\nimport { LoadingSpinner } from '../shared/LoadingSpinner';\n\nexport interface GoogleLoginButtonProps {\n onSuccess?: () => void;\n onError?: (error: Error) => void;\n className?: string;\n variant?: 'default' | 'outline';\n size?: 'sm' | 'md' | 'lg';\n disabled?: boolean;\n}\n\n/**\n * Google OAuth login button\n */\nexport function GoogleLoginButton({\n onSuccess,\n onError,\n className = '',\n variant = 'default',\n size = 'md',\n disabled = false,\n}: GoogleLoginButtonProps) {\n const { signIn, isLoading, isInitialized } = useGoogleAuth();\n\n const handleClick = async () => {\n try {\n await signIn();\n onSuccess?.();\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n onError?.(error);\n }\n };\n\n const sizeClasses = {\n sm: 'cedros-button-sm',\n md: 'cedros-button-md',\n lg: 'cedros-button-lg',\n };\n\n const variantClasses = {\n default: 'cedros-button-social',\n outline: 'cedros-button-social-outline',\n };\n\n return (\n <button\n type=\"button\"\n className={`cedros-button ${variantClasses[variant]} ${sizeClasses[size]} ${className}`}\n onClick={handleClick}\n disabled={disabled || !isInitialized || isLoading}\n aria-label=\"Sign in with Google\"\n >\n {isLoading ? (\n <LoadingSpinner size=\"sm\" />\n ) : (\n <svg\n className=\"cedros-button-icon\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 18 18\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844c-.209 1.125-.843 2.078-1.796 2.717v2.258h2.908c1.702-1.567 2.684-3.874 2.684-6.615z\"\n fill=\"#4285F4\"\n />\n <path\n d=\"M9.003 18c2.43 0 4.467-.806 5.956-2.18l-2.909-2.26c-.806.54-1.836.86-3.047.86-2.344 0-4.328-1.584-5.036-3.711H.96v2.332A8.997 8.997 0 0 0 9.003 18z\"\n fill=\"#34A853\"\n />\n <path\n d=\"M3.964 10.712A5.41 5.41 0 0 1 3.682 9c0-.593.102-1.17.282-1.71V4.958H.96A8.996 8.996 0 0 0 0 9c0 1.452.348 2.827.96 4.042l3.004-2.33z\"\n fill=\"#FBBC05\"\n />\n <path\n d=\"M9.003 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.464.891 11.428 0 9.002 0A8.997 8.997 0 0 0 .96 4.958l3.005 2.332c.708-2.127 2.692-3.71 5.036-3.71z\"\n fill=\"#EA4335\"\n />\n </svg>\n )}\n <span>Continue with Google</span>\n </button>\n );\n}\n"],"names":["scriptLoader","resolve","reject","existingScript","cb","script","error","useGoogleAuth","config","_internal","useCedrosLogin","isLoading","setIsLoading","useState","isInitialized","setIsInitialized","setError","pendingLinkIdToken","setPendingLinkIdToken","promiseCallbacksRef","useRef","configRef","apiClient","useMemo","ApiClient","useEffect","handleCredentialResponse","useCallback","response","callbacks","data","err","authError","handleApiError","isMounted","initializeGoogleSignIn","signIn","notification","clearError","clearPendingLink","GoogleLoginButton","onSuccess","onError","className","variant","size","disabled","handleClick","sizeClasses","jsxs","jsx","LoadingSpinner"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const u=require("react/jsx-runtime"),l=require("react"),I=require("./useCedrosLogin-C9MrcZvh.cjs"),A=require("./LoadingSpinner-d6sSxgQN.cjs"),L={loading:!1,loaded:!1,error:null,callbacks:[],load(){return typeof window>"u"||typeof document>"u"?Promise.reject(new Error("Google Sign-In script loader cannot run in SSR")):this.loaded?Promise.resolve():this.loading?new Promise((e,d)=>{this.callbacks.push({resolve:e,reject:d})}):(this.loading=!0,new Promise((e,d)=>{this.callbacks.push({resolve:e,reject:d});const g=document.getElementById("google-gsi-script");if(g){window.google?.accounts?.id?(this.loaded=!0,this.loading=!1,this.callbacks.forEach(t=>t.resolve()),this.callbacks=[]):g.addEventListener("load",()=>{this.loaded=!0,this.loading=!1,this.callbacks.forEach(t=>t.resolve()),this.callbacks=[]});return}const o=document.createElement("script");o.src="https://accounts.google.com/gsi/client",o.async=!0,o.defer=!0,o.id="google-gsi-script",o.onload=()=>{this.loaded=!0,this.loading=!1,this.callbacks.forEach(t=>t.resolve()),this.callbacks=[]},o.onerror=()=>{this.loading=!1,o.remove();const t=new Error("Failed to load Google Sign-In script");this.callbacks.forEach(h=>h.reject(t)),this.callbacks=[]},document.head.appendChild(o)}))},_reset(){this.loading=!1,this.loaded=!1,this.error=null,this.callbacks=[]}};function k(){const{config:e,_internal:d}=I.useCedrosLogin(),[g,o]=l.useState(!1),[t,h]=l.useState(!1),[E,n]=l.useState(null),[b,p]=l.useState(null),c=l.useRef(null),m=l.useRef(e),f=l.useMemo(()=>new I.ApiClient({baseUrl:e.serverUrl,timeoutMs:e.requestTimeout,retryAttempts:e.retryAttempts}),[e.serverUrl,e.requestTimeout,e.retryAttempts]);l.useEffect(()=>{m.current=e},[e]);const R=l.useCallback(async s=>{const r=c.current;if(r)try{const a=await f.post("/google",{idToken:s.credential});m.current.callbacks?.onLoginSuccess?.(a.user,"google"),d?.handleLoginSuccess(a.user,a.tokens),o(!1),r.resolve(a)}catch(a){const i=I.handleApiError(a,"Google sign-in failed");i.code==="ACCOUNT_LINK_REQUIRED"&&p(s.credential),n(i),o(!1),r.reject(i)}finally{c.current=null}},[f,d]);l.useEffect(()=>{if(!e.googleClientId)return;let s=!0;const r=()=>{s&&(window.google?.accounts?.id?.initialize({client_id:e.googleClientId,callback:R,auto_select:!1,cancel_on_tap_outside:!0}),s&&h(!0))};return L.load().then(()=>{s&&r()}).catch(()=>{s&&n({code:"SERVER_ERROR",message:"Failed to load Google Sign-In"})}),()=>{s=!1}},[e.googleClientId,R]);const w=l.useCallback(async()=>{if(!e.googleClientId){const s={code:"VALIDATION_ERROR",message:"Google Client ID not configured"};throw n(s),s}if(!t){const s={code:"VALIDATION_ERROR",message:"Google Sign-In not initialized"};throw n(s),s}if(c.current){const s={code:"VALIDATION_ERROR",message:"Google Sign-In already in progress"};throw n(s),s}return o(!0),n(null),new Promise((s,r)=>{c.current={resolve:s,reject:r},window.google?.accounts?.id?.prompt(a=>{if(a.isNotDisplayed()){const i={code:"SERVER_ERROR",message:"Google Sign-In popup was blocked. Please allow popups or try again."};n(i),o(!1),c.current=null,r(i)}else if(a.isSkippedMoment()){const i={code:"SERVER_ERROR",message:"Google Sign-In was cancelled"};n(i),o(!1),c.current=null,r(i)}else if(a.isDismissedMoment()){const i={code:"SERVER_ERROR",message:"Google Sign-In was cancelled"};n(i),o(!1),c.current=null,r(i)}})})},[e.googleClientId,t]),S=l.useCallback(()=>n(null),[]),C=l.useCallback(()=>p(null),[]);return{signIn:w,isLoading:g,isInitialized:t,error:E,clearError:S,pendingLinkIdToken:b,clearPendingLink:C}}function y({onSuccess:e,onError:d,className:g="",variant:o="default",size:t="md",disabled:h=!1}){const{signIn:E,isLoading:n,isInitialized:b}=k(),p=async()=>{try{await E(),e?.()}catch(f){const R=f instanceof Error?f:new Error(String(f));d?.(R)}},c={sm:"cedros-button-sm",md:"cedros-button-md",lg:"cedros-button-lg"},m={default:"cedros-button-social",outline:"cedros-button-social-outline"};return u.jsxs("button",{type:"button",className:`cedros-button ${m[o]} ${c[t]} ${g}`,onClick:p,disabled:h||!b||n,"aria-label":"Sign in with Google",children:[n?u.jsx(A.LoadingSpinner,{size:"sm"}):u.jsxs("svg",{className:"cedros-button-icon",width:"18",height:"18",viewBox:"0 0 18 18",fill:"none","aria-hidden":"true",children:[u.jsx("path",{d:"M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844c-.209 1.125-.843 2.078-1.796 2.717v2.258h2.908c1.702-1.567 2.684-3.874 2.684-6.615z",fill:"#4285F4"}),u.jsx("path",{d:"M9.003 18c2.43 0 4.467-.806 5.956-2.18l-2.909-2.26c-.806.54-1.836.86-3.047.86-2.344 0-4.328-1.584-5.036-3.711H.96v2.332A8.997 8.997 0 0 0 9.003 18z",fill:"#34A853"}),u.jsx("path",{d:"M3.964 10.712A5.41 5.41 0 0 1 3.682 9c0-.593.102-1.17.282-1.71V4.958H.96A8.996 8.996 0 0 0 0 9c0 1.452.348 2.827.96 4.042l3.004-2.33z",fill:"#FBBC05"}),u.jsx("path",{d:"M9.003 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.464.891 11.428 0 9.002 0A8.997 8.997 0 0 0 .96 4.958l3.005 2.332c.708-2.127 2.692-3.71 5.036-3.71z",fill:"#EA4335"})]}),u.jsx("span",{children:"Continue with Google"})]})}exports.GoogleLoginButton=y;exports.useGoogleAuth=k;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GoogleLoginButton-D7CoMXLq.cjs","sources":["../src/hooks/useGoogleAuth.ts","../src/components/google/GoogleLoginButton.tsx"],"sourcesContent":["import { useState, useCallback, useEffect, useRef, useMemo } from 'react';\nimport { useCedrosLogin } from '../context/useCedrosLogin';\nimport { ApiClient, handleApiError } from '../utils/apiClient';\nimport type { AuthResponse, AuthError } from '../types';\n\n/**\n * Module-level singleton for Google script loading (P-01)\n *\n * Prevents race conditions when multiple components mount simultaneously.\n * Uses a promise queue pattern to ensure the script is only loaded once.\n *\n * ## SSR Limitations (F-08)\n *\n * This singleton persists across the module lifecycle. In SSR environments:\n * - Module state persists between requests (potential cross-request leakage)\n * - Google Sign-In requires browser APIs (document, window)\n * - The hook guards against SSR with `googleClientId` checks\n *\n * For SSR frameworks (Next.js, Remix), ensure this hook is only used\n * in client-side components.\n *\n * ## Test Isolation\n *\n * For test isolation, call `scriptLoader._reset()` in test setup/teardown.\n *\n * @internal\n */\nconst scriptLoader = {\n loading: false,\n loaded: false,\n error: null as Error | null,\n callbacks: [] as Array<{ resolve: () => void; reject: (err: Error) => void }>,\n\n load(): Promise<void> {\n // SSR guard: avoid touching browser globals when running in Node/SSR.\n if (typeof window === 'undefined' || typeof document === 'undefined') {\n return Promise.reject(new Error('Google Sign-In script loader cannot run in SSR'));\n }\n\n // Already loaded\n if (this.loaded) {\n return Promise.resolve();\n }\n\n // Loading in progress - queue callback\n if (this.loading) {\n return new Promise((resolve, reject) => {\n this.callbacks.push({ resolve, reject });\n });\n }\n\n // Start loading\n this.loading = true;\n return new Promise((resolve, reject) => {\n this.callbacks.push({ resolve, reject });\n\n // Check if script already exists (from previous session or SSR)\n const existingScript = document.getElementById('google-gsi-script');\n if (existingScript) {\n if (window.google?.accounts?.id) {\n this.loaded = true;\n this.loading = false;\n this.callbacks.forEach((cb) => cb.resolve());\n this.callbacks = [];\n } else {\n existingScript.addEventListener('load', () => {\n this.loaded = true;\n this.loading = false;\n this.callbacks.forEach((cb) => cb.resolve());\n this.callbacks = [];\n });\n }\n return;\n }\n\n const script = document.createElement('script');\n script.src = 'https://accounts.google.com/gsi/client';\n script.async = true;\n script.defer = true;\n script.id = 'google-gsi-script';\n\n script.onload = () => {\n this.loaded = true;\n this.loading = false;\n this.callbacks.forEach((cb) => cb.resolve());\n this.callbacks = [];\n };\n\n script.onerror = () => {\n this.loading = false;\n // M-02: Remove failed script from DOM to allow retry on next load() call.\n // Without removal, retry finds existingScript and waits for a load event\n // that will never fire on an already-failed script.\n script.remove();\n const error = new Error('Failed to load Google Sign-In script');\n this.callbacks.forEach((cb) => cb.reject(error));\n this.callbacks = [];\n };\n\n document.head.appendChild(script);\n });\n },\n\n /**\n * Reset singleton state for test isolation (F-08)\n * @internal - Only use in test setup/teardown\n */\n _reset(): void {\n this.loading = false;\n this.loaded = false;\n this.error = null;\n this.callbacks = [];\n },\n};\n\n/** @internal */\nexport const _internalGoogleScriptLoader = scriptLoader;\n\nexport interface UseGoogleAuthReturn {\n signIn: () => Promise<AuthResponse>;\n isLoading: boolean;\n isInitialized: boolean;\n error: AuthError | null;\n clearError: () => void;\n /** ID token saved when ACCOUNT_LINK_REQUIRED is returned. Pass to POST /auth/link-oauth with the user's password. */\n pendingLinkIdToken: string | null;\n /** Clear the pending link state */\n clearPendingLink: () => void;\n}\n\ninterface PromiseCallbacks {\n resolve: (value: AuthResponse) => void;\n reject: (error: AuthError) => void;\n}\n\n/**\n * Hook for Google OAuth authentication.\n *\n * @example\n * ```tsx\n * function GoogleButton() {\n * const { signIn, isLoading, isInitialized, error } = useGoogleAuth();\n *\n * return (\n * <button onClick={signIn} disabled={!isInitialized || isLoading}>\n * {isLoading ? 'Signing in...' : 'Sign in with Google'}\n * </button>\n * );\n * }\n * ```\n */\nexport function useGoogleAuth(): UseGoogleAuthReturn {\n const { config, _internal } = useCedrosLogin();\n const [isLoading, setIsLoading] = useState(false);\n const [isInitialized, setIsInitialized] = useState(false);\n const [error, setError] = useState<AuthError | null>(null);\n\n const [pendingLinkIdToken, setPendingLinkIdToken] = useState<string | null>(null);\n\n const promiseCallbacksRef = useRef<PromiseCallbacks | null>(null);\n const configRef = useRef(config);\n\n const apiClient = useMemo(\n () =>\n new ApiClient({\n baseUrl: config.serverUrl,\n timeoutMs: config.requestTimeout,\n retryAttempts: config.retryAttempts,\n }),\n [config.serverUrl, config.requestTimeout, config.retryAttempts]\n );\n\n // Keep config ref in sync\n useEffect(() => {\n configRef.current = config;\n }, [config]);\n\n // Handle credential response from Google\n const handleCredentialResponse = useCallback(\n async (response: { credential: string }) => {\n const callbacks = promiseCallbacksRef.current;\n if (!callbacks) return;\n\n try {\n const data = await apiClient.post<AuthResponse>('/google', {\n idToken: response.credential,\n });\n configRef.current.callbacks?.onLoginSuccess?.(data.user, 'google');\n _internal?.handleLoginSuccess(data.user, data.tokens);\n setIsLoading(false);\n callbacks.resolve(data);\n } catch (err) {\n const authError = handleApiError(err, 'Google sign-in failed');\n if (authError.code === 'ACCOUNT_LINK_REQUIRED') {\n setPendingLinkIdToken(response.credential);\n }\n setError(authError);\n setIsLoading(false);\n callbacks.reject(authError);\n } finally {\n promiseCallbacksRef.current = null;\n }\n },\n [apiClient, _internal]\n );\n\n // P-01: Initialize Google Sign-In SDK using singleton loader\n useEffect(() => {\n // Early return if Google auth is not enabled\n if (!config.googleClientId) {\n return;\n }\n\n // Track mounted state to prevent state updates after unmount\n let isMounted = true;\n\n const initializeGoogleSignIn = () => {\n if (!isMounted) return;\n\n window.google?.accounts?.id?.initialize({\n client_id: config.googleClientId!,\n callback: handleCredentialResponse,\n auto_select: false,\n cancel_on_tap_outside: true,\n });\n\n if (isMounted) {\n setIsInitialized(true);\n }\n };\n\n // Use singleton loader to handle script loading\n scriptLoader\n .load()\n .then(() => {\n if (isMounted) {\n initializeGoogleSignIn();\n }\n })\n .catch(() => {\n if (isMounted) {\n setError({\n code: 'SERVER_ERROR',\n message: 'Failed to load Google Sign-In',\n });\n }\n });\n\n return () => {\n isMounted = false;\n };\n }, [config.googleClientId, handleCredentialResponse]);\n\n const signIn = useCallback(async (): Promise<AuthResponse> => {\n if (!config.googleClientId) {\n const err: AuthError = {\n code: 'VALIDATION_ERROR',\n message: 'Google Client ID not configured',\n };\n setError(err);\n throw err;\n }\n\n if (!isInitialized) {\n const err: AuthError = {\n code: 'VALIDATION_ERROR',\n message: 'Google Sign-In not initialized',\n };\n setError(err);\n throw err;\n }\n\n if (promiseCallbacksRef.current) {\n const err: AuthError = {\n code: 'VALIDATION_ERROR',\n message: 'Google Sign-In already in progress',\n };\n setError(err);\n throw err;\n }\n\n setIsLoading(true);\n setError(null);\n\n return new Promise<AuthResponse>((resolve, reject) => {\n promiseCallbacksRef.current = { resolve, reject };\n\n // Show Google One Tap prompt\n window.google?.accounts?.id?.prompt((notification) => {\n if (notification.isNotDisplayed()) {\n const err: AuthError = {\n code: 'SERVER_ERROR',\n message: 'Google Sign-In popup was blocked. Please allow popups or try again.',\n };\n setError(err);\n setIsLoading(false);\n promiseCallbacksRef.current = null;\n reject(err);\n } else if (notification.isSkippedMoment()) {\n const err: AuthError = {\n code: 'SERVER_ERROR',\n message: 'Google Sign-In was cancelled',\n };\n setError(err);\n setIsLoading(false);\n promiseCallbacksRef.current = null;\n reject(err);\n } else if (notification.isDismissedMoment()) {\n const err: AuthError = {\n code: 'SERVER_ERROR',\n message: 'Google Sign-In was cancelled',\n };\n setError(err);\n setIsLoading(false);\n promiseCallbacksRef.current = null;\n reject(err);\n }\n });\n });\n }, [config.googleClientId, isInitialized]);\n\n const clearError = useCallback(() => setError(null), []);\n const clearPendingLink = useCallback(() => setPendingLinkIdToken(null), []);\n\n return {\n signIn,\n isLoading,\n isInitialized,\n error,\n clearError,\n pendingLinkIdToken,\n clearPendingLink,\n };\n}\n\n// Type declaration for Google Identity Services\ndeclare global {\n interface Window {\n google?: {\n accounts?: {\n id?: {\n initialize: (config: {\n client_id: string;\n callback: (response: { credential: string }) => void;\n auto_select?: boolean;\n cancel_on_tap_outside?: boolean;\n }) => void;\n prompt: (\n callback: (notification: {\n isNotDisplayed: () => boolean;\n isSkippedMoment: () => boolean;\n isDismissedMoment: () => boolean;\n getMomentType: () => string;\n }) => void\n ) => void;\n renderButton: (element: HTMLElement, config: object) => void;\n disableAutoSelect: () => void;\n };\n };\n };\n }\n}\n","import { useGoogleAuth } from '../../hooks/useGoogleAuth';\nimport { LoadingSpinner } from '../shared/LoadingSpinner';\n\nexport interface GoogleLoginButtonProps {\n onSuccess?: () => void;\n onError?: (error: Error) => void;\n className?: string;\n variant?: 'default' | 'outline';\n size?: 'sm' | 'md' | 'lg';\n disabled?: boolean;\n}\n\n/**\n * Google OAuth login button\n */\nexport function GoogleLoginButton({\n onSuccess,\n onError,\n className = '',\n variant = 'default',\n size = 'md',\n disabled = false,\n}: GoogleLoginButtonProps) {\n const { signIn, isLoading, isInitialized } = useGoogleAuth();\n\n const handleClick = async () => {\n try {\n await signIn();\n onSuccess?.();\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n onError?.(error);\n }\n };\n\n const sizeClasses = {\n sm: 'cedros-button-sm',\n md: 'cedros-button-md',\n lg: 'cedros-button-lg',\n };\n\n const variantClasses = {\n default: 'cedros-button-social',\n outline: 'cedros-button-social-outline',\n };\n\n return (\n <button\n type=\"button\"\n className={`cedros-button ${variantClasses[variant]} ${sizeClasses[size]} ${className}`}\n onClick={handleClick}\n disabled={disabled || !isInitialized || isLoading}\n aria-label=\"Sign in with Google\"\n >\n {isLoading ? (\n <LoadingSpinner size=\"sm\" />\n ) : (\n <svg\n className=\"cedros-button-icon\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 18 18\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844c-.209 1.125-.843 2.078-1.796 2.717v2.258h2.908c1.702-1.567 2.684-3.874 2.684-6.615z\"\n fill=\"#4285F4\"\n />\n <path\n d=\"M9.003 18c2.43 0 4.467-.806 5.956-2.18l-2.909-2.26c-.806.54-1.836.86-3.047.86-2.344 0-4.328-1.584-5.036-3.711H.96v2.332A8.997 8.997 0 0 0 9.003 18z\"\n fill=\"#34A853\"\n />\n <path\n d=\"M3.964 10.712A5.41 5.41 0 0 1 3.682 9c0-.593.102-1.17.282-1.71V4.958H.96A8.996 8.996 0 0 0 0 9c0 1.452.348 2.827.96 4.042l3.004-2.33z\"\n fill=\"#FBBC05\"\n />\n <path\n d=\"M9.003 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.464.891 11.428 0 9.002 0A8.997 8.997 0 0 0 .96 4.958l3.005 2.332c.708-2.127 2.692-3.71 5.036-3.71z\"\n fill=\"#EA4335\"\n />\n </svg>\n )}\n <span>Continue with Google</span>\n </button>\n );\n}\n"],"names":["scriptLoader","resolve","reject","existingScript","cb","script","error","useGoogleAuth","config","_internal","useCedrosLogin","isLoading","setIsLoading","useState","isInitialized","setIsInitialized","setError","pendingLinkIdToken","setPendingLinkIdToken","promiseCallbacksRef","useRef","configRef","apiClient","useMemo","ApiClient","useEffect","handleCredentialResponse","useCallback","response","callbacks","data","err","authError","handleApiError","isMounted","initializeGoogleSignIn","signIn","notification","clearError","clearPendingLink","GoogleLoginButton","onSuccess","onError","className","variant","size","disabled","handleClick","sizeClasses","variantClasses","jsxs","jsx","LoadingSpinner"],"mappings":"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"}
|
package/dist/email-only.d.ts
CHANGED
|
@@ -30,7 +30,7 @@ export declare interface AuthError {
|
|
|
30
30
|
/**
|
|
31
31
|
* Standard error codes
|
|
32
32
|
*/
|
|
33
|
-
export declare type AuthErrorCode = 'INVALID_CREDENTIALS' | 'ACCOUNT_LOCKED' | 'EMAIL_EXISTS' | 'WALLET_EXISTS' | 'INVALID_TOKEN' | 'TOKEN_EXPIRED' | 'INVALID_SIGNATURE' | 'INVALID_PUBLIC_KEY' | 'CHALLENGE_EXPIRED' | 'VALIDATION_ERROR' | 'RATE_LIMITED' | 'NOT_FOUND' | 'FORBIDDEN' | 'UNAUTHORIZED' | 'STEP_UP_REQUIRED' | 'TOTP_REQUIRED' | 'INVALID_TOTP_CODE' | 'SERVICE_UNAVAILABLE' | 'SERVER_ERROR' | 'NETWORK_ERROR' | 'UNKNOWN_ERROR';
|
|
33
|
+
export declare type AuthErrorCode = 'INVALID_CREDENTIALS' | 'ACCOUNT_LOCKED' | 'EMAIL_EXISTS' | 'ACCOUNT_LINK_REQUIRED' | 'WALLET_EXISTS' | 'INVALID_TOKEN' | 'TOKEN_EXPIRED' | 'INVALID_SIGNATURE' | 'INVALID_PUBLIC_KEY' | 'CHALLENGE_EXPIRED' | 'VALIDATION_ERROR' | 'RATE_LIMITED' | 'NOT_FOUND' | 'FORBIDDEN' | 'UNAUTHORIZED' | 'STEP_UP_REQUIRED' | 'TOTP_REQUIRED' | 'INVALID_TOTP_CODE' | 'SERVICE_UNAVAILABLE' | 'SERVER_ERROR' | 'NETWORK_ERROR' | 'UNKNOWN_ERROR';
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
36
|
* Authentication method used for login/registration
|
package/dist/google-only.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./useAuth-X6Ds6WW4.cjs"),r=require("./useCedrosLogin-C9MrcZvh.cjs"),o=require("./GoogleLoginButton-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./useAuth-X6Ds6WW4.cjs"),r=require("./useCedrosLogin-C9MrcZvh.cjs"),o=require("./GoogleLoginButton-D7CoMXLq.cjs"),n=require("./LoadingSpinner-d6sSxgQN.cjs"),s=require("./ErrorMessage-CHbYbVi2.cjs");exports.CedrosLoginProvider=e.CedrosLoginProvider;exports.useAuth=e.useAuth;exports.useCedrosLogin=r.useCedrosLogin;exports.GoogleLoginButton=o.GoogleLoginButton;exports.useGoogleAuth=o.useGoogleAuth;exports.LoadingSpinner=n.LoadingSpinner;exports.ErrorMessage=s.ErrorMessage;
|
package/dist/google-only.d.ts
CHANGED
|
@@ -29,7 +29,7 @@ export declare interface AuthError {
|
|
|
29
29
|
/**
|
|
30
30
|
* Standard error codes
|
|
31
31
|
*/
|
|
32
|
-
export declare type AuthErrorCode = 'INVALID_CREDENTIALS' | 'ACCOUNT_LOCKED' | 'EMAIL_EXISTS' | 'WALLET_EXISTS' | 'INVALID_TOKEN' | 'TOKEN_EXPIRED' | 'INVALID_SIGNATURE' | 'INVALID_PUBLIC_KEY' | 'CHALLENGE_EXPIRED' | 'VALIDATION_ERROR' | 'RATE_LIMITED' | 'NOT_FOUND' | 'FORBIDDEN' | 'UNAUTHORIZED' | 'STEP_UP_REQUIRED' | 'TOTP_REQUIRED' | 'INVALID_TOTP_CODE' | 'SERVICE_UNAVAILABLE' | 'SERVER_ERROR' | 'NETWORK_ERROR' | 'UNKNOWN_ERROR';
|
|
32
|
+
export declare type AuthErrorCode = 'INVALID_CREDENTIALS' | 'ACCOUNT_LOCKED' | 'EMAIL_EXISTS' | 'ACCOUNT_LINK_REQUIRED' | 'WALLET_EXISTS' | 'INVALID_TOKEN' | 'TOKEN_EXPIRED' | 'INVALID_SIGNATURE' | 'INVALID_PUBLIC_KEY' | 'CHALLENGE_EXPIRED' | 'VALIDATION_ERROR' | 'RATE_LIMITED' | 'NOT_FOUND' | 'FORBIDDEN' | 'UNAUTHORIZED' | 'STEP_UP_REQUIRED' | 'TOTP_REQUIRED' | 'INVALID_TOTP_CODE' | 'SERVICE_UNAVAILABLE' | 'SERVER_ERROR' | 'NETWORK_ERROR' | 'UNKNOWN_ERROR';
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
35
|
* Authentication method used for login/registration
|
|
@@ -546,6 +546,10 @@ declare interface UseGoogleAuthReturn {
|
|
|
546
546
|
isInitialized: boolean;
|
|
547
547
|
error: AuthError | null;
|
|
548
548
|
clearError: () => void;
|
|
549
|
+
/** ID token saved when ACCOUNT_LINK_REQUIRED is returned. Pass to POST /auth/link-oauth with the user's password. */
|
|
550
|
+
pendingLinkIdToken: string | null;
|
|
551
|
+
/** Clear the pending link state */
|
|
552
|
+
clearPendingLink: () => void;
|
|
549
553
|
}
|
|
550
554
|
|
|
551
555
|
/**
|
package/dist/google-only.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { C as e, u as s } from "./useAuth-m5Hf89v8.js";
|
|
2
2
|
import { u as t } from "./useCedrosLogin-_94MmGGq.js";
|
|
3
|
-
import { G as g, u as n } from "./GoogleLoginButton-
|
|
3
|
+
import { G as g, u as n } from "./GoogleLoginButton-B6qnNMZp.js";
|
|
4
4
|
import { L as p } from "./LoadingSpinner-6vml-zwr.js";
|
|
5
5
|
import { E as m } from "./ErrorMessage-CcEK0pYO.js";
|
|
6
6
|
export {
|