Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

4 Commits

Folders and files

Repository files navigation

SaaS Backend Platform

A production-ready Backend-as-a-Service (BaaS) API that lets developers register, pick a subscription plan, provision isolated services with unique API keys, and manage end-users within each service — all governed by plan-based quotas. Built with Node.js, Express, and PostgreSQL (via Prisma ORM).


✨ Features

Feature Details
Multi-Tenant Services Developers create isolated services, each with a unique API key and its own user pool
Subscription Plans Admins define plans with price, maxServices, and maxUsersPerService limits
Plan-Based Quotas Service and user creation is enforced against plan limits — exceeding them returns 402 LIMIT_EXCEEDED
Authentication JWT access tokens + refresh token rotation
Token Security Refresh token reuse detection — revokes all tokens on suspected replay attack
Password Reset Time-limited single-use reset tokens
RBAC ADMIN › DEVELOPER role-based permissions with hierarchical access control
Validation Per-route express-validator chains with structured 422 error responses
Rate Limiting Global rate limiter (100 req / 15 min) + stricter auth limiter (20 req / 15 min)
Security Helmet, CORS, body-size limits (10kb), no stack traces in production
Logging Winston (colorized dev / JSON prod) + Morgan HTTP logs
Database Prisma ORM with PostgreSQL, graceful connection shutdown

🗂️ Project Structure

saas-backend-platform/
├── prisma/
│   ├── schema.prisma          # Database schema (PostgreSQL)
│   └── seed.js                # Seed script (Plans, Users, Services)
├── src/
│   ├── config/
│   │   ├── db.js              # Prisma client singleton
│   │   ├── env.js             # Env var loader & validator
│   │   └── logger.js          # Winston logger config
│   ├── middleware/
│   │   ├── auth.js            # JWT verification → req.user
│   │   ├── authorize.js       # RBAC (authorize, requireMinRole, authorizeOwnerOrAdmin)
│   │   ├── validate.js        # express-validator error handler
│   │   └── errorHandler.js    # Global error + 404 handler
│   ├── routes/
│   │   ├── auth.routes.js     # Auth, token rotation & password resets
│   │   ├── user.routes.js     # Profile management & Admin user controls
│   │   ├── plan.routes.js     # Subscription plan CRUD (Admin)
│   │   └── service.routes.js  # Service provisioning & per-service user management
│   ├── controllers/           # Route controller actions
│   ├── services/              # All business & database query logic
│   ├── validators/            # Input validation schemas
│   ├── utils/
│   │   ├── response.js        # Standardized JSON response templates
│   │   └── tokens.js          # JWT sign & verify utilities
│   ├── app.js                 # Express application setup
│   └── server.js              # HTTP server starter & cleanup handles
└── .env.example

🚀 Quick Start

1. Install dependencies

npm install

2. Configure environment

cp .env.example .env
# Edit .env with your DATABASE_URL, JWT secrets, and PORT configuration

3. Set up the database

npm run db:generate    # Generate Prisma client
npm run db:migrate     # Run schema migrations
npm run db:seed        # Seed sample data (Plans, Users, Services)

4. Start the server

npm run dev            # Run in development mode (with nodemon auto-restart)
npm start              # Run in production mode

📡 API Reference

1. Authentication — /api/auth

Method Endpoint Auth Description
POST /register ❌ Register a new user (defaults to DEVELOPER role)
POST /login ❌ Login with email & password → Returns access + refresh tokens
POST /refresh ❌ Rotate refresh token and get a new access token
POST /logout ❌ Revoke the provided refresh token
POST /forgot-password ❌ Trigger a password reset token
POST /reset-password ❌ Reset password using a valid reset token

2. Users — /api/users

Method Endpoint Auth Role Description
GET /me ✅ Any Retrieve authenticated user's profile
PATCH /me ✅ Any Update profile details (first name, last name)
DELETE /me ✅ Any Deactivate own account
GET / ✅ ADMIN List all users (supports filtering by ?role=)
GET /:id ✅ ADMIN Get any user details by ID
PATCH /:id/role ✅ ADMIN Update a user's role

3. Plans — /api/plans

Method Endpoint Auth Role Description
GET / ✅ Any List all subscription plans (sorted by price)
GET /:id ✅ Any Get specific plan details
POST / ✅ ADMIN Create a new subscription plan
PATCH /:id ✅ ADMIN Update plan details (name, price, limits)
DELETE /:id ✅ ADMIN Delete a plan

4. Services — /api/services

Method Endpoint Auth Role Description
GET / ✅ Any List own services (Admin can pass ?all=true to list all)
GET /:id ✅ Owner / ADMIN Get specific service details
POST / ✅ Any Create a new service (enforces plan's maxServices limit)
PATCH /:id/plan ✅ Owner / ADMIN Change a service's subscription plan
DELETE /:id ✅ Owner / ADMIN Delete a service

5. Service Users — /api/services/:serviceId/users

Method Endpoint Auth Role Description
GET / ✅ Owner / ADMIN List all users within a service
POST / ✅ Owner / ADMIN Create a user in the service (enforces plan's maxUsersPerService limit)
PATCH /:userId ✅ Owner / ADMIN Update a service user's details
DELETE /:userId ✅ Owner / ADMIN Remove a user from the service

🛡️ Authentication Flow

Client                                  API
  │                                      │
  │────── POST /api/auth/login ─────────►│
  │◄───── { accessToken, refreshToken } ─┤
  │                                      │
  │────── GET /api/users/me ────────────►│
  │       Authorization: Bearer <accessToken>
  │◄───── 200 { user } ──────────────────┤
  │                                      │
  ╎     (accessToken expires in 15m)     ╎
  │                                      │
  │────── POST /api/auth/refresh ───────►│
  │       { refreshToken }               │
  │◄───── { accessToken (new), refreshToken (new) }
  │       (old refreshToken is marked revoked in DB)

🔐 Refresh Token Rotation & Reuse Detection

To maximize security:

  1. When /refresh is called, the old token is permanently revoked in the database and a new token pair is issued.
  2. If a previously revoked refresh token is presented again:
    • The server detects a potential replay/token theft attack.
    • The server immediately invalidates all active refresh tokens for that user, forcing a complete re-authentication on all devices.

🏗️ Multi-Tenant Architecture

Developer (User)
  │
  ├── Plan (e.g. PRO: 10 services, 1000 users each)
  │
  ├── Service A  [API Key: sk_abc...]
  │   ├── ServiceUser 1
  │   ├── ServiceUser 2
  │   └── ...
  │
  ├── Service B  [API Key: sk_def...]
  │   ├── ServiceUser 1
  │   └── ...
  │
  └── (capped at plan.maxServices)
  • Each Developer signs up and selects a Plan
  • Plans define quotas: maxServices and maxUsersPerService
  • Each Service is an isolated tenant with its own unique API key and independent user pool
  • Creating services or users beyond plan limits returns 402 LIMIT_EXCEEDED

🔧 Tech Stack

  • Runtime: Node.js
  • Framework: Express.js
  • Database: PostgreSQL (managed via Prisma ORM)
  • Auth: jsonwebtoken + bcryptjs
  • Validation: express-validator
  • Security: helmet, cors, express-rate-limit
  • Logging: winston + morgan

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages