/** The supported OAuth and authentication providers. */ declare const AUTH_PROVIDERS: readonly ["google", "github", "gitlab", "bitbucket", "facebook", "email"]; /** A supported authentication provider name (e.g., `'google'`, `'github'`, `'email'`). */ type AuthProvider = (typeof AUTH_PROVIDERS)[number]; /** * Provider and role metadata stored in a user's `app_metadata` field. * The `provider` field is set automatically on signup; `roles` controls authorization. * Additional keys may be present depending on your Identity configuration. * * @example * ```ts * const meta: AppMetadata = { * provider: 'github', * roles: ['admin'], * custom_claim: 'value', * } * ``` */ interface AppMetadata { provider: AuthProvider; roles?: string[]; [key: string]: unknown; } /** * Identity endpoint configuration for the current environment. * In the browser, `url` is derived from `window.location.origin`. * On the server, `token` is the operator token for admin operations. */ interface IdentityConfig { /** The Identity API endpoint URL (e.g., `https://example.com/.netlify/identity`). */ url: string; /** Operator token for server-side admin requests. Only available in Netlify Functions. */ token?: string; } /** * Project-level Identity settings returned by {@link getSettings}. * Reflects the configuration in your Netlify dashboard. */ interface Settings { /** Whether new signups are auto-confirmed (no confirmation email sent). */ autoconfirm: boolean; /** Whether new signups are disabled entirely. */ disableSignup: boolean; /** Map of provider names to whether they are enabled. */ providers: Record; } /** * Fields accepted by {@link updateUser}. All fields are optional. * Pass `data` to update user metadata (e.g., `{ data: { full_name: 'New Name' } }`). * * @example * ```ts * await updateUser({ data: { full_name: 'Jane Doe' } }) * await updateUser({ email: 'new@example.com' }) * await updateUser({ password: 'new-password' }) * ``` */ interface UserUpdates { email?: string; password?: string; data?: Record; [key: string]: unknown; } /** * User metadata passed during signup (e.g., `{ full_name: 'Jane Doe' }`). * Stored in the user's `user_metadata` field. */ type SignupData = Record; /** * Fields accepted by {@link admin.updateUser}. All fields are optional. * * Unlike {@link UserUpdates} (used by the self-service `updateUser`), admin updates * can set `role`, force-confirm a user, and write to `app_metadata`. * * @example * ```ts * await admin.updateUser(userId, { * role: 'editor', * confirm: true, * app_metadata: { plan: 'pro' }, * }) * ``` */ interface AdminUserUpdates { email?: string; password?: string; /** The user's role (e.g., `'admin'`, `'editor'`). */ role?: string; /** Set to `true` to force-confirm the user's email without sending a confirmation email. */ confirm?: boolean; /** Server-managed metadata. Only writable via admin operations. */ app_metadata?: Record; /** User-managed metadata (display name, avatar, preferences, etc.). */ user_metadata?: Record; } /** * Pagination options for {@link admin.listUsers}. */ interface ListUsersOptions { /** 1-based page number. */ page?: number; /** Number of users per page. */ perPage?: number; } /** * Parameters for {@link admin.createUser}. * * The optional `data` fields are forwarded as top-level attributes in the Identity API * request body. Only these keys are accepted: `role`, `app_metadata`, * `user_metadata`. Any other keys are silently ignored. `data` cannot override * `email`, `password`, or `confirm`. * * @example * ```ts * await admin.createUser({ * email: 'jane@example.com', * password: 'secret', * data: { role: 'editor', user_metadata: { full_name: 'Jane Doe' } }, * }) * ``` */ interface CreateUserParams { email: string; password: string; /** Identity user fields: `role`, `app_metadata`, `user_metadata`. Other keys are ignored. */ data?: Record; } /** * A normalized user object returned by all auth and admin functions. * Provides a consistent shape regardless of whether the user was loaded * from the Identity API, a JWT cookie, or the server-side identity context. * * All fields except `id` are optional and may be `undefined`. Empty strings * are normalized to `undefined`. State-dependent fields (invite, * recovery, email-change) are only present when the user is in that state. * * @example * ```ts * const user = await getUser() * if (user) { * console.log(user.email, user.name, user.roles) * } * ``` */ interface User { /** The user's unique identifier. */ id: string; /** The user's email address. */ email?: string; /** ISO 8601 timestamp of when the user's email was confirmed. `undefined` if not yet confirmed. */ confirmedAt?: string; /** ISO 8601 timestamp of when the account was created. */ createdAt?: string; /** ISO 8601 timestamp of the last account update. */ updatedAt?: string; /** * The account-level role string (e.g., `"admin"`). This is a single value * set via the admin API, distinct from `roles` which is an array in `app_metadata`. * `undefined` when not set or empty. */ role?: string; /** The authentication provider used to create the account (from `app_metadata.provider`). */ provider?: AuthProvider; /** Display name from `user_metadata.full_name` or `user_metadata.name`. */ name?: string; /** Avatar URL from `user_metadata.avatar_url`. */ pictureUrl?: string; /** Application-level roles from `app_metadata.roles`, set via the admin API or Netlify UI. */ roles?: string[]; /** ISO 8601 timestamp of when the user was invited. Only present if the user was created via invitation. */ invitedAt?: string; /** ISO 8601 timestamp of when the confirmation email was last sent. */ confirmationSentAt?: string; /** ISO 8601 timestamp of when the recovery email was last sent. */ recoverySentAt?: string; /** The pending email address during an email change flow. Only present while the change is awaiting confirmation. */ pendingEmail?: string; /** ISO 8601 timestamp of when the email change verification was last sent. */ emailChangeSentAt?: string; /** ISO 8601 timestamp of the user's most recent sign-in. */ lastSignInAt?: string; /** Custom user metadata. Contains profile data like `full_name` and `avatar_url`, and any custom fields set via `updateUser()`. */ userMetadata?: Record; /** Application metadata managed by the server. Contains `provider`, `roles`, and other system-managed fields. */ appMetadata?: Record; } /** * Returns the currently authenticated user, or `null` if not logged in. * Never throws; returns `null` on any failure. * * Always returns a full {@link User} object with all available fields * (email, roles, timestamps, metadata, etc.) regardless of whether the * call happens in the browser or on the server. * * In the browser, checks localStorage first. If no localStorage * session exists, hydrates from the `nf_jwt` cookie (set by server-side login). * * On the server, fetches the full user from the Identity API using the JWT from * the request. Falls back to JWT claims if the Identity API is unreachable. * * On the server in a Next.js App Router context, calls `headers()` from * `next/headers` to opt the route into dynamic rendering. Without this, * Next.js may statically cache the page at build time. */ declare const getUser: () => Promise; /** * Returns `true` if a user is currently authenticated. * Never throws; returns `false` on any failure. */ declare const isAuthenticated: () => Promise; /** * Returns the identity configuration for the current environment. * Browser: always returns `{ url }` derived from `window.location.origin`. * Server: returns `{ url, token }` from the identity context, or `null` if unavailable. * Never throws. */ declare const getIdentityConfig: () => IdentityConfig | null; /** * Fetches your project's Identity settings (enabled providers, autoconfirm, signup disabled). * * @throws {MissingIdentityError} If Identity is not configured. * @throws {AuthError} If the endpoint is unreachable. */ declare const getSettings: () => Promise; /** * Constants for the auth events emitted by the library. * Use these instead of string literals when comparing event types. * * @example * ```ts * onAuthChange((event, user) => { * if (event === AUTH_EVENTS.LOGIN) console.log('Logged in:', user) * if (event === AUTH_EVENTS.RECOVERY) redirect('/reset-password') * }) * ``` */ declare const AUTH_EVENTS: { readonly LOGIN: "login"; readonly LOGOUT: "logout"; readonly TOKEN_REFRESH: "token_refresh"; readonly USER_UPDATED: "user_updated"; readonly RECOVERY: "recovery"; }; /** * Union of all auth event names: `'login' | 'logout' | 'token_refresh' | 'user_updated' | 'recovery'`. * Passed as the first argument to {@link AuthCallback} subscribers. */ type AuthEvent = (typeof AUTH_EVENTS)[keyof typeof AUTH_EVENTS]; /** * Callback function signature for {@link onAuthChange} subscribers. * `user` is `null` on logout events. */ type AuthCallback = (event: AuthEvent, user: User | null) => void; /** * Subscribes to auth state changes (login, logout, token refresh, user updates, * and recovery). Returns an unsubscribe function. No-op on the server. * * The `'recovery'` event fires when {@link handleAuthCallback} processes a * password recovery token. The user is logged in but has not yet set a new * password. Redirect them to a password reset form and call * `updateUser({ password })` to complete the flow. */ declare const onAuthChange: (callback: AuthCallback) => (() => void); /** * Logs in with email and password. Works in both browser and server contexts. * * On success, sets `nf_jwt` and `nf_refresh` cookies and returns the authenticated {@link User}. * In the browser, also emits a `'login'` event via {@link onAuthChange}. * * @throws {AuthError} On invalid credentials, network failure, or missing Netlify runtime. * * @remarks * In Next.js server actions, call `redirect()` **after** `login()` returns, not inside a * try/catch. Next.js implements `redirect()` by throwing a special error; wrapping it in * try/catch will swallow the redirect. * * **Server-side CSRF:** When called from a server endpoint, the endpoint must have CSRF * protection. If your framework does not check the request's `Origin` by default, call * {@link verifyRequestOrigin} at the start of the handler before invoking `login()`. * * @example * ```ts * // Next.js server action * const user = await login(email, password) * redirect('/dashboard') // after login, not inside try/catch * ``` */ declare const login: (email: string, password: string) => Promise; /** * Creates a new account. Works in both browser and server contexts. * * If autoconfirm is enabled in your Identity settings, the user is logged in immediately: * cookies are set and a `'login'` event is emitted. If autoconfirm is **disabled** (the default), * the user receives a confirmation email and must click the link before they can log in. * In that case, no cookies are set and no auth event is emitted. * * @throws {AuthError} On duplicate email, validation failure, network error, or missing Netlify runtime. * * @remarks * **Server-side CSRF:** When called from a server endpoint, the endpoint must have CSRF * protection. If your framework does not check the request's `Origin` by default, call * {@link verifyRequestOrigin} at the start of the handler before invoking `signup()`. */ declare const signup: (email: string, password: string, data?: SignupData) => Promise; /** * Logs out the current user and clears the session. Works in both browser and server contexts. * * Always deletes `nf_jwt` and `nf_refresh` cookies, even if the server-side token * invalidation request fails. In the browser, emits a `'logout'` event via {@link onAuthChange}. * * @throws {AuthError} On missing Netlify runtime (server) or logout failure (browser). * * @remarks * **Server-side CSRF:** When called from a server endpoint, the endpoint must have CSRF * protection. If your framework does not check the request's `Origin` by default, call * {@link verifyRequestOrigin} at the start of the handler before invoking `logout()`. */ declare const logout: () => Promise; /** * Initiates an OAuth login by redirecting to the given provider (e.g., `'google'`, `'github'`). * The page navigates away; this function never returns normally. Browser only. * * After the provider redirects back, call {@link handleAuthCallback} on page load * to complete the login and obtain the {@link User}. * * @throws {AuthError} If called on the server. */ declare const oauthLogin: (provider: AuthProvider) => never; /** * Result returned by {@link handleAuthCallback} after processing a URL hash. * * - `'oauth'`: OAuth provider redirect completed. `user` is the authenticated user. * - `'confirmation'`: Email confirmed via token. `user` is the confirmed user. * - `'recovery'`: Password recovery token redeemed. `user` is logged in but must set a new password. * - `'invite'`: Invite token found. `user` is `null`; `token` contains the invite token for {@link acceptInvite}. * - `'email_change'`: Email change verified. `user` reflects the updated email. * * @example * ```ts * const result = await handleAuthCallback() * if (result?.type === 'recovery') { * redirect('/reset-password') * } else if (result?.type === 'invite') { * redirect(`/join?token=${result.token}`) * } * ``` */ interface CallbackResult { /** The type of auth callback that was processed. */ type: 'oauth' | 'confirmation' | 'recovery' | 'invite' | 'email_change'; /** The authenticated user, or `null` for invite callbacks. */ user: User | null; /** The invite token, only present when `type` is `'invite'`. */ token?: string; } /** * Processes the URL hash after an OAuth redirect, email confirmation, password * recovery, invite acceptance, or email change. Call on page load. Browser only. * Returns `null` if the hash contains no auth parameters. * * Call this early in your app's initialization (e.g., in a layout component or * root loader), **not** inside a route that requires authentication, because * the callback URL must match the page where this function runs. * * For recovery callbacks (`result.type === 'recovery'`), the user is logged in * but has **not** set a new password yet. Your app must check the result type * and redirect to a password form that calls `updateUser({ password })`. * A `'recovery'` event (not `'login'`) is emitted via {@link onAuthChange}. * * @throws {AuthError} If the callback token is invalid or the verification request fails. */ declare const handleAuthCallback: () => Promise; /** * Hydrates the browser-side session from server-set auth cookies. * Call this on page load when using server-side login to enable browser * account operations (updateUser, verifyEmailChange, etc.). * * No-op if a browser session already exists or no auth cookies are present. * No-op on the server. */ declare const hydrateSession: () => Promise; /** * Refreshes the session's access token. * * **Browser:** Token refresh is handled automatically after any browser flow * that establishes a session (`login`, `signup`, `hydrateSession`, * `handleAuthCallback`, `confirmEmail`, `recoverPassword`, `acceptInvite`) * and by `getUser` when it finds an existing session. Calling * `refreshSession()` in the browser triggers an * immediate refresh if the token is near expiry. Returns the new JWT on * success, or `null` if no refresh is needed. Browser-side errors (e.g., * revoked refresh token) do not throw; they return `null`. * * **Server:** Reads the `nf_jwt` and `nf_refresh` cookies, checks if the token * is expired or near expiry, and exchanges the refresh token for a new access * token via the Identity `/token` endpoint. Updates both cookies on the response. * Call this in framework middleware or at the start of server-side request * handlers to ensure subsequent requests carry a valid JWT. * * Returns the new access token on success, or `null` if no refresh is needed * or the refresh token is invalid/missing (400/401). * * @throws {AuthError} Server-side only: on network failure or when the Identity URL cannot be determined. * * @example * ```ts * // In server middleware (e.g., Astro, SvelteKit) * import { refreshSession } from '@netlify/identity' * await refreshSession() * ``` */ declare const refreshSession: () => Promise; /** * Thrown by auth operations when something goes wrong: invalid credentials, * network failures, missing runtime context, etc. * * The `status` field contains the HTTP status code from the Identity API when available * (e.g., 401 for bad credentials, 422 for validation errors). * The `cause` field preserves the original error for debugging. * * @example * ```ts * try { * await login(email, password) * } catch (error) { * if (error instanceof AuthError) { * console.error(error.message, error.status) * } * } * ``` */ declare class AuthError extends Error { name: string; /** HTTP status code from the Identity API, if the error originated from an API response. */ status?: number; cause?: unknown; constructor(message: string, status?: number, options?: { cause?: unknown; }); static from(error: unknown): AuthError; } /** * Thrown when a function requires the Identity client but Netlify Identity * is not configured (no endpoint URL could be discovered). * * This typically means the site does not have Identity enabled, or the app * is not running via `netlify dev` / deployed on Netlify. */ declare class MissingIdentityError extends Error { name: string; constructor(message?: string); } /** * Options for {@link verifyRequestOrigin}. */ interface VerifyRequestOriginOptions { /** * Origins that are allowed to make state-changing requests to this endpoint. * * If omitted, the request is only accepted from its own origin (the origin of `request.url`), * which is the right default for sites whose login form and login endpoint live on the same origin. * * Pass an explicit list when you trust additional origins (for example, a separate frontend domain * posting to an API on another domain). The list replaces the default, so it must include every * origin you want to allow, including the request's own origin if applicable. * * Each value should be a full origin string with scheme and host: `'https://example.com'`. */ allowedOrigins?: string[]; } /** * Same-origin check for state-changing requests, can be used to defend against Cross-Site Request * Forgery (CSRF) on server-side endpoints that call {@link login}, {@link signup}, or {@link logout}. * * Compares the incoming request's `Origin` header against the request's own origin (or an explicit * allowlist via `options.allowedOrigins`) and throws if they don't match. Call this at the start of * any server-side handler that performs an auth mutation, before invoking the auth function. * * The check runs unconditionally on every call: any HTTP method, with or without an `Origin` header. * If you don't want the check to apply to a given method or path, simply don't call the helper there. * * @throws {AuthError} with status `403` when the request has no `Origin` header. * @throws {AuthError} with status `403` when the request's `Origin` is not in the allowed origins. * * @example * ```ts * // Netlify Function * import { login, verifyRequestOrigin } from '@netlify/identity' * import type { Context } from '@netlify/functions' * * export default async (req: Request, context: Context) => { * verifyRequestOrigin(req) * const { email, password } = await req.json() * await login(email, password) * return new Response(null, { status: 302, headers: { Location: '/dashboard' } }) * } * ``` * * @example * ```ts * // Allow a separate trusted origin (e.g. a marketing site posting to an app domain). * // The list replaces the default, so include the request's own origin if you still want it allowed. * verifyRequestOrigin(request, { * allowedOrigins: ['https://app.example.com', 'https://www.example.com'], * }) * ``` */ declare const verifyRequestOrigin: (request: Request, options?: VerifyRequestOriginOptions) => void; /** * The admin namespace for privileged user management operations. * All methods are server-only and require the operator token * (automatically available in Netlify Functions and Edge Functions). * * Calling any admin method from a browser environment throws an `AuthError`. */ interface Admin { /** * Lists all users. Server-only. * * Calls `GET /admin/users` with the operator token. Pagination * options (`page`, `perPage`) are forwarded as query parameters. * * @throws {AuthError} If called from a browser, or if the operator token is missing. */ listUsers: (options?: ListUsersOptions) => Promise; /** * Gets a single user by ID. Server-only. * * Calls `GET /admin/users/:id` with the operator token. * * @throws {AuthError} If called from a browser, the user is not found, * or the operator token is missing. */ getUser: (userId: string) => Promise; /** * Creates a new user. The user is auto-confirmed (no confirmation email is sent). * Server-only. * * The optional `data` fields are forwarded as top-level attributes in the Identity API * request body. Accepted fields: `role`, `app_metadata`, `user_metadata`. * Any other keys in `data` are silently ignored. `data` cannot override `email`, * `password`, or `confirm`. * * Calls `POST /admin/users` with the operator token. * * @throws {AuthError} If called from a browser, the email already exists, * or the operator token is missing. */ createUser: (params: CreateUserParams) => Promise; /** * Updates an existing user by ID. Server-only. * * Calls `PUT /admin/users/:id` with the operator token. * * @throws {AuthError} If called from a browser, the user is not found, * the update fails, or the operator token is missing. */ updateUser: (userId: string, attributes: AdminUserUpdates) => Promise; /** * Deletes a user by ID. Server-only. * * Calls `DELETE /admin/users/:id` with the operator token. * * @throws {AuthError} If called from a browser, the user is not found, * the deletion fails, or the operator token is missing. */ deleteUser: (userId: string) => Promise; } declare const admin: Admin; /** * Sends a password recovery email to the given address. * * @throws {AuthError} On network failure or if the request is rejected. */ declare const requestPasswordRecovery: (email: string) => Promise; /** * Redeems a recovery token and sets a new password. Logs the user in on success. * * @throws {AuthError} If the token is invalid, expired, or the update fails. */ declare const recoverPassword: (token: string, newPassword: string) => Promise; /** * Confirms an email address using the token from a confirmation email. Logs the user in on success. * * @throws {AuthError} If the token is invalid or expired. */ declare const confirmEmail: (token: string) => Promise; /** * Accepts an invite token and sets a password for the new account. Logs the user in on success. * * @throws {AuthError} If the token is invalid or expired. */ declare const acceptInvite: (token: string, password: string) => Promise; /** * Verifies an email change using the token from a verification email. * Auto-hydrates from auth cookies if no browser session exists. Browser only. * * @throws {AuthError} If called on the server, no user is logged in, or the token is invalid. */ declare const verifyEmailChange: (token: string) => Promise; /** * Updates the current user's email, password, or user metadata. * Auto-hydrates from auth cookies if no browser session exists. * * @param updates - Fields to update. Pass `email` or `password` to change credentials, * or `data` to update user metadata (e.g., `{ data: { full_name: 'New Name' } }`). * @throws {AuthError} If no user is logged in or the update fails. */ declare const updateUser: (updates: UserUpdates) => Promise; export { AUTH_EVENTS, type Admin, type AdminUserUpdates, type AppMetadata, type AuthCallback, AuthError, type AuthEvent, type AuthProvider, type CallbackResult, type CreateUserParams, type IdentityConfig, type ListUsersOptions, MissingIdentityError, type Settings, type SignupData, type User, type UserUpdates, type VerifyRequestOriginOptions, acceptInvite, admin, confirmEmail, getIdentityConfig, getSettings, getUser, handleAuthCallback, hydrateSession, isAuthenticated, login, logout, oauthLogin, onAuthChange, recoverPassword, refreshSession, requestPasswordRecovery, signup, updateUser, verifyEmailChange, verifyRequestOrigin };