# Authentication System Setup

This document describes the multi-channel authentication system for the Dexorder AI Gateway.

## Overview

The gateway now implements a comprehensive authentication system using **Better Auth** with support for:

- ✅ Email/Password authentication
- ✅ Passkey/WebAuthn (passwordless biometric auth)
- ✅ JWT token-based sessions
- ✅ Multi-channel support (WebSocket, Telegram, REST API)
- ✅ PostgreSQL-based user management
- ✅ Secure password hashing with Argon2

## Architecture

```
┌─────────────────────────────────────────────────────────────┐
│                        Client Apps                          │
│  (Web, Mobile, CLI, Telegram, etc.)                        │
└────────────┬────────────────────────────────┬───────────────┘
             │                                │
             │ HTTP/REST                      │ WebSocket
             │                                │
┌────────────▼────────────────────────────────▼───────────────┐
│                    Gateway (Fastify)                        │
│                                                             │
│  ┌──────────────┐  ┌──────────────┐  ┌─────────────────┐  │
│  │ Auth Routes  │  │ WebSocket    │  │ Telegram        │  │
│  │ /auth/*      │  │ Handler      │  │ Handler         │  │
│  └──────┬───────┘  └──────┬───────┘  └────────┬────────┘  │
│         │                 │                    │           │
│         └─────────────────┴────────────────────┘           │
│                           │                                │
│                  ┌────────▼──────────┐                     │
│                  │   Auth Service    │                     │
│                  │  (Better Auth)    │                     │
│                  └────────┬──────────┘                     │
│                           │                                │
└───────────────────────────┼────────────────────────────────┘
                            │
                   ┌────────▼────────┐
                   │   PostgreSQL    │
                   │  - users        │
                   │  - sessions     │
                   │  - passkeys     │
                   │  - credentials  │
                   └─────────────────┘
```

## Database Schema

The authentication system uses the following PostgreSQL tables:

### Core Tables

1. **users** - Core user accounts
   - `id` (PRIMARY KEY)
   - `email` (UNIQUE)
   - `email_verified`
   - `name`
   - `created_at`, `updated_at`

2. **user_credentials** - Password hashes
   - `user_id` (FOREIGN KEY → users.id)
   - `password_hash` (Argon2)

3. **sessions** - JWT sessions
   - `id` (PRIMARY KEY)
   - `user_id` (FOREIGN KEY → users.id)
   - `expires_at`
   - `ip_address`, `user_agent`

4. **passkeys** - WebAuthn credentials
   - `id` (PRIMARY KEY)
   - `user_id` (FOREIGN KEY → users.id)
   - `credential_id` (UNIQUE)
   - `credential_public_key`
   - `counter`, `transports`

5. **verification_tokens** - Email verification, password reset
   - `identifier`, `token`, `expires_at`

### Integration Tables

6. **user_licenses** - User authorization & feature flags
   - `user_id` (FOREIGN KEY → users.id)
   - `license_type` (free, pro, enterprise)
   - `features` (JSONB)
   - `resource_limits` (JSONB)

7. **user_channel_links** - Multi-channel support
   - `user_id` (FOREIGN KEY → users.id)
   - `channel_type` (telegram, slack, discord, websocket)
   - `channel_user_id`

## Installation

1. **Install dependencies:**

```bash
cd gateway
npm install
```

The following packages are added:
- `better-auth` - Main authentication framework
- `@simplewebauthn/server` - WebAuthn/passkey support
- `@simplewebauthn/browser` - Client-side passkey helpers
- `@fastify/jwt` - JWT utilities
- `argon2` - Secure password hashing

2. **Apply database schema:**

```bash
psql $DATABASE_URL -f schema.sql
```

3. **Configure secrets:**

Copy `secrets.example.yaml` to your actual secrets file and update:

```yaml
auth:
  secret: "YOUR-SUPER-SECRET-KEY-HERE"  # Generate with: openssl rand -base64 32
```

