Skip to content

Server Utilities ​

Server-side utility functions for authentication in API routes and middleware.

Import request handlers and their helpers explicitly from nuxt/server; Nuxt 4 server auto-imports still use h3. Event-taking Aegis utilities accept the portable RequestEvent from nuxt/server.

Authentication Utilities ​

requireAuth(event) ​

Require authentication and return the event with a guaranteed authenticated user in its context.

Type Signature:

typescript
function requireAuth<T extends BaseTokenClaims = BaseTokenClaims>(
  event: RequestEvent,
): RequestEvent & { context: { user: T } }

Parameters:

ParameterTypeDescription
eventRequestEventServer request event

Returns: The same event, with context.user narrowed to T.

Throws: 401 Unauthorized if user is not authenticated or token is invalid/expired

Example:

typescript
// server/routes/api/profile.get.ts
import { defineEventHandler } from 'nuxt/server'

export default defineEventHandler((event) => {
  // Require authentication (throws 401 if not authenticated)
  const { user } = requireAuth(event).context
  
  // User is guaranteed to be authenticated here
  return {
    profile: {
      name: user.name,
      email: user.email,
      role: user.role,
    }
  }
})

Authentication Required

requireAuth() throws a 401 error if the user is not authenticated. Always handle this gracefully on the client side.

getAuthUser(event) ​

Optionally get the current user without throwing an error.

Type Signature:

typescript
function getAuthUser<T extends BaseTokenClaims = BaseTokenClaims>(event: RequestEvent): T | null

Parameters:

ParameterTypeDescription
eventRequestEventServer request event

Returns: T | null - User object if authenticated, null otherwise

Example:

typescript
// server/routes/api/posts.get.ts
import { defineEventHandler } from 'nuxt/server'

export default defineEventHandler(async (event) => {
  // Get user if authenticated (doesn't throw)
  const user = getAuthUser(event)
  
  if (user) {
    // Return personalized content
    return await getPersonalizedPosts(user.sub)
  }
  
  // Return public content
  return await getPublicPosts()
})

Token Utilities ​

generateAuthTokens(event, providerUserInfo, provider, customClaims?) ​

Generate a JWT access token and, when token refresh is enabled, create and store a refresh token. Call this only after authenticating the user. It does not set the refresh-token cookie.

Type Signature:

typescript
async function generateAuthTokens(
  event: RequestEvent,
  providerUserInfo: Record<string, unknown>,
  provider: string,
  customClaims?: Record<string, unknown>,
): Promise<{ accessToken: string, refreshToken?: string }>

Parameters:

ParameterTypeDescription
eventRequestEventServer request event
providerUserInfoRecord<string, unknown>Complete authenticated user data, retained with the refresh token
providerstringProvider name, such as google or github
customClaimsRecord<string, unknown>Optional already-resolved custom claims

Returns: A token pair. refreshToken is absent when token refresh is disabled. Send only accessToken in the response body; use an HttpOnly cookie for the refresh token.

Example:

typescript
// server/utils/createToken.ts
import type { RequestEvent } from 'nuxt/server'
import { generateAuthTokens } from '#nuxt-aegis/server'

export async function createCustomTokens(
  event: RequestEvent,
  user: Record<string, unknown>,
  provider: string,
) {
  return await generateAuthTokens(event, user, provider, {
    role: user.role,
    premium: user.premium,
  })
}

For request authentication, use requireAuth(event).context.user or nullable getAuthUser(event). JWT verification is performed by the module's authentication middleware; there is no public standalone token-verification utility.

Refresh Token Utilities ​

hashRefreshToken(token) ​

Hash a refresh token using SHA-256. Used with revokeRefreshToken() and deleteUserRefreshTokens().

Type Signature:

typescript
function hashRefreshToken(token: string): string

Parameters:

ParameterTypeDescription
tokenstringRefresh token to hash

Returns: string - Hashed token as hex string

Example:

typescript
// server/routes/admin/revoke-token.post.ts
export default defineEventHandler(async (event) => {
  const { refreshToken } = await readBody(event)
  
  const tokenHash = hashRefreshToken(refreshToken)
  await revokeRefreshToken(tokenHash)
  
  return { success: true }
})

revokeRefreshToken(tokenHash) ​

Revoke a refresh token by marking it as revoked without deleting it. This preserves the token data for audit purposes while preventing its use.

Type Signature:

typescript
async function revokeRefreshToken(
  tokenHash: string
): Promise<void>

Parameters:

ParameterTypeDescription
tokenHashstringHashed refresh token (use hashRefreshToken())

Example:

typescript
// server/routes/admin/revoke-session.post.ts
export default defineEventHandler(async (event) => {
  const user = await requireAuth(event)
  
  // Check admin permissions
  if (user.role !== 'admin') {
    throw createError({ status: 403, message: 'Admin access required' })
  }
  
  const { refreshToken } = await readBody(event)
  const tokenHash = hashRefreshToken(refreshToken)
  
  // Revoke the token (marks as revoked, preserves for audit)
  await revokeRefreshToken(tokenHash)
  
  return { 
    success: true,
    message: 'Token revoked successfully' 
  }
})

Audit Trail

Revoked tokens remain in storage with an isRevoked flag, maintaining an audit trail while preventing their use.

deleteUserRefreshTokens(email, exceptTokenHash?) ​

