API & Composable Reference

Complete reference for useBearerAuth composable, types, server handlers, server utilities, and public type exports.

Reference & Recipes Nuxt 4 / TypeScript

useBearerAuth() / useAuth()

typescript
import { useBearerAuth, useAuth } from '#imports'

const auth = useBearerAuth<CustomUser>()

Reactive State Properties

| Property | Type | Description | | :--- | :--- | :--- | | user | Ref<User | null> | Current authenticated user profile object. | | status | Ref<AuthStatus> | 'idle' | 'loading' | 'authenticated' | 'unauthenticated'. | | ready | Ref<boolean> | true once initial auth check (SSR or client) has resolved. | | error | Ref<string | null> | Last authentication error message string. | | abilities | Ref<string[] | null> | Normalized ability strings hydrated from the server session; powers the advisory can() / cannot() checks. | | loading | ComputedRef<boolean> | Convenience computed shorthand for status.value === 'loading'. | | isAuthenticated | ComputedRef<boolean> | Convenience computed shorthand for status.value === 'authenticated'. | | serverReady | ComputedRef<Promise<void>> | Resolves when server-side auth hydration completes. Used internally by the global middleware. |

Composable Methods

typescript
// 1. Login with credentials
login(credentials: LoginCredentials, redirectPath?: string | null): Promise<AuthApiResponse<User>>

// 2. Social login with OAuth provider JWT/Token
socialLogin(credentials: SocialLoginCredentials, redirectPath?: string | null): Promise<AuthApiResponse<User>>

// 3. Register a new user
register(payload: Record<string, unknown>, redirectPath?: string | null): Promise<AuthApiResponse<User>>

// 4. Verify OTP code
verifyOtp(payload: Record<string, unknown>, redirectPath?: string | null): Promise<AuthApiResponse<User>>

// 5. Fetch current user from /api/auth/me
fetchUser(options?: FetchUserOptions): Promise<{ data: User | null; error: string | null }>

// 6. Silent token refresh
refresh(): Promise<AuthApiResponse<User>>

// 7. Logout and destroy session
logout(destination?: string): Promise<void>

// 8. Forgot password request
forgotPassword(payload: Record<string, unknown>): Promise<any>

// 9. Reset password request
resetPassword(payload: Record<string, unknown>): Promise<any>

// 10. Resend OTP code
resendOtp(identifier: string, payload?: Record<string, unknown>): Promise<any>

// 11. Clear client auth state manually
clearAuthState(): void

// 12. Advisory ability check — exact string match against auth.abilities
can(ability: string): boolean

// 13. Inverse of can()
cannot(ability: string): boolean

Built-in Server API Routes

The module mounts these Nitro handlers under routes.localApiPrefix (default: /api/auth): | Method & Route | Backend Endpoint Forwarded | Description | | :--- | :--- | :--- | | POST /api/auth/login | endpoints.login | Authenticates user, creates Redis session, sets cookie. | | POST /api/auth/social-login | endpoints.socialLogin | Passes OAuth token to backend, creates Redis session. | | POST /api/auth/logout | endpoints.logout | Destroys Redis session and cookie; calls backend logout (continues even if backend is unreachable). | | GET /api/auth/me | endpoints.me | Returns current user from Redis session cache or refreshes from backend if ?refresh=true. | | POST /api/auth/refresh | endpoints.refresh | Calls backend refresh using Redis-held refresh token, updates session. New token is not returned to browser. | | POST /api/auth/register | endpoints.register | Forwards registration payload. Creates session if backend returns a token. | | POST /api/auth/otp-verification| endpoints.verifyOtp | Forwards OTP verification payload. Creates session if backend returns a token. | | POST /api/auth/resend-otp/:id | endpoints.resendOtp | Triggers OTP resend for given user identifier. | | POST /api/auth/forgot-password | endpoints.forgotPassword| Forwards forgot-password email/payload. | | POST /api/auth/reset-password | endpoints.resetPassword | Forwards password reset payload with token. | | GET /api/auth/sessions | Local Redis | Lists active sessions for current user as { sessions: PublicSession[] }. | | DELETE /api/auth/sessions/:id | Local Redis | Revokes specific session ID after verifying ownership. |

Server Utilities

