@netlify/identity 0.1.1-alpha.3 → 0.1.1-alpha.4

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
@@ -196,9 +196,19 @@ Accepts an invite token and sets a password for the new account. Logs the user i
196
196
  verifyEmailChange(token: string): Promise<User>
197
197
  ```
198
198
 
199
- Verifies an email change using the token from a verification email. Requires an active session.
199
+ Verifies an email change using the token from a verification email.
200
200
 
201
- **Throws:** `MissingIdentityError` if Identity is not configured. `AuthError` if no user is logged in, or the token is invalid.
201
+ **Throws:** `MissingIdentityError` if Identity is not configured. `AuthError` if the token is invalid.
202
+
203
+ #### `recoverPassword`
204
+
205
+ ```ts
206
+ recoverPassword(token: string, newPassword: string): Promise<User>
207
+ ```
208
+
209
+ Redeems a recovery token and sets a new password. Logs the user in on success.
210
+
211
+ **Throws:** `MissingIdentityError` if Identity is not configured. `AuthError` if the token is invalid or expired.
202
212
 
203
213
  #### `updateUser`
204
214
 
@@ -286,12 +296,10 @@ interface CallbackResult {
286
296
  }
287
297
  ```
288
298
 
289
- The `token` field is only present when the callback cannot complete the flow automatically:
299
+ The `token` field is only present for `invite` callbacks, where the user hasn't set a password yet. Pass `token` to `acceptInvite(token, password)` to finish.
290
300
 
291
- - **`invite`**: The user hasn't set a password yet. Pass `token` to `acceptInvite(token, password)` to finish.
292
- - **`email_change`** (no active session): The user needs to log in first, then call `verifyEmailChange(token)`.
301
+ For all other types (`oauth`, `confirmation`, `recovery`, `email_change`), the user is logged in directly and `token` is not set.
293
302
 
294
- For all other types (`oauth`, `confirmation`, `recovery`), the user is logged in directly and `token` is not set.
295
303
 
296
304
  ### Errors
297
305
 
