managarten/services/mana-core-auth
Till-JS 17313473aa fix(mana-core-auth): use JWKS with jose for JWT verification
The JWT guards were using RS256 algorithm with jsonwebtoken library,
but Better Auth generates EdDSA tokens. This caused all authenticated
requests to fail with "Invalid token".

Changes:
- Replace jsonwebtoken with jose library
- Use JWKS endpoint for key fetching instead of static publicKey
- Support EdDSA algorithm used by Better Auth

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 13:26:19 +01:00
..
docs fix(ci): build shared packages before tests and fix formatting 2025-12-01 23:15:00 +01:00
postgres/init first auth impl 2025-12-01 13:30:58 +01:00
scripts refactor: restructure 2025-11-26 03:03:24 +01:00
src fix(mana-core-auth): use JWKS with jose for JWT verification 2025-12-05 13:26:19 +01:00
test fix(ci): build shared packages before tests and fix formatting 2025-12-01 23:15:00 +01:00
.env.example refactor: restructure 2025-11-26 03:03:24 +01:00
.gitignore refactor: restructure 2025-11-26 03:03:24 +01:00
auth.ts test(auth): update tests for minimal JWT claims architecture 2025-12-01 15:21:19 +01:00
CLAUDE.md fix(ci): build shared packages before tests and fix formatting 2025-12-01 23:15:00 +01:00
docker-entrypoint.sh 🔧 fix(auth): skip migrations in Docker entrypoint 2025-12-02 14:41:34 +01:00
Dockerfile refactor: restructure 2025-11-26 03:03:24 +01:00
drizzle.config.ts 🐛 fix(auth): use Better Auth native JWT validation with EdDSA 2025-12-01 15:18:57 +01:00
jest.config.js fix(ci): build shared packages before tests and fix formatting 2025-12-01 23:15:00 +01:00
MIGRATIONS.md fix(ci): build shared packages before tests and fix formatting 2025-12-01 23:15:00 +01:00
nest-cli.json style: auto-format codebase with Prettier 2025-11-27 18:33:16 +01:00
package.json 🔀 merge: auth/complete branch with Better Auth implementation 2025-12-01 15:25:38 +01:00
pnpm-lock.yaml refactor: restructure 2025-11-26 03:03:24 +01:00
QUICKSTART.md first auth impl 2025-12-01 13:30:58 +01:00
README.md style: auto-format codebase with Prettier 2025-11-27 18:33:16 +01:00
tsconfig.json style: auto-format codebase with Prettier 2025-11-27 18:33:16 +01:00

Mana Core Auth

Central authentication and credit management system for the Mana Universe ecosystem.

Features

  • JWT-based Authentication (RS256 algorithm)

    • User registration and login
    • Refresh token rotation
    • Multi-session management
    • Device tracking
  • Credit System

    • User balance management
    • Transaction ledger with double-entry bookkeeping
    • Optimistic locking for concurrency
    • Daily free credits
    • Signup bonus (150 credits)
    • Idempotency for credit operations
  • Security

    • Row-Level Security (RLS) on PostgreSQL
    • Rate limiting
    • CORS protection
    • Helmet security headers
    • SCRAM-SHA-256 password authentication
  • Infrastructure

    • Docker-based deployment
    • Traefik reverse proxy with automatic SSL
    • PgBouncer connection pooling
    • Redis caching
    • Prometheus + Grafana monitoring

Quick Start

Development Setup

  1. Install dependencies

    pnpm install
    
  2. Generate JWT keys

    cd mana-core-auth
    ./scripts/generate-keys.sh
    
  3. Set up environment variables

    cp .env.example .env
    # Edit .env and add your JWT keys and other configuration
    
  4. Start PostgreSQL and Redis (using Docker)

    docker-compose up postgres redis -d
    
  5. Run migrations

    pnpm migration:generate
    pnpm migration:run
    
  6. Start development server

    pnpm start:dev
    

    The server will be available at http://localhost:3001/api/v1

Production Deployment (Docker)

  1. Set up environment variables

    cp .env.example .env
    # Edit .env with production values
    
  2. Generate JWT keys

    ./mana-core-auth/scripts/generate-keys.sh
    # Add the generated keys to .env
    
  3. Start all services

    docker-compose up -d
    
  4. Check service health

    docker-compose ps
    docker-compose logs -f mana-core-auth
    

API Endpoints

Authentication