When writing custom Nitro endpoints in your application, import these utilities from #imports:
typescript
import {
  // Session read/write
  getBearerAuthSession,       // Read session from Redis by cookie
  createBearerAuthSession,    // Create new session after authentication
  updateBearerAuthSession,    // Update token, refreshToken, or profile in session
  destroyBearerAuthSession,   // Delete session from Redis and clear cookie
  destroyAllBearerAuthSessions, // Delete all sessions for a user ID
  getUserBearerAuthSessions,  // List PublicSession[] for a user (no tokens)
  deleteUserBearerAuthSession, // Delete a specific session with ownership check

  // Guard utility
  requireBearerAuthSession,   // Read event.context.auth or throw 401

  // External API proxy
  callAuthApi,                // Make authenticated request to backend using session token

  // Redis client (advanced use)
  getBearerAuthRedisClient,
} from '#imports'
requireBearerAuthSession(event) reads from event.context.auth (populated by the server middleware) and throws a 401 Unauthenticated error if no valid session is present. It does not make an additional Redis query — the session is already attached to the event context by the time your handler runs. requireAbility(event, abilities, mode?) enforces authorization on top of authentication: it throws 401 Unauthenticated when no session exists and 403 Authorization required when the session lacks the required ability. It is imported from the server-only subpath nuxt-bearer-auth/server rather than #imports so it never reaches client bundles. See the Authorization guide. callAuthApi(endpoint, options) constructs an HTTP request to your backend using apiBaseUrl + endpoint. When an event is provided, it automatically retrieves the bearer token from the Redis session and injects it as an Authorization: Bearer header. The token is never passed through the browser. The nuxt-bearer-auth/server subpath also exports the supporting primitives requireAbility() builds on: normalizeAuthorizationData(), extractAuthorizationFromResponse(), and hasRequiredAbilities(). Treat requireAbility() as the primary API — the others are the same normalization and matching helpers the module uses internally, exported for custom enforcement code.

UI Authorization Components

Two auto-imported components expose declarative authorization over the same client ability state that powers can()/cannot(). Full usage guidance lives in the Authorization guide. | Component | Renders its default slot when | | --- | --- | | <Can> | The current abilities satisfy the requirement. | | <Cannot> | They do not — the exact negation of <Can>, with no separate matching logic. | Shared props: ability?: string (single ability, wins over abilities), abilities?: string[] (evaluated with mode), and mode?: 'all' | 'any' (default 'all'). An optional #fallback slot renders when the check denies, and denied slot content is removed from the DOM. Evaluation is reactive to login, refresh, logout, and session replacement, deterministic across SSR and hydration, and fails closed on malformed props or malformed ability state. An empty requirement means unrestricted.
vue
<Can ability="users.delete">
  <button>Delete user</button>

  <template #fallback>
    <span>You do not have permission to delete users.</span>
  </template>
</Can>
Components control visibility only — they never secure API requests. Enforce authorization in Nitro handlers with requireAbility(), and always enforce it again on your backend.

TypeScript Types

typescript
export type AuthStatus = 'idle' | 'loading' | 'authenticated' | 'unauthenticated'

export interface BearerAuthUser {
  id?: string | number
  uuid?: string
  email?: string
  name?: string
  [key: string]: unknown  // Open-ended — your backend user shape
}

export interface BearerAuthSession<User extends BearerAuthUser = BearerAuthUser> {
  userId: string
  token: string           // Bearer token — server-side only
  refreshToken?: string | null
  profile: User | null
  createdAt: string       // ISO timestamp
  expiresAt: number       // Epoch milliseconds (application-level expiry guard)
  lastActivity: string    // ISO timestamp — updated on each authenticated request
  userAgent?: string
  ipAddress?: string
  abilities?: string[] | null  // Normalized ability strings — server-derived
}

// Safe public shape — omits token, refreshToken, userId, expiresAt
export interface PublicSession {
  id: string
  createdAt: string
  lastActivity: string
  userAgent?: string
  ipAddress?: string
}

export interface AuthApiResponse<T = unknown> {
  success: boolean
  message?: string
  data?: T
  user?: BearerAuthUser | null
  code?: string | number
  nextAction?: string
}