4. **Configure server:**

Update `config.yaml`:

```yaml
server:
  base_url: http://localhost:3000  # Or your production URL
  trusted_origins:
    - http://localhost:3000
    - http://localhost:5173  # Your web app
    - https://yourdomain.com
```

## API Endpoints

### Authentication Routes

All Better Auth automatic routes are available at `/api/auth/*`:

- `POST /api/auth/sign-up/email` - Register with email/password
- `POST /api/auth/sign-in/email` - Sign in with email/password
- `POST /api/auth/sign-out` - Sign out
- `GET /api/auth/session` - Get current session
- `POST /api/auth/passkey/register` - Register passkey
- `POST /api/auth/passkey/authenticate` - Authenticate with passkey

### Custom Routes (Simplified)

- `POST /auth/register` - Register and auto sign-in
- `POST /auth/login` - Sign in
- `POST /auth/logout` - Sign out
- `GET /auth/session` - Get session
- `GET /auth/health` - Auth system health check

### Example Usage

#### Register a new user

```bash
curl -X POST http://localhost:3000/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "SecurePassword123!",
    "name": "John Doe"
  }'
```

Response:
```json
{
  "success": true,
  "userId": "user_1234567890_abc123",
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```

#### Sign in

```bash
curl -X POST http://localhost:3000/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "SecurePassword123!"
  }'
```

Response:
```json
{
  "success": true,
  "userId": "user_1234567890_abc123",
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```

#### Connect to WebSocket with JWT

```javascript
const ws = new WebSocket('ws://localhost:3000/ws/chat');
ws.addEventListener('open', () => {
  // Send auth token in initial message
  ws.send(JSON.stringify({
    type: 'auth',
    token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
  }));
});
```

Or use Authorization header:
```javascript
const ws = new WebSocket('ws://localhost:3000/ws/chat', {
  headers: {
    'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
  }
});
```

#### Get current session

```bash
curl http://localhost:3000/auth/session \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
```

## Passkey (WebAuthn) Support

### Server Setup

Passkeys are automatically configured in `better-auth-config.ts`:

```typescript
passkey({
  rpName: 'Dexorder AI',
  rpID: new URL(config.baseUrl).hostname,
  origin: config.baseUrl,
})
```

### Client-Side Integration

```typescript
import { startRegistration, startAuthentication } from '@simplewebauthn/browser';

// 1. Register a passkey (user must be logged in)
async function registerPasskey(token: string) {
  // Get options from server
  const optionsResponse = await fetch('/auth/passkey/register/options', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`
    }
  });
  const options = await optionsResponse.json();

  // Start WebAuthn registration
  const credential = await startRegistration(options);

  // Send credential to server
  const response = await fetch('/api/auth/passkey/register', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`
    },
    body: JSON.stringify({ credential })
  });

  return response.json();
}

// 2. Authenticate with passkey
async function authenticateWithPasskey() {
  // Get challenge from server
  const optionsResponse = await fetch('/api/auth/passkey/authenticate/options');
  const options = await optionsResponse.json();

  // Start WebAuthn authentication
  const credential = await startAuthentication(options);

  // Verify with server
  const response = await fetch('/auth/passkey/authenticate', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ credential })
  });

  const { token, userId } = await response.json();
  return { token, userId };
}
```

## Multi-Channel Support

### WebSocket Authentication

The WebSocket handler (`websocket-handler.ts`) now properly verifies JWT tokens:

```typescript
// User connects with JWT token in Authorization header
const authContext = await authenticator.authenticateWebSocket(request);
// Returns: { userId, sessionId, license, ... }
```

### Telegram Bot Authentication

Users link their Telegram account via the `user_channel_links` table:

```sql
INSERT INTO user_channel_links (user_id, channel_type, channel_user_id)
VALUES ('user_1234567890_abc123', 'telegram', '987654321');
```

The `authenticator.authenticateTelegram()` method resolves the user from their Telegram ID.

### API Authentication

All REST API calls use the `Authorization: Bearer <token>` header.

## Security Considerations

### Production Checklist

- [ ] Generate a strong random secret: `openssl rand -base64 32`
- [ ] Enable email verification: Set `requireEmailVerification: true`
- [ ] Configure HTTPS only in production
- [ ] Set proper `trusted_origins` for CORS
- [ ] Implement rate limiting (consider adding `@fastify/rate-limit`)
- [ ] Set up email service for password reset
- [ ] Configure session expiry based on security requirements
- [ ] Enable 2FA for sensitive operations
- [ ] Implement audit logging for auth events
- [ ] Set up monitoring for failed login attempts

### Password Security

- Uses **Argon2** (winner of Password Hashing Competition)
- Automatically salted and hashed by Better Auth
- Never stored or logged in plain text

### JWT Security

- Tokens expire after 7 days (configurable)
- Sessions update every 24 hours
- Tokens signed with HMAC-SHA256
- Store secret in k8s secrets, never in code

### Passkey Security

- Uses FIDO2/WebAuthn standards
- Hardware-backed authentication
- Phishing-resistant
- No passwords to leak or forget

## Migration Guide

If you have existing users with a different auth system:

1. **Create users in new schema:**
```sql
INSERT INTO users (id, email, email_verified, name)
SELECT user_id, email, true, name FROM old_users_table;
```

2. **Migrate licenses:**
```sql
-- Ensure user_licenses references users.id
UPDATE user_licenses SET user_id = users.id WHERE ...;
```

3. **User must reset password** or register passkey on first login with new system

## Troubleshooting

### "Authentication failed" on WebSocket

- Check that the JWT token is valid and not expired
- Verify the Authorization header format: `Bearer <token>`
- Check server logs for detailed error messages

### "Invalid credentials" on login

- Verify the user exists in the `users` table
- Check that `user_credentials` has a password_hash for the user
- Passwords are case-sensitive

### Passkey registration fails

- Check browser support for WebAuthn
- Verify HTTPS is enabled (required for WebAuthn in production)
- Check `rpID` matches your domain
- Ensure user is authenticated before registering passkey

## Development Tips

### Testing with dev user

A development user is created automatically:

```javascript
// Email: dev@example.com
// User ID: dev-user-001
// License: pro
```

Generate a token for testing:
```bash
curl -X POST http://localhost:3000/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"dev@example.com","password":"<set-in-db>"}'
```

### Inspecting tokens

```bash
# Decode JWT (header and payload only, signature verification needed)
echo "eyJhbGc..." | cut -d. -f2 | base64 -d | jq
```

### Database queries

```sql
-- List all users
SELECT id, email, name, created_at FROM users;

-- List active sessions
SELECT s.id, s.user_id, u.email, s.expires_at
FROM sessions s
JOIN users u ON s.user_id = u.id
WHERE s.expires_at > NOW();

-- List passkeys
SELECT p.id, p.name, u.email, p.created_at
FROM passkeys p
JOIN users u ON p.user_id = u.id;
```

## Future Enhancements

Potential additions to consider:

- [ ] OAuth providers (Google, GitHub, etc.)
- [ ] Magic link authentication
- [ ] Two-factor authentication (TOTP)
- [ ] Session management dashboard
- [ ] Audit log for security events
- [ ] IP-based restrictions
- [ ] Device management (trusted devices)
- [ ] Anonymous authentication for trials

## References

- [Better Auth Documentation](https://better-auth.com/)
- [SimpleWebAuthn Guide](https://simplewebauthn.dev/)
- [WebAuthn Guide](https://webauthn.guide/)
- [FIDO Alliance](https://fidoalliance.org/)
- [Fastify Authentication](https://fastify.dev/docs/latest/Guides/Getting-Started/#your-first-plugin)
