Skip to content

heysarver/auth-api

Repository files navigation

Auth API

A production-ready authentication service built with Express and better-auth, providing secure user authentication with email/password and OAuth social providers.

🛠 Tech Stack

  • Framework: Express 5
  • Authentication: better-auth
  • Database: PostgreSQL (auth schema)
  • Language: TypeScript
  • Runtime: Node.js 24

📦 Features

  • Email/password authentication
  • GitHub OAuth integration
  • JWT-based sessions
  • Rate limiting
  • CORS support
  • Secure cookie handling
  • PostgreSQL with separate auth schema

🚀 Getting Started

Prerequisites

  • Node.js 24+
  • PostgreSQL 17+
  • GitHub OAuth App (for social login)

Installation

  1. Install dependencies:
npm install
  1. Copy and configure environment variables:
cp .env.example .env
  1. Copy and configure Liquibase properties:
cp migrations/liquibase.properties.example migrations/liquibase.properties
  1. Generate a secure secret key:
# Generate a cryptographically secure secret (min 32 characters)
openssl rand -base64 32
  1. Configure your .env file with:

    • DATABASE_URL - PostgreSQL connection string (format: postgresql://user:password@host:port/database?schema=auth)
    • BETTER_AUTH_SECRET - Use the generated secret key from step 4 (min 32 characters)
    • GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET - GitHub OAuth credentials (optional)
    • SENDGRID_API_KEY - Email service credentials (optional for development)
    • FRONTEND_URL - Your frontend URL for CORS (default: http://localhost:5173)
  2. Configure migrations/liquibase.properties with:

    • url - JDBC connection URL (format: jdbc:postgresql://host:port/database)
    • username - Database username
    • password - Database password

    Note: This file is gitignored as it contains database credentials. Never commit it to version control.

Database Setup

The auth API uses a separate auth schema in PostgreSQL. Database migrations are managed by Liquibase:

  1. Navigate to the migrations folder:
cd ../migrations
  1. Run Liquibase migrations:
liquibase update -Dcontexts=development

Note: Better-auth will also automatically create/update its required tables on first run.

Development

# Run in development mode with hot reload
npm run dev

# Build TypeScript
npm run build

# Run production build
npm start

🔗 API Endpoints

Subdomain Routing Architecture

Production: https://auth.domain.com Staging: https://auth-staging.domain.com Local Development: http://localhost:3002

All auth routes are at the root path (no /api/auth/ prefix):

  • POST /sign-up - Register new user
  • POST /sign-in - Sign in with email/password
  • POST /sign-out - Sign out user
  • GET /session - Get current session
  • GET /github - GitHub OAuth flow
  • GET /callback/github - GitHub OAuth callback
  • GET /jwks - JWKS endpoint for JWT validation

Utility Routes

  • GET /health - Health check endpoint
  • GET / - API info

🔒 Security Features

  • Helmet.js for security headers
  • Rate limiting (100 requests per 15 minutes)
  • CORS configuration for trusted origins
  • Secure cookie settings in production
  • Password hashing with bcrypt
  • JWT token signing

🐳 Docker Support

Development

docker build -f Dockerfile.dev -t auth-api:dev .
docker run -p 3002:3002 --env-file .env auth-api:dev

Production

The production Dockerfile uses multi-stage builds for optimal image size and security:

# Build production image
docker build -t auth-api:latest .

# Run production container
docker run -p 3002:3002 --env-file .env auth-api:latest

Production Features:

  • Multi-stage build for minimal image size
  • Non-root user for enhanced security
  • Health checks for container orchestration
  • Signal handling with dumb-init
  • Production-only dependencies

📝 Environment Variables

Variable Description Default
PORT Server port 3002
NODE_ENV Environment development
DATABASE_URL PostgreSQL connection string -
BETTER_AUTH_SECRET Secret for JWT signing (min 32 chars) -
BETTER_AUTH_URL Base URL for auth (subdomain: auth.domain.com) http://localhost:3002
GITHUB_CLIENT_ID GitHub OAuth client ID -
GITHUB_CLIENT_SECRET GitHub OAuth client secret -
FRONTEND_URL Frontend URL for CORS (domain.com) http://localhost:5173
API_URL Core API URL for CORS (api.domain.com) http://localhost:3001
SESSION_EXPIRES_IN Session duration in seconds 86400
SESSION_UPDATE_AGE Session refresh interval 3600

🧪 Testing

# Run tests
npm test

# Test coverage
npm run test:coverage

🔄 Using as a Git Submodule

This repository is designed to work as a standalone service or as a Git submodule in a larger monorepo.

Initial Setup as Submodule

When first cloning a parent repository that includes this as a submodule:

# In the parent repository
git submodule update --init --recursive
cd auth-api
npm install
cp .env.example .env
cp migrations/liquibase.properties.example migrations/liquibase.properties
# Configure both files with your credentials

Working with Submodules

# Update submodule to latest commit
git submodule update --remote auth-api

# Commit submodule changes in parent repo
git add auth-api
git commit -m "Update auth-api submodule"

Configuration Files

The following files are gitignored and must be configured locally:

  • .env - Application environment variables
  • migrations/liquibase.properties - Database migration credentials

These files contain project-specific credentials and should never be committed to version control.

📄 License

MIT License - See LICENSE file for details

About

Auth API powered by Better-Auth

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors