Skip to content

Authentication

The API supports multiple authentication methods: JWT bearer tokens and API keys.

Authentication Flow

JWT Authentication

Token Format

JWTs contain user claims:

typescript
interface JWTPayload {
 sub: string // User ID
 email: string
 iat: number
 exp: number
}

Usage

Include in the Authorization header:

Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

API Key Authentication

API keys are used for server-to-server communication.

Usage

Include in the X-API-Key header:

X-API-Key: your-api-key

Security Decorators

Basic Security

typescript
@Security({ bearer: [], apiKey: [] })  // Either method
@Security("bearer")                     // JWT only
@Security("apiKey")                     // API key only

Scoped Security

typescript
@Security("bearer", ["admin"])  // Requires admin scope

Route Guards

Guards provide additional authorization beyond authentication.

AccountRouteGuard

Validates access to account-specific resources:

typescript
@Route("v1/accounts/{accountId}/books")
@Middlewares(new AccountRouteGuard().getHandler())
export class AccountBookController extends Controller {
 // Only accessible if user is a member of the account
}

AccessGuard

Permission-based access control:

typescript
import { Role } from "../security/Role"

@Middlewares(new AccessGuard(Role.MANAGE_BOOKS).getHandler())

SubscriptionGuard

Tier-based restrictions:

typescript
@Middlewares(new SubscriptionGuard("premium").getHandler())

Combining Guards

Apply multiple guards for layered security:

typescript
@Route("v1/accounts/{accountId}/admin")
@Security({ bearer: [], apiKey: [] })
@Middlewares([
 new AccountRouteGuard().getHandler(), 
 new AccessGuard(Role.ADMIN).getHandler()
])
export class AdminController extends Controller {
 // Requires: authenticated + account member + admin role
}

Accessing User Context

Access the authenticated user in controllers:

typescript
@Get("/me")
public async getMe(@Request() req: ExpressRequest): Promise<User> {
 const userId = req.user.sub
 return this.userService.findById(userId)
}

Built with VitePress