@netlify/identity 0.1.1-alpha.25 → 0.1.1-alpha.27
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/README.md +9 -1
- package/dist/index.cjs +44 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +44 -29
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ A lightweight, no-config headless authentication library for projects using Netl
|
|
|
9
9
|
- [Netlify Identity](https://docs.netlify.com/security/secure-access-to-sites/identity/) must be enabled on your Netlify project
|
|
10
10
|
- For local development, use [`netlify dev`](https://docs.netlify.com/cli/local-development/) so the Identity endpoint is available
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
## How this library relates to other Netlify auth packages
|
|
13
13
|
|
|
14
14
|
| Package | What it is | When to use it |
|
|
15
15
|
| ------------------------------------------------------------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------ |
|
|
@@ -362,6 +362,14 @@ const AUTH_EVENTS: {
|
|
|
362
362
|
|
|
363
363
|
Constants for auth event names. Use these instead of string literals for type safety and autocomplete.
|
|
364
364
|
|
|
365
|
+
| Event | When it fires |
|
|
366
|
+
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
367
|
+
| `LOGIN` | `login()`, `signup()` (with autoconfirm), `recoverPassword()`, `handleAuthCallback()` (OAuth/confirmation), `hydrateSession()` |
|
|
368
|
+
| `LOGOUT` | `logout()` |
|
|
369
|
+
| `TOKEN_REFRESH` | gotrue-js refreshes an expiring access token in the background |
|
|
370
|
+
| `USER_UPDATED` | `updateUser()`, `verifyEmailChange()`, `handleAuthCallback()` (email change) |
|
|
371
|
+
| `RECOVERY` | `handleAuthCallback()` (recovery token only). The user is authenticated but has **not** set a new password yet. Listen for this to redirect to a password reset form. `recoverPassword()` emits `LOGIN` instead because it completes both steps (token redemption + password change). |
|
|
372
|
+
|
|
365
373
|
#### `AuthEvent`
|
|
366
374
|
|
|
367
375
|
```ts
|
package/dist/index.cjs
CHANGED
|
@@ -60,7 +60,7 @@ var AUTH_PROVIDERS = ["google", "github", "gitlab", "bitbucket", "facebook", "sa
|
|
|
60
60
|
var import_gotrue_js = __toESM(require("gotrue-js"), 1);
|
|
61
61
|
|
|
62
62
|
// src/errors.ts
|
|
63
|
-
var AuthError = class extends Error {
|
|
63
|
+
var AuthError = class _AuthError extends Error {
|
|
64
64
|
constructor(message, status, options) {
|
|
65
65
|
super(message);
|
|
66
66
|
this.name = "AuthError";
|
|
@@ -69,6 +69,10 @@ var AuthError = class extends Error {
|
|
|
69
69
|
this.cause = options.cause;
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
|
+
static from(error) {
|
|
73
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
74
|
+
return new _AuthError(message, void 0, { cause: error });
|
|
75
|
+
}
|
|
72
76
|
};
|
|
73
77
|
var MissingIdentityError = class extends Error {
|
|
74
78
|
constructor(message = "Netlify Identity is not available.") {
|
|
@@ -93,7 +97,7 @@ var discoverApiUrl = () => {
|
|
|
93
97
|
cachedApiUrl = identityContext.url;
|
|
94
98
|
} else if (globalThis.Netlify?.context?.url) {
|
|
95
99
|
cachedApiUrl = new URL(IDENTITY_PATH, globalThis.Netlify.context.url).href;
|
|
96
|
-
} else if (process.env
|
|
100
|
+
} else if (typeof process !== "undefined" && process.env?.URL) {
|
|
97
101
|
cachedApiUrl = new URL(IDENTITY_PATH, process.env.URL).href;
|
|
98
102
|
}
|
|
99
103
|
}
|
|
@@ -130,7 +134,7 @@ var getIdentityContext = () => {
|
|
|
130
134
|
if (globalThis.Netlify?.context?.url) {
|
|
131
135
|
return { url: new URL(IDENTITY_PATH, globalThis.Netlify.context.url).href };
|
|
132
136
|
}
|
|
133
|
-
const siteUrl = process.env
|
|
137
|
+
const siteUrl = typeof process !== "undefined" ? process.env?.URL : void 0;
|
|
134
138
|
if (siteUrl) {
|
|
135
139
|
return { url: new URL(IDENTITY_PATH, siteUrl).href };
|
|
136
140
|
}
|
|
@@ -142,7 +146,12 @@ var NF_JWT_COOKIE = "nf_jwt";
|
|
|
142
146
|
var NF_REFRESH_COOKIE = "nf_refresh";
|
|
143
147
|
var getCookie = (name) => {
|
|
144
148
|
const match = document.cookie.match(new RegExp(`(?:^|; )${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}=([^;]*)`));
|
|
145
|
-
|
|
149
|
+
if (!match) return null;
|
|
150
|
+
try {
|
|
151
|
+
return decodeURIComponent(match[1]);
|
|
152
|
+
} catch {
|
|
153
|
+
return match[1];
|
|
154
|
+
}
|
|
146
155
|
};
|
|
147
156
|
var setAuthCookies = (cookies, accessToken, refreshToken) => {
|
|
148
157
|
cookies.set({
|
|
@@ -427,7 +436,7 @@ var login = async (email, password) => {
|
|
|
427
436
|
body: body.toString()
|
|
428
437
|
});
|
|
429
438
|
} catch (error) {
|
|
430
|
-
throw
|
|
439
|
+
throw AuthError.from(error);
|
|
431
440
|
}
|
|
432
441
|
if (!res.ok) {
|
|
433
442
|
const errorBody = await res.json().catch(() => ({}));
|
|
@@ -441,7 +450,7 @@ var login = async (email, password) => {
|
|
|
441
450
|
headers: { Authorization: `Bearer ${accessToken}` }
|
|
442
451
|
});
|
|
443
452
|
} catch (error) {
|
|
444
|
-
throw
|
|
453
|
+
throw AuthError.from(error);
|
|
445
454
|
}
|
|
446
455
|
if (!userRes.ok) {
|
|
447
456
|
const errorBody = await userRes.json().catch(() => ({}));
|
|
@@ -461,7 +470,7 @@ var login = async (email, password) => {
|
|
|
461
470
|
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
462
471
|
return user;
|
|
463
472
|
} catch (error) {
|
|
464
|
-
throw
|
|
473
|
+
throw AuthError.from(error);
|
|
465
474
|
}
|
|
466
475
|
};
|
|
467
476
|
var signup = async (email, password, data) => {
|
|
@@ -476,7 +485,7 @@ var signup = async (email, password, data) => {
|
|
|
476
485
|
body: JSON.stringify({ email, password, data })
|
|
477
486
|
});
|
|
478
487
|
} catch (error) {
|
|
479
|
-
throw
|
|
488
|
+
throw AuthError.from(error);
|
|
480
489
|
}
|
|
481
490
|
if (!res.ok) {
|
|
482
491
|
const errorBody = await res.json().catch(() => ({}));
|
|
@@ -505,7 +514,7 @@ var signup = async (email, password, data) => {
|
|
|
505
514
|
}
|
|
506
515
|
return user;
|
|
507
516
|
} catch (error) {
|
|
508
|
-
throw
|
|
517
|
+
throw AuthError.from(error);
|
|
509
518
|
}
|
|
510
519
|
};
|
|
511
520
|
var logout = async () => {
|
|
@@ -534,7 +543,7 @@ var logout = async () => {
|
|
|
534
543
|
deleteBrowserAuthCookies();
|
|
535
544
|
emitAuthEvent(AUTH_EVENTS.LOGOUT, null);
|
|
536
545
|
} catch (error) {
|
|
537
|
-
throw
|
|
546
|
+
throw AuthError.from(error);
|
|
538
547
|
}
|
|
539
548
|
};
|
|
540
549
|
var oauthLogin = (provider) => {
|
|
@@ -565,7 +574,7 @@ var handleAuthCallback = async () => {
|
|
|
565
574
|
return null;
|
|
566
575
|
} catch (error) {
|
|
567
576
|
if (error instanceof AuthError) throw error;
|
|
568
|
-
throw
|
|
577
|
+
throw AuthError.from(error);
|
|
569
578
|
}
|
|
570
579
|
};
|
|
571
580
|
var handleOAuthCallback = async (client, params, accessToken) => {
|
|
@@ -650,16 +659,22 @@ var hydrateSession = async () => {
|
|
|
650
659
|
const decoded = decodeJwtPayload(accessToken);
|
|
651
660
|
const expiresAt = decoded?.exp ?? Math.floor(Date.now() / 1e3) + 3600;
|
|
652
661
|
const expiresIn = Math.max(0, expiresAt - Math.floor(Date.now() / 1e3));
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
662
|
+
let gotrueUser;
|
|
663
|
+
try {
|
|
664
|
+
gotrueUser = await client.createUser(
|
|
665
|
+
{
|
|
666
|
+
access_token: accessToken,
|
|
667
|
+
token_type: "bearer",
|
|
668
|
+
expires_in: expiresIn,
|
|
669
|
+
expires_at: expiresAt,
|
|
670
|
+
refresh_token: refreshToken
|
|
671
|
+
},
|
|
672
|
+
persistSession
|
|
673
|
+
);
|
|
674
|
+
} catch {
|
|
675
|
+
deleteBrowserAuthCookies();
|
|
676
|
+
return null;
|
|
677
|
+
}
|
|
663
678
|
const user = toUser(gotrueUser);
|
|
664
679
|
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
665
680
|
return user;
|
|
@@ -684,7 +699,7 @@ var requestPasswordRecovery = async (email) => {
|
|
|
684
699
|
try {
|
|
685
700
|
await client.requestPasswordRecovery(email);
|
|
686
701
|
} catch (error) {
|
|
687
|
-
throw
|
|
702
|
+
throw AuthError.from(error);
|
|
688
703
|
}
|
|
689
704
|
};
|
|
690
705
|
var recoverPassword = async (token, newPassword) => {
|
|
@@ -696,7 +711,7 @@ var recoverPassword = async (token, newPassword) => {
|
|
|
696
711
|
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
697
712
|
return user;
|
|
698
713
|
} catch (error) {
|
|
699
|
-
throw
|
|
714
|
+
throw AuthError.from(error);
|
|
700
715
|
}
|
|
701
716
|
};
|
|
702
717
|
var confirmEmail = async (token) => {
|
|
@@ -707,7 +722,7 @@ var confirmEmail = async (token) => {
|
|
|
707
722
|
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
708
723
|
return user;
|
|
709
724
|
} catch (error) {
|
|
710
|
-
throw
|
|
725
|
+
throw AuthError.from(error);
|
|
711
726
|
}
|
|
712
727
|
};
|
|
713
728
|
var acceptInvite = async (token, password) => {
|
|
@@ -718,15 +733,15 @@ var acceptInvite = async (token, password) => {
|
|
|
718
733
|
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
719
734
|
return user;
|
|
720
735
|
} catch (error) {
|
|
721
|
-
throw
|
|
736
|
+
throw AuthError.from(error);
|
|
722
737
|
}
|
|
723
738
|
};
|
|
724
739
|
var verifyEmailChange = async (token) => {
|
|
725
740
|
if (!isBrowser()) throw new AuthError("verifyEmailChange() is only available in the browser");
|
|
726
741
|
const currentUser = await resolveCurrentUser();
|
|
727
|
-
const jwt = await currentUser.jwt();
|
|
728
|
-
const identityUrl = `${window.location.origin}${IDENTITY_PATH}`;
|
|
729
742
|
try {
|
|
743
|
+
const jwt = await currentUser.jwt();
|
|
744
|
+
const identityUrl = `${window.location.origin}${IDENTITY_PATH}`;
|
|
730
745
|
const res = await fetch(`${identityUrl}/user`, {
|
|
731
746
|
method: "PUT",
|
|
732
747
|
headers: {
|
|
@@ -745,7 +760,7 @@ var verifyEmailChange = async (token) => {
|
|
|
745
760
|
return user;
|
|
746
761
|
} catch (error) {
|
|
747
762
|
if (error instanceof AuthError) throw error;
|
|
748
|
-
throw
|
|
763
|
+
throw AuthError.from(error);
|
|
749
764
|
}
|
|
750
765
|
};
|
|
751
766
|
var updateUser = async (updates) => {
|
|
@@ -756,7 +771,7 @@ var updateUser = async (updates) => {
|
|
|
756
771
|
emitAuthEvent(AUTH_EVENTS.USER_UPDATED, user);
|
|
757
772
|
return user;
|
|
758
773
|
} catch (error) {
|
|
759
|
-
throw
|
|
774
|
+
throw AuthError.from(error);
|
|
760
775
|
}
|
|
761
776
|
};
|
|
762
777
|
// Annotate the CommonJS export names for ESM import in node:
|
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/cookies.ts","../src/nextjs.ts","../src/user.ts","../src/config.ts","../src/events.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 } from './events.js'\nexport { AUTH_EVENTS, onAuthChange } from './events.js'\nexport type { CallbackResult } from './auth.js'\nexport { login, signup, logout, oauthLogin, handleAuthCallback, hydrateSession } from './auth.js'\nexport { AuthError, MissingIdentityError } from './errors.js'\nexport type { AppMetadata, AuthProvider, IdentityConfig, Settings, UserUpdates, SignupData } 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\n/**\n * Fields accepted by {@link updateUser}. All fields are optional.\n * Pass `data` to update user metadata (e.g., `{ data: { full_name: 'New Name' } }`).\n */\nexport interface UserUpdates {\n email?: string\n password?: string\n data?: Record<string, unknown>\n [key: string]: unknown\n}\n\n/**\n * User metadata passed during signup (e.g., `{ full_name: 'Jane Doe' }`).\n * Stored in the user's `user_metadata` field.\n */\nexport type SignupData = Record<string, unknown>\n\n/** GoTrue OAuth2 token response from the /token endpoint. */\nexport interface TokenResponse {\n access_token: string\n token_type: string\n expires_in: number\n refresh_token?: string\n}\n\n/** GoTrue error response body. */\nexport interface GoTrueErrorBody {\n msg?: string\n error_description?: string\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 } else if (process.env.URL) {\n cachedApiUrl = new URL(IDENTITY_PATH, process.env.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: false })\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 // Fallback: Netlify sets the URL env var on all deployed sites\n const siteUrl = process.env.URL\n if (siteUrl) {\n return { url: new URL(IDENTITY_PATH, siteUrl).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 = 'Netlify Identity is not available.') {\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 // httpOnly: false because browser-side hydration (backgroundHydrate, hydrateSession)\n // reads nf_refresh via document.cookie to bootstrap the gotrue-js session.\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/** Sets auth cookies via document.cookie (browser-side). */\nexport const setBrowserAuthCookies = (accessToken: string, refreshToken?: string): void => {\n document.cookie = `${NF_JWT_COOKIE}=${encodeURIComponent(accessToken)}; path=/; secure; samesite=lax`\n if (refreshToken) {\n document.cookie = `${NF_REFRESH_COOKIE}=${encodeURIComponent(refreshToken)}; path=/; secure; samesite=lax`\n }\n}\n\n/** Deletes auth cookies via document.cookie (browser-side). */\nexport const deleteBrowserAuthCookies = (): void => {\n document.cookie = `${NF_JWT_COOKIE}=; path=/; secure; samesite=lax; expires=Thu, 01 Jan 1970 00:00:00 GMT`\n document.cookie = `${NF_REFRESH_COOKIE}=; path=/; secure; samesite=lax; expires=Thu, 01 Jan 1970 00:00:00 GMT`\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","// Minimal declaration so we can use require() without @types/node\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ndeclare const require: ((id: string) => any) | undefined\n\n/**\n * Calls `headers()` from `next/headers` if available, to opt Next.js RSC\n * routes into dynamic rendering. Without this, Next.js may statically\n * optimize pages that call functions in this package, caching the build-time result.\n *\n * Re-throws DynamicServerError so Next.js can catch it and switch to\n * dynamic rendering. Silently ignores if not in a Next.js environment.\n */\nlet nextHeadersFn: (() => unknown) | null | undefined\nexport const triggerNextjsDynamic = (): void => {\n if (nextHeadersFn === null) return\n\n if (nextHeadersFn === undefined) {\n try {\n if (typeof require === 'undefined') {\n nextHeadersFn = null\n return\n }\n const mod = require('next/headers')\n nextHeadersFn = mod.headers\n } catch {\n nextHeadersFn = null\n return\n }\n }\n\n const fn = nextHeadersFn\n if (!fn) return\n\n try {\n fn()\n } catch (e: unknown) {\n // Re-throw DynamicServerError so Next.js can opt into dynamic rendering.\n // These errors have a `digest` property containing 'DYNAMIC_SERVER_USAGE'\n // or a message about bailing out of prerendering.\n if (e instanceof Error && ('digest' in e || /bail\\s*out.*prerende/i.test(e.message))) {\n throw e\n }\n }\n}\n\n/** Reset cached state and optionally inject a headers function. Test use only. */\nexport const resetNextjsState = (headersFn?: (() => unknown) | null): void => {\n nextHeadersFn = headersFn === null ? null : (headersFn ?? undefined)\n}\n","import type { UserData } from 'gotrue-js'\nimport { AUTH_PROVIDERS, type AuthProvider } from './types.js'\nimport { getGoTrueClient, getClient, isBrowser } from './environment.js'\nimport { getCookie, getServerCookie, NF_JWT_COOKIE, NF_REFRESH_COOKIE } from './cookies.js'\nimport { triggerNextjsDynamic } from './nextjs.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\nlet hydrating = false\n\n/**\n * Creates a gotrue-js session from the nf_jwt cookie so that browser-side\n * operations (updateUser, logout, etc.) work after a server-side login.\n * Fire-and-forget: getUser() returns synchronously from the JWT while this\n * runs in the background.\n */\nconst backgroundHydrate = (accessToken: string): void => {\n if (hydrating) return\n hydrating = true\n\n const refreshToken = getCookie(NF_REFRESH_COOKIE) ?? ''\n\n const decoded = decodeJwtPayload(accessToken)\n const expiresAt = decoded?.exp ?? Math.floor(Date.now() / 1000) + 3600\n const expiresIn = Math.max(0, expiresAt - Math.floor(Date.now() / 1000))\n\n // Defer to the next tick so the synchronous getUser() call completes first,\n // and gotrue-js's internal currentUser isn't set until after the caller\n // has received the JWT-decoded result.\n setTimeout(() => {\n try {\n const client = getClient()\n client\n .createUser(\n {\n access_token: accessToken,\n token_type: 'bearer',\n expires_in: expiresIn,\n expires_at: expiresAt,\n refresh_token: refreshToken,\n },\n true,\n )\n .catch(() => {\n // best-effort: if hydration fails, getUser() still works via cookie decode\n })\n .finally(() => {\n hydrating = false\n })\n } catch {\n hydrating = false\n }\n }, 0)\n}\n\n/** Decodes a JWT payload without verifying the signature. */\nexport const 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.\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) and kicks off background hydration of the gotrue-js\n * session so that subsequent operations (updateUser, logout, etc.) work.\n *\n * On the server in a Next.js App Router context, calls `headers()` from\n * `next/headers` to opt the route into dynamic rendering. Without this,\n * Next.js may statically cache the page at build time.\n */\nexport const getUser = (): User | null => {\n if (isBrowser()) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser() ?? null\n\n if (currentUser) {\n // If gotrue-js has a localStorage session but the nf_jwt cookie is gone,\n // the server logged us out. Clear the stale localStorage session.\n const jwt = getCookie(NF_JWT_COOKIE)\n if (!jwt) {\n try {\n currentUser.clearSession()\n } catch {\n // best-effort cleanup\n }\n return null\n }\n return toUser(currentUser)\n }\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 // Hydrate gotrue-js in the background so browser-side operations\n // (updateUser, logout, etc.) work after a server-side login.\n backgroundHydrate(jwt)\n\n return claimsToUser(claims)\n }\n\n // Trigger Next.js dynamic rendering if in a Next.js RSC context\n triggerNextjsDynamic()\n\n // Primary path: identity context populated from the X-Nf-Identity-Info request header\n const identityContext = globalThis.netlifyIdentityContext\n if (identityContext?.user) {\n return claimsToUser(identityContext.user)\n }\n\n // Fallback: read the nf_jwt cookie directly from the Netlify runtime.\n const serverJwt = getServerCookie(NF_JWT_COOKIE)\n if (serverJwt) {\n const claims = decodeJwtPayload(serverJwt)\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 your project's Identity settings (enabled providers, autoconfirm, signup disabled).\n *\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 { getGoTrueClient, isBrowser } from './environment.js'\nimport { toUser, type User } from './user.js'\n\nexport const AUTH_EVENTS = {\n LOGIN: 'login',\n LOGOUT: 'logout',\n TOKEN_REFRESH: 'token_refresh',\n USER_UPDATED: 'user_updated',\n RECOVERY: 'recovery',\n} as const\n\nexport type AuthEvent = (typeof AUTH_EVENTS)[keyof typeof AUTH_EVENTS]\n\nexport type AuthCallback = (event: AuthEvent, user: User | null) => void\n\nconst GOTRUE_STORAGE_KEY = 'gotrue.user'\n\nconst listeners = new Set<AuthCallback>()\n\nexport const emitAuthEvent = (event: AuthEvent, user: User | null): void => {\n for (const listener of listeners) {\n try {\n listener(event, user)\n } catch {\n // Prevent one subscriber from breaking others\n }\n }\n}\n\nlet storageListenerAttached = false\n\nconst attachStorageListener = (): void => {\n if (storageListenerAttached || !isBrowser()) return\n storageListenerAttached = true\n\n window.addEventListener('storage', (event: StorageEvent) => {\n if (event.key !== GOTRUE_STORAGE_KEY) return\n\n if (event.newValue) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser()\n emitAuthEvent(AUTH_EVENTS.LOGIN, currentUser ? toUser(currentUser) : null)\n } else {\n emitAuthEvent(AUTH_EVENTS.LOGOUT, null)\n }\n })\n}\n\n/**\n * Subscribes to auth state changes (login, logout, token refresh, user updates,\n * and recovery). Returns an unsubscribe function. No-op on the server.\n *\n * The `'recovery'` event fires when {@link handleAuthCallback} processes a\n * password recovery token. The user is logged in but has not yet set a new\n * password. Redirect them to a password reset form and call\n * `updateUser({ password })` to complete the flow.\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","import type { UserData } from 'gotrue-js'\n\nimport type { NetlifyCookies, SignupData, TokenResponse, GoTrueErrorBody } from './types.js'\nimport { toUser, decodeJwtPayload } from './user.js'\n\nimport { getClient, getIdentityContext, isBrowser, IDENTITY_PATH } from './environment.js'\nimport {\n getCookie,\n setAuthCookies,\n deleteAuthCookies,\n setBrowserAuthCookies,\n deleteBrowserAuthCookies,\n NF_JWT_COOKIE,\n NF_REFRESH_COOKIE,\n} from './cookies.js'\nimport { AuthError } from './errors.js'\nimport { AUTH_EVENTS, emitAuthEvent } from './events.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\n/** Persist the session to localStorage so it survives page reloads. */\nexport const persistSession = true\n\n/**\n * Logs in with email and password. Works in both browser and server contexts.\n *\n * On success, sets `nf_jwt` and `nf_refresh` cookies and returns the authenticated {@link User}.\n * In the browser, also emits a `'login'` event via {@link onAuthChange}.\n *\n * @throws {AuthError} On invalid credentials, network failure, or missing Netlify runtime.\n *\n * @remarks\n * In Next.js server actions, call `redirect()` **after** `login()` returns, not inside a\n * try/catch. Next.js implements `redirect()` by throwing a special error; wrapping it in\n * try/catch will swallow the redirect.\n *\n * @example\n * ```ts\n * // Next.js server action\n * const user = await login(email, password)\n * redirect('/dashboard') // after login, not inside try/catch\n * ```\n */\nexport const login = async (email: string, password: string): Promise<import('./user.js').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(() => ({}))) as GoTrueErrorBody\n throw new AuthError(errorBody.msg || errorBody.error_description || `Login failed (${res.status})`, res.status)\n }\n\n const data = (await res.json()) as TokenResponse\n const accessToken = data.access_token\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(() => ({}))) as GoTrueErrorBody\n throw new AuthError(errorBody.msg || `Failed to fetch user data (${userRes.status})`, userRes.status)\n }\n\n const userData = (await userRes.json()) as UserData\n const user = toUser(userData)\n\n setAuthCookies(cookies, accessToken, data.refresh_token)\n\n return user\n }\n\n const client = getClient()\n\n try {\n const gotrueUser = await client.login(email, password, persistSession)\n const jwt = await gotrueUser.jwt()\n setBrowserAuthCookies(jwt)\n const user = toUser(gotrueUser)\n emitAuthEvent(AUTH_EVENTS.LOGIN, user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/**\n * Creates a new account. Works in both browser and server contexts.\n *\n * If autoconfirm is enabled in your Identity settings, the user is logged in immediately:\n * cookies are set and a `'login'` event is emitted. If autoconfirm is **disabled** (the default),\n * the user receives a confirmation email and must click the link before they can log in.\n * In that case, no cookies are set and no auth event is emitted.\n *\n * @throws {AuthError} On duplicate email, validation failure, network error, or missing Netlify runtime.\n */\nexport const signup = async (email: string, password: string, data?: SignupData): Promise<import('./user.js').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(() => ({}))) as GoTrueErrorBody\n throw new AuthError(errorBody.msg || `Signup failed (${res.status})`, res.status)\n }\n\n const responseData = (await res.json()) as UserData & Partial<TokenResponse>\n const user = toUser(responseData)\n\n if (responseData.confirmed_at) {\n const accessToken = responseData.access_token\n if (accessToken) {\n setAuthCookies(cookies, accessToken, responseData.refresh_token)\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 const jwt = await (response as { jwt?: () => Promise<string> }).jwt?.()\n if (jwt) {\n setBrowserAuthCookies(jwt)\n }\n emitAuthEvent(AUTH_EVENTS.LOGIN, user)\n }\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/**\n * Logs out the current user and clears the session. Works in both browser and server contexts.\n *\n * Always deletes `nf_jwt` and `nf_refresh` cookies, even if the server-side token\n * invalidation request fails. In the browser, emits a `'logout'` event via {@link onAuthChange}.\n *\n * @throws {AuthError} On missing Netlify runtime (server) or logout failure (browser).\n */\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 {\n // Best-effort: token invalidation may fail, but we always clear cookies below\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 deleteBrowserAuthCookies()\n emitAuthEvent(AUTH_EVENTS.LOGOUT, null)\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/**\n * Initiates an OAuth login by redirecting to the given provider (e.g., `'google'`, `'github'`).\n * The page navigates away; this function never returns normally. Browser only.\n *\n * After the provider redirects back, call {@link handleAuthCallback} on page load\n * to complete the login and obtain the {@link User}.\n *\n * @throws {AuthError} If called on the server.\n */\nexport const oauthLogin = (provider: string): never => {\n if (!isBrowser()) {\n throw new AuthError('oauthLogin() is only available in the browser')\n }\n const client = getClient()\n\n window.location.href = client.loginExternalUrl(provider)\n throw new AuthError('Redirecting to OAuth provider')\n}\n\nexport interface CallbackResult {\n type: 'oauth' | 'confirmation' | 'recovery' | 'invite' | 'email_change'\n user: import('./user.js').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 *\n * Call this early in your app's initialization (e.g., in a layout component or\n * root loader), **not** inside a route that requires authentication, because\n * the callback URL must match the page where this function runs.\n *\n * For recovery callbacks (`result.type === 'recovery'`), the user is logged in\n * but has **not** set a new password yet. Your app must check the result type\n * and redirect to a password form that calls `updateUser({ password })`.\n * A `'recovery'` event (not `'login'`) is emitted via {@link onAuthChange}.\n *\n * @throws {AuthError} If the callback token is invalid or the verification request fails.\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 const params = new URLSearchParams(hash)\n\n try {\n const accessToken = params.get('access_token')\n if (accessToken) return await handleOAuthCallback(client, params, accessToken)\n\n const confirmationToken = params.get('confirmation_token')\n if (confirmationToken) return await handleConfirmationCallback(client, confirmationToken)\n\n const recoveryToken = params.get('recovery_token')\n if (recoveryToken) return await handleRecoveryCallback(client, recoveryToken)\n\n const inviteToken = params.get('invite_token')\n if (inviteToken) return handleInviteCallback(inviteToken)\n\n const emailChangeToken = params.get('email_change_token')\n if (emailChangeToken) return await handleEmailChangeCallback(client, emailChangeToken)\n\n return null\n } catch (error) {\n if (error instanceof AuthError) throw error\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\nimport type GoTrue from 'gotrue-js'\n\nconst handleOAuthCallback = async (\n client: GoTrue,\n params: URLSearchParams,\n accessToken: string,\n): Promise<CallbackResult> => {\n const refreshToken = params.get('refresh_token') ?? ''\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: refreshToken,\n },\n persistSession,\n )\n setBrowserAuthCookies(accessToken, refreshToken || undefined)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent(AUTH_EVENTS.LOGIN, user)\n return { type: 'oauth', user }\n}\n\nconst handleConfirmationCallback = async (client: GoTrue, token: string): Promise<CallbackResult> => {\n const gotrueUser = await client.confirm(token, persistSession)\n const jwt = await gotrueUser.jwt()\n setBrowserAuthCookies(jwt)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent(AUTH_EVENTS.LOGIN, user)\n return { type: 'confirmation', user }\n}\n\nconst handleRecoveryCallback = async (client: GoTrue, token: string): Promise<CallbackResult> => {\n const gotrueUser = await client.recover(token, persistSession)\n const jwt = await gotrueUser.jwt()\n setBrowserAuthCookies(jwt)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent(AUTH_EVENTS.RECOVERY, user)\n return { type: 'recovery', user }\n}\n\nconst handleInviteCallback = (token: string): CallbackResult => {\n clearHash()\n return { type: 'invite', user: null, token }\n}\n\nconst handleEmailChangeCallback = async (client: GoTrue, emailChangeToken: string): Promise<CallbackResult> => {\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(() => ({}))) as GoTrueErrorBody\n throw new AuthError(\n errorBody.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(AUTH_EVENTS.USER_UPDATED, user)\n return { type: 'email_change', user }\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<import('./user.js').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 decoded = decodeJwtPayload(accessToken)\n const expiresAt = decoded?.exp ?? Math.floor(Date.now() / 1000) + 3600\n const expiresIn = Math.max(0, expiresAt - Math.floor(Date.now() / 1000))\n\n const gotrueUser = await client.createUser(\n {\n access_token: accessToken,\n token_type: 'bearer',\n expires_in: expiresIn,\n expires_at: expiresAt,\n refresh_token: refreshToken,\n },\n persistSession,\n )\n\n const user = toUser(gotrueUser)\n emitAuthEvent(AUTH_EVENTS.LOGIN, user)\n return user\n}\n","import type { UserData, User as GoTrueUser } from 'gotrue-js'\n\nimport type { UserUpdates, GoTrueErrorBody } from './types.js'\nimport type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getClient, isBrowser, IDENTITY_PATH } from './environment.js'\nimport { persistSession, hydrateSession } from './auth.js'\nimport { AUTH_EVENTS, emitAuthEvent } from './events.js'\nimport { AuthError } from './errors.js'\n\n/**\n * Returns the current gotrue-js user, attempting hydration from cookies if\n * no in-memory session exists. Throws if no user can be resolved.\n */\nconst resolveCurrentUser = async (): Promise<GoTrueUser> => {\n const client = getClient()\n\n let currentUser = client.currentUser()\n if (!currentUser && isBrowser()) {\n try {\n await hydrateSession()\n } catch {\n // hydration failed (e.g. expired cookie, network error) — fall through\n }\n currentUser = client.currentUser()\n }\n if (!currentUser) throw new AuthError('No user is currently logged in')\n\n return currentUser\n}\n\n/**\n * Sends a password recovery email to the given address.\n *\n * @throws {AuthError} On network failure or if the request is rejected.\n */\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/**\n * Redeems a recovery token and sets a new password. Logs the user in on success.\n *\n * @throws {AuthError} If the token is invalid, expired, or the update fails.\n */\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(AUTH_EVENTS.LOGIN, user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/**\n * Confirms an email address using the token from a confirmation email. Logs the user in on success.\n *\n * @throws {AuthError} If the token is invalid or expired.\n */\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(AUTH_EVENTS.LOGIN, user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/**\n * Accepts an invite token and sets a password for the new account. Logs the user in on success.\n *\n * @throws {AuthError} If the token is invalid or expired.\n */\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(AUTH_EVENTS.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. Browser only.\n *\n * @throws {AuthError} If called on the server, no user is logged in, or the token is invalid.\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 resolveCurrentUser()\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(() => ({}))) as GoTrueErrorBody\n throw new AuthError(errorBody.msg || `Email change verification failed (${res.status})`, res.status)\n }\n\n const userData = (await res.json()) as UserData\n const user = toUser(userData)\n emitAuthEvent(AUTH_EVENTS.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 email, password, or user metadata.\n * Auto-hydrates from auth cookies if no browser session exists.\n *\n * @param updates - Fields to update. Pass `email` or `password` to change credentials,\n * or `data` to update user metadata (e.g., `{ data: { full_name: 'New Name' } }`).\n * @throws {AuthError} If no user is logged in or the update fails.\n */\nexport const updateUser = async (updates: UserUpdates): Promise<User> => {\n const currentUser = await resolveCurrentUser()\n\n try {\n const updatedUser = await currentUser.update(updates)\n const user = toUser(updatedUser)\n emitAuthEvent(AUTH_EVENTS.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"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/environment.ts","../src/errors.ts","../src/cookies.ts","../src/nextjs.ts","../src/user.ts","../src/config.ts","../src/events.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 } from './events.js'\nexport { AUTH_EVENTS, onAuthChange } from './events.js'\nexport type { CallbackResult } from './auth.js'\nexport { login, signup, logout, oauthLogin, handleAuthCallback, hydrateSession } from './auth.js'\nexport { AuthError, MissingIdentityError } from './errors.js'\nexport type { AppMetadata, AuthProvider, IdentityConfig, Settings, UserUpdates, SignupData } 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\n/**\n * Fields accepted by {@link updateUser}. All fields are optional.\n * Pass `data` to update user metadata (e.g., `{ data: { full_name: 'New Name' } }`).\n */\nexport interface UserUpdates {\n email?: string\n password?: string\n data?: Record<string, unknown>\n [key: string]: unknown\n}\n\n/**\n * User metadata passed during signup (e.g., `{ full_name: 'Jane Doe' }`).\n * Stored in the user's `user_metadata` field.\n */\nexport type SignupData = Record<string, unknown>\n\n/** GoTrue OAuth2 token response from the /token endpoint. */\nexport interface TokenResponse {\n access_token: string\n token_type: string\n expires_in: number\n refresh_token?: string\n}\n\n/** GoTrue error response body. */\nexport interface GoTrueErrorBody {\n msg?: string\n error_description?: string\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 } else if (typeof process !== 'undefined' && process.env?.URL) {\n cachedApiUrl = new URL(IDENTITY_PATH, process.env.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: false })\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 // Fallback: Netlify sets the URL env var on all deployed sites\n const siteUrl = typeof process !== 'undefined' ? process.env?.URL : undefined\n if (siteUrl) {\n return { url: new URL(IDENTITY_PATH, siteUrl).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 static from(error: unknown): AuthError {\n const message = error instanceof Error ? error.message : String(error)\n return new AuthError(message, undefined, { cause: error })\n }\n}\n\nexport class MissingIdentityError extends Error {\n override name = 'MissingIdentityError'\n\n constructor(message = 'Netlify Identity is not available.') {\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 if (!match) return null\n try {\n return decodeURIComponent(match[1])\n } catch {\n return match[1]\n }\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 // httpOnly: false because browser-side hydration (backgroundHydrate, hydrateSession)\n // reads nf_refresh via document.cookie to bootstrap the gotrue-js session.\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/** Sets auth cookies via document.cookie (browser-side). */\nexport const setBrowserAuthCookies = (accessToken: string, refreshToken?: string): void => {\n document.cookie = `${NF_JWT_COOKIE}=${encodeURIComponent(accessToken)}; path=/; secure; samesite=lax`\n if (refreshToken) {\n document.cookie = `${NF_REFRESH_COOKIE}=${encodeURIComponent(refreshToken)}; path=/; secure; samesite=lax`\n }\n}\n\n/** Deletes auth cookies via document.cookie (browser-side). */\nexport const deleteBrowserAuthCookies = (): void => {\n document.cookie = `${NF_JWT_COOKIE}=; path=/; secure; samesite=lax; expires=Thu, 01 Jan 1970 00:00:00 GMT`\n document.cookie = `${NF_REFRESH_COOKIE}=; path=/; secure; samesite=lax; expires=Thu, 01 Jan 1970 00:00:00 GMT`\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","// Minimal declaration so we can use require() without @types/node\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ndeclare const require: ((id: string) => any) | undefined\n\n/**\n * Calls `headers()` from `next/headers` if available, to opt Next.js RSC\n * routes into dynamic rendering. Without this, Next.js may statically\n * optimize pages that call functions in this package, caching the build-time result.\n *\n * Re-throws DynamicServerError so Next.js can catch it and switch to\n * dynamic rendering. Silently ignores if not in a Next.js environment.\n */\nlet nextHeadersFn: (() => unknown) | null | undefined\nexport const triggerNextjsDynamic = (): void => {\n if (nextHeadersFn === null) return\n\n if (nextHeadersFn === undefined) {\n try {\n if (typeof require === 'undefined') {\n nextHeadersFn = null\n return\n }\n const mod = require('next/headers')\n nextHeadersFn = mod.headers\n } catch {\n nextHeadersFn = null\n return\n }\n }\n\n const fn = nextHeadersFn\n if (!fn) return\n\n try {\n fn()\n } catch (e: unknown) {\n // Re-throw DynamicServerError so Next.js can opt into dynamic rendering.\n // These errors have a `digest` property containing 'DYNAMIC_SERVER_USAGE'\n // or a message about bailing out of prerendering.\n if (e instanceof Error && ('digest' in e || /bail\\s*out.*prerende/i.test(e.message))) {\n throw e\n }\n }\n}\n\n/** Reset cached state and optionally inject a headers function. Test use only. */\nexport const resetNextjsState = (headersFn?: (() => unknown) | null): void => {\n nextHeadersFn = headersFn === null ? null : (headersFn ?? undefined)\n}\n","import type { UserData } from 'gotrue-js'\nimport { AUTH_PROVIDERS, type AuthProvider } from './types.js'\nimport { getGoTrueClient, getClient, isBrowser } from './environment.js'\nimport { getCookie, getServerCookie, NF_JWT_COOKIE, NF_REFRESH_COOKIE } from './cookies.js'\nimport { triggerNextjsDynamic } from './nextjs.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\nlet hydrating = false\n\n/**\n * Creates a gotrue-js session from the nf_jwt cookie so that browser-side\n * operations (updateUser, logout, etc.) work after a server-side login.\n * Fire-and-forget: getUser() returns synchronously from the JWT while this\n * runs in the background.\n */\nconst backgroundHydrate = (accessToken: string): void => {\n if (hydrating) return\n hydrating = true\n\n const refreshToken = getCookie(NF_REFRESH_COOKIE) ?? ''\n\n const decoded = decodeJwtPayload(accessToken)\n const expiresAt = decoded?.exp ?? Math.floor(Date.now() / 1000) + 3600\n const expiresIn = Math.max(0, expiresAt - Math.floor(Date.now() / 1000))\n\n // Defer to the next tick so the synchronous getUser() call completes first,\n // and gotrue-js's internal currentUser isn't set until after the caller\n // has received the JWT-decoded result.\n setTimeout(() => {\n try {\n const client = getClient()\n client\n .createUser(\n {\n access_token: accessToken,\n token_type: 'bearer',\n expires_in: expiresIn,\n expires_at: expiresAt,\n refresh_token: refreshToken,\n },\n true,\n )\n .catch(() => {\n // best-effort: if hydration fails, getUser() still works via cookie decode\n })\n .finally(() => {\n hydrating = false\n })\n } catch {\n hydrating = false\n }\n }, 0)\n}\n\n/** Decodes a JWT payload without verifying the signature. */\nexport const 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.\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) and kicks off background hydration of the gotrue-js\n * session so that subsequent operations (updateUser, logout, etc.) work.\n *\n * On the server in a Next.js App Router context, calls `headers()` from\n * `next/headers` to opt the route into dynamic rendering. Without this,\n * Next.js may statically cache the page at build time.\n */\nexport const getUser = (): User | null => {\n if (isBrowser()) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser() ?? null\n\n if (currentUser) {\n // If gotrue-js has a localStorage session but the nf_jwt cookie is gone,\n // the server logged us out. Clear the stale localStorage session.\n const jwt = getCookie(NF_JWT_COOKIE)\n if (!jwt) {\n try {\n currentUser.clearSession()\n } catch {\n // best-effort cleanup\n }\n return null\n }\n return toUser(currentUser)\n }\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 // Hydrate gotrue-js in the background so browser-side operations\n // (updateUser, logout, etc.) work after a server-side login.\n backgroundHydrate(jwt)\n\n return claimsToUser(claims)\n }\n\n // Trigger Next.js dynamic rendering if in a Next.js RSC context\n triggerNextjsDynamic()\n\n // Primary path: identity context populated from the X-Nf-Identity-Info request header\n const identityContext = globalThis.netlifyIdentityContext\n if (identityContext?.user) {\n return claimsToUser(identityContext.user)\n }\n\n // Fallback: read the nf_jwt cookie directly from the Netlify runtime.\n const serverJwt = getServerCookie(NF_JWT_COOKIE)\n if (serverJwt) {\n const claims = decodeJwtPayload(serverJwt)\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 your project's Identity settings (enabled providers, autoconfirm, signup disabled).\n *\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 { getGoTrueClient, isBrowser } from './environment.js'\nimport { toUser, type User } from './user.js'\n\nexport const AUTH_EVENTS = {\n LOGIN: 'login',\n LOGOUT: 'logout',\n TOKEN_REFRESH: 'token_refresh',\n USER_UPDATED: 'user_updated',\n RECOVERY: 'recovery',\n} as const\n\nexport type AuthEvent = (typeof AUTH_EVENTS)[keyof typeof AUTH_EVENTS]\n\nexport type AuthCallback = (event: AuthEvent, user: User | null) => void\n\nconst GOTRUE_STORAGE_KEY = 'gotrue.user'\n\nconst listeners = new Set<AuthCallback>()\n\nexport const emitAuthEvent = (event: AuthEvent, user: User | null): void => {\n for (const listener of listeners) {\n try {\n listener(event, user)\n } catch {\n // Prevent one subscriber from breaking others\n }\n }\n}\n\nlet storageListenerAttached = false\n\nconst attachStorageListener = (): void => {\n if (storageListenerAttached || !isBrowser()) return\n storageListenerAttached = true\n\n window.addEventListener('storage', (event: StorageEvent) => {\n if (event.key !== GOTRUE_STORAGE_KEY) return\n\n if (event.newValue) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser()\n emitAuthEvent(AUTH_EVENTS.LOGIN, currentUser ? toUser(currentUser) : null)\n } else {\n emitAuthEvent(AUTH_EVENTS.LOGOUT, null)\n }\n })\n}\n\n/**\n * Subscribes to auth state changes (login, logout, token refresh, user updates,\n * and recovery). Returns an unsubscribe function. No-op on the server.\n *\n * The `'recovery'` event fires when {@link handleAuthCallback} processes a\n * password recovery token. The user is logged in but has not yet set a new\n * password. Redirect them to a password reset form and call\n * `updateUser({ password })` to complete the flow.\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","import type GoTrue from 'gotrue-js'\nimport type { UserData } from 'gotrue-js'\nimport type { NetlifyCookies, SignupData, TokenResponse, GoTrueErrorBody } from './types.js'\nimport { toUser, decodeJwtPayload } from './user.js'\n\nimport { getClient, getIdentityContext, isBrowser, IDENTITY_PATH } from './environment.js'\nimport {\n getCookie,\n setAuthCookies,\n deleteAuthCookies,\n setBrowserAuthCookies,\n deleteBrowserAuthCookies,\n NF_JWT_COOKIE,\n NF_REFRESH_COOKIE,\n} from './cookies.js'\nimport { AuthError } from './errors.js'\nimport { AUTH_EVENTS, emitAuthEvent } from './events.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\n/** Persist the session to localStorage so it survives page reloads. */\nexport const persistSession = true\n\n/**\n * Logs in with email and password. Works in both browser and server contexts.\n *\n * On success, sets `nf_jwt` and `nf_refresh` cookies and returns the authenticated {@link User}.\n * In the browser, also emits a `'login'` event via {@link onAuthChange}.\n *\n * @throws {AuthError} On invalid credentials, network failure, or missing Netlify runtime.\n *\n * @remarks\n * In Next.js server actions, call `redirect()` **after** `login()` returns, not inside a\n * try/catch. Next.js implements `redirect()` by throwing a special error; wrapping it in\n * try/catch will swallow the redirect.\n *\n * @example\n * ```ts\n * // Next.js server action\n * const user = await login(email, password)\n * redirect('/dashboard') // after login, not inside try/catch\n * ```\n */\nexport const login = async (email: string, password: string): Promise<import('./user.js').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 AuthError.from(error)\n }\n\n if (!res.ok) {\n const errorBody = (await res.json().catch(() => ({}))) as GoTrueErrorBody\n throw new AuthError(errorBody.msg || errorBody.error_description || `Login failed (${res.status})`, res.status)\n }\n\n const data = (await res.json()) as TokenResponse\n const accessToken = data.access_token\n\n let userRes: Response\n try {\n userRes = await fetch(`${identityUrl}/user`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n })\n } catch (error) {\n throw AuthError.from(error)\n }\n\n if (!userRes.ok) {\n const errorBody = (await userRes.json().catch(() => ({}))) as GoTrueErrorBody\n throw new AuthError(errorBody.msg || `Failed to fetch user data (${userRes.status})`, userRes.status)\n }\n\n const userData = (await userRes.json()) as UserData\n const user = toUser(userData)\n\n setAuthCookies(cookies, accessToken, data.refresh_token)\n\n return user\n }\n\n const client = getClient()\n\n try {\n const gotrueUser = await client.login(email, password, persistSession)\n const jwt = await gotrueUser.jwt()\n setBrowserAuthCookies(jwt)\n const user = toUser(gotrueUser)\n emitAuthEvent(AUTH_EVENTS.LOGIN, user)\n return user\n } catch (error) {\n throw AuthError.from(error)\n }\n}\n\n/**\n * Creates a new account. Works in both browser and server contexts.\n *\n * If autoconfirm is enabled in your Identity settings, the user is logged in immediately:\n * cookies are set and a `'login'` event is emitted. If autoconfirm is **disabled** (the default),\n * the user receives a confirmation email and must click the link before they can log in.\n * In that case, no cookies are set and no auth event is emitted.\n *\n * @throws {AuthError} On duplicate email, validation failure, network error, or missing Netlify runtime.\n */\nexport const signup = async (email: string, password: string, data?: SignupData): Promise<import('./user.js').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 AuthError.from(error)\n }\n\n if (!res.ok) {\n const errorBody = (await res.json().catch(() => ({}))) as GoTrueErrorBody\n throw new AuthError(errorBody.msg || `Signup failed (${res.status})`, res.status)\n }\n\n const responseData = (await res.json()) as UserData & Partial<TokenResponse>\n const user = toUser(responseData)\n\n if (responseData.confirmed_at) {\n const accessToken = responseData.access_token\n if (accessToken) {\n setAuthCookies(cookies, accessToken, responseData.refresh_token)\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 const jwt = await (response as { jwt?: () => Promise<string> }).jwt?.()\n if (jwt) {\n setBrowserAuthCookies(jwt)\n }\n emitAuthEvent(AUTH_EVENTS.LOGIN, user)\n }\n return user\n } catch (error) {\n throw AuthError.from(error)\n }\n}\n\n/**\n * Logs out the current user and clears the session. Works in both browser and server contexts.\n *\n * Always deletes `nf_jwt` and `nf_refresh` cookies, even if the server-side token\n * invalidation request fails. In the browser, emits a `'logout'` event via {@link onAuthChange}.\n *\n * @throws {AuthError} On missing Netlify runtime (server) or logout failure (browser).\n */\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 {\n // Best-effort: token invalidation may fail, but we always clear cookies below\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 deleteBrowserAuthCookies()\n emitAuthEvent(AUTH_EVENTS.LOGOUT, null)\n } catch (error) {\n throw AuthError.from(error)\n }\n}\n\n/**\n * Initiates an OAuth login by redirecting to the given provider (e.g., `'google'`, `'github'`).\n * The page navigates away; this function never returns normally. Browser only.\n *\n * After the provider redirects back, call {@link handleAuthCallback} on page load\n * to complete the login and obtain the {@link User}.\n *\n * @throws {AuthError} If called on the server.\n */\nexport const oauthLogin = (provider: string): never => {\n if (!isBrowser()) {\n throw new AuthError('oauthLogin() is only available in the browser')\n }\n const client = getClient()\n\n window.location.href = client.loginExternalUrl(provider)\n throw new AuthError('Redirecting to OAuth provider')\n}\n\nexport interface CallbackResult {\n type: 'oauth' | 'confirmation' | 'recovery' | 'invite' | 'email_change'\n user: import('./user.js').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 *\n * Call this early in your app's initialization (e.g., in a layout component or\n * root loader), **not** inside a route that requires authentication, because\n * the callback URL must match the page where this function runs.\n *\n * For recovery callbacks (`result.type === 'recovery'`), the user is logged in\n * but has **not** set a new password yet. Your app must check the result type\n * and redirect to a password form that calls `updateUser({ password })`.\n * A `'recovery'` event (not `'login'`) is emitted via {@link onAuthChange}.\n *\n * @throws {AuthError} If the callback token is invalid or the verification request fails.\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 const params = new URLSearchParams(hash)\n\n try {\n const accessToken = params.get('access_token')\n if (accessToken) return await handleOAuthCallback(client, params, accessToken)\n\n const confirmationToken = params.get('confirmation_token')\n if (confirmationToken) return await handleConfirmationCallback(client, confirmationToken)\n\n const recoveryToken = params.get('recovery_token')\n if (recoveryToken) return await handleRecoveryCallback(client, recoveryToken)\n\n const inviteToken = params.get('invite_token')\n if (inviteToken) return handleInviteCallback(inviteToken)\n\n const emailChangeToken = params.get('email_change_token')\n if (emailChangeToken) return await handleEmailChangeCallback(client, emailChangeToken)\n\n return null\n } catch (error) {\n if (error instanceof AuthError) throw error\n throw AuthError.from(error)\n }\n}\n\nconst handleOAuthCallback = async (\n client: GoTrue,\n params: URLSearchParams,\n accessToken: string,\n): Promise<CallbackResult> => {\n const refreshToken = params.get('refresh_token') ?? ''\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: refreshToken,\n },\n persistSession,\n )\n setBrowserAuthCookies(accessToken, refreshToken || undefined)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent(AUTH_EVENTS.LOGIN, user)\n return { type: 'oauth', user }\n}\n\nconst handleConfirmationCallback = async (client: GoTrue, token: string): Promise<CallbackResult> => {\n const gotrueUser = await client.confirm(token, persistSession)\n const jwt = await gotrueUser.jwt()\n setBrowserAuthCookies(jwt)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent(AUTH_EVENTS.LOGIN, user)\n return { type: 'confirmation', user }\n}\n\nconst handleRecoveryCallback = async (client: GoTrue, token: string): Promise<CallbackResult> => {\n const gotrueUser = await client.recover(token, persistSession)\n const jwt = await gotrueUser.jwt()\n setBrowserAuthCookies(jwt)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent(AUTH_EVENTS.RECOVERY, user)\n return { type: 'recovery', user }\n}\n\nconst handleInviteCallback = (token: string): CallbackResult => {\n clearHash()\n return { type: 'invite', user: null, token }\n}\n\nconst handleEmailChangeCallback = async (client: GoTrue, emailChangeToken: string): Promise<CallbackResult> => {\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(() => ({}))) as GoTrueErrorBody\n throw new AuthError(\n errorBody.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(AUTH_EVENTS.USER_UPDATED, user)\n return { type: 'email_change', user }\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<import('./user.js').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 decoded = decodeJwtPayload(accessToken)\n const expiresAt = decoded?.exp ?? Math.floor(Date.now() / 1000) + 3600\n const expiresIn = Math.max(0, expiresAt - Math.floor(Date.now() / 1000))\n\n let gotrueUser\n try {\n gotrueUser = await client.createUser(\n {\n access_token: accessToken,\n token_type: 'bearer',\n expires_in: expiresIn,\n expires_at: expiresAt,\n refresh_token: refreshToken,\n },\n persistSession,\n )\n } catch {\n deleteBrowserAuthCookies()\n return null\n }\n\n const user = toUser(gotrueUser)\n emitAuthEvent(AUTH_EVENTS.LOGIN, user)\n return user\n}\n","import type { UserData, User as GoTrueUser } from 'gotrue-js'\n\nimport type { UserUpdates, GoTrueErrorBody } from './types.js'\nimport type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getClient, isBrowser, IDENTITY_PATH } from './environment.js'\nimport { persistSession, hydrateSession } from './auth.js'\nimport { AUTH_EVENTS, emitAuthEvent } from './events.js'\nimport { AuthError } from './errors.js'\n\n/**\n * Returns the current gotrue-js user, attempting hydration from cookies if\n * no in-memory session exists. Throws if no user can be resolved.\n */\nconst resolveCurrentUser = async (): Promise<GoTrueUser> => {\n const client = getClient()\n\n let currentUser = client.currentUser()\n if (!currentUser && isBrowser()) {\n try {\n await hydrateSession()\n } catch {\n // hydration failed (e.g. expired cookie, network error) — fall through\n }\n currentUser = client.currentUser()\n }\n if (!currentUser) throw new AuthError('No user is currently logged in')\n\n return currentUser\n}\n\n/**\n * Sends a password recovery email to the given address.\n *\n * @throws {AuthError} On network failure or if the request is rejected.\n */\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 AuthError.from(error)\n }\n}\n\n/**\n * Redeems a recovery token and sets a new password. Logs the user in on success.\n *\n * @throws {AuthError} If the token is invalid, expired, or the update fails.\n */\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 // Emits LOGIN because the recovery is fully complete\n emitAuthEvent(AUTH_EVENTS.LOGIN, user)\n return user\n } catch (error) {\n throw AuthError.from(error)\n }\n}\n\n/**\n * Confirms an email address using the token from a confirmation email. Logs the user in on success.\n *\n * @throws {AuthError} If the token is invalid or expired.\n */\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(AUTH_EVENTS.LOGIN, user)\n return user\n } catch (error) {\n throw AuthError.from(error)\n }\n}\n\n/**\n * Accepts an invite token and sets a password for the new account. Logs the user in on success.\n *\n * @throws {AuthError} If the token is invalid or expired.\n */\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(AUTH_EVENTS.LOGIN, user)\n return user\n } catch (error) {\n throw AuthError.from(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. Browser only.\n *\n * @throws {AuthError} If called on the server, no user is logged in, or the token is invalid.\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 resolveCurrentUser()\n\n try {\n const jwt = await currentUser.jwt()\n const identityUrl = `${window.location.origin}${IDENTITY_PATH}`\n\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(() => ({}))) as GoTrueErrorBody\n throw new AuthError(errorBody.msg || `Email change verification failed (${res.status})`, res.status)\n }\n\n const userData = (await res.json()) as UserData\n const user = toUser(userData)\n emitAuthEvent(AUTH_EVENTS.USER_UPDATED, user)\n return user\n } catch (error) {\n if (error instanceof AuthError) throw error\n throw AuthError.from(error)\n }\n}\n\n/**\n * Updates the current user's email, password, or user metadata.\n * Auto-hydrates from auth cookies if no browser session exists.\n *\n * @param updates - Fields to update. Pass `email` or `password` to change credentials,\n * or `data` to update user metadata (e.g., `{ data: { full_name: 'New Name' } }`).\n * @throws {AuthError} If no user is logged in or the update fails.\n */\nexport const updateUser = async (updates: UserUpdates): Promise<User> => {\n const currentUser = await resolveCurrentUser()\n\n try {\n const updatedUser = await currentUser.update(updates)\n const user = toUser(updatedUser)\n emitAuthEvent(AUTH_EVENTS.USER_UPDATED, user)\n return user\n } catch (error) {\n throw AuthError.from(error)\n }\n}\n"],"mappings":"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","names":["GoTrue","jwt"]}
|
package/dist/index.d.cts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@ var AUTH_PROVIDERS = ["google", "github", "gitlab", "bitbucket", "facebook", "sa
|
|
|
12
12
|
import GoTrue from "gotrue-js";
|
|
13
13
|
|
|
14
14
|
// src/errors.ts
|
|
15
|
-
var AuthError = class extends Error {
|
|
15
|
+
var AuthError = class _AuthError extends Error {
|
|
16
16
|
constructor(message, status, options) {
|
|
17
17
|
super(message);
|
|
18
18
|
this.name = "AuthError";
|
|
@@ -21,6 +21,10 @@ var AuthError = class extends Error {
|
|
|
21
21
|
this.cause = options.cause;
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
|
+
static from(error) {
|
|
25
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
26
|
+
return new _AuthError(message, void 0, { cause: error });
|
|
27
|
+
}
|
|
24
28
|
};
|
|
25
29
|
var MissingIdentityError = class extends Error {
|
|
26
30
|
constructor(message = "Netlify Identity is not available.") {
|
|
@@ -45,7 +49,7 @@ var discoverApiUrl = () => {
|
|
|
45
49
|
cachedApiUrl = identityContext.url;
|
|
46
50
|
} else if (globalThis.Netlify?.context?.url) {
|
|
47
51
|
cachedApiUrl = new URL(IDENTITY_PATH, globalThis.Netlify.context.url).href;
|
|
48
|
-
} else if (process.env
|
|
52
|
+
} else if (typeof process !== "undefined" && process.env?.URL) {
|
|
49
53
|
cachedApiUrl = new URL(IDENTITY_PATH, process.env.URL).href;
|
|
50
54
|
}
|
|
51
55
|
}
|
|
@@ -82,7 +86,7 @@ var getIdentityContext = () => {
|
|
|
82
86
|
if (globalThis.Netlify?.context?.url) {
|
|
83
87
|
return { url: new URL(IDENTITY_PATH, globalThis.Netlify.context.url).href };
|
|
84
88
|
}
|
|
85
|
-
const siteUrl = process.env
|
|
89
|
+
const siteUrl = typeof process !== "undefined" ? process.env?.URL : void 0;
|
|
86
90
|
if (siteUrl) {
|
|
87
91
|
return { url: new URL(IDENTITY_PATH, siteUrl).href };
|
|
88
92
|
}
|
|
@@ -94,7 +98,12 @@ var NF_JWT_COOKIE = "nf_jwt";
|
|
|
94
98
|
var NF_REFRESH_COOKIE = "nf_refresh";
|
|
95
99
|
var getCookie = (name) => {
|
|
96
100
|
const match = document.cookie.match(new RegExp(`(?:^|; )${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}=([^;]*)`));
|
|
97
|
-
|
|
101
|
+
if (!match) return null;
|
|
102
|
+
try {
|
|
103
|
+
return decodeURIComponent(match[1]);
|
|
104
|
+
} catch {
|
|
105
|
+
return match[1];
|
|
106
|
+
}
|
|
98
107
|
};
|
|
99
108
|
var setAuthCookies = (cookies, accessToken, refreshToken) => {
|
|
100
109
|
cookies.set({
|
|
@@ -379,7 +388,7 @@ var login = async (email, password) => {
|
|
|
379
388
|
body: body.toString()
|
|
380
389
|
});
|
|
381
390
|
} catch (error) {
|
|
382
|
-
throw
|
|
391
|
+
throw AuthError.from(error);
|
|
383
392
|
}
|
|
384
393
|
if (!res.ok) {
|
|
385
394
|
const errorBody = await res.json().catch(() => ({}));
|
|
@@ -393,7 +402,7 @@ var login = async (email, password) => {
|
|
|
393
402
|
headers: { Authorization: `Bearer ${accessToken}` }
|
|
394
403
|
});
|
|
395
404
|
} catch (error) {
|
|
396
|
-
throw
|
|
405
|
+
throw AuthError.from(error);
|
|
397
406
|
}
|
|
398
407
|
if (!userRes.ok) {
|
|
399
408
|
const errorBody = await userRes.json().catch(() => ({}));
|
|
@@ -413,7 +422,7 @@ var login = async (email, password) => {
|
|
|
413
422
|
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
414
423
|
return user;
|
|
415
424
|
} catch (error) {
|
|
416
|
-
throw
|
|
425
|
+
throw AuthError.from(error);
|
|
417
426
|
}
|
|
418
427
|
};
|
|
419
428
|
var signup = async (email, password, data) => {
|
|
@@ -428,7 +437,7 @@ var signup = async (email, password, data) => {
|
|
|
428
437
|
body: JSON.stringify({ email, password, data })
|
|
429
438
|
});
|
|
430
439
|
} catch (error) {
|
|
431
|
-
throw
|
|
440
|
+
throw AuthError.from(error);
|
|
432
441
|
}
|
|
433
442
|
if (!res.ok) {
|
|
434
443
|
const errorBody = await res.json().catch(() => ({}));
|
|
@@ -457,7 +466,7 @@ var signup = async (email, password, data) => {
|
|
|
457
466
|
}
|
|
458
467
|
return user;
|
|
459
468
|
} catch (error) {
|
|
460
|
-
throw
|
|
469
|
+
throw AuthError.from(error);
|
|
461
470
|
}
|
|
462
471
|
};
|
|
463
472
|
var logout = async () => {
|
|
@@ -486,7 +495,7 @@ var logout = async () => {
|
|
|
486
495
|
deleteBrowserAuthCookies();
|
|
487
496
|
emitAuthEvent(AUTH_EVENTS.LOGOUT, null);
|
|
488
497
|
} catch (error) {
|
|
489
|
-
throw
|
|
498
|
+
throw AuthError.from(error);
|
|
490
499
|
}
|
|
491
500
|
};
|
|
492
501
|
var oauthLogin = (provider) => {
|
|
@@ -517,7 +526,7 @@ var handleAuthCallback = async () => {
|
|
|
517
526
|
return null;
|
|
518
527
|
} catch (error) {
|
|
519
528
|
if (error instanceof AuthError) throw error;
|
|
520
|
-
throw
|
|
529
|
+
throw AuthError.from(error);
|
|
521
530
|
}
|
|
522
531
|
};
|
|
523
532
|
var handleOAuthCallback = async (client, params, accessToken) => {
|
|
@@ -602,16 +611,22 @@ var hydrateSession = async () => {
|
|
|
602
611
|
const decoded = decodeJwtPayload(accessToken);
|
|
603
612
|
const expiresAt = decoded?.exp ?? Math.floor(Date.now() / 1e3) + 3600;
|
|
604
613
|
const expiresIn = Math.max(0, expiresAt - Math.floor(Date.now() / 1e3));
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
614
|
+
let gotrueUser;
|
|
615
|
+
try {
|
|
616
|
+
gotrueUser = await client.createUser(
|
|
617
|
+
{
|
|
618
|
+
access_token: accessToken,
|
|
619
|
+
token_type: "bearer",
|
|
620
|
+
expires_in: expiresIn,
|
|
621
|
+
expires_at: expiresAt,
|
|
622
|
+
refresh_token: refreshToken
|
|
623
|
+
},
|
|
624
|
+
persistSession
|
|
625
|
+
);
|
|
626
|
+
} catch {
|
|
627
|
+
deleteBrowserAuthCookies();
|
|
628
|
+
return null;
|
|
629
|
+
}
|
|
615
630
|
const user = toUser(gotrueUser);
|
|
616
631
|
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
617
632
|
return user;
|
|
@@ -636,7 +651,7 @@ var requestPasswordRecovery = async (email) => {
|
|
|
636
651
|
try {
|
|
637
652
|
await client.requestPasswordRecovery(email);
|
|
638
653
|
} catch (error) {
|
|
639
|
-
throw
|
|
654
|
+
throw AuthError.from(error);
|
|
640
655
|
}
|
|
641
656
|
};
|
|
642
657
|
var recoverPassword = async (token, newPassword) => {
|
|
@@ -648,7 +663,7 @@ var recoverPassword = async (token, newPassword) => {
|
|
|
648
663
|
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
649
664
|
return user;
|
|
650
665
|
} catch (error) {
|
|
651
|
-
throw
|
|
666
|
+
throw AuthError.from(error);
|
|
652
667
|
}
|
|
653
668
|
};
|
|
654
669
|
var confirmEmail = async (token) => {
|
|
@@ -659,7 +674,7 @@ var confirmEmail = async (token) => {
|
|
|
659
674
|
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
660
675
|
return user;
|
|
661
676
|
} catch (error) {
|
|
662
|
-
throw
|
|
677
|
+
throw AuthError.from(error);
|
|
663
678
|
}
|
|
664
679
|
};
|
|
665
680
|
var acceptInvite = async (token, password) => {
|
|
@@ -670,15 +685,15 @@ var acceptInvite = async (token, password) => {
|
|
|
670
685
|
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
671
686
|
return user;
|
|
672
687
|
} catch (error) {
|
|
673
|
-
throw
|
|
688
|
+
throw AuthError.from(error);
|
|
674
689
|
}
|
|
675
690
|
};
|
|
676
691
|
var verifyEmailChange = async (token) => {
|
|
677
692
|
if (!isBrowser()) throw new AuthError("verifyEmailChange() is only available in the browser");
|
|
678
693
|
const currentUser = await resolveCurrentUser();
|
|
679
|
-
const jwt = await currentUser.jwt();
|
|
680
|
-
const identityUrl = `${window.location.origin}${IDENTITY_PATH}`;
|
|
681
694
|
try {
|
|
695
|
+
const jwt = await currentUser.jwt();
|
|
696
|
+
const identityUrl = `${window.location.origin}${IDENTITY_PATH}`;
|
|
682
697
|
const res = await fetch(`${identityUrl}/user`, {
|
|
683
698
|
method: "PUT",
|
|
684
699
|
headers: {
|
|
@@ -697,7 +712,7 @@ var verifyEmailChange = async (token) => {
|
|
|
697
712
|
return user;
|
|
698
713
|
} catch (error) {
|
|
699
714
|
if (error instanceof AuthError) throw error;
|
|
700
|
-
throw
|
|
715
|
+
throw AuthError.from(error);
|
|
701
716
|
}
|
|
702
717
|
};
|
|
703
718
|
var updateUser = async (updates) => {
|
|
@@ -708,7 +723,7 @@ var updateUser = async (updates) => {
|
|
|
708
723
|
emitAuthEvent(AUTH_EVENTS.USER_UPDATED, user);
|
|
709
724
|
return user;
|
|
710
725
|
} catch (error) {
|
|
711
|
-
throw
|
|
726
|
+
throw AuthError.from(error);
|
|
712
727
|
}
|
|
713
728
|
};
|
|
714
729
|
export {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/environment.ts","../src/errors.ts","../src/cookies.ts","../src/nextjs.ts","../src/user.ts","../src/config.ts","../src/events.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\n/**\n * Fields accepted by {@link updateUser}. All fields are optional.\n * Pass `data` to update user metadata (e.g., `{ data: { full_name: 'New Name' } }`).\n */\nexport interface UserUpdates {\n email?: string\n password?: string\n data?: Record<string, unknown>\n [key: string]: unknown\n}\n\n/**\n * User metadata passed during signup (e.g., `{ full_name: 'Jane Doe' }`).\n * Stored in the user's `user_metadata` field.\n */\nexport type SignupData = Record<string, unknown>\n\n/** GoTrue OAuth2 token response from the /token endpoint. */\nexport interface TokenResponse {\n access_token: string\n token_type: string\n expires_in: number\n refresh_token?: string\n}\n\n/** GoTrue error response body. */\nexport interface GoTrueErrorBody {\n msg?: string\n error_description?: string\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 } else if (process.env.URL) {\n cachedApiUrl = new URL(IDENTITY_PATH, process.env.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: false })\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 // Fallback: Netlify sets the URL env var on all deployed sites\n const siteUrl = process.env.URL\n if (siteUrl) {\n return { url: new URL(IDENTITY_PATH, siteUrl).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 = 'Netlify Identity is not available.') {\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 // httpOnly: false because browser-side hydration (backgroundHydrate, hydrateSession)\n // reads nf_refresh via document.cookie to bootstrap the gotrue-js session.\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/** Sets auth cookies via document.cookie (browser-side). */\nexport const setBrowserAuthCookies = (accessToken: string, refreshToken?: string): void => {\n document.cookie = `${NF_JWT_COOKIE}=${encodeURIComponent(accessToken)}; path=/; secure; samesite=lax`\n if (refreshToken) {\n document.cookie = `${NF_REFRESH_COOKIE}=${encodeURIComponent(refreshToken)}; path=/; secure; samesite=lax`\n }\n}\n\n/** Deletes auth cookies via document.cookie (browser-side). */\nexport const deleteBrowserAuthCookies = (): void => {\n document.cookie = `${NF_JWT_COOKIE}=; path=/; secure; samesite=lax; expires=Thu, 01 Jan 1970 00:00:00 GMT`\n document.cookie = `${NF_REFRESH_COOKIE}=; path=/; secure; samesite=lax; expires=Thu, 01 Jan 1970 00:00:00 GMT`\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","// Minimal declaration so we can use require() without @types/node\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ndeclare const require: ((id: string) => any) | undefined\n\n/**\n * Calls `headers()` from `next/headers` if available, to opt Next.js RSC\n * routes into dynamic rendering. Without this, Next.js may statically\n * optimize pages that call functions in this package, caching the build-time result.\n *\n * Re-throws DynamicServerError so Next.js can catch it and switch to\n * dynamic rendering. Silently ignores if not in a Next.js environment.\n */\nlet nextHeadersFn: (() => unknown) | null | undefined\nexport const triggerNextjsDynamic = (): void => {\n if (nextHeadersFn === null) return\n\n if (nextHeadersFn === undefined) {\n try {\n if (typeof require === 'undefined') {\n nextHeadersFn = null\n return\n }\n const mod = require('next/headers')\n nextHeadersFn = mod.headers\n } catch {\n nextHeadersFn = null\n return\n }\n }\n\n const fn = nextHeadersFn\n if (!fn) return\n\n try {\n fn()\n } catch (e: unknown) {\n // Re-throw DynamicServerError so Next.js can opt into dynamic rendering.\n // These errors have a `digest` property containing 'DYNAMIC_SERVER_USAGE'\n // or a message about bailing out of prerendering.\n if (e instanceof Error && ('digest' in e || /bail\\s*out.*prerende/i.test(e.message))) {\n throw e\n }\n }\n}\n\n/** Reset cached state and optionally inject a headers function. Test use only. */\nexport const resetNextjsState = (headersFn?: (() => unknown) | null): void => {\n nextHeadersFn = headersFn === null ? null : (headersFn ?? undefined)\n}\n","import type { UserData } from 'gotrue-js'\nimport { AUTH_PROVIDERS, type AuthProvider } from './types.js'\nimport { getGoTrueClient, getClient, isBrowser } from './environment.js'\nimport { getCookie, getServerCookie, NF_JWT_COOKIE, NF_REFRESH_COOKIE } from './cookies.js'\nimport { triggerNextjsDynamic } from './nextjs.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\nlet hydrating = false\n\n/**\n * Creates a gotrue-js session from the nf_jwt cookie so that browser-side\n * operations (updateUser, logout, etc.) work after a server-side login.\n * Fire-and-forget: getUser() returns synchronously from the JWT while this\n * runs in the background.\n */\nconst backgroundHydrate = (accessToken: string): void => {\n if (hydrating) return\n hydrating = true\n\n const refreshToken = getCookie(NF_REFRESH_COOKIE) ?? ''\n\n const decoded = decodeJwtPayload(accessToken)\n const expiresAt = decoded?.exp ?? Math.floor(Date.now() / 1000) + 3600\n const expiresIn = Math.max(0, expiresAt - Math.floor(Date.now() / 1000))\n\n // Defer to the next tick so the synchronous getUser() call completes first,\n // and gotrue-js's internal currentUser isn't set until after the caller\n // has received the JWT-decoded result.\n setTimeout(() => {\n try {\n const client = getClient()\n client\n .createUser(\n {\n access_token: accessToken,\n token_type: 'bearer',\n expires_in: expiresIn,\n expires_at: expiresAt,\n refresh_token: refreshToken,\n },\n true,\n )\n .catch(() => {\n // best-effort: if hydration fails, getUser() still works via cookie decode\n })\n .finally(() => {\n hydrating = false\n })\n } catch {\n hydrating = false\n }\n }, 0)\n}\n\n/** Decodes a JWT payload without verifying the signature. */\nexport const 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.\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) and kicks off background hydration of the gotrue-js\n * session so that subsequent operations (updateUser, logout, etc.) work.\n *\n * On the server in a Next.js App Router context, calls `headers()` from\n * `next/headers` to opt the route into dynamic rendering. Without this,\n * Next.js may statically cache the page at build time.\n */\nexport const getUser = (): User | null => {\n if (isBrowser()) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser() ?? null\n\n if (currentUser) {\n // If gotrue-js has a localStorage session but the nf_jwt cookie is gone,\n // the server logged us out. Clear the stale localStorage session.\n const jwt = getCookie(NF_JWT_COOKIE)\n if (!jwt) {\n try {\n currentUser.clearSession()\n } catch {\n // best-effort cleanup\n }\n return null\n }\n return toUser(currentUser)\n }\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 // Hydrate gotrue-js in the background so browser-side operations\n // (updateUser, logout, etc.) work after a server-side login.\n backgroundHydrate(jwt)\n\n return claimsToUser(claims)\n }\n\n // Trigger Next.js dynamic rendering if in a Next.js RSC context\n triggerNextjsDynamic()\n\n // Primary path: identity context populated from the X-Nf-Identity-Info request header\n const identityContext = globalThis.netlifyIdentityContext\n if (identityContext?.user) {\n return claimsToUser(identityContext.user)\n }\n\n // Fallback: read the nf_jwt cookie directly from the Netlify runtime.\n const serverJwt = getServerCookie(NF_JWT_COOKIE)\n if (serverJwt) {\n const claims = decodeJwtPayload(serverJwt)\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 your project's Identity settings (enabled providers, autoconfirm, signup disabled).\n *\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 { getGoTrueClient, isBrowser } from './environment.js'\nimport { toUser, type User } from './user.js'\n\nexport const AUTH_EVENTS = {\n LOGIN: 'login',\n LOGOUT: 'logout',\n TOKEN_REFRESH: 'token_refresh',\n USER_UPDATED: 'user_updated',\n RECOVERY: 'recovery',\n} as const\n\nexport type AuthEvent = (typeof AUTH_EVENTS)[keyof typeof AUTH_EVENTS]\n\nexport type AuthCallback = (event: AuthEvent, user: User | null) => void\n\nconst GOTRUE_STORAGE_KEY = 'gotrue.user'\n\nconst listeners = new Set<AuthCallback>()\n\nexport const emitAuthEvent = (event: AuthEvent, user: User | null): void => {\n for (const listener of listeners) {\n try {\n listener(event, user)\n } catch {\n // Prevent one subscriber from breaking others\n }\n }\n}\n\nlet storageListenerAttached = false\n\nconst attachStorageListener = (): void => {\n if (storageListenerAttached || !isBrowser()) return\n storageListenerAttached = true\n\n window.addEventListener('storage', (event: StorageEvent) => {\n if (event.key !== GOTRUE_STORAGE_KEY) return\n\n if (event.newValue) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser()\n emitAuthEvent(AUTH_EVENTS.LOGIN, currentUser ? toUser(currentUser) : null)\n } else {\n emitAuthEvent(AUTH_EVENTS.LOGOUT, null)\n }\n })\n}\n\n/**\n * Subscribes to auth state changes (login, logout, token refresh, user updates,\n * and recovery). Returns an unsubscribe function. No-op on the server.\n *\n * The `'recovery'` event fires when {@link handleAuthCallback} processes a\n * password recovery token. The user is logged in but has not yet set a new\n * password. Redirect them to a password reset form and call\n * `updateUser({ password })` to complete the flow.\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","import type { UserData } from 'gotrue-js'\n\nimport type { NetlifyCookies, SignupData, TokenResponse, GoTrueErrorBody } from './types.js'\nimport { toUser, decodeJwtPayload } from './user.js'\n\nimport { getClient, getIdentityContext, isBrowser, IDENTITY_PATH } from './environment.js'\nimport {\n getCookie,\n setAuthCookies,\n deleteAuthCookies,\n setBrowserAuthCookies,\n deleteBrowserAuthCookies,\n NF_JWT_COOKIE,\n NF_REFRESH_COOKIE,\n} from './cookies.js'\nimport { AuthError } from './errors.js'\nimport { AUTH_EVENTS, emitAuthEvent } from './events.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\n/** Persist the session to localStorage so it survives page reloads. */\nexport const persistSession = true\n\n/**\n * Logs in with email and password. Works in both browser and server contexts.\n *\n * On success, sets `nf_jwt` and `nf_refresh` cookies and returns the authenticated {@link User}.\n * In the browser, also emits a `'login'` event via {@link onAuthChange}.\n *\n * @throws {AuthError} On invalid credentials, network failure, or missing Netlify runtime.\n *\n * @remarks\n * In Next.js server actions, call `redirect()` **after** `login()` returns, not inside a\n * try/catch. Next.js implements `redirect()` by throwing a special error; wrapping it in\n * try/catch will swallow the redirect.\n *\n * @example\n * ```ts\n * // Next.js server action\n * const user = await login(email, password)\n * redirect('/dashboard') // after login, not inside try/catch\n * ```\n */\nexport const login = async (email: string, password: string): Promise<import('./user.js').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(() => ({}))) as GoTrueErrorBody\n throw new AuthError(errorBody.msg || errorBody.error_description || `Login failed (${res.status})`, res.status)\n }\n\n const data = (await res.json()) as TokenResponse\n const accessToken = data.access_token\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(() => ({}))) as GoTrueErrorBody\n throw new AuthError(errorBody.msg || `Failed to fetch user data (${userRes.status})`, userRes.status)\n }\n\n const userData = (await userRes.json()) as UserData\n const user = toUser(userData)\n\n setAuthCookies(cookies, accessToken, data.refresh_token)\n\n return user\n }\n\n const client = getClient()\n\n try {\n const gotrueUser = await client.login(email, password, persistSession)\n const jwt = await gotrueUser.jwt()\n setBrowserAuthCookies(jwt)\n const user = toUser(gotrueUser)\n emitAuthEvent(AUTH_EVENTS.LOGIN, user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/**\n * Creates a new account. Works in both browser and server contexts.\n *\n * If autoconfirm is enabled in your Identity settings, the user is logged in immediately:\n * cookies are set and a `'login'` event is emitted. If autoconfirm is **disabled** (the default),\n * the user receives a confirmation email and must click the link before they can log in.\n * In that case, no cookies are set and no auth event is emitted.\n *\n * @throws {AuthError} On duplicate email, validation failure, network error, or missing Netlify runtime.\n */\nexport const signup = async (email: string, password: string, data?: SignupData): Promise<import('./user.js').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(() => ({}))) as GoTrueErrorBody\n throw new AuthError(errorBody.msg || `Signup failed (${res.status})`, res.status)\n }\n\n const responseData = (await res.json()) as UserData & Partial<TokenResponse>\n const user = toUser(responseData)\n\n if (responseData.confirmed_at) {\n const accessToken = responseData.access_token\n if (accessToken) {\n setAuthCookies(cookies, accessToken, responseData.refresh_token)\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 const jwt = await (response as { jwt?: () => Promise<string> }).jwt?.()\n if (jwt) {\n setBrowserAuthCookies(jwt)\n }\n emitAuthEvent(AUTH_EVENTS.LOGIN, user)\n }\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/**\n * Logs out the current user and clears the session. Works in both browser and server contexts.\n *\n * Always deletes `nf_jwt` and `nf_refresh` cookies, even if the server-side token\n * invalidation request fails. In the browser, emits a `'logout'` event via {@link onAuthChange}.\n *\n * @throws {AuthError} On missing Netlify runtime (server) or logout failure (browser).\n */\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 {\n // Best-effort: token invalidation may fail, but we always clear cookies below\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 deleteBrowserAuthCookies()\n emitAuthEvent(AUTH_EVENTS.LOGOUT, null)\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/**\n * Initiates an OAuth login by redirecting to the given provider (e.g., `'google'`, `'github'`).\n * The page navigates away; this function never returns normally. Browser only.\n *\n * After the provider redirects back, call {@link handleAuthCallback} on page load\n * to complete the login and obtain the {@link User}.\n *\n * @throws {AuthError} If called on the server.\n */\nexport const oauthLogin = (provider: string): never => {\n if (!isBrowser()) {\n throw new AuthError('oauthLogin() is only available in the browser')\n }\n const client = getClient()\n\n window.location.href = client.loginExternalUrl(provider)\n throw new AuthError('Redirecting to OAuth provider')\n}\n\nexport interface CallbackResult {\n type: 'oauth' | 'confirmation' | 'recovery' | 'invite' | 'email_change'\n user: import('./user.js').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 *\n * Call this early in your app's initialization (e.g., in a layout component or\n * root loader), **not** inside a route that requires authentication, because\n * the callback URL must match the page where this function runs.\n *\n * For recovery callbacks (`result.type === 'recovery'`), the user is logged in\n * but has **not** set a new password yet. Your app must check the result type\n * and redirect to a password form that calls `updateUser({ password })`.\n * A `'recovery'` event (not `'login'`) is emitted via {@link onAuthChange}.\n *\n * @throws {AuthError} If the callback token is invalid or the verification request fails.\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 const params = new URLSearchParams(hash)\n\n try {\n const accessToken = params.get('access_token')\n if (accessToken) return await handleOAuthCallback(client, params, accessToken)\n\n const confirmationToken = params.get('confirmation_token')\n if (confirmationToken) return await handleConfirmationCallback(client, confirmationToken)\n\n const recoveryToken = params.get('recovery_token')\n if (recoveryToken) return await handleRecoveryCallback(client, recoveryToken)\n\n const inviteToken = params.get('invite_token')\n if (inviteToken) return handleInviteCallback(inviteToken)\n\n const emailChangeToken = params.get('email_change_token')\n if (emailChangeToken) return await handleEmailChangeCallback(client, emailChangeToken)\n\n return null\n } catch (error) {\n if (error instanceof AuthError) throw error\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\nimport type GoTrue from 'gotrue-js'\n\nconst handleOAuthCallback = async (\n client: GoTrue,\n params: URLSearchParams,\n accessToken: string,\n): Promise<CallbackResult> => {\n const refreshToken = params.get('refresh_token') ?? ''\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: refreshToken,\n },\n persistSession,\n )\n setBrowserAuthCookies(accessToken, refreshToken || undefined)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent(AUTH_EVENTS.LOGIN, user)\n return { type: 'oauth', user }\n}\n\nconst handleConfirmationCallback = async (client: GoTrue, token: string): Promise<CallbackResult> => {\n const gotrueUser = await client.confirm(token, persistSession)\n const jwt = await gotrueUser.jwt()\n setBrowserAuthCookies(jwt)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent(AUTH_EVENTS.LOGIN, user)\n return { type: 'confirmation', user }\n}\n\nconst handleRecoveryCallback = async (client: GoTrue, token: string): Promise<CallbackResult> => {\n const gotrueUser = await client.recover(token, persistSession)\n const jwt = await gotrueUser.jwt()\n setBrowserAuthCookies(jwt)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent(AUTH_EVENTS.RECOVERY, user)\n return { type: 'recovery', user }\n}\n\nconst handleInviteCallback = (token: string): CallbackResult => {\n clearHash()\n return { type: 'invite', user: null, token }\n}\n\nconst handleEmailChangeCallback = async (client: GoTrue, emailChangeToken: string): Promise<CallbackResult> => {\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(() => ({}))) as GoTrueErrorBody\n throw new AuthError(\n errorBody.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(AUTH_EVENTS.USER_UPDATED, user)\n return { type: 'email_change', user }\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<import('./user.js').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 decoded = decodeJwtPayload(accessToken)\n const expiresAt = decoded?.exp ?? Math.floor(Date.now() / 1000) + 3600\n const expiresIn = Math.max(0, expiresAt - Math.floor(Date.now() / 1000))\n\n const gotrueUser = await client.createUser(\n {\n access_token: accessToken,\n token_type: 'bearer',\n expires_in: expiresIn,\n expires_at: expiresAt,\n refresh_token: refreshToken,\n },\n persistSession,\n )\n\n const user = toUser(gotrueUser)\n emitAuthEvent(AUTH_EVENTS.LOGIN, user)\n return user\n}\n","import type { UserData, User as GoTrueUser } from 'gotrue-js'\n\nimport type { UserUpdates, GoTrueErrorBody } from './types.js'\nimport type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getClient, isBrowser, IDENTITY_PATH } from './environment.js'\nimport { persistSession, hydrateSession } from './auth.js'\nimport { AUTH_EVENTS, emitAuthEvent } from './events.js'\nimport { AuthError } from './errors.js'\n\n/**\n * Returns the current gotrue-js user, attempting hydration from cookies if\n * no in-memory session exists. Throws if no user can be resolved.\n */\nconst resolveCurrentUser = async (): Promise<GoTrueUser> => {\n const client = getClient()\n\n let currentUser = client.currentUser()\n if (!currentUser && isBrowser()) {\n try {\n await hydrateSession()\n } catch {\n // hydration failed (e.g. expired cookie, network error) — fall through\n }\n currentUser = client.currentUser()\n }\n if (!currentUser) throw new AuthError('No user is currently logged in')\n\n return currentUser\n}\n\n/**\n * Sends a password recovery email to the given address.\n *\n * @throws {AuthError} On network failure or if the request is rejected.\n */\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/**\n * Redeems a recovery token and sets a new password. Logs the user in on success.\n *\n * @throws {AuthError} If the token is invalid, expired, or the update fails.\n */\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(AUTH_EVENTS.LOGIN, user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/**\n * Confirms an email address using the token from a confirmation email. Logs the user in on success.\n *\n * @throws {AuthError} If the token is invalid or expired.\n */\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(AUTH_EVENTS.LOGIN, user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/**\n * Accepts an invite token and sets a password for the new account. Logs the user in on success.\n *\n * @throws {AuthError} If the token is invalid or expired.\n */\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(AUTH_EVENTS.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. Browser only.\n *\n * @throws {AuthError} If called on the server, no user is logged in, or the token is invalid.\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 resolveCurrentUser()\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(() => ({}))) as GoTrueErrorBody\n throw new AuthError(errorBody.msg || `Email change verification failed (${res.status})`, res.status)\n }\n\n const userData = (await res.json()) as UserData\n const user = toUser(userData)\n emitAuthEvent(AUTH_EVENTS.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 email, password, or user metadata.\n * Auto-hydrates from auth cookies if no browser session exists.\n *\n * @param updates - Fields to update. Pass `email` or `password` to change credentials,\n * or `data` to update user metadata (e.g., `{ data: { full_name: 'New Name' } }`).\n * @throws {AuthError} If no user is logged in or the update fails.\n */\nexport const updateUser = async (updates: UserUpdates): Promise<User> => {\n const currentUser = await resolveCurrentUser()\n\n try {\n const updatedUser = await currentUser.update(updates)\n const user = toUser(updatedUser)\n emitAuthEvent(AUTH_EVENTS.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"]}
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/environment.ts","../src/errors.ts","../src/cookies.ts","../src/nextjs.ts","../src/user.ts","../src/config.ts","../src/events.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\n/**\n * Fields accepted by {@link updateUser}. All fields are optional.\n * Pass `data` to update user metadata (e.g., `{ data: { full_name: 'New Name' } }`).\n */\nexport interface UserUpdates {\n email?: string\n password?: string\n data?: Record<string, unknown>\n [key: string]: unknown\n}\n\n/**\n * User metadata passed during signup (e.g., `{ full_name: 'Jane Doe' }`).\n * Stored in the user's `user_metadata` field.\n */\nexport type SignupData = Record<string, unknown>\n\n/** GoTrue OAuth2 token response from the /token endpoint. */\nexport interface TokenResponse {\n access_token: string\n token_type: string\n expires_in: number\n refresh_token?: string\n}\n\n/** GoTrue error response body. */\nexport interface GoTrueErrorBody {\n msg?: string\n error_description?: string\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 } else if (typeof process !== 'undefined' && process.env?.URL) {\n cachedApiUrl = new URL(IDENTITY_PATH, process.env.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: false })\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 // Fallback: Netlify sets the URL env var on all deployed sites\n const siteUrl = typeof process !== 'undefined' ? process.env?.URL : undefined\n if (siteUrl) {\n return { url: new URL(IDENTITY_PATH, siteUrl).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 static from(error: unknown): AuthError {\n const message = error instanceof Error ? error.message : String(error)\n return new AuthError(message, undefined, { cause: error })\n }\n}\n\nexport class MissingIdentityError extends Error {\n override name = 'MissingIdentityError'\n\n constructor(message = 'Netlify Identity is not available.') {\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 if (!match) return null\n try {\n return decodeURIComponent(match[1])\n } catch {\n return match[1]\n }\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 // httpOnly: false because browser-side hydration (backgroundHydrate, hydrateSession)\n // reads nf_refresh via document.cookie to bootstrap the gotrue-js session.\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/** Sets auth cookies via document.cookie (browser-side). */\nexport const setBrowserAuthCookies = (accessToken: string, refreshToken?: string): void => {\n document.cookie = `${NF_JWT_COOKIE}=${encodeURIComponent(accessToken)}; path=/; secure; samesite=lax`\n if (refreshToken) {\n document.cookie = `${NF_REFRESH_COOKIE}=${encodeURIComponent(refreshToken)}; path=/; secure; samesite=lax`\n }\n}\n\n/** Deletes auth cookies via document.cookie (browser-side). */\nexport const deleteBrowserAuthCookies = (): void => {\n document.cookie = `${NF_JWT_COOKIE}=; path=/; secure; samesite=lax; expires=Thu, 01 Jan 1970 00:00:00 GMT`\n document.cookie = `${NF_REFRESH_COOKIE}=; path=/; secure; samesite=lax; expires=Thu, 01 Jan 1970 00:00:00 GMT`\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","// Minimal declaration so we can use require() without @types/node\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ndeclare const require: ((id: string) => any) | undefined\n\n/**\n * Calls `headers()` from `next/headers` if available, to opt Next.js RSC\n * routes into dynamic rendering. Without this, Next.js may statically\n * optimize pages that call functions in this package, caching the build-time result.\n *\n * Re-throws DynamicServerError so Next.js can catch it and switch to\n * dynamic rendering. Silently ignores if not in a Next.js environment.\n */\nlet nextHeadersFn: (() => unknown) | null | undefined\nexport const triggerNextjsDynamic = (): void => {\n if (nextHeadersFn === null) return\n\n if (nextHeadersFn === undefined) {\n try {\n if (typeof require === 'undefined') {\n nextHeadersFn = null\n return\n }\n const mod = require('next/headers')\n nextHeadersFn = mod.headers\n } catch {\n nextHeadersFn = null\n return\n }\n }\n\n const fn = nextHeadersFn\n if (!fn) return\n\n try {\n fn()\n } catch (e: unknown) {\n // Re-throw DynamicServerError so Next.js can opt into dynamic rendering.\n // These errors have a `digest` property containing 'DYNAMIC_SERVER_USAGE'\n // or a message about bailing out of prerendering.\n if (e instanceof Error && ('digest' in e || /bail\\s*out.*prerende/i.test(e.message))) {\n throw e\n }\n }\n}\n\n/** Reset cached state and optionally inject a headers function. Test use only. */\nexport const resetNextjsState = (headersFn?: (() => unknown) | null): void => {\n nextHeadersFn = headersFn === null ? null : (headersFn ?? undefined)\n}\n","import type { UserData } from 'gotrue-js'\nimport { AUTH_PROVIDERS, type AuthProvider } from './types.js'\nimport { getGoTrueClient, getClient, isBrowser } from './environment.js'\nimport { getCookie, getServerCookie, NF_JWT_COOKIE, NF_REFRESH_COOKIE } from './cookies.js'\nimport { triggerNextjsDynamic } from './nextjs.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\nlet hydrating = false\n\n/**\n * Creates a gotrue-js session from the nf_jwt cookie so that browser-side\n * operations (updateUser, logout, etc.) work after a server-side login.\n * Fire-and-forget: getUser() returns synchronously from the JWT while this\n * runs in the background.\n */\nconst backgroundHydrate = (accessToken: string): void => {\n if (hydrating) return\n hydrating = true\n\n const refreshToken = getCookie(NF_REFRESH_COOKIE) ?? ''\n\n const decoded = decodeJwtPayload(accessToken)\n const expiresAt = decoded?.exp ?? Math.floor(Date.now() / 1000) + 3600\n const expiresIn = Math.max(0, expiresAt - Math.floor(Date.now() / 1000))\n\n // Defer to the next tick so the synchronous getUser() call completes first,\n // and gotrue-js's internal currentUser isn't set until after the caller\n // has received the JWT-decoded result.\n setTimeout(() => {\n try {\n const client = getClient()\n client\n .createUser(\n {\n access_token: accessToken,\n token_type: 'bearer',\n expires_in: expiresIn,\n expires_at: expiresAt,\n refresh_token: refreshToken,\n },\n true,\n )\n .catch(() => {\n // best-effort: if hydration fails, getUser() still works via cookie decode\n })\n .finally(() => {\n hydrating = false\n })\n } catch {\n hydrating = false\n }\n }, 0)\n}\n\n/** Decodes a JWT payload without verifying the signature. */\nexport const 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.\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) and kicks off background hydration of the gotrue-js\n * session so that subsequent operations (updateUser, logout, etc.) work.\n *\n * On the server in a Next.js App Router context, calls `headers()` from\n * `next/headers` to opt the route into dynamic rendering. Without this,\n * Next.js may statically cache the page at build time.\n */\nexport const getUser = (): User | null => {\n if (isBrowser()) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser() ?? null\n\n if (currentUser) {\n // If gotrue-js has a localStorage session but the nf_jwt cookie is gone,\n // the server logged us out. Clear the stale localStorage session.\n const jwt = getCookie(NF_JWT_COOKIE)\n if (!jwt) {\n try {\n currentUser.clearSession()\n } catch {\n // best-effort cleanup\n }\n return null\n }\n return toUser(currentUser)\n }\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 // Hydrate gotrue-js in the background so browser-side operations\n // (updateUser, logout, etc.) work after a server-side login.\n backgroundHydrate(jwt)\n\n return claimsToUser(claims)\n }\n\n // Trigger Next.js dynamic rendering if in a Next.js RSC context\n triggerNextjsDynamic()\n\n // Primary path: identity context populated from the X-Nf-Identity-Info request header\n const identityContext = globalThis.netlifyIdentityContext\n if (identityContext?.user) {\n return claimsToUser(identityContext.user)\n }\n\n // Fallback: read the nf_jwt cookie directly from the Netlify runtime.\n const serverJwt = getServerCookie(NF_JWT_COOKIE)\n if (serverJwt) {\n const claims = decodeJwtPayload(serverJwt)\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 your project's Identity settings (enabled providers, autoconfirm, signup disabled).\n *\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 { getGoTrueClient, isBrowser } from './environment.js'\nimport { toUser, type User } from './user.js'\n\nexport const AUTH_EVENTS = {\n LOGIN: 'login',\n LOGOUT: 'logout',\n TOKEN_REFRESH: 'token_refresh',\n USER_UPDATED: 'user_updated',\n RECOVERY: 'recovery',\n} as const\n\nexport type AuthEvent = (typeof AUTH_EVENTS)[keyof typeof AUTH_EVENTS]\n\nexport type AuthCallback = (event: AuthEvent, user: User | null) => void\n\nconst GOTRUE_STORAGE_KEY = 'gotrue.user'\n\nconst listeners = new Set<AuthCallback>()\n\nexport const emitAuthEvent = (event: AuthEvent, user: User | null): void => {\n for (const listener of listeners) {\n try {\n listener(event, user)\n } catch {\n // Prevent one subscriber from breaking others\n }\n }\n}\n\nlet storageListenerAttached = false\n\nconst attachStorageListener = (): void => {\n if (storageListenerAttached || !isBrowser()) return\n storageListenerAttached = true\n\n window.addEventListener('storage', (event: StorageEvent) => {\n if (event.key !== GOTRUE_STORAGE_KEY) return\n\n if (event.newValue) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser()\n emitAuthEvent(AUTH_EVENTS.LOGIN, currentUser ? toUser(currentUser) : null)\n } else {\n emitAuthEvent(AUTH_EVENTS.LOGOUT, null)\n }\n })\n}\n\n/**\n * Subscribes to auth state changes (login, logout, token refresh, user updates,\n * and recovery). Returns an unsubscribe function. No-op on the server.\n *\n * The `'recovery'` event fires when {@link handleAuthCallback} processes a\n * password recovery token. The user is logged in but has not yet set a new\n * password. Redirect them to a password reset form and call\n * `updateUser({ password })` to complete the flow.\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","import type GoTrue from 'gotrue-js'\nimport type { UserData } from 'gotrue-js'\nimport type { NetlifyCookies, SignupData, TokenResponse, GoTrueErrorBody } from './types.js'\nimport { toUser, decodeJwtPayload } from './user.js'\n\nimport { getClient, getIdentityContext, isBrowser, IDENTITY_PATH } from './environment.js'\nimport {\n getCookie,\n setAuthCookies,\n deleteAuthCookies,\n setBrowserAuthCookies,\n deleteBrowserAuthCookies,\n NF_JWT_COOKIE,\n NF_REFRESH_COOKIE,\n} from './cookies.js'\nimport { AuthError } from './errors.js'\nimport { AUTH_EVENTS, emitAuthEvent } from './events.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\n/** Persist the session to localStorage so it survives page reloads. */\nexport const persistSession = true\n\n/**\n * Logs in with email and password. Works in both browser and server contexts.\n *\n * On success, sets `nf_jwt` and `nf_refresh` cookies and returns the authenticated {@link User}.\n * In the browser, also emits a `'login'` event via {@link onAuthChange}.\n *\n * @throws {AuthError} On invalid credentials, network failure, or missing Netlify runtime.\n *\n * @remarks\n * In Next.js server actions, call `redirect()` **after** `login()` returns, not inside a\n * try/catch. Next.js implements `redirect()` by throwing a special error; wrapping it in\n * try/catch will swallow the redirect.\n *\n * @example\n * ```ts\n * // Next.js server action\n * const user = await login(email, password)\n * redirect('/dashboard') // after login, not inside try/catch\n * ```\n */\nexport const login = async (email: string, password: string): Promise<import('./user.js').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 AuthError.from(error)\n }\n\n if (!res.ok) {\n const errorBody = (await res.json().catch(() => ({}))) as GoTrueErrorBody\n throw new AuthError(errorBody.msg || errorBody.error_description || `Login failed (${res.status})`, res.status)\n }\n\n const data = (await res.json()) as TokenResponse\n const accessToken = data.access_token\n\n let userRes: Response\n try {\n userRes = await fetch(`${identityUrl}/user`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n })\n } catch (error) {\n throw AuthError.from(error)\n }\n\n if (!userRes.ok) {\n const errorBody = (await userRes.json().catch(() => ({}))) as GoTrueErrorBody\n throw new AuthError(errorBody.msg || `Failed to fetch user data (${userRes.status})`, userRes.status)\n }\n\n const userData = (await userRes.json()) as UserData\n const user = toUser(userData)\n\n setAuthCookies(cookies, accessToken, data.refresh_token)\n\n return user\n }\n\n const client = getClient()\n\n try {\n const gotrueUser = await client.login(email, password, persistSession)\n const jwt = await gotrueUser.jwt()\n setBrowserAuthCookies(jwt)\n const user = toUser(gotrueUser)\n emitAuthEvent(AUTH_EVENTS.LOGIN, user)\n return user\n } catch (error) {\n throw AuthError.from(error)\n }\n}\n\n/**\n * Creates a new account. Works in both browser and server contexts.\n *\n * If autoconfirm is enabled in your Identity settings, the user is logged in immediately:\n * cookies are set and a `'login'` event is emitted. If autoconfirm is **disabled** (the default),\n * the user receives a confirmation email and must click the link before they can log in.\n * In that case, no cookies are set and no auth event is emitted.\n *\n * @throws {AuthError} On duplicate email, validation failure, network error, or missing Netlify runtime.\n */\nexport const signup = async (email: string, password: string, data?: SignupData): Promise<import('./user.js').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 AuthError.from(error)\n }\n\n if (!res.ok) {\n const errorBody = (await res.json().catch(() => ({}))) as GoTrueErrorBody\n throw new AuthError(errorBody.msg || `Signup failed (${res.status})`, res.status)\n }\n\n const responseData = (await res.json()) as UserData & Partial<TokenResponse>\n const user = toUser(responseData)\n\n if (responseData.confirmed_at) {\n const accessToken = responseData.access_token\n if (accessToken) {\n setAuthCookies(cookies, accessToken, responseData.refresh_token)\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 const jwt = await (response as { jwt?: () => Promise<string> }).jwt?.()\n if (jwt) {\n setBrowserAuthCookies(jwt)\n }\n emitAuthEvent(AUTH_EVENTS.LOGIN, user)\n }\n return user\n } catch (error) {\n throw AuthError.from(error)\n }\n}\n\n/**\n * Logs out the current user and clears the session. Works in both browser and server contexts.\n *\n * Always deletes `nf_jwt` and `nf_refresh` cookies, even if the server-side token\n * invalidation request fails. In the browser, emits a `'logout'` event via {@link onAuthChange}.\n *\n * @throws {AuthError} On missing Netlify runtime (server) or logout failure (browser).\n */\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 {\n // Best-effort: token invalidation may fail, but we always clear cookies below\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 deleteBrowserAuthCookies()\n emitAuthEvent(AUTH_EVENTS.LOGOUT, null)\n } catch (error) {\n throw AuthError.from(error)\n }\n}\n\n/**\n * Initiates an OAuth login by redirecting to the given provider (e.g., `'google'`, `'github'`).\n * The page navigates away; this function never returns normally. Browser only.\n *\n * After the provider redirects back, call {@link handleAuthCallback} on page load\n * to complete the login and obtain the {@link User}.\n *\n * @throws {AuthError} If called on the server.\n */\nexport const oauthLogin = (provider: string): never => {\n if (!isBrowser()) {\n throw new AuthError('oauthLogin() is only available in the browser')\n }\n const client = getClient()\n\n window.location.href = client.loginExternalUrl(provider)\n throw new AuthError('Redirecting to OAuth provider')\n}\n\nexport interface CallbackResult {\n type: 'oauth' | 'confirmation' | 'recovery' | 'invite' | 'email_change'\n user: import('./user.js').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 *\n * Call this early in your app's initialization (e.g., in a layout component or\n * root loader), **not** inside a route that requires authentication, because\n * the callback URL must match the page where this function runs.\n *\n * For recovery callbacks (`result.type === 'recovery'`), the user is logged in\n * but has **not** set a new password yet. Your app must check the result type\n * and redirect to a password form that calls `updateUser({ password })`.\n * A `'recovery'` event (not `'login'`) is emitted via {@link onAuthChange}.\n *\n * @throws {AuthError} If the callback token is invalid or the verification request fails.\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 const params = new URLSearchParams(hash)\n\n try {\n const accessToken = params.get('access_token')\n if (accessToken) return await handleOAuthCallback(client, params, accessToken)\n\n const confirmationToken = params.get('confirmation_token')\n if (confirmationToken) return await handleConfirmationCallback(client, confirmationToken)\n\n const recoveryToken = params.get('recovery_token')\n if (recoveryToken) return await handleRecoveryCallback(client, recoveryToken)\n\n const inviteToken = params.get('invite_token')\n if (inviteToken) return handleInviteCallback(inviteToken)\n\n const emailChangeToken = params.get('email_change_token')\n if (emailChangeToken) return await handleEmailChangeCallback(client, emailChangeToken)\n\n return null\n } catch (error) {\n if (error instanceof AuthError) throw error\n throw AuthError.from(error)\n }\n}\n\nconst handleOAuthCallback = async (\n client: GoTrue,\n params: URLSearchParams,\n accessToken: string,\n): Promise<CallbackResult> => {\n const refreshToken = params.get('refresh_token') ?? ''\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: refreshToken,\n },\n persistSession,\n )\n setBrowserAuthCookies(accessToken, refreshToken || undefined)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent(AUTH_EVENTS.LOGIN, user)\n return { type: 'oauth', user }\n}\n\nconst handleConfirmationCallback = async (client: GoTrue, token: string): Promise<CallbackResult> => {\n const gotrueUser = await client.confirm(token, persistSession)\n const jwt = await gotrueUser.jwt()\n setBrowserAuthCookies(jwt)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent(AUTH_EVENTS.LOGIN, user)\n return { type: 'confirmation', user }\n}\n\nconst handleRecoveryCallback = async (client: GoTrue, token: string): Promise<CallbackResult> => {\n const gotrueUser = await client.recover(token, persistSession)\n const jwt = await gotrueUser.jwt()\n setBrowserAuthCookies(jwt)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent(AUTH_EVENTS.RECOVERY, user)\n return { type: 'recovery', user }\n}\n\nconst handleInviteCallback = (token: string): CallbackResult => {\n clearHash()\n return { type: 'invite', user: null, token }\n}\n\nconst handleEmailChangeCallback = async (client: GoTrue, emailChangeToken: string): Promise<CallbackResult> => {\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(() => ({}))) as GoTrueErrorBody\n throw new AuthError(\n errorBody.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(AUTH_EVENTS.USER_UPDATED, user)\n return { type: 'email_change', user }\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<import('./user.js').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 decoded = decodeJwtPayload(accessToken)\n const expiresAt = decoded?.exp ?? Math.floor(Date.now() / 1000) + 3600\n const expiresIn = Math.max(0, expiresAt - Math.floor(Date.now() / 1000))\n\n let gotrueUser\n try {\n gotrueUser = await client.createUser(\n {\n access_token: accessToken,\n token_type: 'bearer',\n expires_in: expiresIn,\n expires_at: expiresAt,\n refresh_token: refreshToken,\n },\n persistSession,\n )\n } catch {\n deleteBrowserAuthCookies()\n return null\n }\n\n const user = toUser(gotrueUser)\n emitAuthEvent(AUTH_EVENTS.LOGIN, user)\n return user\n}\n","import type { UserData, User as GoTrueUser } from 'gotrue-js'\n\nimport type { UserUpdates, GoTrueErrorBody } from './types.js'\nimport type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getClient, isBrowser, IDENTITY_PATH } from './environment.js'\nimport { persistSession, hydrateSession } from './auth.js'\nimport { AUTH_EVENTS, emitAuthEvent } from './events.js'\nimport { AuthError } from './errors.js'\n\n/**\n * Returns the current gotrue-js user, attempting hydration from cookies if\n * no in-memory session exists. Throws if no user can be resolved.\n */\nconst resolveCurrentUser = async (): Promise<GoTrueUser> => {\n const client = getClient()\n\n let currentUser = client.currentUser()\n if (!currentUser && isBrowser()) {\n try {\n await hydrateSession()\n } catch {\n // hydration failed (e.g. expired cookie, network error) — fall through\n }\n currentUser = client.currentUser()\n }\n if (!currentUser) throw new AuthError('No user is currently logged in')\n\n return currentUser\n}\n\n/**\n * Sends a password recovery email to the given address.\n *\n * @throws {AuthError} On network failure or if the request is rejected.\n */\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 AuthError.from(error)\n }\n}\n\n/**\n * Redeems a recovery token and sets a new password. Logs the user in on success.\n *\n * @throws {AuthError} If the token is invalid, expired, or the update fails.\n */\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 // Emits LOGIN because the recovery is fully complete\n emitAuthEvent(AUTH_EVENTS.LOGIN, user)\n return user\n } catch (error) {\n throw AuthError.from(error)\n }\n}\n\n/**\n * Confirms an email address using the token from a confirmation email. Logs the user in on success.\n *\n * @throws {AuthError} If the token is invalid or expired.\n */\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(AUTH_EVENTS.LOGIN, user)\n return user\n } catch (error) {\n throw AuthError.from(error)\n }\n}\n\n/**\n * Accepts an invite token and sets a password for the new account. Logs the user in on success.\n *\n * @throws {AuthError} If the token is invalid or expired.\n */\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(AUTH_EVENTS.LOGIN, user)\n return user\n } catch (error) {\n throw AuthError.from(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. Browser only.\n *\n * @throws {AuthError} If called on the server, no user is logged in, or the token is invalid.\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 resolveCurrentUser()\n\n try {\n const jwt = await currentUser.jwt()\n const identityUrl = `${window.location.origin}${IDENTITY_PATH}`\n\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(() => ({}))) as GoTrueErrorBody\n throw new AuthError(errorBody.msg || `Email change verification failed (${res.status})`, res.status)\n }\n\n const userData = (await res.json()) as UserData\n const user = toUser(userData)\n emitAuthEvent(AUTH_EVENTS.USER_UPDATED, user)\n return user\n } catch (error) {\n if (error instanceof AuthError) throw error\n throw AuthError.from(error)\n }\n}\n\n/**\n * Updates the current user's email, password, or user metadata.\n * Auto-hydrates from auth cookies if no browser session exists.\n *\n * @param updates - Fields to update. Pass `email` or `password` to change credentials,\n * or `data` to update user metadata (e.g., `{ data: { full_name: 'New Name' } }`).\n * @throws {AuthError} If no user is logged in or the update fails.\n */\nexport const updateUser = async (updates: UserUpdates): Promise<User> => {\n const currentUser = await resolveCurrentUser()\n\n try {\n const updatedUser = await currentUser.update(updates)\n const user = toUser(updatedUser)\n emitAuthEvent(AUTH_EVENTS.USER_UPDATED, user)\n return user\n } catch (error) {\n throw AuthError.from(error)\n }\n}\n"],"mappings":"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","names":["jwt"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@netlify/identity",
|
|
3
|
-
"version": "0.1.1-alpha.
|
|
3
|
+
"version": "0.1.1-alpha.27",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Add authentication to your Netlify site with a few lines of code",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
},
|
|
64
64
|
"author": "Netlify Inc.",
|
|
65
65
|
"devDependencies": {
|
|
66
|
-
"@types/node": "^
|
|
66
|
+
"@types/node": "^22.0.0",
|
|
67
67
|
"eslint": "^9.0.0",
|
|
68
68
|
"husky": "^9.1.7",
|
|
69
69
|
"jsdom": "^28.1.0",
|