auth-bff-sms-pin-template Svelte Themes

Auth Bff Sms Pin Template

Production-ready SvelteKit 5 authentication template with SMS and PIN authorization using BFF pattern, PostgreSQL + Drizzle ORM, and enterprise-grade security.

๐Ÿ” Auth BFF SMS + PIN Template

Production-ready SvelteKit 5 authentication template with SMS and PIN authorization using BFF pattern, PostgreSQL + Drizzle ORM, and enterprise-grade security.

๐ŸŒŸ Features

๐Ÿ”’ Security First

  • โœ… Argon2id password hashing (OWASP recommended)
  • โœ… HTTP-only cookies (XSS protection)
  • โœ… SameSite=Strict (CSRF protection)
  • โœ… Rate limiting (brute-force protection)
  • โœ… Security headers (HSTS, CSP, X-Frame-Options)
  • โœ… SQL injection protection (parameterized queries)
  • โœ… IP logging for audit trails

๐Ÿ—๏ธ Modern Architecture

  • โœ… BFF Pattern (Backend for Frontend)
  • โœ… Remote Functions (type-safe client-server communication)
  • โœ… Clean Architecture (separation of concerns)
  • โœ… TypeScript strict mode
  • โœ… Zero client-side secrets (everything server-side)

๐Ÿ“ฑ SMS + PIN Authentication

  • โœ… SMS OTP (6 digits, 5 min expiration)
  • โœ… PIN setup after first login
  • โœ… Quick login with PIN for returning users
  • โœ… Mock SMS provider for development
  • โœ… Easy integration with real SMS providers

๐Ÿ—„๏ธ Database & Session Management

  • โœ… PostgreSQL 18 with Drizzle ORM for data persistence
  • โœ… Redis support for sessions (production-ready)
  • โœ… Memory store for development
  • โœ… Session auto-renewal
  • โœ… Full audit logging
  • โœ… Type-safe database queries

๐Ÿš€ Quick Start

Prerequisites

  • Node.js 20+
  • npm 10+
  • Docker (for PostgreSQL)

Installation

# Clone the repository
git clone https://github.com/FrankFMY/auth-bff-sms-pin-template.git
cd auth-bff-sms-pin-template

# Install dependencies
npm install

# Copy environment variables
cp .env.example .env

# Start PostgreSQL via Docker
docker compose up -d

# Apply database migrations
npm run db:push

# Start development server
npm run dev

Open http://localhost:5173/auth/sms-login


๐Ÿ“‹ Environment Variables

Create .env file:

# PostgreSQL
DB_HOST=localhost
DB_PORT=5433
DB_USER=postgres
DB_PASSWORD=postgres
DB_NAME=myapp

# SMS Provider (mock for development)
SMS_PROVIDER=mock

# Session
SESSION_MAX_AGE=86400

# Rate Limiting
RATE_LIMIT_OTP_MAX=3
RATE_LIMIT_OTP_WINDOW_MS=60000

# Environment
NODE_ENV=development

๐Ÿ—๏ธ Architecture

System Architecture

graph TB
    Client[๐ŸŒ Client Browser<br/>Svelte 5 + Runes Mode]

    subgraph SvelteKit["๐Ÿš€ SvelteKit Server"]
        RemoteFunctions[๐Ÿ“ก Remote Functions Layer<br/>requestOTP, verifyOTP<br/>setupPIN, loginWithPIN]
        ServiceLayer[โš™๏ธ Service Layer<br/>sms-service.ts]

        subgraph AuthLogic["๐Ÿ” Authentication Logic"]
            SMSAuth[SMS Auth Service<br/>Argon2, OTP Generation]
            RateLimit[Rate Limiter<br/>Brute-force Protection]
            SessionStore[Session Store<br/>Memory/Redis]
        end
    end

    Database[(๐Ÿ—„๏ธ PostgreSQL<br/>+ Drizzle ORM<br/>โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”<br/>๐Ÿ“Š Users<br/>๐Ÿ“ฑ OTP Codes<br/>๐Ÿ“ Login Attempts)]

    Client -->|Type-Safe RPC| RemoteFunctions
    RemoteFunctions --> ServiceLayer
    ServiceLayer --> AuthLogic
    SMSAuth --> Database
    RateLimit --> Database
    SessionStore --> Database

    style Client fill:#FF3E00,stroke:#333,stroke-width:2px,color:#fff
    style SvelteKit fill:#FF3E00,stroke:#333,stroke-width:3px,color:#fff
    style Database fill:#9333EA,stroke:#333,stroke-width:2px,color:#fff
    style AuthLogic fill:#10B981,stroke:#333,stroke-width:2px

