🗂️ Fastify User Management Boilerplate

A production-ready back-office boilerplate for user account management, built with Fastify, Prisma, Zod, and PostgreSQL. Designed to be forked and extended as the backend foundation of any application requiring authentication and account lifecycle management.


Features

  • Authentication JWT-based auth with cookie support and token versioning (revocation on password change)
  • Registration & Login Secure password hashing with Argon2
  • Google OAuth Login or register via Google access token, with automatic account merge detection
  • Password recovery Forgot password flow with time-limited action tokens
  • Password change Authenticated password update with session revocation
  • Email change Two-step flow with a 15-minute confirmation window and a 24-hour rollback period
  • Account deletion Soft-delete with a 7-day cancellation window
  • Input validation Zod schemas with shared password rules
  • Email notifications Nodemailer integration (confirmation, recovery, alerts)
  • Scheduled tasks node-cron for background jobs (e.g. purging expired accounts)
  • Security-first error codes Intentionally vague error responses to prevent user enumeration

🧱 Stack

Layer Technology
Framework Fastify v5
ORM Prisma v7
Database PostgreSQL (via pg + @prisma/adapter-pg)
Validation Zod v4
Auth @fastify/jwt + @fastify/cookie
Password hashing Argon2
Email Nodemailer
Scheduled jobs node-cron
Runtime Node.js + tsx
Language TypeScript

📁 Project Structure

src/
├── app.ts              # Fastify app factory & plugin registration
├── server.ts           # Entry point
├── routes/             # Route definitions (declared before services)
├── services/           # Business logic
├── schemas/            # Zod validation schemas (incl. shared.schema.ts)
├── plugins/            # Fastify plugins (JWT, cookies, DB, etc.)
├── middleware/         # Auth guards and request hooks
├── errors/             # Custom error classes and error codes
├── types/              # TypeScript type definitions
└── generated/          # Prisma generated client

🚀 Getting Started

Prerequisites

  • Node.js ≥ 20
  • PostgreSQL database
  • An SMTP server (or service like Mailtrap / Resend for dev)

Installation

git clone https://github.com/your-username/your-repo.git
cd your-repo
npm install

Environment

Rename .env.example to .env and fill in the values:

# Database
DATABASE_URL="postgresql://user:password@localhost:5432/dbname"

# Email
SMTP_HOST="smtp.example.com"
SMTP_PORT=587
SMTP_USER="your@email.com"
SMTP_PASS="your-smtp-password"
MAIL_FROM="no-reply@example.com"

# URLs
APP_URL=BACK_OFFICE_SERVER_URL
FRONT_URL=YOUR_FRONT_URL   # Used for links in emails

# Secrets
JWT_SECRET="your-jwt-secret"

Database

npx prisma migrate dev

Run (development)

npm run dev

🔐 Auth Flow Overview

  • On login, a JWT is issued (stored in an HTTP-only cookie) containing the user's ID and a tokenVersion.
  • On password change, tokenVersion is incremented, invalidating all previously issued tokens.
  • Action tokens (password reset, email confirmation, etc.) are single-use and deleted on consumption.
  • The lang field on requests is derived from the Accept-Language header (defaults to fr).

Google OAuth

The Google flow accepts an access_token obtained by the client after the Google sign-in, and exchanges it for user info via the Google UserInfo API. Three cases are handled:

Situation Behaviour
Email exists, no googleId Returns mergeRequired: true — the client must prompt the user to link their accounts
Existing Google account Logs the user in directly (checks for pending deletion)
New user Creates the account with googleId, picture and display name from Google; sends a confirmation email if the address is not already verified by Google

User preferences (language, theme) are automatically created on first Google sign-in.


🛣️ API Routes

Auth — /auth

Method Route Auth Description
POST /auth/register Create a new account
POST /auth/login Login and receive a JWT cookie
POST /auth/logout Invalidate the session cookie
POST /auth/google Login or register via Google access token

User — /user

Method Route Auth Description
GET /users List all users
GET /user/confirm?token= Confirm email address
PATCH /user/display-name Update display name
POST /user/pwd-recovery-request Request a password reset email
POST /user/pwd-recovery Reset password via token
PATCH /user/pwd-change Change password (re-issues JWT cookie)
POST /user/email-change-request Request an email change (sends confirmation to new address)
GET /user/email-change-confirm?token= Confirm the new email address
GET /user/email-change-rollback?token= Rollback to previous email (24h window)
DELETE /user/account Schedule account deletion (7-day window)
GET /user/delete-cancel?token= Cancel scheduled account deletion

= requires a valid authToken cookie


📋 Available Scripts

npm run dev      # Start development server with tsx
npm run build    # Compile TypeScript to dist/
npm run start    # Run compiled server

📄 License

ISC

Description
Back Office de l'application des listes
Readme 324 KiB
Languages
TypeScript 100%