Docs
Auth Flow
Auth Flow
End-to-end explanation of the authentication flow
Overview
The authentication layer is powered by NextAuth.js with a custom Kysely adapter. It handles Google OAuth sign-in, builds secure JWT-based sessions, and keeps the current user cached for server components. Business logic lives in services/auth, which coordinates repositories (raw SQL via Kysely), OAuth clients, and downstream features such as automatic personal project creation.
Main Libraries/Services:
- NextAuth.js – Manages OAuth redirects, JWT/session callbacks, and session cookies.
- Kysely + raw SQL repositories – Persist users, accounts, sessions, and tokens in PostgreSQL.
- services/auth/* – Orchestrates registration, provider linking, session handling, verification, and platform-admin checks.
- lib/session.ts – Provides request-scoped cached helpers (
getSession,getCurrentUser,getCurrentUserId). - clients/auth – Wraps external OAuth providers for token exchange and profile retrieval.
File Map
auth.ts– NextAuth handler; configures providers, callbacks, events, and exposes theauth()helper.config/auth.ts– Defines Google OAuth provider credentials and shared NextAuth options.lib/adapters/kysely-adapter.ts– Custom NextAuth adapter backed by Kysely repositories.lib/session.ts– Caches server-side session lookups per request to avoid redundant I/O.services/auth/session.ts– Implements JWT/session callbacks and exposes helpers to validate, refresh, and destroy sessions.services/auth/providers.ts– Handles OAuth callbacks, account linking, and provider metadata.services/auth/registration.ts– Creates users, personal projects, and project memberships during onboarding.services/auth/user.ts– User CRUD, profile updates, and activity/statistics queries.services/auth/verification.ts– Placeholder service for verification and password reset workflows.services/auth/platform-admin.ts– Determines platform-admin/owner access based on project roles.repositories/auth/*– Raw SQL queries (via Kysely) for users, accounts, sessions, verification tokens, and roles.
Step-by-Step Flow
OAuth Sign-In (Google)
- The client calls
signIn("google"); NextAuth usesauth.ts/config/auth.tsto redirect to Google with PKCE + state. - After Google calls back, NextAuth invokes
ProviderService.handleOAuthCallback()to exchange the code for tokens throughclients/auth. RegistrationService.handleOAuthRegistration()ensures a user record exists, using repositories plusprojectService.createPersonalProject()to seed a personal workspace with OWNER membership.- Provider accounts are stored with
createAccount/linkProviderAccount, so future sign-ins reuse the same user.
Session & JWT Callbacks
- During sign-in,
SessionManagementService.handleJWTCallback()enriches the JWT withsub,name,email, andpicture. - When a session is read,
handleSessionCallback()mirrors token data back into the session payload, preservingexpires. - If
trigger === "update", the service refetches the latest user viauserService.getUserById()to keep session data in sync after profile edits. SessionServicecan create, validate, refresh, or revoke database-backed sessions for other features (e.g., admin dashboards).
Session Access in Server Components
auth.tscallssetNextAuthConfig()solib/session.tscan reuse the NextAuth options without circular imports.getSession,getCurrentUser, andgetCurrentUserIdare wrapped with React’scache()to dedupe work within a request.- Server components and API routes import these helpers to guard routes or fetch the current user without repeated database calls.
Project Bootstrapping & Admin Detection
- The NextAuth
createUserevent triggersprojectService.createPersonalProject()so every new account has an OWNER project. RegistrationServicereuses the same logic for invitation acceptance to maintain consistent ownership rules.SessionManagementService.isAdmin()relies onplatform-admin.tsto determine whether the authenticated user owns or administers any project and unlock platform-level actions accordingly.
Data Flow Diagram
flowchart TD
A[User clicks Sign in] --> B[NextAuth handler (auth.ts)]
B --> C[services/auth/providers]
C --> D[registrationService + projectService]
D --> E[repositories/auth (Kysely + SQL)]
E --> F[(PostgreSQL)]
F --> G[SessionManagementService callbacks]
G --> H[lib/session cached helpers]
H --> I[Server components & API routes]Dependencies & Contracts
IAuthUser– Canonical user object returned by auth services and stored in JWT/session data.IAuthSession– Session payload emitted bySessionService.IProviderAuthResult– Standard success/error contract for OAuth callbacks and account linking.IUserRegistrationData– Input required when onboarding users via email or provider flows.ISessionValidationResult– Outcome of validating session tokens (valid flag, user, optional error metadata).
Known Limitations
- Email/password and magic-link flows are not implemented;
VerificationServicestill stores tokens in memory. AuthService.signInWithProvider()contains a TODO to coordinate provider callbacks through a single helper.- The legacy Prisma seed script still exists; seeding and migrations must be rewritten around Kysely SQL files.
Notes & TODOs
- Implement persistent verification-token storage using the auth repositories.
- Replace the Prisma-based seed pipeline with a Kysely-driven seeding script.
- Extend
RegistrationServiceonce verification storage is ready to support magic-link or other passwordless flows.