Authentication Flow

sequenceDiagram
    actor User
    participant UI as ๐ŸŽจ Svelte UI
    participant RF as ๐Ÿ“ก Remote Functions
    participant Auth as ๐Ÿ” Auth Service
    participant DB as ๐Ÿ—„๏ธ PostgreSQL
    participant SMS as ๐Ÿ“ฑ SMS Provider

    %% SMS Login Flow
    User->>UI: Enters phone number
    UI->>RF: requestOTP(phone)
    RF->>Auth: sendOTP(phone)
    Auth->>Auth: Generate 6-digit OTP
    Auth->>DB: Store OTP (5 min expiry)
    Auth->>SMS: Send SMS
    SMS-->>User: ๐Ÿ“ฉ SMS with OTP code
    Auth-->>RF: Success
    RF-->>UI: OTP sent

    %% OTP Verification
    User->>UI: Enters OTP code
    UI->>RF: verifyOTP(phone, code)
    RF->>Auth: verifyOTP(phone, code, IP)
    Auth->>DB: Check OTP validity

    alt OTP Valid
        Auth->>DB: Create/Update User
        Auth->>DB: Log login attempt (success)
        Auth->>DB: Delete used OTP
        Auth-->>RF: Success + requiresPinSetup
        RF->>RF: Create HTTP-only session
        RF-->>UI: Success

        alt First Time User
            UI->>UI: Show PIN setup
            User->>UI: Creates PIN (4-6 digits)
            UI->>RF: setupPIN(pin)
            RF->>Auth: setupPIN(userId, pin)
            Auth->>Auth: Hash PIN (Argon2id)
            Auth->>DB: Save PIN hash
            Auth-->>RF: Success
            RF-->>UI: PIN setup complete
        end

        UI->>UI: Redirect to Dashboard
    else OTP Invalid
        Auth->>DB: Increment attempts
        Auth->>DB: Log login attempt (failed)
        Auth-->>RF: Error + attemptsLeft
        RF-->>UI: Show error
    end

    %% PIN Login Flow (Returning Users)
    User->>UI: Enter phone + PIN
    UI->>RF: loginWithPIN(phone, pin)
    RF->>Auth: loginWithPIN(phone, pin, IP)
    Auth->>DB: Get user by phone
    Auth->>Auth: Verify PIN (Argon2)

    alt PIN Valid
        Auth->>DB: Log login attempt (success)
        Auth-->>RF: Success
        RF->>RF: Create HTTP-only session
        RF-->>UI: Success
        UI->>UI: Redirect to Dashboard
    else PIN Invalid
        Auth->>DB: Log login attempt (failed)
        Auth-->>RF: Error
        RF-->>UI: Show error
    end

๐Ÿ“‚ Project Structure

src/
โ”œโ”€โ”€ lib/
โ”‚   โ””โ”€โ”€ server/
โ”‚       โ”œโ”€โ”€ auth/
โ”‚       โ”‚   โ”œโ”€โ”€ sms-auth.ts          # Core SMS/PIN logic
โ”‚       โ”‚   โ”œโ”€โ”€ sms-service.ts       # Service layer for Remote Functions
โ”‚       โ”‚   โ”œโ”€โ”€ sms-bff.ts           # BFF API (HonoJS)
โ”‚       โ”‚   โ”œโ”€โ”€ sms-middleware.ts    # Session middleware
โ”‚       โ”‚   โ”œโ”€โ”€ sms-rate-limiter.ts  # Rate limiting
โ”‚       โ”‚   โ””โ”€โ”€ stores/
โ”‚       โ”‚       โ”œโ”€โ”€ memory.ts        # Memory session store (dev)
โ”‚       โ”‚       โ””โ”€โ”€ redis.ts         # Redis session store (prod)
โ”‚       โ”œโ”€โ”€ db/
โ”‚       โ”‚   โ”œโ”€โ”€ index.ts              # PostgreSQL + Drizzle client
โ”‚       โ”‚   โ””โ”€โ”€ schema.ts             # Database schema
โ”‚       โ””โ”€โ”€ sms/
โ”‚           โ”œโ”€โ”€ mock-provider.ts     # Mock SMS for dev
โ”‚           โ””โ”€โ”€ real-provider.ts     # Real SMS provider
โ””โ”€โ”€ routes/
    โ”œโ”€โ”€ auth/
    โ”‚   โ”œโ”€โ”€ data.remote.ts           # Remote Functions
    โ”‚   โ””โ”€โ”€ sms-login/
    โ”‚       โ””โ”€โ”€ +page.svelte         # Login UI
    โ”œโ”€โ”€ +layout.server.ts            # Global layout load
    โ””โ”€โ”€ +page.svelte                 # Home page

