@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 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
- ### How this library relates to other Netlify auth packages
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.URL) {
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.URL;
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
- return match ? decodeURIComponent(match[1]) : null;
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 new AuthError(error.message, void 0, { cause: error });
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 new AuthError(error.message, void 0, { cause: error });
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 new AuthError(error.message, void 0, { cause: error });
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 new AuthError(error.message, void 0, { cause: error });
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 new AuthError(error.message, void 0, { cause: error });
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 new AuthError(error.message, void 0, { cause: error });
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 new AuthError(error.message, void 0, { cause: error });
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
- const gotrueUser = await client.createUser(
654
- {
655
- access_token: accessToken,
656
- token_type: "bearer",
657
- expires_in: expiresIn,
658
- expires_at: expiresAt,
659
- refresh_token: refreshToken
660
- },
661
- persistSession
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 new AuthError(error.message, void 0, { cause: error });
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 new AuthError(error.message, void 0, { cause: error });
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 new AuthError(error.message, void 0, { cause: error });
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 new AuthError(error.message, void 0, { cause: error });
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 new AuthError(error.message, void 0, { cause: error });
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 new AuthError(error.message, void 0, { cause: error });
774
+ throw AuthError.from(error);
760
775
  }
761
776
  };
762
777
  // Annotate the CommonJS export names for ESM import in node:
@@ -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
@@ -186,6 +186,7 @@ declare class AuthError extends Error {
186
186
  constructor(message: string, status?: number, options?: {
187
187
  cause?: unknown;
188
188
  });
189
+ static from(error: unknown): AuthError;
189
190
  }
190
191
  declare class MissingIdentityError extends Error {
191
192
  name: string;
package/dist/index.d.ts CHANGED
@@ -186,6 +186,7 @@ declare class AuthError extends Error {
186
186
  constructor(message: string, status?: number, options?: {
187
187
  cause?: unknown;
188
188
  });
189
+ static from(error: unknown): AuthError;
189
190
  }
190
191
  declare class MissingIdentityError extends Error {
191
192
  name: string;
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.URL) {
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.URL;
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
- return match ? decodeURIComponent(match[1]) : null;
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 new AuthError(error.message, void 0, { cause: error });
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 new AuthError(error.message, void 0, { cause: error });
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 new AuthError(error.message, void 0, { cause: error });
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 new AuthError(error.message, void 0, { cause: error });
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 new AuthError(error.message, void 0, { cause: error });
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 new AuthError(error.message, void 0, { cause: error });
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 new AuthError(error.message, void 0, { cause: error });
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
- const gotrueUser = await client.createUser(
606
- {
607
- access_token: accessToken,
608
- token_type: "bearer",
609
- expires_in: expiresIn,
610
- expires_at: expiresAt,
611
- refresh_token: refreshToken
612
- },
613
- persistSession
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 new AuthError(error.message, void 0, { cause: error });
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 new AuthError(error.message, void 0, { cause: error });
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 new AuthError(error.message, void 0, { cause: error });
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 new AuthError(error.message, void 0, { cause: error });
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 new AuthError(error.message, void 0, { cause: error });
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 new AuthError(error.message, void 0, { cause: error });
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.25",
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": "^25.3.3",
66
+ "@types/node": "^22.0.0",
67
67
  "eslint": "^9.0.0",
68
68
  "husky": "^9.1.7",
69
69
  "jsdom": "^28.1.0",