@netlify/identity 0.1.1-alpha.6 → 0.1.1-alpha.8
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/index.cjs +105 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -6
- package/dist/index.d.ts +7 -6
- package/dist/index.js +105 -29
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -129,6 +129,43 @@ var getIdentityContext = () => {
|
|
|
129
129
|
return null;
|
|
130
130
|
};
|
|
131
131
|
|
|
132
|
+
// src/cookies.ts
|
|
133
|
+
var NF_JWT_COOKIE = "nf_jwt";
|
|
134
|
+
var NF_REFRESH_COOKIE = "nf_refresh";
|
|
135
|
+
var getCookie = (name) => {
|
|
136
|
+
const match = document.cookie.match(new RegExp(`(?:^|; )${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}=([^;]*)`));
|
|
137
|
+
return match ? decodeURIComponent(match[1]) : null;
|
|
138
|
+
};
|
|
139
|
+
var setAuthCookies = (cookies, accessToken, refreshToken) => {
|
|
140
|
+
cookies.set({
|
|
141
|
+
name: NF_JWT_COOKIE,
|
|
142
|
+
value: accessToken,
|
|
143
|
+
httpOnly: false,
|
|
144
|
+
secure: true,
|
|
145
|
+
path: "/",
|
|
146
|
+
sameSite: "Lax"
|
|
147
|
+
});
|
|
148
|
+
if (refreshToken) {
|
|
149
|
+
cookies.set({
|
|
150
|
+
name: NF_REFRESH_COOKIE,
|
|
151
|
+
value: refreshToken,
|
|
152
|
+
httpOnly: false,
|
|
153
|
+
secure: true,
|
|
154
|
+
path: "/",
|
|
155
|
+
sameSite: "Lax"
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
var deleteAuthCookies = (cookies) => {
|
|
160
|
+
cookies.delete(NF_JWT_COOKIE);
|
|
161
|
+
cookies.delete(NF_REFRESH_COOKIE);
|
|
162
|
+
};
|
|
163
|
+
var getServerCookie = (name) => {
|
|
164
|
+
const cookies = globalThis.Netlify?.context?.cookies;
|
|
165
|
+
if (!cookies || typeof cookies.get !== "function") return null;
|
|
166
|
+
return cookies.get(name) ?? null;
|
|
167
|
+
};
|
|
168
|
+
|
|
132
169
|
// src/user.ts
|
|
133
170
|
var toAuthProvider = (value) => typeof value === "string" && AUTH_PROVIDERS.includes(value) ? value : void 0;
|
|
134
171
|
var toUser = (userData) => {
|
|
@@ -161,16 +198,40 @@ var claimsToUser = (claims) => {
|
|
|
161
198
|
metadata: userMeta
|
|
162
199
|
};
|
|
163
200
|
};
|
|
201
|
+
var decodeJwtPayload = (token) => {
|
|
202
|
+
try {
|
|
203
|
+
const parts = token.split(".");
|
|
204
|
+
if (parts.length !== 3) return null;
|
|
205
|
+
const payload = atob(parts[1].replace(/-/g, "+").replace(/_/g, "/"));
|
|
206
|
+
return JSON.parse(payload);
|
|
207
|
+
} catch {
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
};
|
|
164
211
|
var getUser = () => {
|
|
165
212
|
if (isBrowser()) {
|
|
166
213
|
const client = getGoTrueClient();
|
|
167
214
|
const currentUser = client?.currentUser() ?? null;
|
|
168
|
-
if (
|
|
169
|
-
|
|
215
|
+
if (currentUser) return toUser(currentUser);
|
|
216
|
+
const jwt2 = getCookie(NF_JWT_COOKIE);
|
|
217
|
+
if (!jwt2) return null;
|
|
218
|
+
const claims = decodeJwtPayload(jwt2);
|
|
219
|
+
if (!claims) return null;
|
|
220
|
+
return claimsToUser(claims);
|
|
170
221
|
}
|
|
171
222
|
const identityContext = globalThis.netlifyIdentityContext;
|
|
172
|
-
if (
|
|
173
|
-
|
|
223
|
+
if (identityContext?.user) {
|
|
224
|
+
return claimsToUser(identityContext.user);
|
|
225
|
+
}
|
|
226
|
+
const jwt = getServerCookie(NF_JWT_COOKIE);
|
|
227
|
+
if (jwt) {
|
|
228
|
+
console.debug(
|
|
229
|
+
`[@netlify/identity] getUser: no identityContext.user, but nf_jwt cookie found on request. Decoding JWT from cookie. (identityContext: ${identityContext ? `{ url: ${!!identityContext.url}, token: ${!!identityContext.token}, user: ${!!identityContext.user} }` : "null"}, Netlify.context: ${!!globalThis.Netlify?.context})`
|
|
230
|
+
);
|
|
231
|
+
const claims = decodeJwtPayload(jwt);
|
|
232
|
+
if (claims) return claimsToUser(claims);
|
|
233
|
+
}
|
|
234
|
+
return null;
|
|
174
235
|
};
|
|
175
236
|
var isAuthenticated = () => getUser() !== null;
|
|
176
237
|
|
|
@@ -297,14 +358,7 @@ var login = async (email, password) => {
|
|
|
297
358
|
}
|
|
298
359
|
const userData = await userRes.json();
|
|
299
360
|
const user = toUser(userData);
|
|
300
|
-
cookies.
|
|
301
|
-
name: "nf_jwt",
|
|
302
|
-
value: accessToken,
|
|
303
|
-
httpOnly: true,
|
|
304
|
-
secure: true,
|
|
305
|
-
path: "/",
|
|
306
|
-
sameSite: "Lax"
|
|
307
|
-
});
|
|
361
|
+
setAuthCookies(cookies, accessToken, data.refresh_token);
|
|
308
362
|
return user;
|
|
309
363
|
}
|
|
310
364
|
const client = getClient();
|
|
@@ -338,16 +392,10 @@ var signup = async (email, password, data) => {
|
|
|
338
392
|
const responseData = await res.json();
|
|
339
393
|
const user = toUser(responseData);
|
|
340
394
|
if (responseData.confirmed_at) {
|
|
341
|
-
const
|
|
395
|
+
const responseRecord = responseData;
|
|
396
|
+
const accessToken = responseRecord.access_token;
|
|
342
397
|
if (accessToken) {
|
|
343
|
-
cookies.
|
|
344
|
-
name: "nf_jwt",
|
|
345
|
-
value: accessToken,
|
|
346
|
-
httpOnly: true,
|
|
347
|
-
secure: true,
|
|
348
|
-
path: "/",
|
|
349
|
-
sameSite: "Lax"
|
|
350
|
-
});
|
|
398
|
+
setAuthCookies(cookies, accessToken, responseRecord.refresh_token);
|
|
351
399
|
}
|
|
352
400
|
}
|
|
353
401
|
return user;
|
|
@@ -368,7 +416,7 @@ var logout = async () => {
|
|
|
368
416
|
if (!isBrowser()) {
|
|
369
417
|
const identityUrl = getServerIdentityUrl();
|
|
370
418
|
const cookies = getCookies();
|
|
371
|
-
const jwt = cookies.get(
|
|
419
|
+
const jwt = cookies.get(NF_JWT_COOKIE);
|
|
372
420
|
if (jwt) {
|
|
373
421
|
try {
|
|
374
422
|
await fetch(`${identityUrl}/logout`, {
|
|
@@ -379,7 +427,7 @@ var logout = async () => {
|
|
|
379
427
|
throw new AuthError(error.message, void 0, { cause: error });
|
|
380
428
|
}
|
|
381
429
|
}
|
|
382
|
-
cookies
|
|
430
|
+
deleteAuthCookies(cookies);
|
|
383
431
|
return;
|
|
384
432
|
}
|
|
385
433
|
const client = getClient();
|
|
@@ -483,8 +531,40 @@ var handleAuthCallback = async () => {
|
|
|
483
531
|
var clearHash = () => {
|
|
484
532
|
history.replaceState(null, "", window.location.pathname + window.location.search);
|
|
485
533
|
};
|
|
534
|
+
var hydrateSession = async () => {
|
|
535
|
+
if (!isBrowser()) return null;
|
|
536
|
+
const client = getClient();
|
|
537
|
+
const currentUser = client.currentUser();
|
|
538
|
+
if (currentUser) return toUser(currentUser);
|
|
539
|
+
const accessToken = getCookie(NF_JWT_COOKIE);
|
|
540
|
+
if (!accessToken) return null;
|
|
541
|
+
const refreshToken = getCookie(NF_REFRESH_COOKIE) ?? "";
|
|
542
|
+
const gotrueUser = await client.createUser(
|
|
543
|
+
{
|
|
544
|
+
access_token: accessToken,
|
|
545
|
+
token_type: "bearer",
|
|
546
|
+
expires_in: 3600,
|
|
547
|
+
expires_at: Math.floor(Date.now() / 1e3) + 3600,
|
|
548
|
+
refresh_token: refreshToken
|
|
549
|
+
},
|
|
550
|
+
persistSession
|
|
551
|
+
);
|
|
552
|
+
const user = toUser(gotrueUser);
|
|
553
|
+
emitAuthEvent("login", user);
|
|
554
|
+
return user;
|
|
555
|
+
};
|
|
486
556
|
|
|
487
557
|
// src/account.ts
|
|
558
|
+
var ensureCurrentUser = async () => {
|
|
559
|
+
const client = getClient();
|
|
560
|
+
let currentUser = client.currentUser();
|
|
561
|
+
if (!currentUser && isBrowser()) {
|
|
562
|
+
await hydrateSession();
|
|
563
|
+
currentUser = client.currentUser();
|
|
564
|
+
}
|
|
565
|
+
if (!currentUser) throw new AuthError("No user is currently logged in");
|
|
566
|
+
return currentUser;
|
|
567
|
+
};
|
|
488
568
|
var requestPasswordRecovery = async (email) => {
|
|
489
569
|
const client = getClient();
|
|
490
570
|
try {
|
|
@@ -528,10 +608,8 @@ var acceptInvite = async (token, password) => {
|
|
|
528
608
|
}
|
|
529
609
|
};
|
|
530
610
|
var verifyEmailChange = async (token) => {
|
|
531
|
-
const client = getClient();
|
|
532
|
-
const currentUser = client.currentUser();
|
|
533
|
-
if (!currentUser) throw new AuthError("No user is currently logged in");
|
|
534
611
|
if (!isBrowser()) throw new AuthError("verifyEmailChange() is only available in the browser");
|
|
612
|
+
const currentUser = await ensureCurrentUser();
|
|
535
613
|
const jwt = await currentUser.jwt();
|
|
536
614
|
const identityUrl = `${window.location.origin}${IDENTITY_PATH}`;
|
|
537
615
|
try {
|
|
@@ -560,9 +638,7 @@ var verifyEmailChange = async (token) => {
|
|
|
560
638
|
}
|
|
561
639
|
};
|
|
562
640
|
var updateUser = async (updates) => {
|
|
563
|
-
const
|
|
564
|
-
const currentUser = client.currentUser();
|
|
565
|
-
if (!currentUser) throw new AuthError("No user is currently logged in");
|
|
641
|
+
const currentUser = await ensureCurrentUser();
|
|
566
642
|
try {
|
|
567
643
|
const updatedUser = await currentUser.update(updates);
|
|
568
644
|
const user = toUser(updatedUser);
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/environment.ts","../src/errors.ts","../src/user.ts","../src/config.ts","../src/auth.ts","../src/account.ts"],"sourcesContent":["export type { User } from './user.js'\nexport { getUser, isAuthenticated } from './user.js'\nexport { getIdentityConfig, getSettings } from './config.js'\nexport type { AuthCallback, AuthEvent, CallbackResult } from './auth.js'\nexport { login, signup, logout, oauthLogin, onAuthChange, handleAuthCallback } from './auth.js'\nexport { AuthError, MissingIdentityError } from './errors.js'\nexport type { AppMetadata, AuthProvider, IdentityConfig, Settings } from './types.js'\nexport {\n requestPasswordRecovery,\n recoverPassword,\n confirmEmail,\n acceptInvite,\n verifyEmailChange,\n updateUser,\n} from './account.js'\n","export const AUTH_PROVIDERS = ['google', 'github', 'gitlab', 'bitbucket', 'facebook', 'saml', 'email'] as const\nexport type AuthProvider = (typeof AUTH_PROVIDERS)[number]\n\nexport interface AppMetadata {\n provider: AuthProvider\n roles?: string[]\n [key: string]: unknown\n}\n\nexport interface IdentityConfig {\n url: string\n token?: string // this is an operator token, only available on the server\n}\n\nexport interface Settings {\n autoconfirm: boolean\n disableSignup: boolean\n providers: Record<AuthProvider, boolean>\n}\n\nexport interface NetlifyCookies {\n get(name: string): string | undefined\n set(options: {\n name: string\n value: string\n httpOnly: boolean\n secure: boolean\n path: string\n sameSite: string\n }): void\n delete(name: string): void\n}\n","import GoTrue from 'gotrue-js'\n\nimport type { IdentityConfig } from './types.js'\nimport { MissingIdentityError } from './errors.js'\n\nexport const IDENTITY_PATH = '/.netlify/identity'\n\nlet goTrueClient: GoTrue | null = null\nlet cachedApiUrl: string | null | undefined\nlet warnedMissingUrl = false\n\nexport const isBrowser = (): boolean => typeof window !== 'undefined' && typeof window.location !== 'undefined'\n\n/**\n * Discovers and caches the GoTrue API URL.\n *\n * Browser: uses `window.location.origin` + IDENTITY_PATH.\n * Server: reads from `globalThis.netlifyIdentityContext`.\n */\nconst discoverApiUrl = (): string | null => {\n if (cachedApiUrl !== undefined) return cachedApiUrl\n\n if (isBrowser()) {\n cachedApiUrl = `${window.location.origin}${IDENTITY_PATH}`\n } else {\n const identityContext = getIdentityContext()\n if (identityContext?.url) {\n cachedApiUrl = identityContext.url\n } else if (globalThis.Netlify?.context?.url) {\n cachedApiUrl = new URL(IDENTITY_PATH, globalThis.Netlify.context.url).href\n }\n }\n\n return cachedApiUrl ?? null\n}\n\n/**\n * Returns (and lazily creates) a singleton gotrue-js client.\n * Returns `null` and logs a warning if no identity URL can be discovered.\n */\nexport const getGoTrueClient = (): GoTrue | null => {\n if (goTrueClient) return goTrueClient\n\n const apiUrl = discoverApiUrl()\n if (!apiUrl) {\n if (!warnedMissingUrl) {\n console.warn(\n '@netlify/identity: Could not determine the Identity endpoint URL. ' +\n 'Make sure your site has Netlify Identity enabled, or run your app with `netlify dev`.',\n )\n warnedMissingUrl = true\n }\n return null\n }\n\n goTrueClient = new GoTrue({ APIUrl: apiUrl, setCookie: isBrowser() })\n return goTrueClient\n}\n\n/**\n * Returns the singleton gotrue-js client, or throws if Identity is not configured.\n */\nexport const getClient = (): GoTrue => {\n const client = getGoTrueClient()\n if (!client) throw new MissingIdentityError()\n return client\n}\n\n/**\n * Reads the server-side identity context set by the Netlify bootstrap.\n * Returns `null` outside the Netlify serverless environment.\n */\nexport const getIdentityContext = (): IdentityConfig | null => {\n const identityContext = globalThis.netlifyIdentityContext\n if (identityContext?.url) {\n return {\n url: identityContext.url,\n token: identityContext.token,\n }\n }\n\n if (globalThis.Netlify?.context?.url) {\n return { url: new URL(IDENTITY_PATH, globalThis.Netlify.context.url).href }\n }\n\n return null\n}\n\n/** Reset cached state for tests. */\nexport const resetTestGoTrueClient = (): void => {\n goTrueClient = null\n cachedApiUrl = undefined\n warnedMissingUrl = false\n}\n","export class AuthError extends Error {\n override name = 'AuthError'\n status?: number\n declare cause?: unknown\n\n constructor(message: string, status?: number, options?: { cause?: unknown }) {\n super(message)\n this.status = status\n if (options && 'cause' in options) {\n this.cause = options.cause\n }\n }\n}\n\nexport class MissingIdentityError extends Error {\n override name = 'MissingIdentityError'\n\n constructor(message = 'Identity is not available in this environment') {\n super(message)\n }\n}\n","import type { UserData } from 'gotrue-js'\nimport { AUTH_PROVIDERS, type AuthProvider } from './types.js'\nimport { getGoTrueClient, isBrowser } from './environment.js'\n\nexport interface IdentityUser {\n sub?: string\n email?: string\n exp?: number\n app_metadata?: Record<string, unknown>\n user_metadata?: Record<string, unknown>\n [key: string]: unknown\n}\n\nconst toAuthProvider = (value: unknown): AuthProvider | undefined =>\n typeof value === 'string' && (AUTH_PROVIDERS as readonly string[]).includes(value)\n ? (value as AuthProvider)\n : undefined\n\nexport interface User {\n id: string\n email?: string\n emailVerified?: boolean\n createdAt?: string\n updatedAt?: string\n provider?: AuthProvider\n name?: string\n pictureUrl?: string\n metadata?: Record<string, unknown>\n rawGoTrueData?: Record<string, unknown>\n}\n\nexport const toUser = (userData: UserData): User => {\n const userMeta = userData.user_metadata ?? {}\n const appMeta = userData.app_metadata ?? {}\n const name = userMeta.full_name || userMeta.name\n const pictureUrl = userMeta.avatar_url\n\n return {\n id: userData.id,\n email: userData.email,\n emailVerified: !!userData.confirmed_at,\n createdAt: userData.created_at,\n updatedAt: userData.updated_at,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n pictureUrl: typeof pictureUrl === 'string' ? pictureUrl : undefined,\n metadata: userMeta,\n rawGoTrueData: { ...userData },\n }\n}\n\n/**\n * Converts server-side JWT claims into User\n */\nconst claimsToUser = (claims: IdentityUser): User => {\n const appMeta = claims.app_metadata ?? {}\n const userMeta = claims.user_metadata ?? {}\n const name = userMeta.full_name || userMeta.name\n\n return {\n id: claims.sub ?? '',\n email: claims.email,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n metadata: userMeta,\n }\n}\n\n/**\n * Returns the currently authenticated user, or `null` if not logged in.\n * Synchronous. Never throws.\n */\nexport const getUser = (): User | null => {\n if (isBrowser()) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser() ?? null\n if (!currentUser) return null\n return toUser(currentUser)\n }\n\n const identityContext = globalThis.netlifyIdentityContext\n if (!identityContext?.user) return null\n\n return claimsToUser(identityContext.user)\n}\n\n/**\n * Returns `true` if a user is currently authenticated.\n */\nexport const isAuthenticated = (): boolean => getUser() !== null\n","import type { AuthProvider, IdentityConfig, Settings } from './types.js'\nimport { getClient, getIdentityContext, IDENTITY_PATH, isBrowser } from './environment.js'\nimport { AuthError } from './errors.js'\n\n/**\n * Returns the identity configuration for the current environment.\n * Browser: always returns `{ url }` derived from `window.location.origin`.\n * Server: returns `{ url, token }` from the identity context, or `null` if unavailable.\n * Never throws.\n */\nexport const getIdentityConfig = (): IdentityConfig | null => {\n if (isBrowser()) {\n return { url: `${window.location.origin}${IDENTITY_PATH}` }\n }\n\n return getIdentityContext()\n}\n\n/**\n * Fetches the GoTrue `/settings` endpoint.\n * Throws `MissingIdentityError` if Identity is not configured.\n * Throws `AuthError` if the endpoint is unreachable.\n */\nexport const getSettings = async (): Promise<Settings> => {\n const client = getClient()\n\n try {\n const raw = await client.settings()\n const external: Partial<Record<AuthProvider, boolean>> = raw.external ?? {}\n return {\n autoconfirm: raw.autoconfirm,\n disableSignup: raw.disable_signup,\n providers: {\n google: external.google ?? false,\n github: external.github ?? false,\n gitlab: external.gitlab ?? false,\n bitbucket: external.bitbucket ?? false,\n facebook: external.facebook ?? false,\n email: external.email ?? false,\n saml: external.saml ?? false,\n },\n }\n } catch (err) {\n throw new AuthError(err instanceof Error ? err.message : 'Failed to fetch identity settings', 502, { cause: err })\n }\n}\n","import type { UserData } from 'gotrue-js'\n\nimport type { AppMetadata, NetlifyCookies } from './types.js'\n\nexport type AuthEvent = 'login' | 'logout' | 'token_refresh' | 'user_updated'\nimport type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getGoTrueClient, getClient, getIdentityContext, isBrowser, IDENTITY_PATH } from './environment.js'\nimport { AuthError } from './errors.js'\n\nconst getCookies = (): NetlifyCookies => {\n const cookies = globalThis.Netlify?.context?.cookies\n if (!cookies) {\n throw new AuthError('Server-side auth requires Netlify Functions runtime')\n }\n return cookies\n}\n\nconst getServerIdentityUrl = (): string => {\n const ctx = getIdentityContext()\n if (!ctx?.url) {\n throw new AuthError('Could not determine the Identity endpoint URL on the server')\n }\n return ctx.url\n}\n\nexport interface JWTClaims {\n sub: string // UUID\n email: string\n exp: number\n iat: number\n aud: string\n app_metadata: AppMetadata\n user_metadata: Record<string, unknown>\n}\n\nexport type AuthCallback = (event: AuthEvent, user: User | null) => void\n\n/** Persist the session to localStorage so it survives page reloads. */\nexport const persistSession = true\n\nconst listeners = new Set<AuthCallback>()\n\nexport const emitAuthEvent = (event: AuthEvent, user: User | null): void => {\n for (const listener of listeners) {\n listener(event, user)\n }\n}\n\nlet storageListenerAttached = false\n\nconst attachStorageListener = (): void => {\n if (storageListenerAttached) return\n storageListenerAttached = true\n\n window.addEventListener('storage', (event: StorageEvent) => {\n if (event.key !== 'gotrue.user') return\n\n if (event.newValue) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser()\n emitAuthEvent('login', currentUser ? toUser(currentUser) : null)\n } else {\n emitAuthEvent('logout', null)\n }\n })\n}\n\n/**\n * Subscribes to auth state changes (login, logout, token refresh, user updates).\n * Returns an unsubscribe function. No-op on the server.\n */\nexport const onAuthChange = (callback: AuthCallback): (() => void) => {\n if (!isBrowser()) {\n return () => {}\n }\n\n listeners.add(callback)\n attachStorageListener()\n\n return () => {\n listeners.delete(callback)\n }\n}\n\n/** Logs in with email and password. Works in both browser and server contexts. */\nexport const login = async (email: string, password: string): Promise<User> => {\n if (!isBrowser()) {\n const identityUrl = getServerIdentityUrl()\n const cookies = getCookies()\n\n const body = new URLSearchParams({\n grant_type: 'password',\n username: email,\n password,\n })\n\n let res: Response\n try {\n res = await fetch(`${identityUrl}/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: body.toString(),\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n\n if (!res.ok) {\n const errorBody = await res.json().catch(() => ({}))\n throw new AuthError(\n (errorBody as Record<string, string>).msg ||\n (errorBody as Record<string, string>).error_description ||\n `Login failed (${res.status})`,\n res.status,\n )\n }\n\n const data = (await res.json()) as Record<string, unknown>\n const accessToken = data.access_token as string\n\n let userRes: Response\n try {\n userRes = await fetch(`${identityUrl}/user`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n\n if (!userRes.ok) {\n const errorBody = await userRes.json().catch(() => ({}))\n throw new AuthError(\n (errorBody as Record<string, string>).msg || `Failed to fetch user data (${userRes.status})`,\n userRes.status,\n )\n }\n\n const userData = (await userRes.json()) as UserData\n const user = toUser(userData)\n\n cookies.set({\n name: 'nf_jwt',\n value: accessToken,\n httpOnly: true,\n secure: true,\n path: '/',\n sameSite: 'Lax',\n })\n\n return user\n }\n\n const client = getClient()\n\n try {\n const gotrueUser = await client.login(email, password, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Creates a new account. Emits 'login' if autoconfirm is enabled. Works in both browser and server contexts. */\nexport const signup = async (email: string, password: string, data?: Record<string, unknown>): Promise<User> => {\n if (!isBrowser()) {\n const identityUrl = getServerIdentityUrl()\n const cookies = getCookies()\n\n let res: Response\n try {\n res = await fetch(`${identityUrl}/signup`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ email, password, data }),\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n\n if (!res.ok) {\n const errorBody = await res.json().catch(() => ({}))\n throw new AuthError((errorBody as Record<string, string>).msg || `Signup failed (${res.status})`, res.status)\n }\n\n const responseData = (await res.json()) as UserData\n const user = toUser(responseData)\n\n if (responseData.confirmed_at) {\n const accessToken = (responseData as unknown as Record<string, unknown>).access_token as string | undefined\n if (accessToken) {\n cookies.set({\n name: 'nf_jwt',\n value: accessToken,\n httpOnly: true,\n secure: true,\n path: '/',\n sameSite: 'Lax',\n })\n }\n }\n\n return user\n }\n\n const client = getClient()\n\n try {\n const response = await client.signup(email, password, data)\n const user = toUser(response as UserData)\n if (response.confirmed_at) {\n emitAuthEvent('login', user)\n }\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Logs out the current user and clears the session. Works in both browser and server contexts. */\nexport const logout = async (): Promise<void> => {\n if (!isBrowser()) {\n const identityUrl = getServerIdentityUrl()\n const cookies = getCookies()\n\n const jwt = cookies.get('nf_jwt')\n if (jwt) {\n try {\n await fetch(`${identityUrl}/logout`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}` },\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n }\n\n cookies.delete('nf_jwt')\n return\n }\n\n const client = getClient()\n\n try {\n const currentUser = client.currentUser()\n if (currentUser) {\n await currentUser.logout()\n }\n emitAuthEvent('logout', null)\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Redirects to an OAuth provider. Always throws (the page navigates away). Browser only. */\nexport const oauthLogin = (provider: string): never => {\n if (!isBrowser()) {\n throw new Error('oauthLogin() is only available in the browser')\n }\n const client = getClient()\n\n window.location.href = client.loginExternalUrl(provider)\n throw new Error('Redirecting to OAuth provider')\n}\n\nexport interface CallbackResult {\n type: 'oauth' | 'confirmation' | 'recovery' | 'invite' | 'email_change'\n user: User | null\n token?: string\n}\n\n/**\n * Processes the URL hash after an OAuth redirect, email confirmation, password\n * recovery, invite acceptance, or email change. Call on page load. Browser only.\n * Returns `null` if the hash contains no auth parameters.\n */\nexport const handleAuthCallback = async (): Promise<CallbackResult | null> => {\n if (!isBrowser()) return null\n\n const hash = window.location.hash.substring(1)\n if (!hash) return null\n\n const client = getClient()\n\n try {\n const params = new URLSearchParams(hash)\n\n const accessToken = params.get('access_token')\n if (accessToken) {\n const gotrueUser = await client.createUser(\n {\n access_token: accessToken,\n token_type: (params.get('token_type') as 'bearer') ?? 'bearer',\n expires_in: Number(params.get('expires_in')),\n expires_at: Number(params.get('expires_at')),\n refresh_token: params.get('refresh_token') ?? '',\n },\n persistSession,\n )\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'oauth', user }\n }\n\n const confirmationToken = params.get('confirmation_token')\n if (confirmationToken) {\n const gotrueUser = await client.confirm(confirmationToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'confirmation', user }\n }\n\n const recoveryToken = params.get('recovery_token')\n if (recoveryToken) {\n const gotrueUser = await client.recover(recoveryToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'recovery', user }\n }\n\n const inviteToken = params.get('invite_token')\n if (inviteToken) {\n clearHash()\n return { type: 'invite', user: null, token: inviteToken }\n }\n\n const emailChangeToken = params.get('email_change_token')\n if (emailChangeToken) {\n const currentUser = client.currentUser()\n if (!currentUser) {\n throw new AuthError('Email change verification requires an active browser session')\n }\n\n const jwt = await currentUser.jwt()\n const identityUrl = `${window.location.origin}${IDENTITY_PATH}`\n\n const emailChangeRes = await fetch(`${identityUrl}/user`, {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${jwt}`,\n },\n body: JSON.stringify({ email_change_token: emailChangeToken }),\n })\n\n if (!emailChangeRes.ok) {\n const errorBody = await emailChangeRes.json().catch(() => ({}))\n throw new AuthError(\n (errorBody as Record<string, string>).msg || `Email change verification failed (${emailChangeRes.status})`,\n emailChangeRes.status,\n )\n }\n\n const emailChangeData = (await emailChangeRes.json()) as UserData\n const user = toUser(emailChangeData)\n clearHash()\n emitAuthEvent('user_updated', user)\n return { type: 'email_change', user }\n }\n\n return null\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\nconst clearHash = (): void => {\n history.replaceState(null, '', window.location.pathname + window.location.search)\n}\n","import type { UserData } from 'gotrue-js'\n\nimport type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getClient, isBrowser, IDENTITY_PATH } from './environment.js'\nimport { emitAuthEvent, persistSession } from './auth.js'\nimport { AuthError } from './errors.js'\n\n/** Sends a password recovery email to the given address. */\nexport const requestPasswordRecovery = async (email: string): Promise<void> => {\n const client = getClient()\n\n try {\n await client.requestPasswordRecovery(email)\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Redeems a recovery token and sets a new password. Logs the user in on success. */\nexport const recoverPassword = async (token: string, newPassword: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.recover(token, persistSession)\n const updatedUser = await gotrueUser.update({ password: newPassword })\n const user = toUser(updatedUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Confirms an email address using the token from a confirmation email. Logs the user in on success. */\nexport const confirmEmail = async (token: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.confirm(token, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Accepts an invite token and sets a password for the new account. Logs the user in on success. */\nexport const acceptInvite = async (token: string, password: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.acceptInvite(token, password, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/**\n * Verifies an email change using the token from a verification email.\n *\n * Requires an active browser login session (via localStorage).\n * Server-side login sessions (cookie-based) do not satisfy this requirement.\n */\nexport const verifyEmailChange = async (token: string): Promise<User> => {\n const client = getClient()\n\n const currentUser = client.currentUser()\n if (!currentUser) throw new AuthError('No user is currently logged in')\n\n if (!isBrowser()) throw new AuthError('verifyEmailChange() is only available in the browser')\n\n const jwt = await currentUser.jwt()\n const identityUrl = `${window.location.origin}${IDENTITY_PATH}`\n\n try {\n const res = await fetch(`${identityUrl}/user`, {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${jwt}`,\n },\n body: JSON.stringify({ email_change_token: token }),\n })\n\n if (!res.ok) {\n const errorBody = await res.json().catch(() => ({}))\n throw new AuthError(\n (errorBody as Record<string, string>).msg || `Email change verification failed (${res.status})`,\n res.status,\n )\n }\n\n const userData = (await res.json()) as UserData\n const user = toUser(userData)\n emitAuthEvent('user_updated', user)\n return user\n } catch (error) {\n if (error instanceof AuthError) throw error\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/**\n * Updates the current user's metadata or credentials.\n *\n * Requires an active browser login session (via gotrue-js localStorage).\n * Server-side login sessions (cookie-based) do not satisfy this requirement.\n */\nexport const updateUser = async (updates: Record<string, unknown>): Promise<User> => {\n const client = getClient()\n\n const currentUser = client.currentUser()\n if (!currentUser) throw new AuthError('No user is currently logged in')\n\n try {\n const updatedUser = await currentUser.update(updates)\n const user = toUser(updatedUser)\n emitAuthEvent('user_updated', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAO,IAAM,iBAAiB,CAAC,UAAU,UAAU,UAAU,aAAa,YAAY,QAAQ,OAAO;;;ACArG,uBAAmB;;;ACAZ,IAAM,YAAN,cAAwB,MAAM;AAAA,EAKnC,YAAY,SAAiB,QAAiB,SAA+B;AAC3E,UAAM,OAAO;AALf,SAAS,OAAO;AAMd,SAAK,SAAS;AACd,QAAI,WAAW,WAAW,SAAS;AACjC,WAAK,QAAQ,QAAQ;AAAA,IACvB;AAAA,EACF;AACF;AAEO,IAAM,uBAAN,cAAmC,MAAM;AAAA,EAG9C,YAAY,UAAU,iDAAiD;AACrE,UAAM,OAAO;AAHf,SAAS,OAAO;AAAA,EAIhB;AACF;;;ADfO,IAAM,gBAAgB;AAE7B,IAAI,eAA8B;AAClC,IAAI;AACJ,IAAI,mBAAmB;AAEhB,IAAM,YAAY,MAAe,OAAO,WAAW,eAAe,OAAO,OAAO,aAAa;AAQpG,IAAM,iBAAiB,MAAqB;AAC1C,MAAI,iBAAiB,OAAW,QAAO;AAEvC,MAAI,UAAU,GAAG;AACf,mBAAe,GAAG,OAAO,SAAS,MAAM,GAAG,aAAa;AAAA,EAC1D,OAAO;AACL,UAAM,kBAAkB,mBAAmB;AAC3C,QAAI,iBAAiB,KAAK;AACxB,qBAAe,gBAAgB;AAAA,IACjC,WAAW,WAAW,SAAS,SAAS,KAAK;AAC3C,qBAAe,IAAI,IAAI,eAAe,WAAW,QAAQ,QAAQ,GAAG,EAAE;AAAA,IACxE;AAAA,EACF;AAEA,SAAO,gBAAgB;AACzB;AAMO,IAAM,kBAAkB,MAAqB;AAClD,MAAI,aAAc,QAAO;AAEzB,QAAM,SAAS,eAAe;AAC9B,MAAI,CAAC,QAAQ;AACX,QAAI,CAAC,kBAAkB;AACrB,cAAQ;AAAA,QACN;AAAA,MAEF;AACA,yBAAmB;AAAA,IACrB;AACA,WAAO;AAAA,EACT;AAEA,iBAAe,IAAI,iBAAAA,QAAO,EAAE,QAAQ,QAAQ,WAAW,UAAU,EAAE,CAAC;AACpE,SAAO;AACT;AAKO,IAAM,YAAY,MAAc;AACrC,QAAM,SAAS,gBAAgB;AAC/B,MAAI,CAAC,OAAQ,OAAM,IAAI,qBAAqB;AAC5C,SAAO;AACT;AAMO,IAAM,qBAAqB,MAA6B;AAC7D,QAAM,kBAAkB,WAAW;AACnC,MAAI,iBAAiB,KAAK;AACxB,WAAO;AAAA,MACL,KAAK,gBAAgB;AAAA,MACrB,OAAO,gBAAgB;AAAA,IACzB;AAAA,EACF;AAEA,MAAI,WAAW,SAAS,SAAS,KAAK;AACpC,WAAO,EAAE,KAAK,IAAI,IAAI,eAAe,WAAW,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAAA,EAC5E;AAEA,SAAO;AACT;;;AEzEA,IAAM,iBAAiB,CAAC,UACtB,OAAO,UAAU,YAAa,eAAqC,SAAS,KAAK,IAC5E,QACD;AAeC,IAAM,SAAS,CAAC,aAA6B;AAClD,QAAM,WAAW,SAAS,iBAAiB,CAAC;AAC5C,QAAM,UAAU,SAAS,gBAAgB,CAAC;AAC1C,QAAM,OAAO,SAAS,aAAa,SAAS;AAC5C,QAAM,aAAa,SAAS;AAE5B,SAAO;AAAA,IACL,IAAI,SAAS;AAAA,IACb,OAAO,SAAS;AAAA,IAChB,eAAe,CAAC,CAAC,SAAS;AAAA,IAC1B,WAAW,SAAS;AAAA,IACpB,WAAW,SAAS;AAAA,IACpB,UAAU,eAAe,QAAQ,QAAQ;AAAA,IACzC,MAAM,OAAO,SAAS,WAAW,OAAO;AAAA,IACxC,YAAY,OAAO,eAAe,WAAW,aAAa;AAAA,IAC1D,UAAU;AAAA,IACV,eAAe,EAAE,GAAG,SAAS;AAAA,EAC/B;AACF;AAKA,IAAM,eAAe,CAAC,WAA+B;AACnD,QAAM,UAAU,OAAO,gBAAgB,CAAC;AACxC,QAAM,WAAW,OAAO,iBAAiB,CAAC;AAC1C,QAAM,OAAO,SAAS,aAAa,SAAS;AAE5C,SAAO;AAAA,IACL,IAAI,OAAO,OAAO;AAAA,IAClB,OAAO,OAAO;AAAA,IACd,UAAU,eAAe,QAAQ,QAAQ;AAAA,IACzC,MAAM,OAAO,SAAS,WAAW,OAAO;AAAA,IACxC,UAAU;AAAA,EACZ;AACF;AAMO,IAAM,UAAU,MAAmB;AACxC,MAAI,UAAU,GAAG;AACf,UAAM,SAAS,gBAAgB;AAC/B,UAAM,cAAc,QAAQ,YAAY,KAAK;AAC7C,QAAI,CAAC,YAAa,QAAO;AACzB,WAAO,OAAO,WAAW;AAAA,EAC3B;AAEA,QAAM,kBAAkB,WAAW;AACnC,MAAI,CAAC,iBAAiB,KAAM,QAAO;AAEnC,SAAO,aAAa,gBAAgB,IAAI;AAC1C;AAKO,IAAM,kBAAkB,MAAe,QAAQ,MAAM;;;AC/ErD,IAAM,oBAAoB,MAA6B;AAC5D,MAAI,UAAU,GAAG;AACf,WAAO,EAAE,KAAK,GAAG,OAAO,SAAS,MAAM,GAAG,aAAa,GAAG;AAAA,EAC5D;AAEA,SAAO,mBAAmB;AAC5B;AAOO,IAAM,cAAc,YAA+B;AACxD,QAAM,SAAS,UAAU;AAEzB,MAAI;AACF,UAAM,MAAM,MAAM,OAAO,SAAS;AAClC,UAAM,WAAmD,IAAI,YAAY,CAAC;AAC1E,WAAO;AAAA,MACL,aAAa,IAAI;AAAA,MACjB,eAAe,IAAI;AAAA,MACnB,WAAW;AAAA,QACT,QAAQ,SAAS,UAAU;AAAA,QAC3B,QAAQ,SAAS,UAAU;AAAA,QAC3B,QAAQ,SAAS,UAAU;AAAA,QAC3B,WAAW,SAAS,aAAa;AAAA,QACjC,UAAU,SAAS,YAAY;AAAA,QAC/B,OAAO,SAAS,SAAS;AAAA,QACzB,MAAM,SAAS,QAAQ;AAAA,MACzB;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AACZ,UAAM,IAAI,UAAU,eAAe,QAAQ,IAAI,UAAU,qCAAqC,KAAK,EAAE,OAAO,IAAI,CAAC;AAAA,EACnH;AACF;;;ACnCA,IAAM,aAAa,MAAsB;AACvC,QAAM,UAAU,WAAW,SAAS,SAAS;AAC7C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,UAAU,qDAAqD;AAAA,EAC3E;AACA,SAAO;AACT;AAEA,IAAM,uBAAuB,MAAc;AACzC,QAAM,MAAM,mBAAmB;AAC/B,MAAI,CAAC,KAAK,KAAK;AACb,UAAM,IAAI,UAAU,6DAA6D;AAAA,EACnF;AACA,SAAO,IAAI;AACb;AAeO,IAAM,iBAAiB;AAE9B,IAAM,YAAY,oBAAI,IAAkB;AAEjC,IAAM,gBAAgB,CAAC,OAAkB,SAA4B;AAC1E,aAAW,YAAY,WAAW;AAChC,aAAS,OAAO,IAAI;AAAA,EACtB;AACF;AAEA,IAAI,0BAA0B;AAE9B,IAAM,wBAAwB,MAAY;AACxC,MAAI,wBAAyB;AAC7B,4BAA0B;AAE1B,SAAO,iBAAiB,WAAW,CAAC,UAAwB;AAC1D,QAAI,MAAM,QAAQ,cAAe;AAEjC,QAAI,MAAM,UAAU;AAClB,YAAM,SAAS,gBAAgB;AAC/B,YAAM,cAAc,QAAQ,YAAY;AACxC,oBAAc,SAAS,cAAc,OAAO,WAAW,IAAI,IAAI;AAAA,IACjE,OAAO;AACL,oBAAc,UAAU,IAAI;AAAA,IAC9B;AAAA,EACF,CAAC;AACH;AAMO,IAAM,eAAe,CAAC,aAAyC;AACpE,MAAI,CAAC,UAAU,GAAG;AAChB,WAAO,MAAM;AAAA,IAAC;AAAA,EAChB;AAEA,YAAU,IAAI,QAAQ;AACtB,wBAAsB;AAEtB,SAAO,MAAM;AACX,cAAU,OAAO,QAAQ;AAAA,EAC3B;AACF;AAGO,IAAM,QAAQ,OAAO,OAAe,aAAoC;AAC7E,MAAI,CAAC,UAAU,GAAG;AAChB,UAAM,cAAc,qBAAqB;AACzC,UAAM,UAAU,WAAW;AAE3B,UAAM,OAAO,IAAI,gBAAgB;AAAA,MAC/B,YAAY;AAAA,MACZ,UAAU;AAAA,MACV;AAAA,IACF,CAAC;AAED,QAAI;AACJ,QAAI;AACF,YAAM,MAAM,MAAM,GAAG,WAAW,UAAU;AAAA,QACxC,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,oCAAoC;AAAA,QAC/D,MAAM,KAAK,SAAS;AAAA,MACtB,CAAC;AAAA,IACH,SAAS,OAAO;AACd,YAAM,IAAI,UAAW,MAAgB,SAAS,QAAW,EAAE,OAAO,MAAM,CAAC;AAAA,IAC3E;AAEA,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,YAAY,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACnD,YAAM,IAAI;AAAA,QACP,UAAqC,OACnC,UAAqC,qBACtC,iBAAiB,IAAI,MAAM;AAAA,QAC7B,IAAI;AAAA,MACN;AAAA,IACF;AAEA,UAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,UAAM,cAAc,KAAK;AAEzB,QAAI;AACJ,QAAI;AACF,gBAAU,MAAM,MAAM,GAAG,WAAW,SAAS;AAAA,QAC3C,SAAS,EAAE,eAAe,UAAU,WAAW,GAAG;AAAA,MACpD,CAAC;AAAA,IACH,SAAS,OAAO;AACd,YAAM,IAAI,UAAW,MAAgB,SAAS,QAAW,EAAE,OAAO,MAAM,CAAC;AAAA,IAC3E;AAEA,QAAI,CAAC,QAAQ,IAAI;AACf,YAAM,YAAY,MAAM,QAAQ,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACvD,YAAM,IAAI;AAAA,QACP,UAAqC,OAAO,8BAA8B,QAAQ,MAAM;AAAA,QACzF,QAAQ;AAAA,MACV;AAAA,IACF;AAEA,UAAM,WAAY,MAAM,QAAQ,KAAK;AACrC,UAAM,OAAO,OAAO,QAAQ;AAE5B,YAAQ,IAAI;AAAA,MACV,MAAM;AAAA,MACN,OAAO;AAAA,MACP,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,UAAU;AAAA,IACZ,CAAC;AAED,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,UAAU;AAEzB,MAAI;AACF,UAAM,aAAa,MAAM,OAAO,MAAM,OAAO,UAAU,cAAc;AACrE,UAAM,OAAO,OAAO,UAAU;AAC9B,kBAAc,SAAS,IAAI;AAC3B,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI,UAAW,MAAgB,SAAS,QAAW,EAAE,OAAO,MAAM,CAAC;AAAA,EAC3E;AACF;AAGO,IAAM,SAAS,OAAO,OAAe,UAAkB,SAAkD;AAC9G,MAAI,CAAC,UAAU,GAAG;AAChB,UAAM,cAAc,qBAAqB;AACzC,UAAM,UAAU,WAAW;AAE3B,QAAI;AACJ,QAAI;AACF,YAAM,MAAM,MAAM,GAAG,WAAW,WAAW;AAAA,QACzC,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU,EAAE,OAAO,UAAU,KAAK,CAAC;AAAA,MAChD,CAAC;AAAA,IACH,SAAS,OAAO;AACd,YAAM,IAAI,UAAW,MAAgB,SAAS,QAAW,EAAE,OAAO,MAAM,CAAC;AAAA,IAC3E;AAEA,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,YAAY,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACnD,YAAM,IAAI,UAAW,UAAqC,OAAO,kBAAkB,IAAI,MAAM,KAAK,IAAI,MAAM;AAAA,IAC9G;AAEA,UAAM,eAAgB,MAAM,IAAI,KAAK;AACrC,UAAM,OAAO,OAAO,YAAY;AAEhC,QAAI,aAAa,cAAc;AAC7B,YAAM,cAAe,aAAoD;AACzE,UAAI,aAAa;AACf,gBAAQ,IAAI;AAAA,UACV,MAAM;AAAA,UACN,OAAO;AAAA,UACP,UAAU;AAAA,UACV,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,UAAU;AAAA,QACZ,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,UAAU;AAEzB,MAAI;AACF,UAAM,WAAW,MAAM,OAAO,OAAO,OAAO,UAAU,IAAI;AAC1D,UAAM,OAAO,OAAO,QAAoB;AACxC,QAAI,SAAS,cAAc;AACzB,oBAAc,SAAS,IAAI;AAAA,IAC7B;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI,UAAW,MAAgB,SAAS,QAAW,EAAE,OAAO,MAAM,CAAC;AAAA,EAC3E;AACF;AAGO,IAAM,SAAS,YAA2B;AAC/C,MAAI,CAAC,UAAU,GAAG;AAChB,UAAM,cAAc,qBAAqB;AACzC,UAAM,UAAU,WAAW;AAE3B,UAAM,MAAM,QAAQ,IAAI,QAAQ;AAChC,QAAI,KAAK;AACP,UAAI;AACF,cAAM,MAAM,GAAG,WAAW,WAAW;AAAA,UACnC,QAAQ;AAAA,UACR,SAAS,EAAE,eAAe,UAAU,GAAG,GAAG;AAAA,QAC5C,CAAC;AAAA,MACH,SAAS,OAAO;AACd,cAAM,IAAI,UAAW,MAAgB,SAAS,QAAW,EAAE,OAAO,MAAM,CAAC;AAAA,MAC3E;AAAA,IACF;AAEA,YAAQ,OAAO,QAAQ;AACvB;AAAA,EACF;AAEA,QAAM,SAAS,UAAU;AAEzB,MAAI;AACF,UAAM,cAAc,OAAO,YAAY;AACvC,QAAI,aAAa;AACf,YAAM,YAAY,OAAO;AAAA,IAC3B;AACA,kBAAc,UAAU,IAAI;AAAA,EAC9B,SAAS,OAAO;AACd,UAAM,IAAI,UAAW,MAAgB,SAAS,QAAW,EAAE,OAAO,MAAM,CAAC;AAAA,EAC3E;AACF;AAGO,IAAM,aAAa,CAAC,aAA4B;AACrD,MAAI,CAAC,UAAU,GAAG;AAChB,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACjE;AACA,QAAM,SAAS,UAAU;AAEzB,SAAO,SAAS,OAAO,OAAO,iBAAiB,QAAQ;AACvD,QAAM,IAAI,MAAM,+BAA+B;AACjD;AAaO,IAAM,qBAAqB,YAA4C;AAC5E,MAAI,CAAC,UAAU,EAAG,QAAO;AAEzB,QAAM,OAAO,OAAO,SAAS,KAAK,UAAU,CAAC;AAC7C,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,SAAS,UAAU;AAEzB,MAAI;AACF,UAAM,SAAS,IAAI,gBAAgB,IAAI;AAEvC,UAAM,cAAc,OAAO,IAAI,cAAc;AAC7C,QAAI,aAAa;AACf,YAAM,aAAa,MAAM,OAAO;AAAA,QAC9B;AAAA,UACE,cAAc;AAAA,UACd,YAAa,OAAO,IAAI,YAAY,KAAkB;AAAA,UACtD,YAAY,OAAO,OAAO,IAAI,YAAY,CAAC;AAAA,UAC3C,YAAY,OAAO,OAAO,IAAI,YAAY,CAAC;AAAA,UAC3C,eAAe,OAAO,IAAI,eAAe,KAAK;AAAA,QAChD;AAAA,QACA;AAAA,MACF;AACA,YAAM,OAAO,OAAO,UAAU;AAC9B,gBAAU;AACV,oBAAc,SAAS,IAAI;AAC3B,aAAO,EAAE,MAAM,SAAS,KAAK;AAAA,IAC/B;AAEA,UAAM,oBAAoB,OAAO,IAAI,oBAAoB;AACzD,QAAI,mBAAmB;AACrB,YAAM,aAAa,MAAM,OAAO,QAAQ,mBAAmB,cAAc;AACzE,YAAM,OAAO,OAAO,UAAU;AAC9B,gBAAU;AACV,oBAAc,SAAS,IAAI;AAC3B,aAAO,EAAE,MAAM,gBAAgB,KAAK;AAAA,IACtC;AAEA,UAAM,gBAAgB,OAAO,IAAI,gBAAgB;AACjD,QAAI,eAAe;AACjB,YAAM,aAAa,MAAM,OAAO,QAAQ,eAAe,cAAc;AACrE,YAAM,OAAO,OAAO,UAAU;AAC9B,gBAAU;AACV,oBAAc,SAAS,IAAI;AAC3B,aAAO,EAAE,MAAM,YAAY,KAAK;AAAA,IAClC;AAEA,UAAM,cAAc,OAAO,IAAI,cAAc;AAC7C,QAAI,aAAa;AACf,gBAAU;AACV,aAAO,EAAE,MAAM,UAAU,MAAM,MAAM,OAAO,YAAY;AAAA,IAC1D;AAEA,UAAM,mBAAmB,OAAO,IAAI,oBAAoB;AACxD,QAAI,kBAAkB;AACpB,YAAM,cAAc,OAAO,YAAY;AACvC,UAAI,CAAC,aAAa;AAChB,cAAM,IAAI,UAAU,8DAA8D;AAAA,MACpF;AAEA,YAAM,MAAM,MAAM,YAAY,IAAI;AAClC,YAAM,cAAc,GAAG,OAAO,SAAS,MAAM,GAAG,aAAa;AAE7D,YAAM,iBAAiB,MAAM,MAAM,GAAG,WAAW,SAAS;AAAA,QACxD,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,eAAe,UAAU,GAAG;AAAA,QAC9B;AAAA,QACA,MAAM,KAAK,UAAU,EAAE,oBAAoB,iBAAiB,CAAC;AAAA,MAC/D,CAAC;AAED,UAAI,CAAC,eAAe,IAAI;AACtB,cAAM,YAAY,MAAM,eAAe,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AAC9D,cAAM,IAAI;AAAA,UACP,UAAqC,OAAO,qCAAqC,eAAe,MAAM;AAAA,UACvG,eAAe;AAAA,QACjB;AAAA,MACF;AAEA,YAAM,kBAAmB,MAAM,eAAe,KAAK;AACnD,YAAM,OAAO,OAAO,eAAe;AACnC,gBAAU;AACV,oBAAc,gBAAgB,IAAI;AAClC,aAAO,EAAE,MAAM,gBAAgB,KAAK;AAAA,IACtC;AAEA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI,UAAW,MAAgB,SAAS,QAAW,EAAE,OAAO,MAAM,CAAC;AAAA,EAC3E;AACF;AAEA,IAAM,YAAY,MAAY;AAC5B,UAAQ,aAAa,MAAM,IAAI,OAAO,SAAS,WAAW,OAAO,SAAS,MAAM;AAClF;;;AC5WO,IAAM,0BAA0B,OAAO,UAAiC;AAC7E,QAAM,SAAS,UAAU;AAEzB,MAAI;AACF,UAAM,OAAO,wBAAwB,KAAK;AAAA,EAC5C,SAAS,OAAO;AACd,UAAM,IAAI,UAAW,MAAgB,SAAS,QAAW,EAAE,OAAO,MAAM,CAAC;AAAA,EAC3E;AACF;AAGO,IAAM,kBAAkB,OAAO,OAAe,gBAAuC;AAC1F,QAAM,SAAS,UAAU;AAEzB,MAAI;AACF,UAAM,aAAa,MAAM,OAAO,QAAQ,OAAO,cAAc;AAC7D,UAAM,cAAc,MAAM,WAAW,OAAO,EAAE,UAAU,YAAY,CAAC;AACrE,UAAM,OAAO,OAAO,WAAW;AAC/B,kBAAc,SAAS,IAAI;AAC3B,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI,UAAW,MAAgB,SAAS,QAAW,EAAE,OAAO,MAAM,CAAC;AAAA,EAC3E;AACF;AAGO,IAAM,eAAe,OAAO,UAAiC;AAClE,QAAM,SAAS,UAAU;AAEzB,MAAI;AACF,UAAM,aAAa,MAAM,OAAO,QAAQ,OAAO,cAAc;AAC7D,UAAM,OAAO,OAAO,UAAU;AAC9B,kBAAc,SAAS,IAAI;AAC3B,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI,UAAW,MAAgB,SAAS,QAAW,EAAE,OAAO,MAAM,CAAC;AAAA,EAC3E;AACF;AAGO,IAAM,eAAe,OAAO,OAAe,aAAoC;AACpF,QAAM,SAAS,UAAU;AAEzB,MAAI;AACF,UAAM,aAAa,MAAM,OAAO,aAAa,OAAO,UAAU,cAAc;AAC5E,UAAM,OAAO,OAAO,UAAU;AAC9B,kBAAc,SAAS,IAAI;AAC3B,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI,UAAW,MAAgB,SAAS,QAAW,EAAE,OAAO,MAAM,CAAC;AAAA,EAC3E;AACF;AAQO,IAAM,oBAAoB,OAAO,UAAiC;AACvE,QAAM,SAAS,UAAU;AAEzB,QAAM,cAAc,OAAO,YAAY;AACvC,MAAI,CAAC,YAAa,OAAM,IAAI,UAAU,gCAAgC;AAEtE,MAAI,CAAC,UAAU,EAAG,OAAM,IAAI,UAAU,sDAAsD;AAE5F,QAAM,MAAM,MAAM,YAAY,IAAI;AAClC,QAAM,cAAc,GAAG,OAAO,SAAS,MAAM,GAAG,aAAa;AAE7D,MAAI;AACF,UAAM,MAAM,MAAM,MAAM,GAAG,WAAW,SAAS;AAAA,MAC7C,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,UAAU,GAAG;AAAA,MAC9B;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,oBAAoB,MAAM,CAAC;AAAA,IACpD,CAAC;AAED,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,YAAY,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACnD,YAAM,IAAI;AAAA,QACP,UAAqC,OAAO,qCAAqC,IAAI,MAAM;AAAA,QAC5F,IAAI;AAAA,MACN;AAAA,IACF;AAEA,UAAM,WAAY,MAAM,IAAI,KAAK;AACjC,UAAM,OAAO,OAAO,QAAQ;AAC5B,kBAAc,gBAAgB,IAAI;AAClC,WAAO;AAAA,EACT,SAAS,OAAO;AACd,QAAI,iBAAiB,UAAW,OAAM;AACtC,UAAM,IAAI,UAAW,MAAgB,SAAS,QAAW,EAAE,OAAO,MAAM,CAAC;AAAA,EAC3E;AACF;AAQO,IAAM,aAAa,OAAO,YAAoD;AACnF,QAAM,SAAS,UAAU;AAEzB,QAAM,cAAc,OAAO,YAAY;AACvC,MAAI,CAAC,YAAa,OAAM,IAAI,UAAU,gCAAgC;AAEtE,MAAI;AACF,UAAM,cAAc,MAAM,YAAY,OAAO,OAAO;AACpD,UAAM,OAAO,OAAO,WAAW;AAC/B,kBAAc,gBAAgB,IAAI;AAClC,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI,UAAW,MAAgB,SAAS,QAAW,EAAE,OAAO,MAAM,CAAC;AAAA,EAC3E;AACF;","names":["GoTrue"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/environment.ts","../src/errors.ts","../src/cookies.ts","../src/user.ts","../src/config.ts","../src/auth.ts","../src/account.ts"],"sourcesContent":["export type { User } from './user.js'\nexport { getUser, isAuthenticated } from './user.js'\nexport { getIdentityConfig, getSettings } from './config.js'\nexport type { AuthCallback, AuthEvent, CallbackResult } from './auth.js'\nexport { login, signup, logout, oauthLogin, onAuthChange, handleAuthCallback } from './auth.js'\nexport { AuthError, MissingIdentityError } from './errors.js'\nexport type { AppMetadata, AuthProvider, IdentityConfig, Settings } from './types.js'\nexport {\n requestPasswordRecovery,\n recoverPassword,\n confirmEmail,\n acceptInvite,\n verifyEmailChange,\n updateUser,\n} from './account.js'\n","export const AUTH_PROVIDERS = ['google', 'github', 'gitlab', 'bitbucket', 'facebook', 'saml', 'email'] as const\nexport type AuthProvider = (typeof AUTH_PROVIDERS)[number]\n\nexport interface AppMetadata {\n provider: AuthProvider\n roles?: string[]\n [key: string]: unknown\n}\n\nexport interface IdentityConfig {\n url: string\n token?: string // this is an operator token, only available on the server\n}\n\nexport interface Settings {\n autoconfirm: boolean\n disableSignup: boolean\n providers: Record<AuthProvider, boolean>\n}\n\nexport interface NetlifyCookies {\n get(name: string): string | undefined\n set(options: {\n name: string\n value: string\n httpOnly: boolean\n secure: boolean\n path: string\n sameSite: string\n }): void\n delete(name: string): void\n}\n","import GoTrue from 'gotrue-js'\n\nimport type { IdentityConfig } from './types.js'\nimport { MissingIdentityError } from './errors.js'\n\nexport const IDENTITY_PATH = '/.netlify/identity'\n\nlet goTrueClient: GoTrue | null = null\nlet cachedApiUrl: string | null | undefined\nlet warnedMissingUrl = false\n\nexport const isBrowser = (): boolean => typeof window !== 'undefined' && typeof window.location !== 'undefined'\n\n/**\n * Discovers and caches the GoTrue API URL.\n *\n * Browser: uses `window.location.origin` + IDENTITY_PATH.\n * Server: reads from `globalThis.netlifyIdentityContext`.\n */\nconst discoverApiUrl = (): string | null => {\n if (cachedApiUrl !== undefined) return cachedApiUrl\n\n if (isBrowser()) {\n cachedApiUrl = `${window.location.origin}${IDENTITY_PATH}`\n } else {\n const identityContext = getIdentityContext()\n if (identityContext?.url) {\n cachedApiUrl = identityContext.url\n } else if (globalThis.Netlify?.context?.url) {\n cachedApiUrl = new URL(IDENTITY_PATH, globalThis.Netlify.context.url).href\n }\n }\n\n return cachedApiUrl ?? null\n}\n\n/**\n * Returns (and lazily creates) a singleton gotrue-js client.\n * Returns `null` and logs a warning if no identity URL can be discovered.\n */\nexport const getGoTrueClient = (): GoTrue | null => {\n if (goTrueClient) return goTrueClient\n\n const apiUrl = discoverApiUrl()\n if (!apiUrl) {\n if (!warnedMissingUrl) {\n console.warn(\n '@netlify/identity: Could not determine the Identity endpoint URL. ' +\n 'Make sure your site has Netlify Identity enabled, or run your app with `netlify dev`.',\n )\n warnedMissingUrl = true\n }\n return null\n }\n\n goTrueClient = new GoTrue({ APIUrl: apiUrl, setCookie: isBrowser() })\n return goTrueClient\n}\n\n/**\n * Returns the singleton gotrue-js client, or throws if Identity is not configured.\n */\nexport const getClient = (): GoTrue => {\n const client = getGoTrueClient()\n if (!client) throw new MissingIdentityError()\n return client\n}\n\n/**\n * Reads the server-side identity context set by the Netlify bootstrap.\n * Returns `null` outside the Netlify serverless environment.\n */\nexport const getIdentityContext = (): IdentityConfig | null => {\n const identityContext = globalThis.netlifyIdentityContext\n if (identityContext?.url) {\n return {\n url: identityContext.url,\n token: identityContext.token,\n }\n }\n\n if (globalThis.Netlify?.context?.url) {\n return { url: new URL(IDENTITY_PATH, globalThis.Netlify.context.url).href }\n }\n\n return null\n}\n\n/** Reset cached state for tests. */\nexport const resetTestGoTrueClient = (): void => {\n goTrueClient = null\n cachedApiUrl = undefined\n warnedMissingUrl = false\n}\n","export class AuthError extends Error {\n override name = 'AuthError'\n status?: number\n declare cause?: unknown\n\n constructor(message: string, status?: number, options?: { cause?: unknown }) {\n super(message)\n this.status = status\n if (options && 'cause' in options) {\n this.cause = options.cause\n }\n }\n}\n\nexport class MissingIdentityError extends Error {\n override name = 'MissingIdentityError'\n\n constructor(message = 'Identity is not available in this environment') {\n super(message)\n }\n}\n","import type { NetlifyCookies } from './types.js'\n\nexport const NF_JWT_COOKIE = 'nf_jwt'\nexport const NF_REFRESH_COOKIE = 'nf_refresh'\n\n/** Reads a cookie value from `document.cookie` by name. Returns `null` if not found. */\nexport const getCookie = (name: string): string | null => {\n const match = document.cookie.match(new RegExp(`(?:^|; )${name.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}=([^;]*)`))\n return match ? decodeURIComponent(match[1]) : null\n}\n\n/** Sets the `nf_jwt` and (optionally) `nf_refresh` auth cookies via the Netlify runtime. */\nexport const setAuthCookies = (cookies: NetlifyCookies, accessToken: string, refreshToken?: string): void => {\n cookies.set({\n name: NF_JWT_COOKIE,\n value: accessToken,\n httpOnly: false,\n secure: true,\n path: '/',\n sameSite: 'Lax',\n })\n\n if (refreshToken) {\n cookies.set({\n name: NF_REFRESH_COOKIE,\n value: refreshToken,\n httpOnly: false,\n secure: true,\n path: '/',\n sameSite: 'Lax',\n })\n }\n}\n\n/** Deletes both auth cookies via the Netlify runtime. */\nexport const deleteAuthCookies = (cookies: NetlifyCookies): void => {\n cookies.delete(NF_JWT_COOKIE)\n cookies.delete(NF_REFRESH_COOKIE)\n}\n\n/** Reads a cookie from the server-side Netlify runtime. Returns `null` if not available. */\nexport const getServerCookie = (name: string): string | null => {\n const cookies = globalThis.Netlify?.context?.cookies\n if (!cookies || typeof cookies.get !== 'function') return null\n return cookies.get(name) ?? null\n}\n","import type { UserData } from 'gotrue-js'\nimport { AUTH_PROVIDERS, type AuthProvider } from './types.js'\nimport { getGoTrueClient, isBrowser } from './environment.js'\nimport { getCookie, getServerCookie, NF_JWT_COOKIE } from './cookies.js'\n\nexport interface IdentityUser {\n sub?: string\n email?: string\n exp?: number\n app_metadata?: Record<string, unknown>\n user_metadata?: Record<string, unknown>\n [key: string]: unknown\n}\n\nconst toAuthProvider = (value: unknown): AuthProvider | undefined =>\n typeof value === 'string' && (AUTH_PROVIDERS as readonly string[]).includes(value)\n ? (value as AuthProvider)\n : undefined\n\nexport interface User {\n id: string\n email?: string\n emailVerified?: boolean\n createdAt?: string\n updatedAt?: string\n provider?: AuthProvider\n name?: string\n pictureUrl?: string\n metadata?: Record<string, unknown>\n rawGoTrueData?: Record<string, unknown>\n}\n\nexport const toUser = (userData: UserData): User => {\n const userMeta = userData.user_metadata ?? {}\n const appMeta = userData.app_metadata ?? {}\n const name = userMeta.full_name || userMeta.name\n const pictureUrl = userMeta.avatar_url\n\n return {\n id: userData.id,\n email: userData.email,\n emailVerified: !!userData.confirmed_at,\n createdAt: userData.created_at,\n updatedAt: userData.updated_at,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n pictureUrl: typeof pictureUrl === 'string' ? pictureUrl : undefined,\n metadata: userMeta,\n rawGoTrueData: { ...userData },\n }\n}\n\n/**\n * Converts server-side JWT claims into User\n */\nconst claimsToUser = (claims: IdentityUser): User => {\n const appMeta = claims.app_metadata ?? {}\n const userMeta = claims.user_metadata ?? {}\n const name = userMeta.full_name || userMeta.name\n\n return {\n id: claims.sub ?? '',\n email: claims.email,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n metadata: userMeta,\n }\n}\n\n/** Decodes a JWT payload without verifying the signature. */\nconst decodeJwtPayload = (token: string): IdentityUser | null => {\n try {\n const parts = token.split('.')\n if (parts.length !== 3) return null\n const payload = atob(parts[1].replace(/-/g, '+').replace(/_/g, '/'))\n return JSON.parse(payload) as IdentityUser\n } catch {\n return null\n }\n}\n\n/**\n * Returns the currently authenticated user, or `null` if not logged in.\n * Synchronous. Never throws.\n *\n * In the browser, checks gotrue-js localStorage first. If no localStorage\n * session exists, falls back to decoding the `nf_jwt` cookie (set by\n * server-side login). This gives immediate synchronous read access without\n * waiting for async hydration via `hydrateSession()`.\n */\nexport const getUser = (): User | null => {\n if (isBrowser()) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser() ?? null\n if (currentUser) return toUser(currentUser)\n\n const jwt = getCookie(NF_JWT_COOKIE)\n if (!jwt) return null\n\n const claims = decodeJwtPayload(jwt)\n if (!claims) return null\n\n return claimsToUser(claims)\n }\n\n // Primary path: identity context populated by Stargate via X-Nf-Identity-Info header\n const identityContext = globalThis.netlifyIdentityContext\n if (identityContext?.user) {\n return claimsToUser(identityContext.user)\n }\n\n // Fallback: read nf_jwt cookie directly from the request via Netlify runtime\n const jwt = getServerCookie(NF_JWT_COOKIE)\n if (jwt) {\n console.debug(\n '[@netlify/identity] getUser: no identityContext.user, but nf_jwt cookie found on request. ' +\n 'Decoding JWT from cookie. ' +\n `(identityContext: ${identityContext ? `{ url: ${!!identityContext.url}, token: ${!!identityContext.token}, user: ${!!identityContext.user} }` : 'null'}, ` +\n `Netlify.context: ${!!globalThis.Netlify?.context})`,\n )\n const claims = decodeJwtPayload(jwt)\n if (claims) return claimsToUser(claims)\n }\n\n return null\n}\n\n/**\n * Returns `true` if a user is currently authenticated.\n */\nexport const isAuthenticated = (): boolean => getUser() !== null\n","import type { AuthProvider, IdentityConfig, Settings } from './types.js'\nimport { getClient, getIdentityContext, IDENTITY_PATH, isBrowser } from './environment.js'\nimport { AuthError } from './errors.js'\n\n/**\n * Returns the identity configuration for the current environment.\n * Browser: always returns `{ url }` derived from `window.location.origin`.\n * Server: returns `{ url, token }` from the identity context, or `null` if unavailable.\n * Never throws.\n */\nexport const getIdentityConfig = (): IdentityConfig | null => {\n if (isBrowser()) {\n return { url: `${window.location.origin}${IDENTITY_PATH}` }\n }\n\n return getIdentityContext()\n}\n\n/**\n * Fetches the GoTrue `/settings` endpoint.\n * Throws `MissingIdentityError` if Identity is not configured.\n * Throws `AuthError` if the endpoint is unreachable.\n */\nexport const getSettings = async (): Promise<Settings> => {\n const client = getClient()\n\n try {\n const raw = await client.settings()\n const external: Partial<Record<AuthProvider, boolean>> = raw.external ?? {}\n return {\n autoconfirm: raw.autoconfirm,\n disableSignup: raw.disable_signup,\n providers: {\n google: external.google ?? false,\n github: external.github ?? false,\n gitlab: external.gitlab ?? false,\n bitbucket: external.bitbucket ?? false,\n facebook: external.facebook ?? false,\n email: external.email ?? false,\n saml: external.saml ?? false,\n },\n }\n } catch (err) {\n throw new AuthError(err instanceof Error ? err.message : 'Failed to fetch identity settings', 502, { cause: err })\n }\n}\n","import type { UserData } from 'gotrue-js'\n\nimport type { AppMetadata, NetlifyCookies } from './types.js'\n\nexport type AuthEvent = 'login' | 'logout' | 'token_refresh' | 'user_updated'\nimport type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getGoTrueClient, getClient, getIdentityContext, isBrowser, IDENTITY_PATH } from './environment.js'\nimport { getCookie, setAuthCookies, deleteAuthCookies, NF_JWT_COOKIE, NF_REFRESH_COOKIE } from './cookies.js'\nimport { AuthError } from './errors.js'\n\nconst getCookies = (): NetlifyCookies => {\n const cookies = globalThis.Netlify?.context?.cookies\n if (!cookies) {\n throw new AuthError('Server-side auth requires Netlify Functions runtime')\n }\n return cookies\n}\n\nconst getServerIdentityUrl = (): string => {\n const ctx = getIdentityContext()\n if (!ctx?.url) {\n throw new AuthError('Could not determine the Identity endpoint URL on the server')\n }\n return ctx.url\n}\n\nexport interface JWTClaims {\n sub: string // UUID\n email: string\n exp: number\n iat: number\n aud: string\n app_metadata: AppMetadata\n user_metadata: Record<string, unknown>\n}\n\nexport type AuthCallback = (event: AuthEvent, user: User | null) => void\n\n/** Persist the session to localStorage so it survives page reloads. */\nexport const persistSession = true\n\nconst listeners = new Set<AuthCallback>()\n\nexport const emitAuthEvent = (event: AuthEvent, user: User | null): void => {\n for (const listener of listeners) {\n listener(event, user)\n }\n}\n\nlet storageListenerAttached = false\n\nconst attachStorageListener = (): void => {\n if (storageListenerAttached) return\n storageListenerAttached = true\n\n window.addEventListener('storage', (event: StorageEvent) => {\n if (event.key !== 'gotrue.user') return\n\n if (event.newValue) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser()\n emitAuthEvent('login', currentUser ? toUser(currentUser) : null)\n } else {\n emitAuthEvent('logout', null)\n }\n })\n}\n\n/**\n * Subscribes to auth state changes (login, logout, token refresh, user updates).\n * Returns an unsubscribe function. No-op on the server.\n */\nexport const onAuthChange = (callback: AuthCallback): (() => void) => {\n if (!isBrowser()) {\n return () => {}\n }\n\n listeners.add(callback)\n attachStorageListener()\n\n return () => {\n listeners.delete(callback)\n }\n}\n\n/** Logs in with email and password. Works in both browser and server contexts. */\nexport const login = async (email: string, password: string): Promise<User> => {\n if (!isBrowser()) {\n const identityUrl = getServerIdentityUrl()\n const cookies = getCookies()\n\n const body = new URLSearchParams({\n grant_type: 'password',\n username: email,\n password,\n })\n\n let res: Response\n try {\n res = await fetch(`${identityUrl}/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: body.toString(),\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n\n if (!res.ok) {\n const errorBody = await res.json().catch(() => ({}))\n throw new AuthError(\n (errorBody as Record<string, string>).msg ||\n (errorBody as Record<string, string>).error_description ||\n `Login failed (${res.status})`,\n res.status,\n )\n }\n\n const data = (await res.json()) as Record<string, unknown>\n const accessToken = data.access_token as string\n\n let userRes: Response\n try {\n userRes = await fetch(`${identityUrl}/user`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n\n if (!userRes.ok) {\n const errorBody = await userRes.json().catch(() => ({}))\n throw new AuthError(\n (errorBody as Record<string, string>).msg || `Failed to fetch user data (${userRes.status})`,\n userRes.status,\n )\n }\n\n const userData = (await userRes.json()) as UserData\n const user = toUser(userData)\n\n setAuthCookies(cookies, accessToken, data.refresh_token as string | undefined)\n\n return user\n }\n\n const client = getClient()\n\n try {\n const gotrueUser = await client.login(email, password, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Creates a new account. Emits 'login' if autoconfirm is enabled. Works in both browser and server contexts. */\nexport const signup = async (email: string, password: string, data?: Record<string, unknown>): Promise<User> => {\n if (!isBrowser()) {\n const identityUrl = getServerIdentityUrl()\n const cookies = getCookies()\n\n let res: Response\n try {\n res = await fetch(`${identityUrl}/signup`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ email, password, data }),\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n\n if (!res.ok) {\n const errorBody = await res.json().catch(() => ({}))\n throw new AuthError((errorBody as Record<string, string>).msg || `Signup failed (${res.status})`, res.status)\n }\n\n const responseData = (await res.json()) as UserData\n const user = toUser(responseData)\n\n if (responseData.confirmed_at) {\n const responseRecord = responseData as unknown as Record<string, unknown>\n const accessToken = responseRecord.access_token as string | undefined\n if (accessToken) {\n setAuthCookies(cookies, accessToken, responseRecord.refresh_token as string | undefined)\n }\n }\n\n return user\n }\n\n const client = getClient()\n\n try {\n const response = await client.signup(email, password, data)\n const user = toUser(response as UserData)\n if (response.confirmed_at) {\n emitAuthEvent('login', user)\n }\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Logs out the current user and clears the session. Works in both browser and server contexts. */\nexport const logout = async (): Promise<void> => {\n if (!isBrowser()) {\n const identityUrl = getServerIdentityUrl()\n const cookies = getCookies()\n\n const jwt = cookies.get(NF_JWT_COOKIE)\n if (jwt) {\n try {\n await fetch(`${identityUrl}/logout`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}` },\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n }\n\n deleteAuthCookies(cookies)\n return\n }\n\n const client = getClient()\n\n try {\n const currentUser = client.currentUser()\n if (currentUser) {\n await currentUser.logout()\n }\n emitAuthEvent('logout', null)\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Redirects to an OAuth provider. Always throws (the page navigates away). Browser only. */\nexport const oauthLogin = (provider: string): never => {\n if (!isBrowser()) {\n throw new Error('oauthLogin() is only available in the browser')\n }\n const client = getClient()\n\n window.location.href = client.loginExternalUrl(provider)\n throw new Error('Redirecting to OAuth provider')\n}\n\nexport interface CallbackResult {\n type: 'oauth' | 'confirmation' | 'recovery' | 'invite' | 'email_change'\n user: User | null\n token?: string\n}\n\n/**\n * Processes the URL hash after an OAuth redirect, email confirmation, password\n * recovery, invite acceptance, or email change. Call on page load. Browser only.\n * Returns `null` if the hash contains no auth parameters.\n */\nexport const handleAuthCallback = async (): Promise<CallbackResult | null> => {\n if (!isBrowser()) return null\n\n const hash = window.location.hash.substring(1)\n if (!hash) return null\n\n const client = getClient()\n\n try {\n const params = new URLSearchParams(hash)\n\n const accessToken = params.get('access_token')\n if (accessToken) {\n const gotrueUser = await client.createUser(\n {\n access_token: accessToken,\n token_type: (params.get('token_type') as 'bearer') ?? 'bearer',\n expires_in: Number(params.get('expires_in')),\n expires_at: Number(params.get('expires_at')),\n refresh_token: params.get('refresh_token') ?? '',\n },\n persistSession,\n )\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'oauth', user }\n }\n\n const confirmationToken = params.get('confirmation_token')\n if (confirmationToken) {\n const gotrueUser = await client.confirm(confirmationToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'confirmation', user }\n }\n\n const recoveryToken = params.get('recovery_token')\n if (recoveryToken) {\n const gotrueUser = await client.recover(recoveryToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'recovery', user }\n }\n\n const inviteToken = params.get('invite_token')\n if (inviteToken) {\n clearHash()\n return { type: 'invite', user: null, token: inviteToken }\n }\n\n const emailChangeToken = params.get('email_change_token')\n if (emailChangeToken) {\n const currentUser = client.currentUser()\n if (!currentUser) {\n throw new AuthError('Email change verification requires an active browser session')\n }\n\n const jwt = await currentUser.jwt()\n const identityUrl = `${window.location.origin}${IDENTITY_PATH}`\n\n const emailChangeRes = await fetch(`${identityUrl}/user`, {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${jwt}`,\n },\n body: JSON.stringify({ email_change_token: emailChangeToken }),\n })\n\n if (!emailChangeRes.ok) {\n const errorBody = await emailChangeRes.json().catch(() => ({}))\n throw new AuthError(\n (errorBody as Record<string, string>).msg || `Email change verification failed (${emailChangeRes.status})`,\n emailChangeRes.status,\n )\n }\n\n const emailChangeData = (await emailChangeRes.json()) as UserData\n const user = toUser(emailChangeData)\n clearHash()\n emitAuthEvent('user_updated', user)\n return { type: 'email_change', user }\n }\n\n return null\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\nconst clearHash = (): void => {\n history.replaceState(null, '', window.location.pathname + window.location.search)\n}\n\n/**\n * Hydrates the browser-side gotrue-js session from server-set auth cookies.\n * Call this on page load when using server-side login to enable browser\n * account operations (updateUser, verifyEmailChange, etc.).\n *\n * No-op if a browser session already exists or no auth cookies are present.\n * No-op on the server.\n */\nexport const hydrateSession = async (): Promise<User | null> => {\n if (!isBrowser()) return null\n\n const client = getClient()\n const currentUser = client.currentUser()\n if (currentUser) return toUser(currentUser)\n\n const accessToken = getCookie(NF_JWT_COOKIE)\n if (!accessToken) return null\n\n const refreshToken = getCookie(NF_REFRESH_COOKIE) ?? ''\n\n const gotrueUser = await client.createUser(\n {\n access_token: accessToken,\n token_type: 'bearer',\n expires_in: 3600,\n expires_at: Math.floor(Date.now() / 1000) + 3600,\n refresh_token: refreshToken,\n },\n persistSession,\n )\n\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n}\n","import type { UserData, User as GoTrueUser } from 'gotrue-js'\n\nimport type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getClient, isBrowser, IDENTITY_PATH } from './environment.js'\nimport { emitAuthEvent, persistSession, hydrateSession } from './auth.js'\nimport { AuthError } from './errors.js'\n\n/**\n * Returns the current gotrue-js user, auto-hydrating from cookies if needed.\n * Throws AuthError if no user can be resolved.\n */\nconst ensureCurrentUser = async (): Promise<GoTrueUser> => {\n const client = getClient()\n\n let currentUser = client.currentUser()\n if (!currentUser && isBrowser()) {\n await hydrateSession()\n currentUser = client.currentUser()\n }\n if (!currentUser) throw new AuthError('No user is currently logged in')\n\n return currentUser\n}\n\n/** Sends a password recovery email to the given address. */\nexport const requestPasswordRecovery = async (email: string): Promise<void> => {\n const client = getClient()\n\n try {\n await client.requestPasswordRecovery(email)\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Redeems a recovery token and sets a new password. Logs the user in on success. */\nexport const recoverPassword = async (token: string, newPassword: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.recover(token, persistSession)\n const updatedUser = await gotrueUser.update({ password: newPassword })\n const user = toUser(updatedUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Confirms an email address using the token from a confirmation email. Logs the user in on success. */\nexport const confirmEmail = async (token: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.confirm(token, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Accepts an invite token and sets a password for the new account. Logs the user in on success. */\nexport const acceptInvite = async (token: string, password: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.acceptInvite(token, password, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/**\n * Verifies an email change using the token from a verification email.\n * Auto-hydrates from auth cookies if no browser session exists.\n */\nexport const verifyEmailChange = async (token: string): Promise<User> => {\n if (!isBrowser()) throw new AuthError('verifyEmailChange() is only available in the browser')\n\n const currentUser = await ensureCurrentUser()\n\n const jwt = await currentUser.jwt()\n const identityUrl = `${window.location.origin}${IDENTITY_PATH}`\n\n try {\n const res = await fetch(`${identityUrl}/user`, {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${jwt}`,\n },\n body: JSON.stringify({ email_change_token: token }),\n })\n\n if (!res.ok) {\n const errorBody = await res.json().catch(() => ({}))\n throw new AuthError(\n (errorBody as Record<string, string>).msg || `Email change verification failed (${res.status})`,\n res.status,\n )\n }\n\n const userData = (await res.json()) as UserData\n const user = toUser(userData)\n emitAuthEvent('user_updated', user)\n return user\n } catch (error) {\n if (error instanceof AuthError) throw error\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/**\n * Updates the current user's metadata or credentials.\n * Auto-hydrates from auth cookies if no browser session exists.\n */\nexport const updateUser = async (updates: Record<string, unknown>): Promise<User> => {\n const currentUser = await ensureCurrentUser()\n\n try {\n const updatedUser = await currentUser.update(updates)\n const user = toUser(updatedUser)\n emitAuthEvent('user_updated', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n"],"mappings":"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","names":["GoTrue","jwt"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -30,6 +30,11 @@ interface User {
|
|
|
30
30
|
/**
|
|
31
31
|
* Returns the currently authenticated user, or `null` if not logged in.
|
|
32
32
|
* Synchronous. Never throws.
|
|
33
|
+
*
|
|
34
|
+
* In the browser, checks gotrue-js localStorage first. If no localStorage
|
|
35
|
+
* session exists, falls back to decoding the `nf_jwt` cookie (set by
|
|
36
|
+
* server-side login). This gives immediate synchronous read access without
|
|
37
|
+
* waiting for async hydration via `hydrateSession()`.
|
|
33
38
|
*/
|
|
34
39
|
declare const getUser: () => User | null;
|
|
35
40
|
/**
|
|
@@ -102,16 +107,12 @@ declare const confirmEmail: (token: string) => Promise<User>;
|
|
|
102
107
|
declare const acceptInvite: (token: string, password: string) => Promise<User>;
|
|
103
108
|
/**
|
|
104
109
|
* Verifies an email change using the token from a verification email.
|
|
105
|
-
*
|
|
106
|
-
* Requires an active browser login session (via localStorage).
|
|
107
|
-
* Server-side login sessions (cookie-based) do not satisfy this requirement.
|
|
110
|
+
* Auto-hydrates from auth cookies if no browser session exists.
|
|
108
111
|
*/
|
|
109
112
|
declare const verifyEmailChange: (token: string) => Promise<User>;
|
|
110
113
|
/**
|
|
111
114
|
* Updates the current user's metadata or credentials.
|
|
112
|
-
*
|
|
113
|
-
* Requires an active browser login session (via gotrue-js localStorage).
|
|
114
|
-
* Server-side login sessions (cookie-based) do not satisfy this requirement.
|
|
115
|
+
* Auto-hydrates from auth cookies if no browser session exists.
|
|
115
116
|
*/
|
|
116
117
|
declare const updateUser: (updates: Record<string, unknown>) => Promise<User>;
|
|
117
118
|
|
package/dist/index.d.ts
CHANGED
|
@@ -30,6 +30,11 @@ interface User {
|
|
|
30
30
|
/**
|
|
31
31
|
* Returns the currently authenticated user, or `null` if not logged in.
|
|
32
32
|
* Synchronous. Never throws.
|
|
33
|
+
*
|
|
34
|
+
* In the browser, checks gotrue-js localStorage first. If no localStorage
|
|
35
|
+
* session exists, falls back to decoding the `nf_jwt` cookie (set by
|
|
36
|
+
* server-side login). This gives immediate synchronous read access without
|
|
37
|
+
* waiting for async hydration via `hydrateSession()`.
|
|
33
38
|
*/
|
|
34
39
|
declare const getUser: () => User | null;
|
|
35
40
|
/**
|
|
@@ -102,16 +107,12 @@ declare const confirmEmail: (token: string) => Promise<User>;
|
|
|
102
107
|
declare const acceptInvite: (token: string, password: string) => Promise<User>;
|
|
103
108
|
/**
|
|
104
109
|
* Verifies an email change using the token from a verification email.
|
|
105
|
-
*
|
|
106
|
-
* Requires an active browser login session (via localStorage).
|
|
107
|
-
* Server-side login sessions (cookie-based) do not satisfy this requirement.
|
|
110
|
+
* Auto-hydrates from auth cookies if no browser session exists.
|
|
108
111
|
*/
|
|
109
112
|
declare const verifyEmailChange: (token: string) => Promise<User>;
|
|
110
113
|
/**
|
|
111
114
|
* Updates the current user's metadata or credentials.
|
|
112
|
-
*
|
|
113
|
-
* Requires an active browser login session (via gotrue-js localStorage).
|
|
114
|
-
* Server-side login sessions (cookie-based) do not satisfy this requirement.
|
|
115
|
+
* Auto-hydrates from auth cookies if no browser session exists.
|
|
115
116
|
*/
|
|
116
117
|
declare const updateUser: (updates: Record<string, unknown>) => Promise<User>;
|
|
117
118
|
|
package/dist/index.js
CHANGED
|
@@ -76,6 +76,43 @@ var getIdentityContext = () => {
|
|
|
76
76
|
return null;
|
|
77
77
|
};
|
|
78
78
|
|
|
79
|
+
// src/cookies.ts
|
|
80
|
+
var NF_JWT_COOKIE = "nf_jwt";
|
|
81
|
+
var NF_REFRESH_COOKIE = "nf_refresh";
|
|
82
|
+
var getCookie = (name) => {
|
|
83
|
+
const match = document.cookie.match(new RegExp(`(?:^|; )${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}=([^;]*)`));
|
|
84
|
+
return match ? decodeURIComponent(match[1]) : null;
|
|
85
|
+
};
|
|
86
|
+
var setAuthCookies = (cookies, accessToken, refreshToken) => {
|
|
87
|
+
cookies.set({
|
|
88
|
+
name: NF_JWT_COOKIE,
|
|
89
|
+
value: accessToken,
|
|
90
|
+
httpOnly: false,
|
|
91
|
+
secure: true,
|
|
92
|
+
path: "/",
|
|
93
|
+
sameSite: "Lax"
|
|
94
|
+
});
|
|
95
|
+
if (refreshToken) {
|
|
96
|
+
cookies.set({
|
|
97
|
+
name: NF_REFRESH_COOKIE,
|
|
98
|
+
value: refreshToken,
|
|
99
|
+
httpOnly: false,
|
|
100
|
+
secure: true,
|
|
101
|
+
path: "/",
|
|
102
|
+
sameSite: "Lax"
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
var deleteAuthCookies = (cookies) => {
|
|
107
|
+
cookies.delete(NF_JWT_COOKIE);
|
|
108
|
+
cookies.delete(NF_REFRESH_COOKIE);
|
|
109
|
+
};
|
|
110
|
+
var getServerCookie = (name) => {
|
|
111
|
+
const cookies = globalThis.Netlify?.context?.cookies;
|
|
112
|
+
if (!cookies || typeof cookies.get !== "function") return null;
|
|
113
|
+
return cookies.get(name) ?? null;
|
|
114
|
+
};
|
|
115
|
+
|
|
79
116
|
// src/user.ts
|
|
80
117
|
var toAuthProvider = (value) => typeof value === "string" && AUTH_PROVIDERS.includes(value) ? value : void 0;
|
|
81
118
|
var toUser = (userData) => {
|
|
@@ -108,16 +145,40 @@ var claimsToUser = (claims) => {
|
|
|
108
145
|
metadata: userMeta
|
|
109
146
|
};
|
|
110
147
|
};
|
|
148
|
+
var decodeJwtPayload = (token) => {
|
|
149
|
+
try {
|
|
150
|
+
const parts = token.split(".");
|
|
151
|
+
if (parts.length !== 3) return null;
|
|
152
|
+
const payload = atob(parts[1].replace(/-/g, "+").replace(/_/g, "/"));
|
|
153
|
+
return JSON.parse(payload);
|
|
154
|
+
} catch {
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
};
|
|
111
158
|
var getUser = () => {
|
|
112
159
|
if (isBrowser()) {
|
|
113
160
|
const client = getGoTrueClient();
|
|
114
161
|
const currentUser = client?.currentUser() ?? null;
|
|
115
|
-
if (
|
|
116
|
-
|
|
162
|
+
if (currentUser) return toUser(currentUser);
|
|
163
|
+
const jwt2 = getCookie(NF_JWT_COOKIE);
|
|
164
|
+
if (!jwt2) return null;
|
|
165
|
+
const claims = decodeJwtPayload(jwt2);
|
|
166
|
+
if (!claims) return null;
|
|
167
|
+
return claimsToUser(claims);
|
|
117
168
|
}
|
|
118
169
|
const identityContext = globalThis.netlifyIdentityContext;
|
|
119
|
-
if (
|
|
120
|
-
|
|
170
|
+
if (identityContext?.user) {
|
|
171
|
+
return claimsToUser(identityContext.user);
|
|
172
|
+
}
|
|
173
|
+
const jwt = getServerCookie(NF_JWT_COOKIE);
|
|
174
|
+
if (jwt) {
|
|
175
|
+
console.debug(
|
|
176
|
+
`[@netlify/identity] getUser: no identityContext.user, but nf_jwt cookie found on request. Decoding JWT from cookie. (identityContext: ${identityContext ? `{ url: ${!!identityContext.url}, token: ${!!identityContext.token}, user: ${!!identityContext.user} }` : "null"}, Netlify.context: ${!!globalThis.Netlify?.context})`
|
|
177
|
+
);
|
|
178
|
+
const claims = decodeJwtPayload(jwt);
|
|
179
|
+
if (claims) return claimsToUser(claims);
|
|
180
|
+
}
|
|
181
|
+
return null;
|
|
121
182
|
};
|
|
122
183
|
var isAuthenticated = () => getUser() !== null;
|
|
123
184
|
|
|
@@ -244,14 +305,7 @@ var login = async (email, password) => {
|
|
|
244
305
|
}
|
|
245
306
|
const userData = await userRes.json();
|
|
246
307
|
const user = toUser(userData);
|
|
247
|
-
cookies.
|
|
248
|
-
name: "nf_jwt",
|
|
249
|
-
value: accessToken,
|
|
250
|
-
httpOnly: true,
|
|
251
|
-
secure: true,
|
|
252
|
-
path: "/",
|
|
253
|
-
sameSite: "Lax"
|
|
254
|
-
});
|
|
308
|
+
setAuthCookies(cookies, accessToken, data.refresh_token);
|
|
255
309
|
return user;
|
|
256
310
|
}
|
|
257
311
|
const client = getClient();
|
|
@@ -285,16 +339,10 @@ var signup = async (email, password, data) => {
|
|
|
285
339
|
const responseData = await res.json();
|
|
286
340
|
const user = toUser(responseData);
|
|
287
341
|
if (responseData.confirmed_at) {
|
|
288
|
-
const
|
|
342
|
+
const responseRecord = responseData;
|
|
343
|
+
const accessToken = responseRecord.access_token;
|
|
289
344
|
if (accessToken) {
|
|
290
|
-
cookies.
|
|
291
|
-
name: "nf_jwt",
|
|
292
|
-
value: accessToken,
|
|
293
|
-
httpOnly: true,
|
|
294
|
-
secure: true,
|
|
295
|
-
path: "/",
|
|
296
|
-
sameSite: "Lax"
|
|
297
|
-
});
|
|
345
|
+
setAuthCookies(cookies, accessToken, responseRecord.refresh_token);
|
|
298
346
|
}
|
|
299
347
|
}
|
|
300
348
|
return user;
|
|
@@ -315,7 +363,7 @@ var logout = async () => {
|
|
|
315
363
|
if (!isBrowser()) {
|
|
316
364
|
const identityUrl = getServerIdentityUrl();
|
|
317
365
|
const cookies = getCookies();
|
|
318
|
-
const jwt = cookies.get(
|
|
366
|
+
const jwt = cookies.get(NF_JWT_COOKIE);
|
|
319
367
|
if (jwt) {
|
|
320
368
|
try {
|
|
321
369
|
await fetch(`${identityUrl}/logout`, {
|
|
@@ -326,7 +374,7 @@ var logout = async () => {
|
|
|
326
374
|
throw new AuthError(error.message, void 0, { cause: error });
|
|
327
375
|
}
|
|
328
376
|
}
|
|
329
|
-
cookies
|
|
377
|
+
deleteAuthCookies(cookies);
|
|
330
378
|
return;
|
|
331
379
|
}
|
|
332
380
|
const client = getClient();
|
|
@@ -430,8 +478,40 @@ var handleAuthCallback = async () => {
|
|
|
430
478
|
var clearHash = () => {
|
|
431
479
|
history.replaceState(null, "", window.location.pathname + window.location.search);
|
|
432
480
|
};
|
|
481
|
+
var hydrateSession = async () => {
|
|
482
|
+
if (!isBrowser()) return null;
|
|
483
|
+
const client = getClient();
|
|
484
|
+
const currentUser = client.currentUser();
|
|
485
|
+
if (currentUser) return toUser(currentUser);
|
|
486
|
+
const accessToken = getCookie(NF_JWT_COOKIE);
|
|
487
|
+
if (!accessToken) return null;
|
|
488
|
+
const refreshToken = getCookie(NF_REFRESH_COOKIE) ?? "";
|
|
489
|
+
const gotrueUser = await client.createUser(
|
|
490
|
+
{
|
|
491
|
+
access_token: accessToken,
|
|
492
|
+
token_type: "bearer",
|
|
493
|
+
expires_in: 3600,
|
|
494
|
+
expires_at: Math.floor(Date.now() / 1e3) + 3600,
|
|
495
|
+
refresh_token: refreshToken
|
|
496
|
+
},
|
|
497
|
+
persistSession
|
|
498
|
+
);
|
|
499
|
+
const user = toUser(gotrueUser);
|
|
500
|
+
emitAuthEvent("login", user);
|
|
501
|
+
return user;
|
|
502
|
+
};
|
|
433
503
|
|
|
434
504
|
// src/account.ts
|
|
505
|
+
var ensureCurrentUser = async () => {
|
|
506
|
+
const client = getClient();
|
|
507
|
+
let currentUser = client.currentUser();
|
|
508
|
+
if (!currentUser && isBrowser()) {
|
|
509
|
+
await hydrateSession();
|
|
510
|
+
currentUser = client.currentUser();
|
|
511
|
+
}
|
|
512
|
+
if (!currentUser) throw new AuthError("No user is currently logged in");
|
|
513
|
+
return currentUser;
|
|
514
|
+
};
|
|
435
515
|
var requestPasswordRecovery = async (email) => {
|
|
436
516
|
const client = getClient();
|
|
437
517
|
try {
|
|
@@ -475,10 +555,8 @@ var acceptInvite = async (token, password) => {
|
|
|
475
555
|
}
|
|
476
556
|
};
|
|
477
557
|
var verifyEmailChange = async (token) => {
|
|
478
|
-
const client = getClient();
|
|
479
|
-
const currentUser = client.currentUser();
|
|
480
|
-
if (!currentUser) throw new AuthError("No user is currently logged in");
|
|
481
558
|
if (!isBrowser()) throw new AuthError("verifyEmailChange() is only available in the browser");
|
|
559
|
+
const currentUser = await ensureCurrentUser();
|
|
482
560
|
const jwt = await currentUser.jwt();
|
|
483
561
|
const identityUrl = `${window.location.origin}${IDENTITY_PATH}`;
|
|
484
562
|
try {
|
|
@@ -507,9 +585,7 @@ var verifyEmailChange = async (token) => {
|
|
|
507
585
|
}
|
|
508
586
|
};
|
|
509
587
|
var updateUser = async (updates) => {
|
|
510
|
-
const
|
|
511
|
-
const currentUser = client.currentUser();
|
|
512
|
-
if (!currentUser) throw new AuthError("No user is currently logged in");
|
|
588
|
+
const currentUser = await ensureCurrentUser();
|
|
513
589
|
try {
|
|
514
590
|
const updatedUser = await currentUser.update(updates);
|
|
515
591
|
const user = toUser(updatedUser);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/environment.ts","../src/errors.ts","../src/user.ts","../src/config.ts","../src/auth.ts","../src/account.ts"],"sourcesContent":["export const AUTH_PROVIDERS = ['google', 'github', 'gitlab', 'bitbucket', 'facebook', 'saml', 'email'] as const\nexport type AuthProvider = (typeof AUTH_PROVIDERS)[number]\n\nexport interface AppMetadata {\n provider: AuthProvider\n roles?: string[]\n [key: string]: unknown\n}\n\nexport interface IdentityConfig {\n url: string\n token?: string // this is an operator token, only available on the server\n}\n\nexport interface Settings {\n autoconfirm: boolean\n disableSignup: boolean\n providers: Record<AuthProvider, boolean>\n}\n\nexport interface NetlifyCookies {\n get(name: string): string | undefined\n set(options: {\n name: string\n value: string\n httpOnly: boolean\n secure: boolean\n path: string\n sameSite: string\n }): void\n delete(name: string): void\n}\n","import GoTrue from 'gotrue-js'\n\nimport type { IdentityConfig } from './types.js'\nimport { MissingIdentityError } from './errors.js'\n\nexport const IDENTITY_PATH = '/.netlify/identity'\n\nlet goTrueClient: GoTrue | null = null\nlet cachedApiUrl: string | null | undefined\nlet warnedMissingUrl = false\n\nexport const isBrowser = (): boolean => typeof window !== 'undefined' && typeof window.location !== 'undefined'\n\n/**\n * Discovers and caches the GoTrue API URL.\n *\n * Browser: uses `window.location.origin` + IDENTITY_PATH.\n * Server: reads from `globalThis.netlifyIdentityContext`.\n */\nconst discoverApiUrl = (): string | null => {\n if (cachedApiUrl !== undefined) return cachedApiUrl\n\n if (isBrowser()) {\n cachedApiUrl = `${window.location.origin}${IDENTITY_PATH}`\n } else {\n const identityContext = getIdentityContext()\n if (identityContext?.url) {\n cachedApiUrl = identityContext.url\n } else if (globalThis.Netlify?.context?.url) {\n cachedApiUrl = new URL(IDENTITY_PATH, globalThis.Netlify.context.url).href\n }\n }\n\n return cachedApiUrl ?? null\n}\n\n/**\n * Returns (and lazily creates) a singleton gotrue-js client.\n * Returns `null` and logs a warning if no identity URL can be discovered.\n */\nexport const getGoTrueClient = (): GoTrue | null => {\n if (goTrueClient) return goTrueClient\n\n const apiUrl = discoverApiUrl()\n if (!apiUrl) {\n if (!warnedMissingUrl) {\n console.warn(\n '@netlify/identity: Could not determine the Identity endpoint URL. ' +\n 'Make sure your site has Netlify Identity enabled, or run your app with `netlify dev`.',\n )\n warnedMissingUrl = true\n }\n return null\n }\n\n goTrueClient = new GoTrue({ APIUrl: apiUrl, setCookie: isBrowser() })\n return goTrueClient\n}\n\n/**\n * Returns the singleton gotrue-js client, or throws if Identity is not configured.\n */\nexport const getClient = (): GoTrue => {\n const client = getGoTrueClient()\n if (!client) throw new MissingIdentityError()\n return client\n}\n\n/**\n * Reads the server-side identity context set by the Netlify bootstrap.\n * Returns `null` outside the Netlify serverless environment.\n */\nexport const getIdentityContext = (): IdentityConfig | null => {\n const identityContext = globalThis.netlifyIdentityContext\n if (identityContext?.url) {\n return {\n url: identityContext.url,\n token: identityContext.token,\n }\n }\n\n if (globalThis.Netlify?.context?.url) {\n return { url: new URL(IDENTITY_PATH, globalThis.Netlify.context.url).href }\n }\n\n return null\n}\n\n/** Reset cached state for tests. */\nexport const resetTestGoTrueClient = (): void => {\n goTrueClient = null\n cachedApiUrl = undefined\n warnedMissingUrl = false\n}\n","export class AuthError extends Error {\n override name = 'AuthError'\n status?: number\n declare cause?: unknown\n\n constructor(message: string, status?: number, options?: { cause?: unknown }) {\n super(message)\n this.status = status\n if (options && 'cause' in options) {\n this.cause = options.cause\n }\n }\n}\n\nexport class MissingIdentityError extends Error {\n override name = 'MissingIdentityError'\n\n constructor(message = 'Identity is not available in this environment') {\n super(message)\n }\n}\n","import type { UserData } from 'gotrue-js'\nimport { AUTH_PROVIDERS, type AuthProvider } from './types.js'\nimport { getGoTrueClient, isBrowser } from './environment.js'\n\nexport interface IdentityUser {\n sub?: string\n email?: string\n exp?: number\n app_metadata?: Record<string, unknown>\n user_metadata?: Record<string, unknown>\n [key: string]: unknown\n}\n\nconst toAuthProvider = (value: unknown): AuthProvider | undefined =>\n typeof value === 'string' && (AUTH_PROVIDERS as readonly string[]).includes(value)\n ? (value as AuthProvider)\n : undefined\n\nexport interface User {\n id: string\n email?: string\n emailVerified?: boolean\n createdAt?: string\n updatedAt?: string\n provider?: AuthProvider\n name?: string\n pictureUrl?: string\n metadata?: Record<string, unknown>\n rawGoTrueData?: Record<string, unknown>\n}\n\nexport const toUser = (userData: UserData): User => {\n const userMeta = userData.user_metadata ?? {}\n const appMeta = userData.app_metadata ?? {}\n const name = userMeta.full_name || userMeta.name\n const pictureUrl = userMeta.avatar_url\n\n return {\n id: userData.id,\n email: userData.email,\n emailVerified: !!userData.confirmed_at,\n createdAt: userData.created_at,\n updatedAt: userData.updated_at,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n pictureUrl: typeof pictureUrl === 'string' ? pictureUrl : undefined,\n metadata: userMeta,\n rawGoTrueData: { ...userData },\n }\n}\n\n/**\n * Converts server-side JWT claims into User\n */\nconst claimsToUser = (claims: IdentityUser): User => {\n const appMeta = claims.app_metadata ?? {}\n const userMeta = claims.user_metadata ?? {}\n const name = userMeta.full_name || userMeta.name\n\n return {\n id: claims.sub ?? '',\n email: claims.email,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n metadata: userMeta,\n }\n}\n\n/**\n * Returns the currently authenticated user, or `null` if not logged in.\n * Synchronous. Never throws.\n */\nexport const getUser = (): User | null => {\n if (isBrowser()) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser() ?? null\n if (!currentUser) return null\n return toUser(currentUser)\n }\n\n const identityContext = globalThis.netlifyIdentityContext\n if (!identityContext?.user) return null\n\n return claimsToUser(identityContext.user)\n}\n\n/**\n * Returns `true` if a user is currently authenticated.\n */\nexport const isAuthenticated = (): boolean => getUser() !== null\n","import type { AuthProvider, IdentityConfig, Settings } from './types.js'\nimport { getClient, getIdentityContext, IDENTITY_PATH, isBrowser } from './environment.js'\nimport { AuthError } from './errors.js'\n\n/**\n * Returns the identity configuration for the current environment.\n * Browser: always returns `{ url }` derived from `window.location.origin`.\n * Server: returns `{ url, token }` from the identity context, or `null` if unavailable.\n * Never throws.\n */\nexport const getIdentityConfig = (): IdentityConfig | null => {\n if (isBrowser()) {\n return { url: `${window.location.origin}${IDENTITY_PATH}` }\n }\n\n return getIdentityContext()\n}\n\n/**\n * Fetches the GoTrue `/settings` endpoint.\n * Throws `MissingIdentityError` if Identity is not configured.\n * Throws `AuthError` if the endpoint is unreachable.\n */\nexport const getSettings = async (): Promise<Settings> => {\n const client = getClient()\n\n try {\n const raw = await client.settings()\n const external: Partial<Record<AuthProvider, boolean>> = raw.external ?? {}\n return {\n autoconfirm: raw.autoconfirm,\n disableSignup: raw.disable_signup,\n providers: {\n google: external.google ?? false,\n github: external.github ?? false,\n gitlab: external.gitlab ?? false,\n bitbucket: external.bitbucket ?? false,\n facebook: external.facebook ?? false,\n email: external.email ?? false,\n saml: external.saml ?? false,\n },\n }\n } catch (err) {\n throw new AuthError(err instanceof Error ? err.message : 'Failed to fetch identity settings', 502, { cause: err })\n }\n}\n","import type { UserData } from 'gotrue-js'\n\nimport type { AppMetadata, NetlifyCookies } from './types.js'\n\nexport type AuthEvent = 'login' | 'logout' | 'token_refresh' | 'user_updated'\nimport type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getGoTrueClient, getClient, getIdentityContext, isBrowser, IDENTITY_PATH } from './environment.js'\nimport { AuthError } from './errors.js'\n\nconst getCookies = (): NetlifyCookies => {\n const cookies = globalThis.Netlify?.context?.cookies\n if (!cookies) {\n throw new AuthError('Server-side auth requires Netlify Functions runtime')\n }\n return cookies\n}\n\nconst getServerIdentityUrl = (): string => {\n const ctx = getIdentityContext()\n if (!ctx?.url) {\n throw new AuthError('Could not determine the Identity endpoint URL on the server')\n }\n return ctx.url\n}\n\nexport interface JWTClaims {\n sub: string // UUID\n email: string\n exp: number\n iat: number\n aud: string\n app_metadata: AppMetadata\n user_metadata: Record<string, unknown>\n}\n\nexport type AuthCallback = (event: AuthEvent, user: User | null) => void\n\n/** Persist the session to localStorage so it survives page reloads. */\nexport const persistSession = true\n\nconst listeners = new Set<AuthCallback>()\n\nexport const emitAuthEvent = (event: AuthEvent, user: User | null): void => {\n for (const listener of listeners) {\n listener(event, user)\n }\n}\n\nlet storageListenerAttached = false\n\nconst attachStorageListener = (): void => {\n if (storageListenerAttached) return\n storageListenerAttached = true\n\n window.addEventListener('storage', (event: StorageEvent) => {\n if (event.key !== 'gotrue.user') return\n\n if (event.newValue) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser()\n emitAuthEvent('login', currentUser ? toUser(currentUser) : null)\n } else {\n emitAuthEvent('logout', null)\n }\n })\n}\n\n/**\n * Subscribes to auth state changes (login, logout, token refresh, user updates).\n * Returns an unsubscribe function. No-op on the server.\n */\nexport const onAuthChange = (callback: AuthCallback): (() => void) => {\n if (!isBrowser()) {\n return () => {}\n }\n\n listeners.add(callback)\n attachStorageListener()\n\n return () => {\n listeners.delete(callback)\n }\n}\n\n/** Logs in with email and password. Works in both browser and server contexts. */\nexport const login = async (email: string, password: string): Promise<User> => {\n if (!isBrowser()) {\n const identityUrl = getServerIdentityUrl()\n const cookies = getCookies()\n\n const body = new URLSearchParams({\n grant_type: 'password',\n username: email,\n password,\n })\n\n let res: Response\n try {\n res = await fetch(`${identityUrl}/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: body.toString(),\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n\n if (!res.ok) {\n const errorBody = await res.json().catch(() => ({}))\n throw new AuthError(\n (errorBody as Record<string, string>).msg ||\n (errorBody as Record<string, string>).error_description ||\n `Login failed (${res.status})`,\n res.status,\n )\n }\n\n const data = (await res.json()) as Record<string, unknown>\n const accessToken = data.access_token as string\n\n let userRes: Response\n try {\n userRes = await fetch(`${identityUrl}/user`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n\n if (!userRes.ok) {\n const errorBody = await userRes.json().catch(() => ({}))\n throw new AuthError(\n (errorBody as Record<string, string>).msg || `Failed to fetch user data (${userRes.status})`,\n userRes.status,\n )\n }\n\n const userData = (await userRes.json()) as UserData\n const user = toUser(userData)\n\n cookies.set({\n name: 'nf_jwt',\n value: accessToken,\n httpOnly: true,\n secure: true,\n path: '/',\n sameSite: 'Lax',\n })\n\n return user\n }\n\n const client = getClient()\n\n try {\n const gotrueUser = await client.login(email, password, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Creates a new account. Emits 'login' if autoconfirm is enabled. Works in both browser and server contexts. */\nexport const signup = async (email: string, password: string, data?: Record<string, unknown>): Promise<User> => {\n if (!isBrowser()) {\n const identityUrl = getServerIdentityUrl()\n const cookies = getCookies()\n\n let res: Response\n try {\n res = await fetch(`${identityUrl}/signup`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ email, password, data }),\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n\n if (!res.ok) {\n const errorBody = await res.json().catch(() => ({}))\n throw new AuthError((errorBody as Record<string, string>).msg || `Signup failed (${res.status})`, res.status)\n }\n\n const responseData = (await res.json()) as UserData\n const user = toUser(responseData)\n\n if (responseData.confirmed_at) {\n const accessToken = (responseData as unknown as Record<string, unknown>).access_token as string | undefined\n if (accessToken) {\n cookies.set({\n name: 'nf_jwt',\n value: accessToken,\n httpOnly: true,\n secure: true,\n path: '/',\n sameSite: 'Lax',\n })\n }\n }\n\n return user\n }\n\n const client = getClient()\n\n try {\n const response = await client.signup(email, password, data)\n const user = toUser(response as UserData)\n if (response.confirmed_at) {\n emitAuthEvent('login', user)\n }\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Logs out the current user and clears the session. Works in both browser and server contexts. */\nexport const logout = async (): Promise<void> => {\n if (!isBrowser()) {\n const identityUrl = getServerIdentityUrl()\n const cookies = getCookies()\n\n const jwt = cookies.get('nf_jwt')\n if (jwt) {\n try {\n await fetch(`${identityUrl}/logout`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}` },\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n }\n\n cookies.delete('nf_jwt')\n return\n }\n\n const client = getClient()\n\n try {\n const currentUser = client.currentUser()\n if (currentUser) {\n await currentUser.logout()\n }\n emitAuthEvent('logout', null)\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Redirects to an OAuth provider. Always throws (the page navigates away). Browser only. */\nexport const oauthLogin = (provider: string): never => {\n if (!isBrowser()) {\n throw new Error('oauthLogin() is only available in the browser')\n }\n const client = getClient()\n\n window.location.href = client.loginExternalUrl(provider)\n throw new Error('Redirecting to OAuth provider')\n}\n\nexport interface CallbackResult {\n type: 'oauth' | 'confirmation' | 'recovery' | 'invite' | 'email_change'\n user: User | null\n token?: string\n}\n\n/**\n * Processes the URL hash after an OAuth redirect, email confirmation, password\n * recovery, invite acceptance, or email change. Call on page load. Browser only.\n * Returns `null` if the hash contains no auth parameters.\n */\nexport const handleAuthCallback = async (): Promise<CallbackResult | null> => {\n if (!isBrowser()) return null\n\n const hash = window.location.hash.substring(1)\n if (!hash) return null\n\n const client = getClient()\n\n try {\n const params = new URLSearchParams(hash)\n\n const accessToken = params.get('access_token')\n if (accessToken) {\n const gotrueUser = await client.createUser(\n {\n access_token: accessToken,\n token_type: (params.get('token_type') as 'bearer') ?? 'bearer',\n expires_in: Number(params.get('expires_in')),\n expires_at: Number(params.get('expires_at')),\n refresh_token: params.get('refresh_token') ?? '',\n },\n persistSession,\n )\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'oauth', user }\n }\n\n const confirmationToken = params.get('confirmation_token')\n if (confirmationToken) {\n const gotrueUser = await client.confirm(confirmationToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'confirmation', user }\n }\n\n const recoveryToken = params.get('recovery_token')\n if (recoveryToken) {\n const gotrueUser = await client.recover(recoveryToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'recovery', user }\n }\n\n const inviteToken = params.get('invite_token')\n if (inviteToken) {\n clearHash()\n return { type: 'invite', user: null, token: inviteToken }\n }\n\n const emailChangeToken = params.get('email_change_token')\n if (emailChangeToken) {\n const currentUser = client.currentUser()\n if (!currentUser) {\n throw new AuthError('Email change verification requires an active browser session')\n }\n\n const jwt = await currentUser.jwt()\n const identityUrl = `${window.location.origin}${IDENTITY_PATH}`\n\n const emailChangeRes = await fetch(`${identityUrl}/user`, {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${jwt}`,\n },\n body: JSON.stringify({ email_change_token: emailChangeToken }),\n })\n\n if (!emailChangeRes.ok) {\n const errorBody = await emailChangeRes.json().catch(() => ({}))\n throw new AuthError(\n (errorBody as Record<string, string>).msg || `Email change verification failed (${emailChangeRes.status})`,\n emailChangeRes.status,\n )\n }\n\n const emailChangeData = (await emailChangeRes.json()) as UserData\n const user = toUser(emailChangeData)\n clearHash()\n emitAuthEvent('user_updated', user)\n return { type: 'email_change', user }\n }\n\n return null\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\nconst clearHash = (): void => {\n history.replaceState(null, '', window.location.pathname + window.location.search)\n}\n","import type { UserData } from 'gotrue-js'\n\nimport type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getClient, isBrowser, IDENTITY_PATH } from './environment.js'\nimport { emitAuthEvent, persistSession } from './auth.js'\nimport { AuthError } from './errors.js'\n\n/** Sends a password recovery email to the given address. */\nexport const requestPasswordRecovery = async (email: string): Promise<void> => {\n const client = getClient()\n\n try {\n await client.requestPasswordRecovery(email)\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Redeems a recovery token and sets a new password. Logs the user in on success. */\nexport const recoverPassword = async (token: string, newPassword: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.recover(token, persistSession)\n const updatedUser = await gotrueUser.update({ password: newPassword })\n const user = toUser(updatedUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Confirms an email address using the token from a confirmation email. Logs the user in on success. */\nexport const confirmEmail = async (token: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.confirm(token, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Accepts an invite token and sets a password for the new account. Logs the user in on success. */\nexport const acceptInvite = async (token: string, password: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.acceptInvite(token, password, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/**\n * Verifies an email change using the token from a verification email.\n *\n * Requires an active browser login session (via localStorage).\n * Server-side login sessions (cookie-based) do not satisfy this requirement.\n */\nexport const verifyEmailChange = async (token: string): Promise<User> => {\n const client = getClient()\n\n const currentUser = client.currentUser()\n if (!currentUser) throw new AuthError('No user is currently logged in')\n\n if (!isBrowser()) throw new AuthError('verifyEmailChange() is only available in the browser')\n\n const jwt = await currentUser.jwt()\n const identityUrl = `${window.location.origin}${IDENTITY_PATH}`\n\n try {\n const res = await fetch(`${identityUrl}/user`, {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${jwt}`,\n },\n body: JSON.stringify({ email_change_token: token }),\n })\n\n if (!res.ok) {\n const errorBody = await res.json().catch(() => ({}))\n throw new AuthError(\n (errorBody as Record<string, string>).msg || `Email change verification failed (${res.status})`,\n res.status,\n )\n }\n\n const userData = (await res.json()) as UserData\n const user = toUser(userData)\n emitAuthEvent('user_updated', user)\n return user\n } catch (error) {\n if (error instanceof AuthError) throw error\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/**\n * Updates the current user's metadata or credentials.\n *\n * Requires an active browser login session (via gotrue-js localStorage).\n * Server-side login sessions (cookie-based) do not satisfy this requirement.\n */\nexport const updateUser = async (updates: Record<string, unknown>): Promise<User> => {\n const client = getClient()\n\n const currentUser = client.currentUser()\n if (!currentUser) throw new AuthError('No user is currently logged in')\n\n try {\n const updatedUser = await currentUser.update(updates)\n const user = toUser(updatedUser)\n emitAuthEvent('user_updated', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/environment.ts","../src/errors.ts","../src/cookies.ts","../src/user.ts","../src/config.ts","../src/auth.ts","../src/account.ts"],"sourcesContent":["export const AUTH_PROVIDERS = ['google', 'github', 'gitlab', 'bitbucket', 'facebook', 'saml', 'email'] as const\nexport type AuthProvider = (typeof AUTH_PROVIDERS)[number]\n\nexport interface AppMetadata {\n provider: AuthProvider\n roles?: string[]\n [key: string]: unknown\n}\n\nexport interface IdentityConfig {\n url: string\n token?: string // this is an operator token, only available on the server\n}\n\nexport interface Settings {\n autoconfirm: boolean\n disableSignup: boolean\n providers: Record<AuthProvider, boolean>\n}\n\nexport interface NetlifyCookies {\n get(name: string): string | undefined\n set(options: {\n name: string\n value: string\n httpOnly: boolean\n secure: boolean\n path: string\n sameSite: string\n }): void\n delete(name: string): void\n}\n","import GoTrue from 'gotrue-js'\n\nimport type { IdentityConfig } from './types.js'\nimport { MissingIdentityError } from './errors.js'\n\nexport const IDENTITY_PATH = '/.netlify/identity'\n\nlet goTrueClient: GoTrue | null = null\nlet cachedApiUrl: string | null | undefined\nlet warnedMissingUrl = false\n\nexport const isBrowser = (): boolean => typeof window !== 'undefined' && typeof window.location !== 'undefined'\n\n/**\n * Discovers and caches the GoTrue API URL.\n *\n * Browser: uses `window.location.origin` + IDENTITY_PATH.\n * Server: reads from `globalThis.netlifyIdentityContext`.\n */\nconst discoverApiUrl = (): string | null => {\n if (cachedApiUrl !== undefined) return cachedApiUrl\n\n if (isBrowser()) {\n cachedApiUrl = `${window.location.origin}${IDENTITY_PATH}`\n } else {\n const identityContext = getIdentityContext()\n if (identityContext?.url) {\n cachedApiUrl = identityContext.url\n } else if (globalThis.Netlify?.context?.url) {\n cachedApiUrl = new URL(IDENTITY_PATH, globalThis.Netlify.context.url).href\n }\n }\n\n return cachedApiUrl ?? null\n}\n\n/**\n * Returns (and lazily creates) a singleton gotrue-js client.\n * Returns `null` and logs a warning if no identity URL can be discovered.\n */\nexport const getGoTrueClient = (): GoTrue | null => {\n if (goTrueClient) return goTrueClient\n\n const apiUrl = discoverApiUrl()\n if (!apiUrl) {\n if (!warnedMissingUrl) {\n console.warn(\n '@netlify/identity: Could not determine the Identity endpoint URL. ' +\n 'Make sure your site has Netlify Identity enabled, or run your app with `netlify dev`.',\n )\n warnedMissingUrl = true\n }\n return null\n }\n\n goTrueClient = new GoTrue({ APIUrl: apiUrl, setCookie: isBrowser() })\n return goTrueClient\n}\n\n/**\n * Returns the singleton gotrue-js client, or throws if Identity is not configured.\n */\nexport const getClient = (): GoTrue => {\n const client = getGoTrueClient()\n if (!client) throw new MissingIdentityError()\n return client\n}\n\n/**\n * Reads the server-side identity context set by the Netlify bootstrap.\n * Returns `null` outside the Netlify serverless environment.\n */\nexport const getIdentityContext = (): IdentityConfig | null => {\n const identityContext = globalThis.netlifyIdentityContext\n if (identityContext?.url) {\n return {\n url: identityContext.url,\n token: identityContext.token,\n }\n }\n\n if (globalThis.Netlify?.context?.url) {\n return { url: new URL(IDENTITY_PATH, globalThis.Netlify.context.url).href }\n }\n\n return null\n}\n\n/** Reset cached state for tests. */\nexport const resetTestGoTrueClient = (): void => {\n goTrueClient = null\n cachedApiUrl = undefined\n warnedMissingUrl = false\n}\n","export class AuthError extends Error {\n override name = 'AuthError'\n status?: number\n declare cause?: unknown\n\n constructor(message: string, status?: number, options?: { cause?: unknown }) {\n super(message)\n this.status = status\n if (options && 'cause' in options) {\n this.cause = options.cause\n }\n }\n}\n\nexport class MissingIdentityError extends Error {\n override name = 'MissingIdentityError'\n\n constructor(message = 'Identity is not available in this environment') {\n super(message)\n }\n}\n","import type { NetlifyCookies } from './types.js'\n\nexport const NF_JWT_COOKIE = 'nf_jwt'\nexport const NF_REFRESH_COOKIE = 'nf_refresh'\n\n/** Reads a cookie value from `document.cookie` by name. Returns `null` if not found. */\nexport const getCookie = (name: string): string | null => {\n const match = document.cookie.match(new RegExp(`(?:^|; )${name.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}=([^;]*)`))\n return match ? decodeURIComponent(match[1]) : null\n}\n\n/** Sets the `nf_jwt` and (optionally) `nf_refresh` auth cookies via the Netlify runtime. */\nexport const setAuthCookies = (cookies: NetlifyCookies, accessToken: string, refreshToken?: string): void => {\n cookies.set({\n name: NF_JWT_COOKIE,\n value: accessToken,\n httpOnly: false,\n secure: true,\n path: '/',\n sameSite: 'Lax',\n })\n\n if (refreshToken) {\n cookies.set({\n name: NF_REFRESH_COOKIE,\n value: refreshToken,\n httpOnly: false,\n secure: true,\n path: '/',\n sameSite: 'Lax',\n })\n }\n}\n\n/** Deletes both auth cookies via the Netlify runtime. */\nexport const deleteAuthCookies = (cookies: NetlifyCookies): void => {\n cookies.delete(NF_JWT_COOKIE)\n cookies.delete(NF_REFRESH_COOKIE)\n}\n\n/** Reads a cookie from the server-side Netlify runtime. Returns `null` if not available. */\nexport const getServerCookie = (name: string): string | null => {\n const cookies = globalThis.Netlify?.context?.cookies\n if (!cookies || typeof cookies.get !== 'function') return null\n return cookies.get(name) ?? null\n}\n","import type { UserData } from 'gotrue-js'\nimport { AUTH_PROVIDERS, type AuthProvider } from './types.js'\nimport { getGoTrueClient, isBrowser } from './environment.js'\nimport { getCookie, getServerCookie, NF_JWT_COOKIE } from './cookies.js'\n\nexport interface IdentityUser {\n sub?: string\n email?: string\n exp?: number\n app_metadata?: Record<string, unknown>\n user_metadata?: Record<string, unknown>\n [key: string]: unknown\n}\n\nconst toAuthProvider = (value: unknown): AuthProvider | undefined =>\n typeof value === 'string' && (AUTH_PROVIDERS as readonly string[]).includes(value)\n ? (value as AuthProvider)\n : undefined\n\nexport interface User {\n id: string\n email?: string\n emailVerified?: boolean\n createdAt?: string\n updatedAt?: string\n provider?: AuthProvider\n name?: string\n pictureUrl?: string\n metadata?: Record<string, unknown>\n rawGoTrueData?: Record<string, unknown>\n}\n\nexport const toUser = (userData: UserData): User => {\n const userMeta = userData.user_metadata ?? {}\n const appMeta = userData.app_metadata ?? {}\n const name = userMeta.full_name || userMeta.name\n const pictureUrl = userMeta.avatar_url\n\n return {\n id: userData.id,\n email: userData.email,\n emailVerified: !!userData.confirmed_at,\n createdAt: userData.created_at,\n updatedAt: userData.updated_at,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n pictureUrl: typeof pictureUrl === 'string' ? pictureUrl : undefined,\n metadata: userMeta,\n rawGoTrueData: { ...userData },\n }\n}\n\n/**\n * Converts server-side JWT claims into User\n */\nconst claimsToUser = (claims: IdentityUser): User => {\n const appMeta = claims.app_metadata ?? {}\n const userMeta = claims.user_metadata ?? {}\n const name = userMeta.full_name || userMeta.name\n\n return {\n id: claims.sub ?? '',\n email: claims.email,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n metadata: userMeta,\n }\n}\n\n/** Decodes a JWT payload without verifying the signature. */\nconst decodeJwtPayload = (token: string): IdentityUser | null => {\n try {\n const parts = token.split('.')\n if (parts.length !== 3) return null\n const payload = atob(parts[1].replace(/-/g, '+').replace(/_/g, '/'))\n return JSON.parse(payload) as IdentityUser\n } catch {\n return null\n }\n}\n\n/**\n * Returns the currently authenticated user, or `null` if not logged in.\n * Synchronous. Never throws.\n *\n * In the browser, checks gotrue-js localStorage first. If no localStorage\n * session exists, falls back to decoding the `nf_jwt` cookie (set by\n * server-side login). This gives immediate synchronous read access without\n * waiting for async hydration via `hydrateSession()`.\n */\nexport const getUser = (): User | null => {\n if (isBrowser()) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser() ?? null\n if (currentUser) return toUser(currentUser)\n\n const jwt = getCookie(NF_JWT_COOKIE)\n if (!jwt) return null\n\n const claims = decodeJwtPayload(jwt)\n if (!claims) return null\n\n return claimsToUser(claims)\n }\n\n // Primary path: identity context populated by Stargate via X-Nf-Identity-Info header\n const identityContext = globalThis.netlifyIdentityContext\n if (identityContext?.user) {\n return claimsToUser(identityContext.user)\n }\n\n // Fallback: read nf_jwt cookie directly from the request via Netlify runtime\n const jwt = getServerCookie(NF_JWT_COOKIE)\n if (jwt) {\n console.debug(\n '[@netlify/identity] getUser: no identityContext.user, but nf_jwt cookie found on request. ' +\n 'Decoding JWT from cookie. ' +\n `(identityContext: ${identityContext ? `{ url: ${!!identityContext.url}, token: ${!!identityContext.token}, user: ${!!identityContext.user} }` : 'null'}, ` +\n `Netlify.context: ${!!globalThis.Netlify?.context})`,\n )\n const claims = decodeJwtPayload(jwt)\n if (claims) return claimsToUser(claims)\n }\n\n return null\n}\n\n/**\n * Returns `true` if a user is currently authenticated.\n */\nexport const isAuthenticated = (): boolean => getUser() !== null\n","import type { AuthProvider, IdentityConfig, Settings } from './types.js'\nimport { getClient, getIdentityContext, IDENTITY_PATH, isBrowser } from './environment.js'\nimport { AuthError } from './errors.js'\n\n/**\n * Returns the identity configuration for the current environment.\n * Browser: always returns `{ url }` derived from `window.location.origin`.\n * Server: returns `{ url, token }` from the identity context, or `null` if unavailable.\n * Never throws.\n */\nexport const getIdentityConfig = (): IdentityConfig | null => {\n if (isBrowser()) {\n return { url: `${window.location.origin}${IDENTITY_PATH}` }\n }\n\n return getIdentityContext()\n}\n\n/**\n * Fetches the GoTrue `/settings` endpoint.\n * Throws `MissingIdentityError` if Identity is not configured.\n * Throws `AuthError` if the endpoint is unreachable.\n */\nexport const getSettings = async (): Promise<Settings> => {\n const client = getClient()\n\n try {\n const raw = await client.settings()\n const external: Partial<Record<AuthProvider, boolean>> = raw.external ?? {}\n return {\n autoconfirm: raw.autoconfirm,\n disableSignup: raw.disable_signup,\n providers: {\n google: external.google ?? false,\n github: external.github ?? false,\n gitlab: external.gitlab ?? false,\n bitbucket: external.bitbucket ?? false,\n facebook: external.facebook ?? false,\n email: external.email ?? false,\n saml: external.saml ?? false,\n },\n }\n } catch (err) {\n throw new AuthError(err instanceof Error ? err.message : 'Failed to fetch identity settings', 502, { cause: err })\n }\n}\n","import type { UserData } from 'gotrue-js'\n\nimport type { AppMetadata, NetlifyCookies } from './types.js'\n\nexport type AuthEvent = 'login' | 'logout' | 'token_refresh' | 'user_updated'\nimport type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getGoTrueClient, getClient, getIdentityContext, isBrowser, IDENTITY_PATH } from './environment.js'\nimport { getCookie, setAuthCookies, deleteAuthCookies, NF_JWT_COOKIE, NF_REFRESH_COOKIE } from './cookies.js'\nimport { AuthError } from './errors.js'\n\nconst getCookies = (): NetlifyCookies => {\n const cookies = globalThis.Netlify?.context?.cookies\n if (!cookies) {\n throw new AuthError('Server-side auth requires Netlify Functions runtime')\n }\n return cookies\n}\n\nconst getServerIdentityUrl = (): string => {\n const ctx = getIdentityContext()\n if (!ctx?.url) {\n throw new AuthError('Could not determine the Identity endpoint URL on the server')\n }\n return ctx.url\n}\n\nexport interface JWTClaims {\n sub: string // UUID\n email: string\n exp: number\n iat: number\n aud: string\n app_metadata: AppMetadata\n user_metadata: Record<string, unknown>\n}\n\nexport type AuthCallback = (event: AuthEvent, user: User | null) => void\n\n/** Persist the session to localStorage so it survives page reloads. */\nexport const persistSession = true\n\nconst listeners = new Set<AuthCallback>()\n\nexport const emitAuthEvent = (event: AuthEvent, user: User | null): void => {\n for (const listener of listeners) {\n listener(event, user)\n }\n}\n\nlet storageListenerAttached = false\n\nconst attachStorageListener = (): void => {\n if (storageListenerAttached) return\n storageListenerAttached = true\n\n window.addEventListener('storage', (event: StorageEvent) => {\n if (event.key !== 'gotrue.user') return\n\n if (event.newValue) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser()\n emitAuthEvent('login', currentUser ? toUser(currentUser) : null)\n } else {\n emitAuthEvent('logout', null)\n }\n })\n}\n\n/**\n * Subscribes to auth state changes (login, logout, token refresh, user updates).\n * Returns an unsubscribe function. No-op on the server.\n */\nexport const onAuthChange = (callback: AuthCallback): (() => void) => {\n if (!isBrowser()) {\n return () => {}\n }\n\n listeners.add(callback)\n attachStorageListener()\n\n return () => {\n listeners.delete(callback)\n }\n}\n\n/** Logs in with email and password. Works in both browser and server contexts. */\nexport const login = async (email: string, password: string): Promise<User> => {\n if (!isBrowser()) {\n const identityUrl = getServerIdentityUrl()\n const cookies = getCookies()\n\n const body = new URLSearchParams({\n grant_type: 'password',\n username: email,\n password,\n })\n\n let res: Response\n try {\n res = await fetch(`${identityUrl}/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: body.toString(),\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n\n if (!res.ok) {\n const errorBody = await res.json().catch(() => ({}))\n throw new AuthError(\n (errorBody as Record<string, string>).msg ||\n (errorBody as Record<string, string>).error_description ||\n `Login failed (${res.status})`,\n res.status,\n )\n }\n\n const data = (await res.json()) as Record<string, unknown>\n const accessToken = data.access_token as string\n\n let userRes: Response\n try {\n userRes = await fetch(`${identityUrl}/user`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n\n if (!userRes.ok) {\n const errorBody = await userRes.json().catch(() => ({}))\n throw new AuthError(\n (errorBody as Record<string, string>).msg || `Failed to fetch user data (${userRes.status})`,\n userRes.status,\n )\n }\n\n const userData = (await userRes.json()) as UserData\n const user = toUser(userData)\n\n setAuthCookies(cookies, accessToken, data.refresh_token as string | undefined)\n\n return user\n }\n\n const client = getClient()\n\n try {\n const gotrueUser = await client.login(email, password, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Creates a new account. Emits 'login' if autoconfirm is enabled. Works in both browser and server contexts. */\nexport const signup = async (email: string, password: string, data?: Record<string, unknown>): Promise<User> => {\n if (!isBrowser()) {\n const identityUrl = getServerIdentityUrl()\n const cookies = getCookies()\n\n let res: Response\n try {\n res = await fetch(`${identityUrl}/signup`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ email, password, data }),\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n\n if (!res.ok) {\n const errorBody = await res.json().catch(() => ({}))\n throw new AuthError((errorBody as Record<string, string>).msg || `Signup failed (${res.status})`, res.status)\n }\n\n const responseData = (await res.json()) as UserData\n const user = toUser(responseData)\n\n if (responseData.confirmed_at) {\n const responseRecord = responseData as unknown as Record<string, unknown>\n const accessToken = responseRecord.access_token as string | undefined\n if (accessToken) {\n setAuthCookies(cookies, accessToken, responseRecord.refresh_token as string | undefined)\n }\n }\n\n return user\n }\n\n const client = getClient()\n\n try {\n const response = await client.signup(email, password, data)\n const user = toUser(response as UserData)\n if (response.confirmed_at) {\n emitAuthEvent('login', user)\n }\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Logs out the current user and clears the session. Works in both browser and server contexts. */\nexport const logout = async (): Promise<void> => {\n if (!isBrowser()) {\n const identityUrl = getServerIdentityUrl()\n const cookies = getCookies()\n\n const jwt = cookies.get(NF_JWT_COOKIE)\n if (jwt) {\n try {\n await fetch(`${identityUrl}/logout`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}` },\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n }\n\n deleteAuthCookies(cookies)\n return\n }\n\n const client = getClient()\n\n try {\n const currentUser = client.currentUser()\n if (currentUser) {\n await currentUser.logout()\n }\n emitAuthEvent('logout', null)\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Redirects to an OAuth provider. Always throws (the page navigates away). Browser only. */\nexport const oauthLogin = (provider: string): never => {\n if (!isBrowser()) {\n throw new Error('oauthLogin() is only available in the browser')\n }\n const client = getClient()\n\n window.location.href = client.loginExternalUrl(provider)\n throw new Error('Redirecting to OAuth provider')\n}\n\nexport interface CallbackResult {\n type: 'oauth' | 'confirmation' | 'recovery' | 'invite' | 'email_change'\n user: User | null\n token?: string\n}\n\n/**\n * Processes the URL hash after an OAuth redirect, email confirmation, password\n * recovery, invite acceptance, or email change. Call on page load. Browser only.\n * Returns `null` if the hash contains no auth parameters.\n */\nexport const handleAuthCallback = async (): Promise<CallbackResult | null> => {\n if (!isBrowser()) return null\n\n const hash = window.location.hash.substring(1)\n if (!hash) return null\n\n const client = getClient()\n\n try {\n const params = new URLSearchParams(hash)\n\n const accessToken = params.get('access_token')\n if (accessToken) {\n const gotrueUser = await client.createUser(\n {\n access_token: accessToken,\n token_type: (params.get('token_type') as 'bearer') ?? 'bearer',\n expires_in: Number(params.get('expires_in')),\n expires_at: Number(params.get('expires_at')),\n refresh_token: params.get('refresh_token') ?? '',\n },\n persistSession,\n )\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'oauth', user }\n }\n\n const confirmationToken = params.get('confirmation_token')\n if (confirmationToken) {\n const gotrueUser = await client.confirm(confirmationToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'confirmation', user }\n }\n\n const recoveryToken = params.get('recovery_token')\n if (recoveryToken) {\n const gotrueUser = await client.recover(recoveryToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'recovery', user }\n }\n\n const inviteToken = params.get('invite_token')\n if (inviteToken) {\n clearHash()\n return { type: 'invite', user: null, token: inviteToken }\n }\n\n const emailChangeToken = params.get('email_change_token')\n if (emailChangeToken) {\n const currentUser = client.currentUser()\n if (!currentUser) {\n throw new AuthError('Email change verification requires an active browser session')\n }\n\n const jwt = await currentUser.jwt()\n const identityUrl = `${window.location.origin}${IDENTITY_PATH}`\n\n const emailChangeRes = await fetch(`${identityUrl}/user`, {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${jwt}`,\n },\n body: JSON.stringify({ email_change_token: emailChangeToken }),\n })\n\n if (!emailChangeRes.ok) {\n const errorBody = await emailChangeRes.json().catch(() => ({}))\n throw new AuthError(\n (errorBody as Record<string, string>).msg || `Email change verification failed (${emailChangeRes.status})`,\n emailChangeRes.status,\n )\n }\n\n const emailChangeData = (await emailChangeRes.json()) as UserData\n const user = toUser(emailChangeData)\n clearHash()\n emitAuthEvent('user_updated', user)\n return { type: 'email_change', user }\n }\n\n return null\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\nconst clearHash = (): void => {\n history.replaceState(null, '', window.location.pathname + window.location.search)\n}\n\n/**\n * Hydrates the browser-side gotrue-js session from server-set auth cookies.\n * Call this on page load when using server-side login to enable browser\n * account operations (updateUser, verifyEmailChange, etc.).\n *\n * No-op if a browser session already exists or no auth cookies are present.\n * No-op on the server.\n */\nexport const hydrateSession = async (): Promise<User | null> => {\n if (!isBrowser()) return null\n\n const client = getClient()\n const currentUser = client.currentUser()\n if (currentUser) return toUser(currentUser)\n\n const accessToken = getCookie(NF_JWT_COOKIE)\n if (!accessToken) return null\n\n const refreshToken = getCookie(NF_REFRESH_COOKIE) ?? ''\n\n const gotrueUser = await client.createUser(\n {\n access_token: accessToken,\n token_type: 'bearer',\n expires_in: 3600,\n expires_at: Math.floor(Date.now() / 1000) + 3600,\n refresh_token: refreshToken,\n },\n persistSession,\n )\n\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n}\n","import type { UserData, User as GoTrueUser } from 'gotrue-js'\n\nimport type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getClient, isBrowser, IDENTITY_PATH } from './environment.js'\nimport { emitAuthEvent, persistSession, hydrateSession } from './auth.js'\nimport { AuthError } from './errors.js'\n\n/**\n * Returns the current gotrue-js user, auto-hydrating from cookies if needed.\n * Throws AuthError if no user can be resolved.\n */\nconst ensureCurrentUser = async (): Promise<GoTrueUser> => {\n const client = getClient()\n\n let currentUser = client.currentUser()\n if (!currentUser && isBrowser()) {\n await hydrateSession()\n currentUser = client.currentUser()\n }\n if (!currentUser) throw new AuthError('No user is currently logged in')\n\n return currentUser\n}\n\n/** Sends a password recovery email to the given address. */\nexport const requestPasswordRecovery = async (email: string): Promise<void> => {\n const client = getClient()\n\n try {\n await client.requestPasswordRecovery(email)\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Redeems a recovery token and sets a new password. Logs the user in on success. */\nexport const recoverPassword = async (token: string, newPassword: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.recover(token, persistSession)\n const updatedUser = await gotrueUser.update({ password: newPassword })\n const user = toUser(updatedUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Confirms an email address using the token from a confirmation email. Logs the user in on success. */\nexport const confirmEmail = async (token: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.confirm(token, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Accepts an invite token and sets a password for the new account. Logs the user in on success. */\nexport const acceptInvite = async (token: string, password: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.acceptInvite(token, password, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/**\n * Verifies an email change using the token from a verification email.\n * Auto-hydrates from auth cookies if no browser session exists.\n */\nexport const verifyEmailChange = async (token: string): Promise<User> => {\n if (!isBrowser()) throw new AuthError('verifyEmailChange() is only available in the browser')\n\n const currentUser = await ensureCurrentUser()\n\n const jwt = await currentUser.jwt()\n const identityUrl = `${window.location.origin}${IDENTITY_PATH}`\n\n try {\n const res = await fetch(`${identityUrl}/user`, {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${jwt}`,\n },\n body: JSON.stringify({ email_change_token: token }),\n })\n\n if (!res.ok) {\n const errorBody = await res.json().catch(() => ({}))\n throw new AuthError(\n (errorBody as Record<string, string>).msg || `Email change verification failed (${res.status})`,\n res.status,\n )\n }\n\n const userData = (await res.json()) as UserData\n const user = toUser(userData)\n emitAuthEvent('user_updated', user)\n return user\n } catch (error) {\n if (error instanceof AuthError) throw error\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/**\n * Updates the current user's metadata or credentials.\n * Auto-hydrates from auth cookies if no browser session exists.\n */\nexport const updateUser = async (updates: Record<string, unknown>): Promise<User> => {\n const currentUser = await ensureCurrentUser()\n\n try {\n const updatedUser = await currentUser.update(updates)\n const user = toUser(updatedUser)\n emitAuthEvent('user_updated', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n"],"mappings":"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","names":["jwt"]}
|