๐Ÿ”’ Security Features

Authentication Flow

  1. SMS OTP Request

    • User enters phone number
    • System generates 6-digit OTP (crypto.randomInt)
    • OTP stored in PostgreSQL with 5-minute expiration
    • SMS sent (mock in dev, real in prod)
  2. OTP Verification

    • User enters OTP code
    • System validates against PostgreSQL
    • Max 3 attempts before lockout
    • IP address logged for audit
  3. PIN Setup (first-time users)

    • User creates 4-6 digit PIN
    • Validated against weak patterns (1234, 1111, etc.)
    • Hashed with Argon2id (64MB memory, 3 iterations)
    • Stored in PostgreSQL
  4. PIN Login (returning users)

    • User enters phone + PIN
    • PIN verified against Argon2 hash
    • Max 5 attempts per 15 minutes
    • Session created with HTTP-only cookie

Rate Limiting

Operation Limit Window
OTP Request 3 attempts 1 minute
OTP Verification 3 attempts 1 minute
PIN Login 5 attempts 15 minutes

Security Headers

  • X-Frame-Options: DENY
  • X-Content-Type-Options: nosniff
  • X-XSS-Protection: 1; mode=block
  • Referrer-Policy: strict-origin-when-cross-origin
  • Strict-Transport-Security (production only)
  • Content-Security-Policy

๐Ÿงช Testing

# Type checking
npm run check

# Linting
npm run lint

# Format code
npm run format

# Build for production
npm run build

๐Ÿš€ Production Deployment

1. Generate Secrets

# Generate SESSION_SECRET
openssl rand -base64 32

# Update .env.production
SESSION_SECRET=<generated_key>
DB_USER=prod_user_$(openssl rand -hex 4)
DB_PASSWORD=$(openssl rand -base64 24)

Edit src/lib/server/auth/sms-bff.ts:

// Replace:
import { MemorySessionStore } from "./stores/memory";
this.sessionStore = sessionStore ?? new MemorySessionStore();

// With:
import { RedisSessionStore } from "./stores/redis";
this.sessionStore = sessionStore ?? new RedisSessionStore();

Add Redis to docker-compose.yml:

services:
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    command: redis-server --requirepass ${REDIS_PASSWORD}

3. Configure Real SMS Provider

Update src/lib/server/sms/index.ts:

import { RealSMSProvider } from "./real-provider";

export const smsProvider = new RealSMSProvider({
  apiKey: process.env.SMS_API_KEY!,
  apiUrl: process.env.SMS_API_URL!,
});

4. Deploy

npm run build
npm run preview

๐Ÿ“š Documentation


๐Ÿ› ๏ธ Tech Stack


๐Ÿ“ License

MIT License - see LICENSE file for details


๐Ÿ‘ค Author

FrankFMY


๐Ÿค Contributing

Contributions, issues and feature requests are welcome!

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

โญ Show your support

Give a โญ๏ธ if this project helped you!


๐Ÿ” Security

If you discover a security vulnerability, please email Pryanishnikovartem@gmail.com

Do NOT open a public issue.


๐Ÿ“Š Project Status

โœ… Production Ready - Fully tested and secure

  • โœ… 0 TypeScript errors
  • โœ… 0 ESLint warnings
  • โœ… 100% security audit passed
  • โœ… Parameterized SQL queries
  • โœ… IP logging implemented
  • โœ… Rate limiting configured
  • โœ… Security headers enabled

Made with โค๏ธ by FrankFMY

Top categories

Loading Svelte Themes