export interface LoginCredentials {
  identifier?: string
  email?: string
  username?: string
  phone?: string
  mobile?: string
  password?: string
  [key: string]: unknown
}

export interface SocialLoginCredentials {
  jwt?: string
  token?: string
  provider?: string
  [key: string]: unknown
}

export interface FetchUserOptions {
  refresh?: boolean
}

Public Type Exports

All core authentication types are exported from the package root and can be imported directly in your application:

typescript
import type {
  // Auth state and response types
  AuthStatus,
  AuthApiResponse,
  BearerAuthUser,
  BearerAuthSession,
  PublicSession,

  // Credential types
  LoginCredentials,
  SocialLoginCredentials,
  FetchUserOptions,

  // Module configuration types
  BearerAuthModuleOptions,
  BearerAuthEndpointOptions,
  BearerAuthResponsePaths,
  BearerAuthRedirectOptions,
  BearerAuthRouteOptions,
  BearerAuthCookieOptions,
  BearerAuthCsrfOptions,

  // Authorization types
  Ability,
  AuthorizationSource,
  AuthorizationMatchMode,
  AuthorizationRouteRequirement,
  AuthorizationResponsePaths,
  AuthorizationState,
  BearerAuthAuthorizationConfig,
} from 'nuxt-bearer-auth'
These types are useful when extending the module, writing typed custom middleware, building strongly-typed composables around useBearerAuth, or constructing typed server API handlers.
typescript
// Example: extending BearerAuthUser with your own fields
import type { BearerAuthUser } from 'nuxt-bearer-auth'

interface AppUser extends BearerAuthUser {
  role: 'admin' | 'editor' | 'viewer'
  organizationId: string
  avatarUrl?: string
}

// Pass your type to the composable for full type inference
const auth = useBearerAuth<AppUser>()

// auth.user.value is now typed as AppUser | null
console.log(auth.user.value?.role)

Testing Foundation

nuxt-bearer-auth ships with a comprehensive automated test suite to give you confidence in the authentication and authorization foundation you are building on. Test runner: Vitest Test results: 15 test files · 163 tests · 163 passing (verified after the Phase 4 UI authorization release)

The suite covers:

| Suite | What it tests | | :--- | :--- | | sessions.test.ts | Session creation, retrieval, update, sliding TTL, destroy, destroy-all, multi-device listing, per-user revocation, requireBearerAuthSession | | auth-handlers.test.ts | Login, social login, logout resilience, token refresh, /me cached vs. forced refresh | | otp-register.test.ts | OTP verification flow, registration with and without auto-login | | server-middleware.test.ts | Public route bypass, safe method bypass, authenticated context attachment, 401 on protected routes | | route-middleware.test.ts | Client route guard — public access, protected redirect, auth-page redirect for authenticated users, Phase 3 authorization metadata enforcement (disabled mode inert, all/any modes, exact matching, custom unauthorized route, fail-closed malformed client state) | | authorization-normalization.test.ts | Abilities/roles/permissions normalization into sorted unique strings, disabled/missing configuration safety | | authorization-client.test.ts | Client ability synchronization across login/refresh/me, omission preservation, logout clearing stale abilities | | authorization-enforcement.test.ts | Server requireAbility() — 401 vs 403, all/any semantics, exact matching, fail-closed malformed session data, rejection of client-supplied state/headers/query | | authorization-ui-evaluator.test.ts | Pure Phase 4 evaluator — all/any modes, exact and case-sensitive matching, wildcard/prefix/role non-implication, empty requirements unrestricted, fail-closed malformed state and requirements, input immutability | | authorization-ui-components.test.ts | <Can>/<Cannot> component matrix — prop normalization and precedence, fallback slots, reactivity to login/logout/refresh, SSR determinism, fail-closed behavior | | ssr-plugin.test.ts | SSR hydration with valid session, unauthenticated SSR, Redis error resilience | | normalize.test.ts | Response path normalization for multiple backend response shapes | | paths.test.ts | JSON path traversal, $ root selector, dot notation, null safety, URL interpolation | | errors.test.ts | FetchError normalization, H3 error passthrough, generic error → 500 | | redis-reliability.test.ts | Edge cases: missing cookie, missing session key, partial context |

Run the tests yourself:

bash
# In the nuxt-bearer-auth package directory
npm test