Skip to content

Auth System ​

Authentication is handled by better-auth, a session-based auth library. There are no JWT tokens — authentication state lives in a server-side session tied to a cookie.

Session flow ​

  1. User clicks "Sign in with Google"
  2. Browser redirects to /api/auth/signin/google
  3. better-auth redirects to Google's OAuth consent screen
  4. Google redirects back to /api/auth/callback/google
  5. better-auth creates or updates a User, Account, and Session record in the database
  6. A session cookie (better-auth.session_token) is set on the browser
  7. Every subsequent request sends the cookie automatically

Routes ​

better-auth mounts its routes under /api/auth/. Key endpoints:

EndpointDescription
GET /api/auth/signin/googleInitiate Google OAuth flow
GET /api/auth/callback/googleOAuth callback (handled by better-auth)
POST /api/auth/signoutInvalidate the current session
GET /api/auth/sessionReturn the current session and user

Guards and decorators ​

AuthGuard (global) ​

Applied globally in AppModule. Validates the session cookie and attaches the User object to request.user. Returns 401 if no valid session exists.

@Public() ​

Marks a route as publicly accessible (bypasses AuthGuard):

typescript
import { Public } from '../auth/decorators'

@Public()
@Get('health')
health() { return 'ok' }

@CurrentUser() ​

Injects the authenticated User object:

typescript
@Get('me')
getProfile(@CurrentUser() user: User) {
  return user
}

@TenantId() ​

Extracts tenantId from request.params.tenantId (set by TenantGuard):

typescript
@Get()
findAll(@TenantId() tenantId: string) { ... }

@TenantUserId() ​

Injects the tenantUserId resolved by TenantGuard for the current user within the requested tenant.

API Key authentication ​

Requests can also authenticate with an API key in the Authorization header:

Authorization: Bearer tt_<key>

The ApiKeyGuard (applied globally alongside AuthGuard) recognises this prefix, hashes the key, and looks it up in the api_keys table. If valid and not revoked/expired, it grants admin-level access to the key's tenant.

Database tables ​

better-auth manages these tables automatically (do not modify them manually):

  • users — Global user accounts
  • sessions — Active sessions
  • accounts — OAuth provider links (Google)
  • verifications — Email verification tokens

TT Time Tracker — Internal Documentation