package/dist/index.cjs CHANGED
@@ -43,6 +43,7 @@ __export(index_exports, {
43
43
  logout: () => logout,
44
44
  oauthLogin: () => oauthLogin,
45
45
  onAuthChange: () => onAuthChange,
46
+ recoverPassword: () => recoverPassword,
46
47
  requestPasswordRecovery: () => requestPasswordRecovery,
47
48
  signup: () => signup,
48
49
  updateUser: () => updateUser,
@@ -75,6 +76,7 @@ var MissingIdentityError = class extends Error {
75
76
  };
76
77
 
77
78
  // src/environment.ts
79
+ var IDENTITY_PATH = "/.netlify/identity";
78
80
  var goTrueClient = null;
79
81
  var cachedApiUrl;
80
82
  var warnedMissingUrl = false;
@@ -82,13 +84,13 @@ var isBrowser = () => typeof window !== "undefined" && typeof window.location !=
82
84
  var discoverApiUrl = () => {
83
85
  if (cachedApiUrl !== void 0) return cachedApiUrl;
84
86
  if (isBrowser()) {
85
- cachedApiUrl = `${window.location.origin}/.netlify/identity`;
87
+ cachedApiUrl = `${window.location.origin}${IDENTITY_PATH}`;
86
88
  } else {
87
89
  const identityContext = getIdentityContext();
88
90
  if (identityContext?.url) {
89
91
  cachedApiUrl = identityContext.url;
90
92
  } else if (globalThis.Netlify?.context?.url) {
91
- cachedApiUrl = new URL("/.netlify/identity", globalThis.Netlify.context.url).href;
93
+ cachedApiUrl = new URL(IDENTITY_PATH, globalThis.Netlify.context.url).href;
92
94
  }
93
95
  }
94
96
  return cachedApiUrl ?? null;
@@ -115,14 +117,14 @@ var getClient = () => {
115
117
  };
116
118
  var getIdentityContext = () => {
117
119
  const identityContext = globalThis.netlifyIdentityContext;
118
- if (identityContext?.url && typeof identityContext.url === "string") {
120
+ if (identityContext?.url) {
119
121
  return {
120
122
  url: identityContext.url,
121
- token: typeof identityContext.token === "string" ? identityContext.token : void 0
123
+ token: identityContext.token
122
124
  };
123
125
  }
124
126
  if (globalThis.Netlify?.context?.url) {
125
- return { url: new URL("/.netlify/identity", globalThis.Netlify.context.url).href };
127
+ return { url: new URL(IDENTITY_PATH, globalThis.Netlify.context.url).href };
126
128
  }
127
129
  return null;
128
130
  };
@@ -152,8 +154,8 @@ var claimsToUser = (claims) => {
152
154
  const userMeta = claims.user_metadata ?? {};
153
155
  const name = userMeta.full_name || userMeta.name;
154
156
  return {
155
- id: typeof claims.sub === "string" ? claims.sub : "",
156
- email: typeof claims.email === "string" ? claims.email : void 0,
157
+ id: claims.sub ?? "",
158
+ email: claims.email,
157
159
  provider: toAuthProvider(appMeta.provider),
158
160
  name: typeof name === "string" ? name : void 0,
159
161
  metadata: userMeta
@@ -167,17 +169,15 @@ var getUser = () => {
167
169
  return toUser(currentUser);
168
170
  }
169
171
  const identityContext = globalThis.netlifyIdentityContext;
170
- if (!identityContext) return null;
171
- const claims = identityContext.user ?? (identityContext.sub ? identityContext : null);
172
- if (!claims) return null;
173
- return claimsToUser(claims);
172
+ if (!identityContext?.user) return null;
173
+ return claimsToUser(identityContext.user);
174
174
  };
175
175
  var isAuthenticated = () => getUser() !== null;
176
176
 
177
177
  // src/config.ts
178
178
  var getIdentityConfig = () => {
179
179
  if (isBrowser()) {
180
- return { url: `${window.location.origin}/.netlify/identity` };
180
+ return { url: `${window.location.origin}${IDENTITY_PATH}` };
181
181
  }
182
182
  return getIdentityContext();
183
183
  };
@@ -433,12 +433,7 @@ var handleAuthCallback = async () => {
433
433
  }
434
434
  const emailChangeToken = params.get("email_change_token");
435
435
  if (emailChangeToken) {
436
- const currentUser = client.currentUser();
437
- if (!currentUser) {
438
- clearHash();
439
- return { type: "email_change", user: null, token: emailChangeToken };
440
- }
441
- const gotrueUser = await currentUser.update({ email_change_token: emailChangeToken });
436
+ const gotrueUser = await client.verify("email_change", emailChangeToken, persistSession);
442
437
  const user = toUser(gotrueUser);
443
438
  clearHash();
444
439
  emitAuthEvent("user_updated", user);
@@ -462,6 +457,18 @@ var requestPasswordRecovery = async (email) => {
462
457
  throw new AuthError(error.message, void 0, { cause: error });
463
458
  }
464
459
  };
460
+ var recoverPassword = async (token, newPassword) => {
461
+ const client = getClient();
462
+ try {
463
+ const gotrueUser = await client.recover(token, persistSession);
464
+ const updatedUser = await gotrueUser.update({ password: newPassword });
465
+ const user = toUser(updatedUser);
466
+ emitAuthEvent("login", user);
467
+ return user;
468
+ } catch (error) {
469
+ throw new AuthError(error.message, void 0, { cause: error });
470
+ }
471
+ };
465
472
  var confirmEmail = async (token) => {
466
473
  const client = getClient();
467
474
  try {
@@ -486,10 +493,8 @@ var acceptInvite = async (token, password) => {
486
493
  };
487
494
  var verifyEmailChange = async (token) => {
488
495
  const client = getClient();
489
- const currentUser = client.currentUser();
490
- if (!currentUser) throw new AuthError("No user is currently logged in");
491
496
  try {
492
- const gotrueUser = await currentUser.update({ email_change_token: token });
497
+ const gotrueUser = await client.verify("email_change", token, persistSession);
493
498
  const user = toUser(gotrueUser);
494
499
  emitAuthEvent("user_updated", user);
495
500
  return user;
@@ -525,6 +530,7 @@ var updateUser = async (updates) => {
525
530
  logout,
526
531
  oauthLogin,
527
532
  onAuthChange,
533
+ recoverPassword,
528
534
  requestPasswordRecovery,
529
535
  signup,
530
536
  updateUser,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/types.ts","../src/environment.ts","../src/errors.ts","../src/user.ts","../src/config.ts","../src/auth.ts","../src/account.ts"],"sourcesContent":["export type { User } from './user.js'\nexport { getUser, isAuthenticated } from './user.js'\nexport { getIdentityConfig, getSettings } from './config.js'\nexport type { AuthCallback, AuthEvent, CallbackResult } from './auth.js'\nexport { login, signup, logout, oauthLogin, onAuthChange, handleAuthCallback } from './auth.js'\nexport { AuthError, MissingIdentityError } from './errors.js'\nexport type { AppMetadata, AuthProvider, IdentityConfig, Settings } from './types.js'\nexport { requestPasswordRecovery, confirmEmail, acceptInvite, verifyEmailChange, updateUser } from './account.js'\n","export const AUTH_PROVIDERS = ['google', 'github', 'gitlab', 'bitbucket', 'facebook', 'saml', 'email'] as const\nexport type AuthProvider = (typeof AUTH_PROVIDERS)[number]\n\nexport interface AppMetadata {\n provider: AuthProvider\n roles?: string[]\n [key: string]: unknown\n}\n\nexport interface IdentityConfig {\n url: string\n token?: string // this is an operator token, only available on the server\n}\n\nexport interface Settings {\n autoconfirm: boolean\n disableSignup: boolean\n providers: Record<AuthProvider, boolean>\n}\n\nexport interface NetlifyCookies {\n get(name: string): string | undefined\n set(options: {\n name: string\n value: string\n httpOnly: boolean\n secure: boolean\n path: string\n sameSite: string\n }): void\n delete(name: string): void\n}\n","import GoTrue from 'gotrue-js'\n\nimport type { IdentityConfig } from './types.js'\nimport { MissingIdentityError } from './errors.js'\n\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` + `/.netlify/identity`.\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}/.netlify/identity`\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('/.netlify/identity', globalThis.Netlify.context.url).href\n }\n }\n\n return cachedApiUrl ?? null\n}\n\n/**\n * Returns (and lazily creates) a singleton gotrue-js client.\n * Returns `null` and logs a warning if no identity URL can be discovered.\n */\nexport const getGoTrueClient = (): GoTrue | null => {\n if (goTrueClient) return goTrueClient\n\n const apiUrl = discoverApiUrl()\n if (!apiUrl) {\n if (!warnedMissingUrl) {\n console.warn(\n '@netlify/identity: Could not determine the Identity endpoint URL. ' +\n 'Make sure your site has Netlify Identity enabled, or run your app with `netlify dev`.',\n )\n warnedMissingUrl = true\n }\n return null\n }\n\n goTrueClient = new GoTrue({ APIUrl: apiUrl, setCookie: isBrowser() })\n return goTrueClient\n}\n\n/**\n * Returns the singleton gotrue-js client, or throws if Identity is not configured.\n */\nexport const getClient = (): GoTrue => {\n const client = getGoTrueClient()\n if (!client) throw new MissingIdentityError()\n return client\n}\n\n/**\n * Reads the server-side identity context set by the Netlify bootstrap.\n * Returns `null` outside the Netlify serverless environment.\n */\nexport const getIdentityContext = (): IdentityConfig | null => {\n // TODO(kh): After Stargate deploys EX-1764, netlifyIdentityContext will have\n // typed `url` and `token` fields. Remove the typeof guards and use direct access.\n // https://linear.app/netlify/issue/EX-1764/identity-stargate-needs-to-set-identity-url-and-providertoken\n const identityContext = globalThis.netlifyIdentityContext\n if (identityContext?.url && typeof identityContext.url === 'string') {\n return {\n url: identityContext.url,\n token: typeof identityContext.token === 'string' ? identityContext.token : undefined,\n }\n }\n\n if (globalThis.Netlify?.context?.url) {\n return { url: new URL('/.netlify/identity', globalThis.Netlify.context.url).href }\n }\n\n return null\n}\n\n/** Reset cached state for tests. */\nexport const resetTestGoTrueClient = (): void => {\n goTrueClient = null\n cachedApiUrl = undefined\n warnedMissingUrl = false\n}\n","export class AuthError extends Error {\n override name = 'AuthError'\n status?: number\n declare cause?: unknown\n\n constructor(message: string, status?: number, options?: { cause?: unknown }) {\n super(message)\n this.status = status\n if (options && 'cause' in options) {\n this.cause = options.cause\n }\n }\n}\n\nexport class MissingIdentityError extends Error {\n override name = 'MissingIdentityError'\n\n constructor(message = 'Identity is not available in this environment') {\n super(message)\n }\n}\n","import type { UserData } from 'gotrue-js'\nimport { AUTH_PROVIDERS, type AuthProvider } from './types.js'\nimport { getGoTrueClient, isBrowser } from './environment.js'\n\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 raw JWT claims from the identity header into a User.\n * JWT claims use a different shape than the gotrue-js UserData class.\n */\nconst claimsToUser = (claims: Record<string, unknown>): User => {\n const appMeta = (claims.app_metadata ?? {}) as Record<string, unknown>\n const userMeta = (claims.user_metadata ?? {}) as Record<string, unknown>\n const name = userMeta.full_name || userMeta.name\n\n return {\n id: typeof claims.sub === 'string' ? claims.sub : '',\n email: typeof claims.email === 'string' ? claims.email : undefined,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n metadata: userMeta,\n }\n}\n\n/**\n * Returns the currently authenticated user, or `null` if not logged in.\n * Synchronous. Never throws.\n */\nexport const getUser = (): User | null => {\n if (isBrowser()) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser() ?? null\n if (!currentUser) return null\n return toUser(currentUser)\n }\n\n const identityContext = globalThis.netlifyIdentityContext\n if (!identityContext) return null\n\n const claims = identityContext.user ?? (identityContext.sub ? identityContext : null)\n if (!claims) return null\n return claimsToUser(claims as Record<string, unknown>)\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 { AuthError } from './errors.js'\nimport { getClient, getIdentityContext, isBrowser } from './environment.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}/.netlify/identity` }\n }\n\n return getIdentityContext()\n}\n\n/**\n * Fetches the GoTrue `/settings` endpoint.\n * Throws `MissingIdentityError` if Identity is not configured.\n * Throws `AuthError` if the endpoint is unreachable.\n */\nexport const getSettings = async (): Promise<Settings> => {\n const client = getClient()\n\n try {\n const raw = await client.settings()\n const external: Partial<Record<AuthProvider, boolean>> = raw.external ?? {}\n return {\n autoconfirm: raw.autoconfirm,\n disableSignup: raw.disable_signup,\n providers: {\n google: external.google ?? false,\n github: external.github ?? false,\n gitlab: external.gitlab ?? false,\n bitbucket: external.bitbucket ?? false,\n facebook: external.facebook ?? false,\n email: external.email ?? false,\n saml: external.saml ?? false,\n },\n }\n } catch (err) {\n throw new AuthError(err instanceof Error ? err.message : 'Failed to fetch identity settings', 502, { cause: err })\n }\n}\n","import type { UserData } from 'gotrue-js'\n\nimport type { AppMetadata, NetlifyCookies } from './types.js'\n\nexport type AuthEvent = 'login' | 'logout' | 'token_refresh' | 'user_updated'\nimport type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getGoTrueClient, getClient, getIdentityContext, isBrowser } from './environment.js'\nimport { AuthError } from './errors.js'\n\nconst getCookies = (): NetlifyCookies => {\n const cookies = globalThis.Netlify?.context?.cookies\n if (!cookies) {\n throw new AuthError('Server-side auth requires Netlify Functions runtime')\n }\n return cookies\n}\n\nconst getServerIdentityUrl = (): string => {\n const ctx = getIdentityContext()\n if (!ctx?.url) {\n throw new AuthError('Could not determine the Identity endpoint URL on the server')\n }\n return ctx.url\n}\n\nexport interface JWTClaims {\n sub: string // UUID\n email: string\n exp: number\n iat: number\n aud: string\n app_metadata: AppMetadata\n user_metadata: Record<string, unknown>\n}\n\nexport type AuthCallback = (event: AuthEvent, user: User | null) => void\n\n/** Persist the session to localStorage so it survives page reloads. */\nexport const persistSession = true\n\nconst listeners = new Set<AuthCallback>()\n\nexport const emitAuthEvent = (event: AuthEvent, user: User | null): void => {\n for (const listener of listeners) {\n listener(event, user)\n }\n}\n\nlet storageListenerAttached = false\n\nconst attachStorageListener = (): void => {\n if (storageListenerAttached) return\n storageListenerAttached = true\n\n window.addEventListener('storage', (event: StorageEvent) => {\n if (event.key !== 'gotrue.user') return\n\n if (event.newValue) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser()\n emitAuthEvent('login', currentUser ? toUser(currentUser) : null)\n } else {\n emitAuthEvent('logout', null)\n }\n })\n}\n\n/**\n * Subscribes to auth state changes (login, logout, token refresh, user updates).\n * Returns an unsubscribe function. No-op on the server.\n */\nexport const onAuthChange = (callback: AuthCallback): (() => void) => {\n if (!isBrowser()) {\n return () => {}\n }\n\n listeners.add(callback)\n attachStorageListener()\n\n return () => {\n listeners.delete(callback)\n }\n}\n\n/** Logs in with email and password. Works in both browser and server contexts. */\nexport const login = async (email: string, password: string): Promise<User> => {\n if (!isBrowser()) {\n const identityUrl = getServerIdentityUrl()\n const cookies = getCookies()\n\n const body = new URLSearchParams({\n grant_type: 'password',\n username: email,\n password,\n })\n\n let res: Response\n try {\n res = await fetch(`${identityUrl}/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: body.toString(),\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n\n if (!res.ok) {\n const errorBody = await res.json().catch(() => ({}))\n throw new AuthError(\n (errorBody as Record<string, string>).msg ||\n (errorBody as Record<string, string>).error_description ||\n `Login failed (${res.status})`,\n res.status,\n )\n }\n\n const data = (await res.json()) as Record<string, unknown>\n const accessToken = data.access_token as string\n const userData = data as unknown as UserData\n const user = toUser(userData)\n\n cookies.set({\n name: 'nf_jwt',\n value: accessToken,\n httpOnly: true,\n secure: true,\n path: '/',\n sameSite: 'Lax',\n })\n\n return user\n }\n\n const client = getClient()\n\n try {\n const gotrueUser = await client.login(email, password, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Creates a new account. Emits 'login' if autoconfirm is enabled. Works in both browser and server contexts. */\nexport const signup = async (email: string, password: string, data?: Record<string, unknown>): Promise<User> => {\n if (!isBrowser()) {\n const identityUrl = getServerIdentityUrl()\n const cookies = getCookies()\n\n let res: Response\n try {\n res = await fetch(`${identityUrl}/signup`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ email, password, data }),\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n\n if (!res.ok) {\n const errorBody = await res.json().catch(() => ({}))\n throw new AuthError((errorBody as Record<string, string>).msg || `Signup failed (${res.status})`, res.status)\n }\n\n const responseData = (await res.json()) as UserData\n const user = toUser(responseData)\n\n if (responseData.confirmed_at) {\n const accessToken = (responseData as unknown as Record<string, unknown>).access_token as string | undefined\n if (accessToken) {\n cookies.set({\n name: 'nf_jwt',\n value: accessToken,\n httpOnly: true,\n secure: true,\n path: '/',\n sameSite: 'Lax',\n })\n }\n }\n\n return user\n }\n\n const client = getClient()\n\n try {\n const response = await client.signup(email, password, data)\n const user = toUser(response as UserData)\n if (response.confirmed_at) {\n emitAuthEvent('login', user)\n }\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Logs out the current user and clears the session. Works in both browser and server contexts. */\nexport const logout = async (): Promise<void> => {\n if (!isBrowser()) {\n const identityUrl = getServerIdentityUrl()\n const cookies = getCookies()\n\n const jwt = cookies.get('nf_jwt')\n if (jwt) {\n try {\n await fetch(`${identityUrl}/logout`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}` },\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n }\n\n cookies.delete('nf_jwt')\n return\n }\n\n const client = getClient()\n\n try {\n const currentUser = client.currentUser()\n if (currentUser) {\n await currentUser.logout()\n }\n emitAuthEvent('logout', null)\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Redirects to an OAuth provider. Always throws (the page navigates away). Browser only. */\nexport const oauthLogin = (provider: string): never => {\n if (!isBrowser()) {\n throw new Error('oauthLogin() is only available in the browser')\n }\n const client = getClient()\n\n window.location.href = client.loginExternalUrl(provider)\n throw new Error('Redirecting to OAuth provider')\n}\n\nexport interface CallbackResult {\n type: 'oauth' | 'confirmation' | 'recovery' | 'invite' | 'email_change'\n user: User | null\n token?: string\n}\n\n/**\n * Processes the URL hash after an OAuth redirect, email confirmation, password\n * recovery, invite acceptance, or email change. Call on page load. Browser only.\n * Returns `null` if the hash contains no auth parameters.\n */\nexport const handleAuthCallback = async (): Promise<CallbackResult | null> => {\n if (!isBrowser()) return null\n\n const hash = window.location.hash.substring(1)\n if (!hash) return null\n\n const client = getClient()\n\n try {\n const params = new URLSearchParams(hash)\n\n const accessToken = params.get('access_token')\n if (accessToken) {\n const gotrueUser = await client.createUser(\n {\n access_token: accessToken,\n token_type: (params.get('token_type') as 'bearer') ?? 'bearer',\n expires_in: Number(params.get('expires_in')),\n expires_at: Number(params.get('expires_at')),\n refresh_token: params.get('refresh_token') ?? '',\n },\n persistSession,\n )\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'oauth', user }\n }\n\n const confirmationToken = params.get('confirmation_token')\n if (confirmationToken) {\n const gotrueUser = await client.confirm(confirmationToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'confirmation', user }\n }\n\n const recoveryToken = params.get('recovery_token')\n if (recoveryToken) {\n const gotrueUser = await client.recover(recoveryToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'recovery', user }\n }\n\n const inviteToken = params.get('invite_token')\n if (inviteToken) {\n clearHash()\n return { type: 'invite', user: null, token: inviteToken }\n }\n\n const emailChangeToken = params.get('email_change_token')\n if (emailChangeToken) {\n const currentUser = client.currentUser()\n if (!currentUser) {\n clearHash()\n return { type: 'email_change', user: null, token: emailChangeToken }\n }\n const gotrueUser = await currentUser.update({ email_change_token: emailChangeToken })\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('user_updated', user)\n return { type: 'email_change', user }\n }\n\n return null\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\nconst clearHash = (): void => {\n history.replaceState(null, '', window.location.pathname + window.location.search)\n}\n","import type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getClient } from './environment.js'\nimport { emitAuthEvent, persistSession } from './auth.js'\nimport { AuthError } from './errors.js'\n\n/** Sends a password recovery email to the given address. */\nexport const requestPasswordRecovery = async (email: string): Promise<void> => {\n const client = getClient()\n\n try {\n await client.requestPasswordRecovery(email)\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Confirms an email address using the token from a confirmation email. Logs the user in on success. */\nexport const confirmEmail = async (token: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.confirm(token, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Accepts an invite token and sets a password for the new account. Logs the user in on success. */\nexport const acceptInvite = async (token: string, password: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.acceptInvite(token, password, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Verifies an email change using the token from a verification email. Requires an active session. */\nexport const verifyEmailChange = async (token: string): Promise<User> => {\n const client = getClient()\n\n const currentUser = client.currentUser()\n if (!currentUser) throw new AuthError('No user is currently logged in')\n\n try {\n const gotrueUser = await currentUser.update({ email_change_token: token })\n const user = toUser(gotrueUser)\n emitAuthEvent('user_updated', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Updates the current user's metadata or credentials. Requires an active session. */\nexport const updateUser = async (updates: Record<string, unknown>): Promise<User> => {\n const client = getClient()\n\n const currentUser = client.currentUser()\n if (!currentUser) throw new AuthError('No user is currently logged in')\n\n try {\n const updatedUser = await currentUser.update(updates)\n const user = toUser(updatedUser)\n emitAuthEvent('user_updated', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n"],"mappings":"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","names":["GoTrue"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/types.ts","../src/environment.ts","../src/errors.ts","../src/user.ts","../src/config.ts","../src/auth.ts","../src/account.ts"],"sourcesContent":["export type { User } from './user.js'\nexport { getUser, isAuthenticated } from './user.js'\nexport { getIdentityConfig, getSettings } from './config.js'\nexport type { AuthCallback, AuthEvent, CallbackResult } from './auth.js'\nexport { login, signup, logout, oauthLogin, onAuthChange, handleAuthCallback } from './auth.js'\nexport { AuthError, MissingIdentityError } from './errors.js'\nexport type { AppMetadata, AuthProvider, IdentityConfig, Settings } from './types.js'\nexport {\n requestPasswordRecovery,\n recoverPassword,\n confirmEmail,\n acceptInvite,\n verifyEmailChange,\n updateUser,\n} from './account.js'\n","export const AUTH_PROVIDERS = ['google', 'github', 'gitlab', 'bitbucket', 'facebook', 'saml', 'email'] as const\nexport type AuthProvider = (typeof AUTH_PROVIDERS)[number]\n\nexport interface AppMetadata {\n provider: AuthProvider\n roles?: string[]\n [key: string]: unknown\n}\n\nexport interface IdentityConfig {\n url: string\n token?: string // this is an operator token, only available on the server\n}\n\nexport interface Settings {\n autoconfirm: boolean\n disableSignup: boolean\n providers: Record<AuthProvider, boolean>\n}\n\nexport interface NetlifyCookies {\n get(name: string): string | undefined\n set(options: {\n name: string\n value: string\n httpOnly: boolean\n secure: boolean\n path: string\n sameSite: string\n }): void\n delete(name: string): void\n}\n","import GoTrue from 'gotrue-js'\n\nimport type { IdentityConfig } from './types.js'\nimport { MissingIdentityError } from './errors.js'\n\nexport const IDENTITY_PATH = '/.netlify/identity'\n\nlet goTrueClient: GoTrue | null = null\nlet cachedApiUrl: string | null | undefined\nlet warnedMissingUrl = false\n\nexport const isBrowser = (): boolean => typeof window !== 'undefined' && typeof window.location !== 'undefined'\n\n/**\n * Discovers and caches the GoTrue API URL.\n *\n * Browser: uses `window.location.origin` + IDENTITY_PATH.\n * Server: reads from `globalThis.netlifyIdentityContext`.\n */\nconst discoverApiUrl = (): string | null => {\n if (cachedApiUrl !== undefined) return cachedApiUrl\n\n if (isBrowser()) {\n cachedApiUrl = `${window.location.origin}${IDENTITY_PATH}`\n } else {\n const identityContext = getIdentityContext()\n if (identityContext?.url) {\n cachedApiUrl = identityContext.url\n } else if (globalThis.Netlify?.context?.url) {\n cachedApiUrl = new URL(IDENTITY_PATH, globalThis.Netlify.context.url).href\n }\n }\n\n return cachedApiUrl ?? null\n}\n\n/**\n * Returns (and lazily creates) a singleton gotrue-js client.\n * Returns `null` and logs a warning if no identity URL can be discovered.\n */\nexport const getGoTrueClient = (): GoTrue | null => {\n if (goTrueClient) return goTrueClient\n\n const apiUrl = discoverApiUrl()\n if (!apiUrl) {\n if (!warnedMissingUrl) {\n console.warn(\n '@netlify/identity: Could not determine the Identity endpoint URL. ' +\n 'Make sure your site has Netlify Identity enabled, or run your app with `netlify dev`.',\n )\n warnedMissingUrl = true\n }\n return null\n }\n\n goTrueClient = new GoTrue({ APIUrl: apiUrl, setCookie: isBrowser() })\n return goTrueClient\n}\n\n/**\n * Returns the singleton gotrue-js client, or throws if Identity is not configured.\n */\nexport const getClient = (): GoTrue => {\n const client = getGoTrueClient()\n if (!client) throw new MissingIdentityError()\n return client\n}\n\n/**\n * Reads the server-side identity context set by the Netlify bootstrap.\n * Returns `null` outside the Netlify serverless environment.\n */\nexport const getIdentityContext = (): IdentityConfig | null => {\n const identityContext = globalThis.netlifyIdentityContext\n if (identityContext?.url) {\n return {\n url: identityContext.url,\n token: identityContext.token,\n }\n }\n\n if (globalThis.Netlify?.context?.url) {\n return { url: new URL(IDENTITY_PATH, globalThis.Netlify.context.url).href }\n }\n\n return null\n}\n\n/** Reset cached state for tests. */\nexport const resetTestGoTrueClient = (): void => {\n goTrueClient = null\n cachedApiUrl = undefined\n warnedMissingUrl = false\n}\n","export class AuthError extends Error {\n override name = 'AuthError'\n status?: number\n declare cause?: unknown\n\n constructor(message: string, status?: number, options?: { cause?: unknown }) {\n super(message)\n this.status = status\n if (options && 'cause' in options) {\n this.cause = options.cause\n }\n }\n}\n\nexport class MissingIdentityError extends Error {\n override name = 'MissingIdentityError'\n\n constructor(message = 'Identity is not available in this environment') {\n super(message)\n }\n}\n","import type { UserData } from 'gotrue-js'\nimport { AUTH_PROVIDERS, type AuthProvider } from './types.js'\nimport { getGoTrueClient, isBrowser } from './environment.js'\n\nexport interface IdentityUser {\n sub?: string\n email?: string\n exp?: number\n app_metadata?: Record<string, unknown>\n user_metadata?: Record<string, unknown>\n [key: string]: unknown\n}\n\nconst toAuthProvider = (value: unknown): AuthProvider | undefined =>\n typeof value === 'string' && (AUTH_PROVIDERS as readonly string[]).includes(value)\n ? (value as AuthProvider)\n : undefined\n\nexport interface User {\n id: string\n email?: string\n emailVerified?: boolean\n createdAt?: string\n updatedAt?: string\n provider?: AuthProvider\n name?: string\n pictureUrl?: string\n metadata?: Record<string, unknown>\n rawGoTrueData?: Record<string, unknown>\n}\n\nexport const toUser = (userData: UserData): User => {\n const userMeta = userData.user_metadata ?? {}\n const appMeta = userData.app_metadata ?? {}\n const name = userMeta.full_name || userMeta.name\n const pictureUrl = userMeta.avatar_url\n\n return {\n id: userData.id,\n email: userData.email,\n emailVerified: !!userData.confirmed_at,\n createdAt: userData.created_at,\n updatedAt: userData.updated_at,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n pictureUrl: typeof pictureUrl === 'string' ? pictureUrl : undefined,\n metadata: userMeta,\n rawGoTrueData: { ...userData },\n }\n}\n\n/**\n * Converts server-side JWT claims into User\n */\nconst claimsToUser = (claims: IdentityUser): User => {\n const appMeta = claims.app_metadata ?? {}\n const userMeta = claims.user_metadata ?? {}\n const name = userMeta.full_name || userMeta.name\n\n return {\n id: claims.sub ?? '',\n email: claims.email,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n metadata: userMeta,\n }\n}\n\n/**\n * Returns the currently authenticated user, or `null` if not logged in.\n * Synchronous. Never throws.\n */\nexport const getUser = (): User | null => {\n if (isBrowser()) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser() ?? null\n if (!currentUser) return null\n return toUser(currentUser)\n }\n\n const identityContext = globalThis.netlifyIdentityContext\n if (!identityContext?.user) return null\n\n return claimsToUser(identityContext.user)\n}\n\n/**\n * Returns `true` if a user is currently authenticated.\n */\nexport const isAuthenticated = (): boolean => getUser() !== null\n","import type { AuthProvider, IdentityConfig, Settings } from './types.js'\nimport { getClient, getIdentityContext, IDENTITY_PATH, isBrowser } from './environment.js'\nimport { AuthError } from './errors.js'\n\n/**\n * Returns the identity configuration for the current environment.\n * Browser: always returns `{ url }` derived from `window.location.origin`.\n * Server: returns `{ url, token }` from the identity context, or `null` if unavailable.\n * Never throws.\n */\nexport const getIdentityConfig = (): IdentityConfig | null => {\n if (isBrowser()) {\n return { url: `${window.location.origin}${IDENTITY_PATH}` }\n }\n\n return getIdentityContext()\n}\n\n/**\n * Fetches the GoTrue `/settings` endpoint.\n * Throws `MissingIdentityError` if Identity is not configured.\n * Throws `AuthError` if the endpoint is unreachable.\n */\nexport const getSettings = async (): Promise<Settings> => {\n const client = getClient()\n\n try {\n const raw = await client.settings()\n const external: Partial<Record<AuthProvider, boolean>> = raw.external ?? {}\n return {\n autoconfirm: raw.autoconfirm,\n disableSignup: raw.disable_signup,\n providers: {\n google: external.google ?? false,\n github: external.github ?? false,\n gitlab: external.gitlab ?? false,\n bitbucket: external.bitbucket ?? false,\n facebook: external.facebook ?? false,\n email: external.email ?? false,\n saml: external.saml ?? false,\n },\n }\n } catch (err) {\n throw new AuthError(err instanceof Error ? err.message : 'Failed to fetch identity settings', 502, { cause: err })\n }\n}\n","import type { UserData } from 'gotrue-js'\n\nimport type { AppMetadata, NetlifyCookies } from './types.js'\n\nexport type AuthEvent = 'login' | 'logout' | 'token_refresh' | 'user_updated'\nimport type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getGoTrueClient, getClient, getIdentityContext, isBrowser } from './environment.js'\nimport { AuthError } from './errors.js'\n\nconst getCookies = (): NetlifyCookies => {\n const cookies = globalThis.Netlify?.context?.cookies\n if (!cookies) {\n throw new AuthError('Server-side auth requires Netlify Functions runtime')\n }\n return cookies\n}\n\nconst getServerIdentityUrl = (): string => {\n const ctx = getIdentityContext()\n if (!ctx?.url) {\n throw new AuthError('Could not determine the Identity endpoint URL on the server')\n }\n return ctx.url\n}\n\nexport interface JWTClaims {\n sub: string // UUID\n email: string\n exp: number\n iat: number\n aud: string\n app_metadata: AppMetadata\n user_metadata: Record<string, unknown>\n}\n\nexport type AuthCallback = (event: AuthEvent, user: User | null) => void\n\n/** Persist the session to localStorage so it survives page reloads. */\nexport const persistSession = true\n\nconst listeners = new Set<AuthCallback>()\n\nexport const emitAuthEvent = (event: AuthEvent, user: User | null): void => {\n for (const listener of listeners) {\n listener(event, user)\n }\n}\n\nlet storageListenerAttached = false\n\nconst attachStorageListener = (): void => {\n if (storageListenerAttached) return\n storageListenerAttached = true\n\n window.addEventListener('storage', (event: StorageEvent) => {\n if (event.key !== 'gotrue.user') return\n\n if (event.newValue) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser()\n emitAuthEvent('login', currentUser ? toUser(currentUser) : null)\n } else {\n emitAuthEvent('logout', null)\n }\n })\n}\n\n/**\n * Subscribes to auth state changes (login, logout, token refresh, user updates).\n * Returns an unsubscribe function. No-op on the server.\n */\nexport const onAuthChange = (callback: AuthCallback): (() => void) => {\n if (!isBrowser()) {\n return () => {}\n }\n\n listeners.add(callback)\n attachStorageListener()\n\n return () => {\n listeners.delete(callback)\n }\n}\n\n/** Logs in with email and password. Works in both browser and server contexts. */\nexport const login = async (email: string, password: string): Promise<User> => {\n if (!isBrowser()) {\n const identityUrl = getServerIdentityUrl()\n const cookies = getCookies()\n\n const body = new URLSearchParams({\n grant_type: 'password',\n username: email,\n password,\n })\n\n let res: Response\n try {\n res = await fetch(`${identityUrl}/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: body.toString(),\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n\n if (!res.ok) {\n const errorBody = await res.json().catch(() => ({}))\n throw new AuthError(\n (errorBody as Record<string, string>).msg ||\n (errorBody as Record<string, string>).error_description ||\n `Login failed (${res.status})`,\n res.status,\n )\n }\n\n const data = (await res.json()) as Record<string, unknown>\n const accessToken = data.access_token as string\n const userData = data as unknown as UserData\n const user = toUser(userData)\n\n cookies.set({\n name: 'nf_jwt',\n value: accessToken,\n httpOnly: true,\n secure: true,\n path: '/',\n sameSite: 'Lax',\n })\n\n return user\n }\n\n const client = getClient()\n\n try {\n const gotrueUser = await client.login(email, password, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Creates a new account. Emits 'login' if autoconfirm is enabled. Works in both browser and server contexts. */\nexport const signup = async (email: string, password: string, data?: Record<string, unknown>): Promise<User> => {\n if (!isBrowser()) {\n const identityUrl = getServerIdentityUrl()\n const cookies = getCookies()\n\n let res: Response\n try {\n res = await fetch(`${identityUrl}/signup`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ email, password, data }),\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n\n if (!res.ok) {\n const errorBody = await res.json().catch(() => ({}))\n throw new AuthError((errorBody as Record<string, string>).msg || `Signup failed (${res.status})`, res.status)\n }\n\n const responseData = (await res.json()) as UserData\n const user = toUser(responseData)\n\n if (responseData.confirmed_at) {\n const accessToken = (responseData as unknown as Record<string, unknown>).access_token as string | undefined\n if (accessToken) {\n cookies.set({\n name: 'nf_jwt',\n value: accessToken,\n httpOnly: true,\n secure: true,\n path: '/',\n sameSite: 'Lax',\n })\n }\n }\n\n return user\n }\n\n const client = getClient()\n\n try {\n const response = await client.signup(email, password, data)\n const user = toUser(response as UserData)\n if (response.confirmed_at) {\n emitAuthEvent('login', user)\n }\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Logs out the current user and clears the session. Works in both browser and server contexts. */\nexport const logout = async (): Promise<void> => {\n if (!isBrowser()) {\n const identityUrl = getServerIdentityUrl()\n const cookies = getCookies()\n\n const jwt = cookies.get('nf_jwt')\n if (jwt) {\n try {\n await fetch(`${identityUrl}/logout`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}` },\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n }\n\n cookies.delete('nf_jwt')\n return\n }\n\n const client = getClient()\n\n try {\n const currentUser = client.currentUser()\n if (currentUser) {\n await currentUser.logout()\n }\n emitAuthEvent('logout', null)\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Redirects to an OAuth provider. Always throws (the page navigates away). Browser only. */\nexport const oauthLogin = (provider: string): never => {\n if (!isBrowser()) {\n throw new Error('oauthLogin() is only available in the browser')\n }\n const client = getClient()\n\n window.location.href = client.loginExternalUrl(provider)\n throw new Error('Redirecting to OAuth provider')\n}\n\nexport interface CallbackResult {\n type: 'oauth' | 'confirmation' | 'recovery' | 'invite' | 'email_change'\n user: User | null\n token?: string\n}\n\n/**\n * Processes the URL hash after an OAuth redirect, email confirmation, password\n * recovery, invite acceptance, or email change. Call on page load. Browser only.\n * Returns `null` if the hash contains no auth parameters.\n */\nexport const handleAuthCallback = async (): Promise<CallbackResult | null> => {\n if (!isBrowser()) return null\n\n const hash = window.location.hash.substring(1)\n if (!hash) return null\n\n const client = getClient()\n\n try {\n const params = new URLSearchParams(hash)\n\n const accessToken = params.get('access_token')\n if (accessToken) {\n const gotrueUser = await client.createUser(\n {\n access_token: accessToken,\n token_type: (params.get('token_type') as 'bearer') ?? 'bearer',\n expires_in: Number(params.get('expires_in')),\n expires_at: Number(params.get('expires_at')),\n refresh_token: params.get('refresh_token') ?? '',\n },\n persistSession,\n )\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'oauth', user }\n }\n\n const confirmationToken = params.get('confirmation_token')\n if (confirmationToken) {\n const gotrueUser = await client.confirm(confirmationToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'confirmation', user }\n }\n\n const recoveryToken = params.get('recovery_token')\n if (recoveryToken) {\n const gotrueUser = await client.recover(recoveryToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'recovery', user }\n }\n\n const inviteToken = params.get('invite_token')\n if (inviteToken) {\n clearHash()\n return { type: 'invite', user: null, token: inviteToken }\n }\n\n const emailChangeToken = params.get('email_change_token')\n if (emailChangeToken) {\n const gotrueUser = await client.verify('email_change', emailChangeToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('user_updated', user)\n return { type: 'email_change', user }\n }\n\n return null\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\nconst clearHash = (): void => {\n history.replaceState(null, '', window.location.pathname + window.location.search)\n}\n","import type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getClient } from './environment.js'\nimport { emitAuthEvent, persistSession } from './auth.js'\nimport { AuthError } from './errors.js'\n\n/** Sends a password recovery email to the given address. */\nexport const requestPasswordRecovery = async (email: string): Promise<void> => {\n const client = getClient()\n\n try {\n await client.requestPasswordRecovery(email)\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Redeems a recovery token and sets a new password. Logs the user in on success. */\nexport const recoverPassword = async (token: string, newPassword: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.recover(token, persistSession)\n const updatedUser = await gotrueUser.update({ password: newPassword })\n const user = toUser(updatedUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n\n/** Confirms an email address using the token from a confirmation email. Logs the user in on success. */\nexport const confirmEmail = async (token: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.confirm(token, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Accepts an invite token and sets a password for the new account. Logs the user in on success. */\nexport const acceptInvite = async (token: string, password: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.acceptInvite(token, password, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Verifies an email change using the token from a verification email. */\nexport const verifyEmailChange = async (token: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.verify('email_change', token, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('user_updated', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Updates the current user's metadata or credentials. Requires an active session. */\nexport const updateUser = async (updates: Record<string, unknown>): Promise<User> => {\n const client = getClient()\n\n const currentUser = client.currentUser()\n if (!currentUser) throw new AuthError('No user is currently logged in')\n\n try {\n const updatedUser = await currentUser.update(updates)\n const user = toUser(updatedUser)\n emitAuthEvent('user_updated', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n"],"mappings":"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","names":["GoTrue"]}
package/dist/index.d.cts CHANGED
@@ -94,13 +94,15 @@ declare class MissingIdentityError extends Error {
94
94
 
95
95
  /** Sends a password recovery email to the given address. */
96
96
  declare const requestPasswordRecovery: (email: string) => Promise<void>;
97
+ /** Redeems a recovery token and sets a new password. Logs the user in on success. */
98
+ declare const recoverPassword: (token: string, newPassword: string) => Promise<User>;
97
99
  /** Confirms an email address using the token from a confirmation email. Logs the user in on success. */
98
100
  declare const confirmEmail: (token: string) => Promise<User>;
99
101
  /** Accepts an invite token and sets a password for the new account. Logs the user in on success. */
100
102
  declare const acceptInvite: (token: string, password: string) => Promise<User>;
101
- /** Verifies an email change using the token from a verification email. Requires an active session. */
103
+ /** Verifies an email change using the token from a verification email. */
102
104
  declare const verifyEmailChange: (token: string) => Promise<User>;
103
105
  /** Updates the current user's metadata or credentials. Requires an active session. */
104
106
  declare const updateUser: (updates: Record<string, unknown>) => Promise<User>;
105
107
 
106
- export { type AppMetadata, type AuthCallback, AuthError, type AuthEvent, type AuthProvider, type CallbackResult, type IdentityConfig, MissingIdentityError, type Settings, type User, acceptInvite, confirmEmail, getIdentityConfig, getSettings, getUser, handleAuthCallback, isAuthenticated, login, logout, oauthLogin, onAuthChange, requestPasswordRecovery, signup, updateUser, verifyEmailChange };
108
+ export { type AppMetadata, type AuthCallback, AuthError, type AuthEvent, type AuthProvider, type CallbackResult, type IdentityConfig, MissingIdentityError, type Settings, type User, acceptInvite, confirmEmail, getIdentityConfig, getSettings, getUser, handleAuthCallback, isAuthenticated, login, logout, oauthLogin, onAuthChange, recoverPassword, requestPasswordRecovery, signup, updateUser, verifyEmailChange };
package/dist/index.d.ts CHANGED
@@ -94,13 +94,15 @@ declare class MissingIdentityError extends Error {
94
94
 
95
95
  /** Sends a password recovery email to the given address. */
96
96
  declare const requestPasswordRecovery: (email: string) => Promise<void>;
97
+ /** Redeems a recovery token and sets a new password. Logs the user in on success. */
98
+ declare const recoverPassword: (token: string, newPassword: string) => Promise<User>;
97
99
  /** Confirms an email address using the token from a confirmation email. Logs the user in on success. */
98
100
  declare const confirmEmail: (token: string) => Promise<User>;
99
101
  /** Accepts an invite token and sets a password for the new account. Logs the user in on success. */
100
102
  declare const acceptInvite: (token: string, password: string) => Promise<User>;
101
- /** Verifies an email change using the token from a verification email. Requires an active session. */
103
+ /** Verifies an email change using the token from a verification email. */
102
104
  declare const verifyEmailChange: (token: string) => Promise<User>;
103
105
  /** Updates the current user's metadata or credentials. Requires an active session. */
104
106
  declare const updateUser: (updates: Record<string, unknown>) => Promise<User>;
105
107
 
106
- export { type AppMetadata, type AuthCallback, AuthError, type AuthEvent, type AuthProvider, type CallbackResult, type IdentityConfig, MissingIdentityError, type Settings, type User, acceptInvite, confirmEmail, getIdentityConfig, getSettings, getUser, handleAuthCallback, isAuthenticated, login, logout, oauthLogin, onAuthChange, requestPasswordRecovery, signup, updateUser, verifyEmailChange };
108
+ export { type AppMetadata, type AuthCallback, AuthError, type AuthEvent, type AuthProvider, type CallbackResult, type IdentityConfig, MissingIdentityError, type Settings, type User, acceptInvite, confirmEmail, getIdentityConfig, getSettings, getUser, handleAuthCallback, isAuthenticated, login, logout, oauthLogin, onAuthChange, recoverPassword, requestPasswordRecovery, signup, updateUser, verifyEmailChange };
package/dist/index.js CHANGED
@@ -23,6 +23,7 @@ var MissingIdentityError = class extends Error {
23
23
  };
24
24
 
25
25
  // src/environment.ts
26
+ var IDENTITY_PATH = "/.netlify/identity";
26
27
  var goTrueClient = null;
27
28
  var cachedApiUrl;
28
29
  var warnedMissingUrl = false;
@@ -30,13 +31,13 @@ var isBrowser = () => typeof window !== "undefined" && typeof window.location !=
30
31
  var discoverApiUrl = () => {
31
32
  if (cachedApiUrl !== void 0) return cachedApiUrl;
32
33
  if (isBrowser()) {
33
- cachedApiUrl = `${window.location.origin}/.netlify/identity`;
34
+ cachedApiUrl = `${window.location.origin}${IDENTITY_PATH}`;
34
35
  } else {
35
36
  const identityContext = getIdentityContext();
36
37
  if (identityContext?.url) {
37
38
  cachedApiUrl = identityContext.url;
38
39
  } else if (globalThis.Netlify?.context?.url) {
39
- cachedApiUrl = new URL("/.netlify/identity", globalThis.Netlify.context.url).href;
40
+ cachedApiUrl = new URL(IDENTITY_PATH, globalThis.Netlify.context.url).href;
40
41
  }
41
42
  }
42
43
  return cachedApiUrl ?? null;
@@ -63,14 +64,14 @@ var getClient = () => {
63
64
  };
64
65
  var getIdentityContext = () => {
65
66
  const identityContext = globalThis.netlifyIdentityContext;
66
- if (identityContext?.url && typeof identityContext.url === "string") {
67
+ if (identityContext?.url) {
67
68
  return {
68
69
  url: identityContext.url,
69
- token: typeof identityContext.token === "string" ? identityContext.token : void 0
70
+ token: identityContext.token
70
71
  };
71
72
  }
72
73
  if (globalThis.Netlify?.context?.url) {
73
- return { url: new URL("/.netlify/identity", globalThis.Netlify.context.url).href };
74
+ return { url: new URL(IDENTITY_PATH, globalThis.Netlify.context.url).href };
74
75
  }
75
76
  return null;
76
77
  };
@@ -100,8 +101,8 @@ var claimsToUser = (claims) => {
100
101
  const userMeta = claims.user_metadata ?? {};
101
102
  const name = userMeta.full_name || userMeta.name;
102
103
  return {
103
- id: typeof claims.sub === "string" ? claims.sub : "",
104
- email: typeof claims.email === "string" ? claims.email : void 0,
104
+ id: claims.sub ?? "",
105
+ email: claims.email,
105
106
  provider: toAuthProvider(appMeta.provider),
106
107
  name: typeof name === "string" ? name : void 0,
107
108
  metadata: userMeta
@@ -115,17 +116,15 @@ var getUser = () => {
115
116
  return toUser(currentUser);
116
117
  }
117
118
  const identityContext = globalThis.netlifyIdentityContext;
118
- if (!identityContext) return null;
119
- const claims = identityContext.user ?? (identityContext.sub ? identityContext : null);
120
- if (!claims) return null;
121
- return claimsToUser(claims);
119
+ if (!identityContext?.user) return null;
120
+ return claimsToUser(identityContext.user);
122
121
  };
123
122
  var isAuthenticated = () => getUser() !== null;
124
123
 
125
124
  // src/config.ts
126
125
  var getIdentityConfig = () => {
127
126
  if (isBrowser()) {
128
- return { url: `${window.location.origin}/.netlify/identity` };
127
+ return { url: `${window.location.origin}${IDENTITY_PATH}` };
129
128
  }
130
129
  return getIdentityContext();
131
130
  };
@@ -381,12 +380,7 @@ var handleAuthCallback = async () => {
381
380
  }
382
381
  const emailChangeToken = params.get("email_change_token");
383
382
  if (emailChangeToken) {
384
- const currentUser = client.currentUser();
385
- if (!currentUser) {
386
- clearHash();
387
- return { type: "email_change", user: null, token: emailChangeToken };
388
- }
389
- const gotrueUser = await currentUser.update({ email_change_token: emailChangeToken });
383
+ const gotrueUser = await client.verify("email_change", emailChangeToken, persistSession);
390
384
  const user = toUser(gotrueUser);
391
385
  clearHash();
392
386
  emitAuthEvent("user_updated", user);
@@ -410,6 +404,18 @@ var requestPasswordRecovery = async (email) => {
410
404
  throw new AuthError(error.message, void 0, { cause: error });
411
405
  }
412
406
  };
407
+ var recoverPassword = async (token, newPassword) => {
408
+ const client = getClient();
409
+ try {
410
+ const gotrueUser = await client.recover(token, persistSession);
411
+ const updatedUser = await gotrueUser.update({ password: newPassword });
412
+ const user = toUser(updatedUser);
413
+ emitAuthEvent("login", user);
414
+ return user;
415
+ } catch (error) {
416
+ throw new AuthError(error.message, void 0, { cause: error });
417
+ }
418
+ };
413
419
  var confirmEmail = async (token) => {
414
420
  const client = getClient();
415
421
  try {
@@ -434,10 +440,8 @@ var acceptInvite = async (token, password) => {
434
440
  };
435
441
  var verifyEmailChange = async (token) => {
436
442
  const client = getClient();
437
- const currentUser = client.currentUser();
438
- if (!currentUser) throw new AuthError("No user is currently logged in");
439
443
  try {
440
- const gotrueUser = await currentUser.update({ email_change_token: token });
444
+ const gotrueUser = await client.verify("email_change", token, persistSession);
441
445
  const user = toUser(gotrueUser);
442
446
  emitAuthEvent("user_updated", user);
443
447
  return user;
@@ -472,6 +476,7 @@ export {
472
476
  logout,
473
477
  oauthLogin,
474
478
  onAuthChange,
479
+ recoverPassword,
475
480
  requestPasswordRecovery,
476
481
  signup,
477
482
  updateUser,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts","../src/environment.ts","../src/errors.ts","../src/user.ts","../src/config.ts","../src/auth.ts","../src/account.ts"],"sourcesContent":["export const AUTH_PROVIDERS = ['google', 'github', 'gitlab', 'bitbucket', 'facebook', 'saml', 'email'] as const\nexport type AuthProvider = (typeof AUTH_PROVIDERS)[number]\n\nexport interface AppMetadata {\n provider: AuthProvider\n roles?: string[]\n [key: string]: unknown\n}\n\nexport interface IdentityConfig {\n url: string\n token?: string // this is an operator token, only available on the server\n}\n\nexport interface Settings {\n autoconfirm: boolean\n disableSignup: boolean\n providers: Record<AuthProvider, boolean>\n}\n\nexport interface NetlifyCookies {\n get(name: string): string | undefined\n set(options: {\n name: string\n value: string\n httpOnly: boolean\n secure: boolean\n path: string\n sameSite: string\n }): void\n delete(name: string): void\n}\n","import GoTrue from 'gotrue-js'\n\nimport type { IdentityConfig } from './types.js'\nimport { MissingIdentityError } from './errors.js'\n\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` + `/.netlify/identity`.\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}/.netlify/identity`\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('/.netlify/identity', globalThis.Netlify.context.url).href\n }\n }\n\n return cachedApiUrl ?? null\n}\n\n/**\n * Returns (and lazily creates) a singleton gotrue-js client.\n * Returns `null` and logs a warning if no identity URL can be discovered.\n */\nexport const getGoTrueClient = (): GoTrue | null => {\n if (goTrueClient) return goTrueClient\n\n const apiUrl = discoverApiUrl()\n if (!apiUrl) {\n if (!warnedMissingUrl) {\n console.warn(\n '@netlify/identity: Could not determine the Identity endpoint URL. ' +\n 'Make sure your site has Netlify Identity enabled, or run your app with `netlify dev`.',\n )\n warnedMissingUrl = true\n }\n return null\n }\n\n goTrueClient = new GoTrue({ APIUrl: apiUrl, setCookie: isBrowser() })\n return goTrueClient\n}\n\n/**\n * Returns the singleton gotrue-js client, or throws if Identity is not configured.\n */\nexport const getClient = (): GoTrue => {\n const client = getGoTrueClient()\n if (!client) throw new MissingIdentityError()\n return client\n}\n\n/**\n * Reads the server-side identity context set by the Netlify bootstrap.\n * Returns `null` outside the Netlify serverless environment.\n */\nexport const getIdentityContext = (): IdentityConfig | null => {\n // TODO(kh): After Stargate deploys EX-1764, netlifyIdentityContext will have\n // typed `url` and `token` fields. Remove the typeof guards and use direct access.\n // https://linear.app/netlify/issue/EX-1764/identity-stargate-needs-to-set-identity-url-and-providertoken\n const identityContext = globalThis.netlifyIdentityContext\n if (identityContext?.url && typeof identityContext.url === 'string') {\n return {\n url: identityContext.url,\n token: typeof identityContext.token === 'string' ? identityContext.token : undefined,\n }\n }\n\n if (globalThis.Netlify?.context?.url) {\n return { url: new URL('/.netlify/identity', globalThis.Netlify.context.url).href }\n }\n\n return null\n}\n\n/** Reset cached state for tests. */\nexport const resetTestGoTrueClient = (): void => {\n goTrueClient = null\n cachedApiUrl = undefined\n warnedMissingUrl = false\n}\n","export class AuthError extends Error {\n override name = 'AuthError'\n status?: number\n declare cause?: unknown\n\n constructor(message: string, status?: number, options?: { cause?: unknown }) {\n super(message)\n this.status = status\n if (options && 'cause' in options) {\n this.cause = options.cause\n }\n }\n}\n\nexport class MissingIdentityError extends Error {\n override name = 'MissingIdentityError'\n\n constructor(message = 'Identity is not available in this environment') {\n super(message)\n }\n}\n","import type { UserData } from 'gotrue-js'\nimport { AUTH_PROVIDERS, type AuthProvider } from './types.js'\nimport { getGoTrueClient, isBrowser } from './environment.js'\n\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 raw JWT claims from the identity header into a User.\n * JWT claims use a different shape than the gotrue-js UserData class.\n */\nconst claimsToUser = (claims: Record<string, unknown>): User => {\n const appMeta = (claims.app_metadata ?? {}) as Record<string, unknown>\n const userMeta = (claims.user_metadata ?? {}) as Record<string, unknown>\n const name = userMeta.full_name || userMeta.name\n\n return {\n id: typeof claims.sub === 'string' ? claims.sub : '',\n email: typeof claims.email === 'string' ? claims.email : undefined,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n metadata: userMeta,\n }\n}\n\n/**\n * Returns the currently authenticated user, or `null` if not logged in.\n * Synchronous. Never throws.\n */\nexport const getUser = (): User | null => {\n if (isBrowser()) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser() ?? null\n if (!currentUser) return null\n return toUser(currentUser)\n }\n\n const identityContext = globalThis.netlifyIdentityContext\n if (!identityContext) return null\n\n const claims = identityContext.user ?? (identityContext.sub ? identityContext : null)\n if (!claims) return null\n return claimsToUser(claims as Record<string, unknown>)\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 { AuthError } from './errors.js'\nimport { getClient, getIdentityContext, isBrowser } from './environment.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}/.netlify/identity` }\n }\n\n return getIdentityContext()\n}\n\n/**\n * Fetches the GoTrue `/settings` endpoint.\n * Throws `MissingIdentityError` if Identity is not configured.\n * Throws `AuthError` if the endpoint is unreachable.\n */\nexport const getSettings = async (): Promise<Settings> => {\n const client = getClient()\n\n try {\n const raw = await client.settings()\n const external: Partial<Record<AuthProvider, boolean>> = raw.external ?? {}\n return {\n autoconfirm: raw.autoconfirm,\n disableSignup: raw.disable_signup,\n providers: {\n google: external.google ?? false,\n github: external.github ?? false,\n gitlab: external.gitlab ?? false,\n bitbucket: external.bitbucket ?? false,\n facebook: external.facebook ?? false,\n email: external.email ?? false,\n saml: external.saml ?? false,\n },\n }\n } catch (err) {\n throw new AuthError(err instanceof Error ? err.message : 'Failed to fetch identity settings', 502, { cause: err })\n }\n}\n","import type { UserData } from 'gotrue-js'\n\nimport type { AppMetadata, NetlifyCookies } from './types.js'\n\nexport type AuthEvent = 'login' | 'logout' | 'token_refresh' | 'user_updated'\nimport type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getGoTrueClient, getClient, getIdentityContext, isBrowser } from './environment.js'\nimport { AuthError } from './errors.js'\n\nconst getCookies = (): NetlifyCookies => {\n const cookies = globalThis.Netlify?.context?.cookies\n if (!cookies) {\n throw new AuthError('Server-side auth requires Netlify Functions runtime')\n }\n return cookies\n}\n\nconst getServerIdentityUrl = (): string => {\n const ctx = getIdentityContext()\n if (!ctx?.url) {\n throw new AuthError('Could not determine the Identity endpoint URL on the server')\n }\n return ctx.url\n}\n\nexport interface JWTClaims {\n sub: string // UUID\n email: string\n exp: number\n iat: number\n aud: string\n app_metadata: AppMetadata\n user_metadata: Record<string, unknown>\n}\n\nexport type AuthCallback = (event: AuthEvent, user: User | null) => void\n\n/** Persist the session to localStorage so it survives page reloads. */\nexport const persistSession = true\n\nconst listeners = new Set<AuthCallback>()\n\nexport const emitAuthEvent = (event: AuthEvent, user: User | null): void => {\n for (const listener of listeners) {\n listener(event, user)\n }\n}\n\nlet storageListenerAttached = false\n\nconst attachStorageListener = (): void => {\n if (storageListenerAttached) return\n storageListenerAttached = true\n\n window.addEventListener('storage', (event: StorageEvent) => {\n if (event.key !== 'gotrue.user') return\n\n if (event.newValue) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser()\n emitAuthEvent('login', currentUser ? toUser(currentUser) : null)\n } else {\n emitAuthEvent('logout', null)\n }\n })\n}\n\n/**\n * Subscribes to auth state changes (login, logout, token refresh, user updates).\n * Returns an unsubscribe function. No-op on the server.\n */\nexport const onAuthChange = (callback: AuthCallback): (() => void) => {\n if (!isBrowser()) {\n return () => {}\n }\n\n listeners.add(callback)\n attachStorageListener()\n\n return () => {\n listeners.delete(callback)\n }\n}\n\n/** Logs in with email and password. Works in both browser and server contexts. */\nexport const login = async (email: string, password: string): Promise<User> => {\n if (!isBrowser()) {\n const identityUrl = getServerIdentityUrl()\n const cookies = getCookies()\n\n const body = new URLSearchParams({\n grant_type: 'password',\n username: email,\n password,\n })\n\n let res: Response\n try {\n res = await fetch(`${identityUrl}/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: body.toString(),\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n\n if (!res.ok) {\n const errorBody = await res.json().catch(() => ({}))\n throw new AuthError(\n (errorBody as Record<string, string>).msg ||\n (errorBody as Record<string, string>).error_description ||\n `Login failed (${res.status})`,\n res.status,\n )\n }\n\n const data = (await res.json()) as Record<string, unknown>\n const accessToken = data.access_token as string\n const userData = data as unknown as UserData\n const user = toUser(userData)\n\n cookies.set({\n name: 'nf_jwt',\n value: accessToken,\n httpOnly: true,\n secure: true,\n path: '/',\n sameSite: 'Lax',\n })\n\n return user\n }\n\n const client = getClient()\n\n try {\n const gotrueUser = await client.login(email, password, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Creates a new account. Emits 'login' if autoconfirm is enabled. Works in both browser and server contexts. */\nexport const signup = async (email: string, password: string, data?: Record<string, unknown>): Promise<User> => {\n if (!isBrowser()) {\n const identityUrl = getServerIdentityUrl()\n const cookies = getCookies()\n\n let res: Response\n try {\n res = await fetch(`${identityUrl}/signup`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ email, password, data }),\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n\n if (!res.ok) {\n const errorBody = await res.json().catch(() => ({}))\n throw new AuthError((errorBody as Record<string, string>).msg || `Signup failed (${res.status})`, res.status)\n }\n\n const responseData = (await res.json()) as UserData\n const user = toUser(responseData)\n\n if (responseData.confirmed_at) {\n const accessToken = (responseData as unknown as Record<string, unknown>).access_token as string | undefined\n if (accessToken) {\n cookies.set({\n name: 'nf_jwt',\n value: accessToken,\n httpOnly: true,\n secure: true,\n path: '/',\n sameSite: 'Lax',\n })\n }\n }\n\n return user\n }\n\n const client = getClient()\n\n try {\n const response = await client.signup(email, password, data)\n const user = toUser(response as UserData)\n if (response.confirmed_at) {\n emitAuthEvent('login', user)\n }\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Logs out the current user and clears the session. Works in both browser and server contexts. */\nexport const logout = async (): Promise<void> => {\n if (!isBrowser()) {\n const identityUrl = getServerIdentityUrl()\n const cookies = getCookies()\n\n const jwt = cookies.get('nf_jwt')\n if (jwt) {\n try {\n await fetch(`${identityUrl}/logout`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}` },\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n }\n\n cookies.delete('nf_jwt')\n return\n }\n\n const client = getClient()\n\n try {\n const currentUser = client.currentUser()\n if (currentUser) {\n await currentUser.logout()\n }\n emitAuthEvent('logout', null)\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Redirects to an OAuth provider. Always throws (the page navigates away). Browser only. */\nexport const oauthLogin = (provider: string): never => {\n if (!isBrowser()) {\n throw new Error('oauthLogin() is only available in the browser')\n }\n const client = getClient()\n\n window.location.href = client.loginExternalUrl(provider)\n throw new Error('Redirecting to OAuth provider')\n}\n\nexport interface CallbackResult {\n type: 'oauth' | 'confirmation' | 'recovery' | 'invite' | 'email_change'\n user: User | null\n token?: string\n}\n\n/**\n * Processes the URL hash after an OAuth redirect, email confirmation, password\n * recovery, invite acceptance, or email change. Call on page load. Browser only.\n * Returns `null` if the hash contains no auth parameters.\n */\nexport const handleAuthCallback = async (): Promise<CallbackResult | null> => {\n if (!isBrowser()) return null\n\n const hash = window.location.hash.substring(1)\n if (!hash) return null\n\n const client = getClient()\n\n try {\n const params = new URLSearchParams(hash)\n\n const accessToken = params.get('access_token')\n if (accessToken) {\n const gotrueUser = await client.createUser(\n {\n access_token: accessToken,\n token_type: (params.get('token_type') as 'bearer') ?? 'bearer',\n expires_in: Number(params.get('expires_in')),\n expires_at: Number(params.get('expires_at')),\n refresh_token: params.get('refresh_token') ?? '',\n },\n persistSession,\n )\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'oauth', user }\n }\n\n const confirmationToken = params.get('confirmation_token')\n if (confirmationToken) {\n const gotrueUser = await client.confirm(confirmationToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'confirmation', user }\n }\n\n const recoveryToken = params.get('recovery_token')\n if (recoveryToken) {\n const gotrueUser = await client.recover(recoveryToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'recovery', user }\n }\n\n const inviteToken = params.get('invite_token')\n if (inviteToken) {\n clearHash()\n return { type: 'invite', user: null, token: inviteToken }\n }\n\n const emailChangeToken = params.get('email_change_token')\n if (emailChangeToken) {\n const currentUser = client.currentUser()\n if (!currentUser) {\n clearHash()\n return { type: 'email_change', user: null, token: emailChangeToken }\n }\n const gotrueUser = await currentUser.update({ email_change_token: emailChangeToken })\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('user_updated', user)\n return { type: 'email_change', user }\n }\n\n return null\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\nconst clearHash = (): void => {\n history.replaceState(null, '', window.location.pathname + window.location.search)\n}\n","import type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getClient } from './environment.js'\nimport { emitAuthEvent, persistSession } from './auth.js'\nimport { AuthError } from './errors.js'\n\n/** Sends a password recovery email to the given address. */\nexport const requestPasswordRecovery = async (email: string): Promise<void> => {\n const client = getClient()\n\n try {\n await client.requestPasswordRecovery(email)\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Confirms an email address using the token from a confirmation email. Logs the user in on success. */\nexport const confirmEmail = async (token: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.confirm(token, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Accepts an invite token and sets a password for the new account. Logs the user in on success. */\nexport const acceptInvite = async (token: string, password: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.acceptInvite(token, password, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Verifies an email change using the token from a verification email. Requires an active session. */\nexport const verifyEmailChange = async (token: string): Promise<User> => {\n const client = getClient()\n\n const currentUser = client.currentUser()\n if (!currentUser) throw new AuthError('No user is currently logged in')\n\n try {\n const gotrueUser = await currentUser.update({ email_change_token: token })\n const user = toUser(gotrueUser)\n emitAuthEvent('user_updated', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Updates the current user's metadata or credentials. Requires an active session. */\nexport const updateUser = async (updates: Record<string, unknown>): Promise<User> => {\n const client = getClient()\n\n const currentUser = client.currentUser()\n if (!currentUser) throw new AuthError('No user is currently logged in')\n\n try {\n const updatedUser = await currentUser.update(updates)\n const user = toUser(updatedUser)\n emitAuthEvent('user_updated', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/types.ts","../src/environment.ts","../src/errors.ts","../src/user.ts","../src/config.ts","../src/auth.ts","../src/account.ts"],"sourcesContent":["export const AUTH_PROVIDERS = ['google', 'github', 'gitlab', 'bitbucket', 'facebook', 'saml', 'email'] as const\nexport type AuthProvider = (typeof AUTH_PROVIDERS)[number]\n\nexport interface AppMetadata {\n provider: AuthProvider\n roles?: string[]\n [key: string]: unknown\n}\n\nexport interface IdentityConfig {\n url: string\n token?: string // this is an operator token, only available on the server\n}\n\nexport interface Settings {\n autoconfirm: boolean\n disableSignup: boolean\n providers: Record<AuthProvider, boolean>\n}\n\nexport interface NetlifyCookies {\n get(name: string): string | undefined\n set(options: {\n name: string\n value: string\n httpOnly: boolean\n secure: boolean\n path: string\n sameSite: string\n }): void\n delete(name: string): void\n}\n","import GoTrue from 'gotrue-js'\n\nimport type { IdentityConfig } from './types.js'\nimport { MissingIdentityError } from './errors.js'\n\nexport const IDENTITY_PATH = '/.netlify/identity'\n\nlet goTrueClient: GoTrue | null = null\nlet cachedApiUrl: string | null | undefined\nlet warnedMissingUrl = false\n\nexport const isBrowser = (): boolean => typeof window !== 'undefined' && typeof window.location !== 'undefined'\n\n/**\n * Discovers and caches the GoTrue API URL.\n *\n * Browser: uses `window.location.origin` + IDENTITY_PATH.\n * Server: reads from `globalThis.netlifyIdentityContext`.\n */\nconst discoverApiUrl = (): string | null => {\n if (cachedApiUrl !== undefined) return cachedApiUrl\n\n if (isBrowser()) {\n cachedApiUrl = `${window.location.origin}${IDENTITY_PATH}`\n } else {\n const identityContext = getIdentityContext()\n if (identityContext?.url) {\n cachedApiUrl = identityContext.url\n } else if (globalThis.Netlify?.context?.url) {\n cachedApiUrl = new URL(IDENTITY_PATH, globalThis.Netlify.context.url).href\n }\n }\n\n return cachedApiUrl ?? null\n}\n\n/**\n * Returns (and lazily creates) a singleton gotrue-js client.\n * Returns `null` and logs a warning if no identity URL can be discovered.\n */\nexport const getGoTrueClient = (): GoTrue | null => {\n if (goTrueClient) return goTrueClient\n\n const apiUrl = discoverApiUrl()\n if (!apiUrl) {\n if (!warnedMissingUrl) {\n console.warn(\n '@netlify/identity: Could not determine the Identity endpoint URL. ' +\n 'Make sure your site has Netlify Identity enabled, or run your app with `netlify dev`.',\n )\n warnedMissingUrl = true\n }\n return null\n }\n\n goTrueClient = new GoTrue({ APIUrl: apiUrl, setCookie: isBrowser() })\n return goTrueClient\n}\n\n/**\n * Returns the singleton gotrue-js client, or throws if Identity is not configured.\n */\nexport const getClient = (): GoTrue => {\n const client = getGoTrueClient()\n if (!client) throw new MissingIdentityError()\n return client\n}\n\n/**\n * Reads the server-side identity context set by the Netlify bootstrap.\n * Returns `null` outside the Netlify serverless environment.\n */\nexport const getIdentityContext = (): IdentityConfig | null => {\n const identityContext = globalThis.netlifyIdentityContext\n if (identityContext?.url) {\n return {\n url: identityContext.url,\n token: identityContext.token,\n }\n }\n\n if (globalThis.Netlify?.context?.url) {\n return { url: new URL(IDENTITY_PATH, globalThis.Netlify.context.url).href }\n }\n\n return null\n}\n\n/** Reset cached state for tests. */\nexport const resetTestGoTrueClient = (): void => {\n goTrueClient = null\n cachedApiUrl = undefined\n warnedMissingUrl = false\n}\n","export class AuthError extends Error {\n override name = 'AuthError'\n status?: number\n declare cause?: unknown\n\n constructor(message: string, status?: number, options?: { cause?: unknown }) {\n super(message)\n this.status = status\n if (options && 'cause' in options) {\n this.cause = options.cause\n }\n }\n}\n\nexport class MissingIdentityError extends Error {\n override name = 'MissingIdentityError'\n\n constructor(message = 'Identity is not available in this environment') {\n super(message)\n }\n}\n","import type { UserData } from 'gotrue-js'\nimport { AUTH_PROVIDERS, type AuthProvider } from './types.js'\nimport { getGoTrueClient, isBrowser } from './environment.js'\n\nexport interface IdentityUser {\n sub?: string\n email?: string\n exp?: number\n app_metadata?: Record<string, unknown>\n user_metadata?: Record<string, unknown>\n [key: string]: unknown\n}\n\nconst toAuthProvider = (value: unknown): AuthProvider | undefined =>\n typeof value === 'string' && (AUTH_PROVIDERS as readonly string[]).includes(value)\n ? (value as AuthProvider)\n : undefined\n\nexport interface User {\n id: string\n email?: string\n emailVerified?: boolean\n createdAt?: string\n updatedAt?: string\n provider?: AuthProvider\n name?: string\n pictureUrl?: string\n metadata?: Record<string, unknown>\n rawGoTrueData?: Record<string, unknown>\n}\n\nexport const toUser = (userData: UserData): User => {\n const userMeta = userData.user_metadata ?? {}\n const appMeta = userData.app_metadata ?? {}\n const name = userMeta.full_name || userMeta.name\n const pictureUrl = userMeta.avatar_url\n\n return {\n id: userData.id,\n email: userData.email,\n emailVerified: !!userData.confirmed_at,\n createdAt: userData.created_at,\n updatedAt: userData.updated_at,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n pictureUrl: typeof pictureUrl === 'string' ? pictureUrl : undefined,\n metadata: userMeta,\n rawGoTrueData: { ...userData },\n }\n}\n\n/**\n * Converts server-side JWT claims into User\n */\nconst claimsToUser = (claims: IdentityUser): User => {\n const appMeta = claims.app_metadata ?? {}\n const userMeta = claims.user_metadata ?? {}\n const name = userMeta.full_name || userMeta.name\n\n return {\n id: claims.sub ?? '',\n email: claims.email,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n metadata: userMeta,\n }\n}\n\n/**\n * Returns the currently authenticated user, or `null` if not logged in.\n * Synchronous. Never throws.\n */\nexport const getUser = (): User | null => {\n if (isBrowser()) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser() ?? null\n if (!currentUser) return null\n return toUser(currentUser)\n }\n\n const identityContext = globalThis.netlifyIdentityContext\n if (!identityContext?.user) return null\n\n return claimsToUser(identityContext.user)\n}\n\n/**\n * Returns `true` if a user is currently authenticated.\n */\nexport const isAuthenticated = (): boolean => getUser() !== null\n","import type { AuthProvider, IdentityConfig, Settings } from './types.js'\nimport { getClient, getIdentityContext, IDENTITY_PATH, isBrowser } from './environment.js'\nimport { AuthError } from './errors.js'\n\n/**\n * Returns the identity configuration for the current environment.\n * Browser: always returns `{ url }` derived from `window.location.origin`.\n * Server: returns `{ url, token }` from the identity context, or `null` if unavailable.\n * Never throws.\n */\nexport const getIdentityConfig = (): IdentityConfig | null => {\n if (isBrowser()) {\n return { url: `${window.location.origin}${IDENTITY_PATH}` }\n }\n\n return getIdentityContext()\n}\n\n/**\n * Fetches the GoTrue `/settings` endpoint.\n * Throws `MissingIdentityError` if Identity is not configured.\n * Throws `AuthError` if the endpoint is unreachable.\n */\nexport const getSettings = async (): Promise<Settings> => {\n const client = getClient()\n\n try {\n const raw = await client.settings()\n const external: Partial<Record<AuthProvider, boolean>> = raw.external ?? {}\n return {\n autoconfirm: raw.autoconfirm,\n disableSignup: raw.disable_signup,\n providers: {\n google: external.google ?? false,\n github: external.github ?? false,\n gitlab: external.gitlab ?? false,\n bitbucket: external.bitbucket ?? false,\n facebook: external.facebook ?? false,\n email: external.email ?? false,\n saml: external.saml ?? false,\n },\n }\n } catch (err) {\n throw new AuthError(err instanceof Error ? err.message : 'Failed to fetch identity settings', 502, { cause: err })\n }\n}\n","import type { UserData } from 'gotrue-js'\n\nimport type { AppMetadata, NetlifyCookies } from './types.js'\n\nexport type AuthEvent = 'login' | 'logout' | 'token_refresh' | 'user_updated'\nimport type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getGoTrueClient, getClient, getIdentityContext, isBrowser } from './environment.js'\nimport { AuthError } from './errors.js'\n\nconst getCookies = (): NetlifyCookies => {\n const cookies = globalThis.Netlify?.context?.cookies\n if (!cookies) {\n throw new AuthError('Server-side auth requires Netlify Functions runtime')\n }\n return cookies\n}\n\nconst getServerIdentityUrl = (): string => {\n const ctx = getIdentityContext()\n if (!ctx?.url) {\n throw new AuthError('Could not determine the Identity endpoint URL on the server')\n }\n return ctx.url\n}\n\nexport interface JWTClaims {\n sub: string // UUID\n email: string\n exp: number\n iat: number\n aud: string\n app_metadata: AppMetadata\n user_metadata: Record<string, unknown>\n}\n\nexport type AuthCallback = (event: AuthEvent, user: User | null) => void\n\n/** Persist the session to localStorage so it survives page reloads. */\nexport const persistSession = true\n\nconst listeners = new Set<AuthCallback>()\n\nexport const emitAuthEvent = (event: AuthEvent, user: User | null): void => {\n for (const listener of listeners) {\n listener(event, user)\n }\n}\n\nlet storageListenerAttached = false\n\nconst attachStorageListener = (): void => {\n if (storageListenerAttached) return\n storageListenerAttached = true\n\n window.addEventListener('storage', (event: StorageEvent) => {\n if (event.key !== 'gotrue.user') return\n\n if (event.newValue) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser()\n emitAuthEvent('login', currentUser ? toUser(currentUser) : null)\n } else {\n emitAuthEvent('logout', null)\n }\n })\n}\n\n/**\n * Subscribes to auth state changes (login, logout, token refresh, user updates).\n * Returns an unsubscribe function. No-op on the server.\n */\nexport const onAuthChange = (callback: AuthCallback): (() => void) => {\n if (!isBrowser()) {\n return () => {}\n }\n\n listeners.add(callback)\n attachStorageListener()\n\n return () => {\n listeners.delete(callback)\n }\n}\n\n/** Logs in with email and password. Works in both browser and server contexts. */\nexport const login = async (email: string, password: string): Promise<User> => {\n if (!isBrowser()) {\n const identityUrl = getServerIdentityUrl()\n const cookies = getCookies()\n\n const body = new URLSearchParams({\n grant_type: 'password',\n username: email,\n password,\n })\n\n let res: Response\n try {\n res = await fetch(`${identityUrl}/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: body.toString(),\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n\n if (!res.ok) {\n const errorBody = await res.json().catch(() => ({}))\n throw new AuthError(\n (errorBody as Record<string, string>).msg ||\n (errorBody as Record<string, string>).error_description ||\n `Login failed (${res.status})`,\n res.status,\n )\n }\n\n const data = (await res.json()) as Record<string, unknown>\n const accessToken = data.access_token as string\n const userData = data as unknown as UserData\n const user = toUser(userData)\n\n cookies.set({\n name: 'nf_jwt',\n value: accessToken,\n httpOnly: true,\n secure: true,\n path: '/',\n sameSite: 'Lax',\n })\n\n return user\n }\n\n const client = getClient()\n\n try {\n const gotrueUser = await client.login(email, password, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Creates a new account. Emits 'login' if autoconfirm is enabled. Works in both browser and server contexts. */\nexport const signup = async (email: string, password: string, data?: Record<string, unknown>): Promise<User> => {\n if (!isBrowser()) {\n const identityUrl = getServerIdentityUrl()\n const cookies = getCookies()\n\n let res: Response\n try {\n res = await fetch(`${identityUrl}/signup`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ email, password, data }),\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n\n if (!res.ok) {\n const errorBody = await res.json().catch(() => ({}))\n throw new AuthError((errorBody as Record<string, string>).msg || `Signup failed (${res.status})`, res.status)\n }\n\n const responseData = (await res.json()) as UserData\n const user = toUser(responseData)\n\n if (responseData.confirmed_at) {\n const accessToken = (responseData as unknown as Record<string, unknown>).access_token as string | undefined\n if (accessToken) {\n cookies.set({\n name: 'nf_jwt',\n value: accessToken,\n httpOnly: true,\n secure: true,\n path: '/',\n sameSite: 'Lax',\n })\n }\n }\n\n return user\n }\n\n const client = getClient()\n\n try {\n const response = await client.signup(email, password, data)\n const user = toUser(response as UserData)\n if (response.confirmed_at) {\n emitAuthEvent('login', user)\n }\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Logs out the current user and clears the session. Works in both browser and server contexts. */\nexport const logout = async (): Promise<void> => {\n if (!isBrowser()) {\n const identityUrl = getServerIdentityUrl()\n const cookies = getCookies()\n\n const jwt = cookies.get('nf_jwt')\n if (jwt) {\n try {\n await fetch(`${identityUrl}/logout`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}` },\n })\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n }\n\n cookies.delete('nf_jwt')\n return\n }\n\n const client = getClient()\n\n try {\n const currentUser = client.currentUser()\n if (currentUser) {\n await currentUser.logout()\n }\n emitAuthEvent('logout', null)\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Redirects to an OAuth provider. Always throws (the page navigates away). Browser only. */\nexport const oauthLogin = (provider: string): never => {\n if (!isBrowser()) {\n throw new Error('oauthLogin() is only available in the browser')\n }\n const client = getClient()\n\n window.location.href = client.loginExternalUrl(provider)\n throw new Error('Redirecting to OAuth provider')\n}\n\nexport interface CallbackResult {\n type: 'oauth' | 'confirmation' | 'recovery' | 'invite' | 'email_change'\n user: User | null\n token?: string\n}\n\n/**\n * Processes the URL hash after an OAuth redirect, email confirmation, password\n * recovery, invite acceptance, or email change. Call on page load. Browser only.\n * Returns `null` if the hash contains no auth parameters.\n */\nexport const handleAuthCallback = async (): Promise<CallbackResult | null> => {\n if (!isBrowser()) return null\n\n const hash = window.location.hash.substring(1)\n if (!hash) return null\n\n const client = getClient()\n\n try {\n const params = new URLSearchParams(hash)\n\n const accessToken = params.get('access_token')\n if (accessToken) {\n const gotrueUser = await client.createUser(\n {\n access_token: accessToken,\n token_type: (params.get('token_type') as 'bearer') ?? 'bearer',\n expires_in: Number(params.get('expires_in')),\n expires_at: Number(params.get('expires_at')),\n refresh_token: params.get('refresh_token') ?? '',\n },\n persistSession,\n )\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'oauth', user }\n }\n\n const confirmationToken = params.get('confirmation_token')\n if (confirmationToken) {\n const gotrueUser = await client.confirm(confirmationToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'confirmation', user }\n }\n\n const recoveryToken = params.get('recovery_token')\n if (recoveryToken) {\n const gotrueUser = await client.recover(recoveryToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'recovery', user }\n }\n\n const inviteToken = params.get('invite_token')\n if (inviteToken) {\n clearHash()\n return { type: 'invite', user: null, token: inviteToken }\n }\n\n const emailChangeToken = params.get('email_change_token')\n if (emailChangeToken) {\n const gotrueUser = await client.verify('email_change', emailChangeToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('user_updated', user)\n return { type: 'email_change', user }\n }\n\n return null\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\nconst clearHash = (): void => {\n history.replaceState(null, '', window.location.pathname + window.location.search)\n}\n","import type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getClient } from './environment.js'\nimport { emitAuthEvent, persistSession } from './auth.js'\nimport { AuthError } from './errors.js'\n\n/** Sends a password recovery email to the given address. */\nexport const requestPasswordRecovery = async (email: string): Promise<void> => {\n const client = getClient()\n\n try {\n await client.requestPasswordRecovery(email)\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Redeems a recovery token and sets a new password. Logs the user in on success. */\nexport const recoverPassword = async (token: string, newPassword: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.recover(token, persistSession)\n const updatedUser = await gotrueUser.update({ password: newPassword })\n const user = toUser(updatedUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n\n/** Confirms an email address using the token from a confirmation email. Logs the user in on success. */\nexport const confirmEmail = async (token: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.confirm(token, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Accepts an invite token and sets a password for the new account. Logs the user in on success. */\nexport const acceptInvite = async (token: string, password: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.acceptInvite(token, password, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Verifies an email change using the token from a verification email. */\nexport const verifyEmailChange = async (token: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.verify('email_change', token, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('user_updated', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Updates the current user's metadata or credentials. Requires an active session. */\nexport const updateUser = async (updates: Record<string, unknown>): Promise<User> => {\n const client = getClient()\n\n const currentUser = client.currentUser()\n if (!currentUser) throw new AuthError('No user is currently logged in')\n\n try {\n const updatedUser = await currentUser.update(updates)\n const user = toUser(updatedUser)\n emitAuthEvent('user_updated', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netlify/identity",
3
- "version": "0.1.1-alpha.3",
3
+ "version": "0.1.1-alpha.4",
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",