POST /api/v1/auth/register

  • Register a new user
  • Body: { email, password, name? }
  • Returns: User object

POST /api/v1/auth/login

  • Login with email and password
  • Body: { email, password, deviceId?, deviceName? }
  • Returns: { user, accessToken, refreshToken, expiresIn, tokenType }

POST /api/v1/auth/refresh

  • Refresh access token
  • Body: { refreshToken }
  • Returns: New token pair

POST /api/v1/auth/logout

  • Logout and revoke session
  • Requires: Bearer token
  • Returns: Success message

POST /api/v1/auth/validate

  • Validate a JWT token
  • Body: { token }
  • Returns: { valid, payload }

Credits

GET /api/v1/credits/balance

  • Get current credit balance
  • Requires: Bearer token
  • Returns: { balance, freeCreditsRemaining, totalEarned, totalSpent }

POST /api/v1/credits/use

  • Deduct credits from balance
  • Requires: Bearer token
  • Body: { amount, appId, description, idempotencyKey?, metadata? }
  • Returns: Transaction details

GET /api/v1/credits/transactions?limit=50&offset=0

  • Get transaction history
  • Requires: Bearer token
  • Returns: Array of transactions

GET /api/v1/credits/purchases

  • Get purchase history
  • Requires: Bearer token
  • Returns: Array of purchases

GET /api/v1/credits/packages

  • Get available credit packages
  • Requires: Bearer token
  • Returns: Array of packages

Database Schema

Auth Schema

  • auth.users - User accounts
  • auth.sessions - Active sessions
  • auth.passwords - Hashed passwords
  • auth.accounts - OAuth provider accounts
  • auth.verification_tokens - Email verification & password reset
  • auth.two_factor_auth - 2FA configuration
  • auth.security_events - Security audit log

Credits Schema

  • credits.balances - User credit balances
  • credits.transactions - Transaction ledger
  • credits.packages - Available credit packages
  • credits.purchases - Purchase history
  • credits.usage_stats - Usage analytics

Environment Variables

See .env.example for all available configuration options.

Key variables:

  • DATABASE_URL - PostgreSQL connection string
  • JWT_PUBLIC_KEY - RS256 public key (PEM format)
  • JWT_PRIVATE_KEY - RS256 private key (PEM format)
  • REDIS_HOST, REDIS_PORT, REDIS_PASSWORD - Redis configuration
  • STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET - Stripe integration
  • CORS_ORIGINS - Allowed origins for CORS
  • CREDITS_SIGNUP_BONUS - Free credits on signup (default: 150)
  • CREDITS_DAILY_FREE - Daily free credits (default: 5)

Development

Available Scripts

# Start development server with hot-reload
pnpm start:dev

# Build for production
pnpm build

# Start production server
pnpm start:prod

# Run tests
pnpm test

# Generate database migration
pnpm migration:generate

# Run migrations
pnpm migration:run

# Open Drizzle Studio (database GUI)
pnpm db:studio

# Lint and format
pnpm lint
pnpm format

Architecture

Token Flow

  1. User registers/logs in → Receives accessToken (15min) + refreshToken (7 days)
  2. Client stores tokens securely (httpOnly cookies on web, SecureStore on mobile)
  3. Client includes Authorization: Bearer <accessToken> in requests
  4. When access token expires, client uses refresh token to get new pair
  5. Refresh tokens are single-use (rotation for security)

Credit System

  • Signup Bonus: 150 free credits on registration
  • Daily Free Credits: 5 credits added every 24 hours
  • Paid Credits: Purchased via Stripe (100 mana = €1)
  • Usage Priority: Free credits used first, then paid credits
  • Idempotency: Duplicate requests with same key are detected and ignored
  • Concurrency: Optimistic locking prevents race conditions

Security Considerations

  1. JWT Keys: Generate strong RS256 keys and keep private key secure
  2. Database: Use strong passwords and enable SSL in production
  3. Redis: Always set a password for Redis
  4. CORS: Only allow trusted origins
  5. Rate Limiting: Configured via Traefik and NestJS throttler
  6. RLS Policies: Enforce data isolation at database level
  7. HTTPS: Always use SSL/TLS in production (via Traefik)

Monitoring

  • Prometheus: Available at http://localhost:9090
  • Grafana: Available at http://localhost:3000
  • Logs: docker-compose logs -f mana-core-auth

License

Private - Mana Universe

Support

For issues and questions, contact the development team.