Delete all refresh tokens for a specific user. Useful for security operations like password changes or account deletion.

Type Signature:

typescript
async function deleteUserRefreshTokens(
  email: string,
  exceptTokenHash?: string
): Promise<void>

Parameters:

ParameterTypeDescription
emailstringUser email to match
exceptTokenHashstringOptional token hash to preserve (e.g., current session)

Example:

typescript
// server/routes/auth/password/change.post.ts
export default defineEventHandler(async (event) => {
  const user = await requireAuth(event)
  const { oldPassword, newPassword } = await readBody(event)
  
  // Verify old password and update to new password
  await updateUserPassword(user.email, oldPassword, newPassword)
  
  // Get current refresh token hash to preserve current session
  const currentRefreshToken = getRefreshTokenFromCookie(event)
  const currentTokenHash = currentRefreshToken 
    ? hashRefreshToken(currentRefreshToken) 
    : undefined
  
  // Revoke all other sessions for security
  await deleteUserRefreshTokens(user.email, currentTokenHash)
  
  return { 
    success: true,
    message: 'Password changed, other sessions revoked' 
  }
})

Security Best Practice

Always call deleteUserRefreshTokens() when users change their password or when accounts are deleted to prevent unauthorized access through old refresh tokens.

setRefreshTokenCookie(event, token, cookieConfig?) ​

Set the refresh token cookie. This helper is available as a server auto-import, not as a named export from #nuxt-aegis/server.

Type Signature:

typescript
function setRefreshTokenCookie(
  event: RequestEvent,
  token: string,
  cookieConfig?: CookieConfig,
): void

Parameters:

ParameterTypeDescription
eventRequestEventServer request event
tokenstringRefresh token
cookieConfigCookieConfigOptional cookie settings, including maxAge in seconds; pass nuxtAegis.tokenRefresh.cookie to honor module configuration

Example:

typescript
// server/utils/customAuth.ts
import { useRuntimeConfig } from 'nuxt/server'
import type { RequestEvent } from 'nuxt/server'
import { generateAuthTokens } from '#nuxt-aegis/server'

export async function loginUser(
  event: RequestEvent,
  user: Record<string, unknown>,
  provider: string,
) {
  const { accessToken, refreshToken } = await generateAuthTokens(event, user, provider)

  if (refreshToken) {
    const cookieConfig = useRuntimeConfig().nuxtAegis.tokenRefresh?.cookie
    setRefreshTokenCookie(event, refreshToken, cookieConfig)
  }

  return { accessToken }
}

getRefreshTokenFromCookie(event) ​

Get the refresh token from cookie.

Type Signature:

typescript
function getRefreshTokenFromCookie(event: RequestEvent): string | undefined

Parameters:

ParameterTypeDescription
eventRequestEventServer request event

Returns: string | undefined - Refresh token or undefined if not found

Example:

typescript
// server/routes/check-session.get.ts
export default defineEventHandler(async (event) => {
  const refreshToken = getRefreshTokenFromCookie(event)
  
  return {
    hasSession: !!refreshToken
  }
})

Custom Claims Utilities ​

applyCustomClaims(user, customClaims) ​

Apply custom claims to a user object.

Type Signature:

typescript
function applyCustomClaims(
  user: Record<string, unknown>,
  customClaims: Record<string, unknown> | ((user: Record<string, unknown>) => Record<string, unknown> | Promise<Record<string, unknown>>)
): Promise<Record<string, unknown>>

Parameters:

ParameterTypeDescription
userRecord<string, unknown>User object
customClaimsRecord | FunctionCustom claims object or callback

Returns: Promise<Record<string, unknown>> - User with custom claims applied

Example:

typescript
// server/utils/enrichUser.ts
export async function enrichUserData(user: User) {
  const enriched = await applyCustomClaims(user, async (u) => {
    const profile = await db.getUserProfile(u.email)
    
    return {
      role: profile.role,
      permissions: profile.permissions,
      organizationId: profile.organizationId,
    }
  })
  
  return enriched
}

Complete Example ​

typescript
// server/routes/api/admin/users.get.ts
export default defineEventHandler(async (event) => {
  // Require authentication
  const user = await requireAuth(event)
  
  // Check if user has admin role
  if (user.role !== 'admin') {
    throw createError({
      status: 403,
      message: 'Admin access required'
    })
  }
  
  // Get all users
  const users = await db.users.findMany()
  
  return { users }
})
typescript
// server/routes/api/posts.get.ts
export default defineEventHandler(async (event) => {
  // Optional authentication
  const user = await getAuthUser(event)
  
  if (user) {
    // Personalized posts for authenticated users
    return await db.posts.findMany({
      where: {
        OR: [
          { public: true },
          { authorId: user.sub },
        ]
      }
    })
  }
  
  // Public posts only
  return await db.posts.findMany({
    where: { public: true }
  })
})

Error Handling ​

Handle authentication errors gracefully:

typescript
// server/routes/api/protected.get.ts
export default defineEventHandler(async (event) => {
  try {
    const user = await requireAuth(event)
    
    return { data: 'protected' }
  } catch (error) {
    // Log error but don't expose details
    console.error('Auth error:', error)
    
    throw createError({
      status: 401,
      message: 'Authentication required'
    })
  }
})

Released under the MIT License.