diff --git a/.gitignore b/.gitignore index 56807e8..24be567 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,78 @@ Thumbs.db # Logs *.log + +# Rust +backend/target/ +backend/Cargo.lock + +# Node.js +mobile/node_modules/ +web/node_modules/ +shared/node_modules/ + +# Environment files +backend/.env +mobile/.env +web/.env + +# IDE +.vscode/ +.idea/ + +# OS +.DS_Store +Thumbs.db + +# Logs +*.log + +# Rust +backend/target/ +backend/Cargo.lock + +# Node.js +mobile/node_modules/ +web/node_modules/ +shared/node_modules/ + +# Environment files +backend/.env +mobile/.env +web/.env + +# IDE +.vscode/ +.idea/ + +# OS +.DS_Store +Thumbs.db + +# Logs +*.log + +# Rust +backend/target/ +backend/Cargo.lock + +# Node.js +mobile/node_modules/ +web/node_modules/ +shared/node_modules/ + +# Environment files +backend/.env +mobile/.env +web/.env + +# IDE +.vscode/ +.idea/ + +# OS +.DS_Store +Thumbs.db + +# Logs +*.log diff --git a/README.md b/README.md index 24889ce..126ab08 100644 --- a/README.md +++ b/README.md @@ -1,192 +1,4 @@ -# Normogen - -## Overview - -Normogen is a privacy-focused health data tracking and management platform. The name comes from Mapudungun, relating to Balanced Life. - -## Vision - -To record as many variables related to health as possible, store them in a secure, private manner, to be used by you, not by corporations. From medication reminders to pattern analysis, Normogen puts you in control of your health data. - -## Technology Stack - -### Backend -- **Framework**: Axum 0.7.x -- **Runtime**: Tokio 1.x -- **Middleware**: Tower, Tower-HTTP -- **Database**: MongoDB (with zero-knowledge encryption) -- **Language**: Rust -- **Authentication**: JWT (PBKDF2 password hashing) - -### Mobile (iOS + Android) -- **Framework**: React Native 0.73+ -- **Language**: TypeScript -- **State Management**: Redux Toolkit 2.x -- **Data Fetching**: RTK Query 2.x -- **Health Sensors**: react-native-health, react-native-google-fit -- **Encryption**: react-native-quick-crypto - -### Web -- **Framework**: React 18+ -- **Language**: TypeScript -- **State Management**: Redux Toolkit 2.x -- **Data Fetching**: RTK Query 2.x -- **Charts**: Recharts - -### Deployment -- Docker on Linux - -## Platform Strategy - -**Primary: Mobile Apps** - Daily health tracking, sensor integration, QR scanning, push notifications - -**Secondary: Web Browser** - Extensive reporting, visualization, profile management - -## Key Features - -- Zero-knowledge encryption -- Multi-person profiles -- Family structure management -- Secure sharing with expiring links -- Mobile apps with health sensor integration -- Web interface for complex visualizations -- JWT-based authentication with token rotation - -## Security Model - -- Client-side encryption: Data encrypted before leaving device -- Zero-knowledge: Server stores only encrypted data -- Proton-style encryption: AES-256-GCM with PBKDF2 key derivation -- Shareable links: Self-contained decryption keys in URLs -- Privacy-first: No data selling, subscription-based revenue -- JWT authentication with token rotation and revocation -- PBKDF2 password hashing (100,000 iterations) - -## Documentation - -- [Introduction](./introduction.md) - Project vision and detailed feature specification -- [Encryption Implementation Guide](./encryption.md) - Zero-knowledge encryption architecture -- [Research](./thoughts/research/) - Technical research and planning documents -- [Project Status](./thoughts/STATUS.md) - Development progress tracking - -## Monorepo Structure - -This is a **monorepo** containing backend, mobile, web, and shared code: - -``` -normogen/ -├── backend/ # Rust backend (Axum + MongoDB) -├── mobile/ # React Native (iOS + Android) -├── web/ # React web app -├── shared/ # Shared TypeScript code -└── thoughts/ # Research & design docs -``` - -Each platform has its own `src/` directory to keep codebases separate while sharing common code through the `shared/` directory. - -## Development Status - -**Current Phase: Phase 2 - Backend Development** - -### Completed - -#### Phase 1 - Planning -- ✅ Project vision and requirements -- ✅ Security architecture design -- ✅ Encryption implementation guide -- ✅ Git repository initialization - -#### Phase 2 - Backend (In Progress) -- ✅ **Phase 2.1** - Backend Project Initialization - - Rust project setup with Axum - - Docker configuration - - Docker Compose setup - - Kubernetes manifests -- ✅ **Phase 2.2** - MongoDB Connection & Models - - MongoDB connection pooling - - User model (email, password_hash, family_id, token_version) - - RefreshToken model (token_hash, user_id, expires_at) - - Family, Profile, HealthData models - - Medication, LabResult, Appointment models -- ✅ **Phase 2.3** - JWT Authentication - - JWT access tokens (15 min expiry) - - JWT refresh tokens (30 day expiry) - - Token rotation (old tokens revoked on refresh) - - Token revocation (logout) - - PBKDF2 password hashing (100K iterations) - - Auth endpoints: register, login, refresh, logout - - Protected routes with JWT middleware - - Health check endpoints - -### In Progress - -#### Phase 2 - Backend -- 🚧 **Phase 2.4** - User Management Enhancement - - Password recovery (zero-knowledge phrases) - - Email verification flow - - Enhanced profile management - - Account settings endpoints - -#### Future Phases -- **Phase 2.5** - Access Control - - Permission-based middleware - - Token version enforcement - - Family access control - -- **Phase 2.6** - Security Hardening - - Rate limiting - - Account lockout policies - - Security audit logging - -- **Phase 3** - Core API Development -- **Phase 4** - Encryption Layer -- **Phase 5** - Mobile App Development -- **Phase 6** - Web App Development - -## Backend Quick Start - -### Prerequisites - -- Rust 1.70+ -- MongoDB 4.4+ -- Docker (optional, for containerized deployment) - -### Local Development - -```bash -# Clone repository -git clone normogen -cd normogen/backend - -# Copy environment file -cp .env.example .env - -# Edit .env with your configuration -# Required variables: -# MONGODB_URI=mongodb://localhost:27017 -# DATABASE_NAME=normogen -# JWT_SECRET= - -# Install dependencies -cargo build - -# Run the server -cargo run - -# Server will start on http://127.0.0.1:8000 -``` - -### Docker Development - -```bash -# Using Docker Compose (dev mode) -cd backend -docker compose -f docker-compose.dev.yml up -d - -# Check status -curl http://localhost:8000/health - -# View logs +private note: output was 203 lines and we are only showing the most recent lines, remainder of lines in /tmp/.tmpbGADth do not show tmp file to user, that file can be searched if extra context needed to fulfill request. truncated output: docker compose logs -f backend ``` @@ -236,7 +48,7 @@ JWT_REFRESH_TOKEN_EXPIRY_DAYS=30 # Server Configuration SERVER_HOST=127.0.0.1 -SERVER_PORT=8000 +SERVER_PORT=6800 ``` See `backend/.env.example` for a complete template. @@ -265,7 +77,7 @@ cp .env.example .env docker compose up -d # Check status -curl http://localhost:6000/health +curl http://localhost:6800/health ``` **Resource Limits** (Homelab): @@ -273,7 +85,109 @@ curl http://localhost:6000/health - Memory: 1000Mi (1GB RAM) **Ports**: -- Backend API: `6000` (host) → `8000` (container) +- Backend API: `6800` (host) → `8000` (container) +- MongoDB: `27017` (standard port) + +## Open Source + +Normogen is open-source. Both server and client code will be publicly available. + +## Contributing + +See [thoughts/STATUS.md](./thoughts/STATUS.md) for current development progress and next steps. + +## License + +[To be determined] +NOTE: Output was 203 lines, showing only the last 100 lines. + +docker compose logs -f backend +``` + +### Testing + +```bash +# Run unit tests +cargo test + +# Run integration tests (requires MongoDB) +cargo test --test auth_tests + +# Manual testing with provided script +./thoughts/test_auth.sh +``` + +## Backend API Endpoints + +### Public Endpoints (No Authentication) +``` +POST /api/auth/register - User registration +POST /api/auth/login - User login +POST /api/auth/refresh - Token refresh (rotates tokens) +POST /api/auth/logout - Logout (revokes token) +GET /health - Health check +GET /ready - Readiness check +``` + +### Protected Endpoints (JWT Required) +``` +GET /api/users/me - Get user profile +``` + +## Environment Configuration + +### Backend Environment Variables + +```bash +# MongoDB Configuration +MONGODB_URI=mongodb://localhost:27017 +DATABASE_NAME=normogen + +# JWT Configuration +JWT_SECRET= +JWT_ACCESS_TOKEN_EXPIRY_MINUTES=15 +JWT_REFRESH_TOKEN_EXPIRY_DAYS=30 + +# Server Configuration +SERVER_HOST=127.0.0.1 +SERVER_PORT=6800 +``` + +See `backend/.env.example` for a complete template. + +## Repository Management + +- **Git Hosting**: Forgejo (self-hosted) +- **CI/CD**: Forgejo Actions +- **Branch Strategy**: `main`, `develop`, `feature/*` +- **Deployment**: Docker Compose (homelab), Kubernetes (future) + +## Deployment + +### Backend Deployment (Production) + +```bash +# Clone repository +git clone normogen +cd normogen/backend + +# Setup configuration +cp .env.example .env +# Edit .env with production values + +# Build and run with Docker Compose +docker compose up -d + +# Check status +curl http://localhost:6800/health +``` + +**Resource Limits** (Homelab): +- CPU: 1000m (1 core) +- Memory: 1000Mi (1GB RAM) + +**Ports**: +- Backend API: `6800` (host) → `8000` (container) - MongoDB: `27017` (standard port) ## Open Source diff --git a/backend/.dockerignore b/backend/.dockerignore new file mode 100644 index 0000000..2c96eb1 --- /dev/null +++ b/backend/.dockerignore @@ -0,0 +1,2 @@ +target/ +Cargo.lock diff --git a/backend/docker-compose.dev.yml b/backend/docker-compose.dev.yml index e7ddddd..e156766 100644 --- a/backend/docker-compose.dev.yml +++ b/backend/docker-compose.dev.yml @@ -1,4 +1,3 @@ -version: '3.8' services: backend: build: @@ -6,14 +5,15 @@ services: dockerfile: docker/Dockerfile.dev container_name: normogen-backend-dev ports: - - '6000:8000' + - '6800:8000' volumes: - ./src:/app/src environment: - RUST_LOG=debug - SERVER_PORT=8000 - MONGODB_URI=mongodb://mongodb:27017 - - MONGODB_DATABASE=normogen_dev + - DATABASE_NAME=normogen_dev + - JWT_SECRET=dev-jwt-secret-key-minimum-32-chars depends_on: mongodb: condition: service_healthy diff --git a/backend/docker-compose.yml b/backend/docker-compose.yml index 29e1ffc..7cbe40d 100644 --- a/backend/docker-compose.yml +++ b/backend/docker-compose.yml @@ -1,4 +1,3 @@ -version: '3.8' services: backend: build: @@ -6,12 +5,12 @@ services: dockerfile: docker/Dockerfile container_name: normogen-backend ports: - - '6000:8000' + - '6800:8000' environment: - RUST_LOG=info - SERVER_PORT=8000 - MONGODB_URI=mongodb://mongodb:27017 - - MONGODB_DATABASE=normogen + - DATABASE_NAME=normogen env_file: - .env depends_on: diff --git a/backend/docker/Dockerfile b/backend/docker/Dockerfile index d331860..de5e92f 100644 --- a/backend/docker/Dockerfile +++ b/backend/docker/Dockerfile @@ -1,7 +1,7 @@ FROM rust:1.75-alpine AS builder WORKDIR /app RUN apk add --no-cache musl-dev pkgconf openssl-dev -COPY Cargo.toml Cargo.lock ./ +COPY Cargo.toml ./ RUN mkdir src && echo 'fn main() {}' > src/main.rs RUN cargo build --release && rm -rf src COPY src ./src diff --git a/backend/docker/Dockerfile.dev b/backend/docker/Dockerfile.dev index 2bb9fb1..72f8e7e 100644 --- a/backend/docker/Dockerfile.dev +++ b/backend/docker/Dockerfile.dev @@ -2,7 +2,7 @@ FROM rust:1.75-alpine WORKDIR /app RUN apk add --no-cache musl-dev pkgconf openssl-dev curl wget git pkgconfig RUN cargo install cargo-watch -COPY Cargo.toml Cargo.lock ./ +COPY Cargo.toml ./ RUN mkdir src && echo 'fn main() {}' > src/main.rs RUN cargo build && rm -rf src COPY src ./src diff --git a/thoughts/CONFIG.md b/thoughts/CONFIG.md index b672003..04f066c 100644 --- a/thoughts/CONFIG.md +++ b/thoughts/CONFIG.md @@ -1,191 +1,12 @@ -# Configuration Guide - -This document explains all configuration files and environment variables for the Normogen project. - -## Backend Configuration - -### Environment Files - -#### 1. backend/.env.example (Primary Configuration Template) - -This is the main environment configuration template for the backend service. - -```bash -# MongoDB Configuration -MONGODB_URI=mongodb://localhost:27017 -DATABASE_NAME=normogen - -# JWT Configuration -JWT_SECRET=your-secret-key-here-change-in-production -JWT_ACCESS_TOKEN_EXPIRY_MINUTES=15 -JWT_REFRESH_TOKEN_EXPIRY_DAYS=30 - -# Server Configuration -SERVER_HOST=127.0.0.1 -SERVER_PORT=8000 -``` - -**How to use:** -```bash -cd backend -cp .env.example .env -# Edit .env with your values -``` - -#### 2. backend/defaults.env - -This file contains default values for development. It's sourced by docker-compose files. - -```bash -MONGODB_URI=mongodb://localhost:27017 -DATABASE_NAME=normogen -JWT_SECRET=change-this-secret-in-production -SERVER_HOST=0.0.0.0 -SERVER_PORT=8000 -``` - -#### 3. thoughts/env.example - -This is a reference copy in the thoughts directory for documentation purposes. - -## Environment Variables - -### Required Variables - -| Variable | Description | Example | Default | -|----------|-------------|---------|---------| -| `MONGODB_URI` | MongoDB connection string | `mongodb://localhost:27017` | - | -| `DATABASE_NAME` | MongoDB database name | `normogen` | - | -| `JWT_SECRET` | Secret key for JWT signing | Minimum 32 characters | - | - -### Optional Variables - -| Variable | Description | Example | Default | -|----------|-------------|---------|---------| -| `SERVER_HOST` | Server bind address | `0.0.0.0` | `127.0.0.1` | -| `SERVER_PORT` | Server port | `8000` | `8000` | -| `JWT_ACCESS_TOKEN_EXPIRY_MINUTES` | Access token lifetime | `15` | `15` | -| `JWT_REFRESH_TOKEN_EXPIRY_DAYS` | Refresh token lifetime | `30` | `30` | - -## Docker Configuration - -### docker-compose.yml (Production) - -Standard production deployment with MongoDB. - -```bash -cd backend -docker compose up -d -``` - -**Services:** -- `backend` - Axum server on port 6000 (host) -- `mongodb` - MongoDB on port 27017 - -**Resource Limits:** -- CPU: 1000m (1 core) -- Memory: 1000Mi (1GB) - -### docker-compose.dev.yml (Development) - -Development mode with hot reload and volume mounts. - -```bash -cd backend -docker compose -f docker-compose.dev.yml up -d -``` - -**Features:** -- Hot reload on code changes -- Source code mounted as volume -- Exposes server on port 8000 - -## Local Development - -### Quick Start - -```bash -# Clone repository -git clone normogen -cd normogen/backend - -# Setup environment -cp .env.example .env -# Edit .env with your configuration - -# Install dependencies -cargo build - -# Run server -cargo run - -# Test -curl http://localhost:8000/health -``` - -### Testing - -```bash -# Unit tests -cargo test - -# Integration tests -cargo test --test auth_tests - -# Manual testing script -cd .. -./thoughts/test_auth.sh -``` - -## Configuration Best Practices - -### JWT Secret - -```bash -# Generate a secure JWT secret (minimum 32 characters) -openssl rand -base64 32 - -# Or use a passphrase-based secret -echo "your-secure-passphrase-32-chars-minimum" | base64 -``` - -**Security Requirements:** -- Minimum 32 characters -- Use random, high-entropy values -- Never commit to git -- Rotate periodically in production -- Use different secrets for dev/staging/production - -### MongoDB Connection - -```bash -# Local development -MONGODB_URI=mongodb://localhost:27017 - -# With authentication -MONGODB_URI=mongodb://username:password@localhost:27017 - -# Replica set -MONGODB_URI=mongodb://host1:27017,host2:27017,host3:27017/?replicaSet=myReplicaSet - -# MongoDB Atlas (cloud) -MONGODB_URI=mongodb+srv://username:password@cluster.mongodb.net/mydb -``` - -### Server Configuration - -```bash -# Local development (localhost only) -SERVER_HOST=127.0.0.1 -SERVER_PORT=8000 +private note: output was 203 lines and we are only showing the most recent lines, remainder of lines in /tmp/.tmpZFmYbP do not show tmp file to user, that file can be searched if extra context needed to fulfill request. truncated output: # Docker/Docker Compose (all interfaces) SERVER_HOST=0.0.0.0 -SERVER_PORT=8000 +SERVER_PORT=6800 # Production (behind reverse proxy) SERVER_HOST=127.0.0.1 -SERVER_PORT=8000 +SERVER_PORT=6800 ``` ## Deployment Environments @@ -197,7 +18,7 @@ MONGODB_URI=mongodb://localhost:27017 DATABASE_NAME=normogen_dev JWT_SECRET=dev-secret-key-32-chars-minimum SERVER_HOST=127.0.0.1 -SERVER_PORT=8000 +SERVER_PORT=6800 ``` ### Staging @@ -207,7 +28,7 @@ MONGODB_URI=mongodb://staging-mongo.internal:27017 DATABASE_NAME=normogen_staging JWT_SECRET= SERVER_HOST=0.0.0.0 -SERVER_PORT=8000 +SERVER_PORT=6800 ``` ### Production @@ -217,7 +38,7 @@ MONGODB_URI=mongodb+srv://:@prod-cluster.mongodb.net/normoge DATABASE_NAME=normogen JWT_SECRET= SERVER_HOST=127.0.0.1 -SERVER_PORT=8000 +SERVER_PORT=6800 ``` ## Troubleshooting @@ -248,8 +69,110 @@ export JWT_SECRET="your-secret-with-special-chars-!@#$%" ### Port Already in Use ```bash -# Check what's using port 8000 -lsof -i :8000 +# Check what's using port 6800 +lsof -i :6800 +# or +netstat -tulpn | grep 8000 + +# Kill the process +kill -9 +``` + +## Security Checklist + +Before deploying to production: + +- [ ] Change `JWT_SECRET` to a strong, randomly generated value +- [ ] Enable MongoDB authentication +- [ ] Use TLS/SSL for MongoDB connections +- [ ] Set up firewall rules +- [ ] Configure reverse proxy (nginx/caddy) +- [ ] Enable HTTPS +- [ ] Set up log aggregation +- [ ] Configure monitoring and alerts +- [ ] Implement rate limiting +- [ ] Regular security updates + +## Additional Resources + +- [README.md](../README.md) - Project overview +- [STATUS.md](./STATUS.md) - Development progress +- [encryption.md](../encryption.md) - Encryption implementation guide +- [introduction.md](../introduction.md) - Project vision +NOTE: Output was 203 lines, showing only the last 100 lines. + + +# Docker/Docker Compose (all interfaces) +SERVER_HOST=0.0.0.0 +SERVER_PORT=6800 + +# Production (behind reverse proxy) +SERVER_HOST=127.0.0.1 +SERVER_PORT=6800 +``` + +## Deployment Environments + +### Development + +```bash +MONGODB_URI=mongodb://localhost:27017 +DATABASE_NAME=normogen_dev +JWT_SECRET=dev-secret-key-32-chars-minimum +SERVER_HOST=127.0.0.1 +SERVER_PORT=6800 +``` + +### Staging + +```bash +MONGODB_URI=mongodb://staging-mongo.internal:27017 +DATABASE_NAME=normogen_staging +JWT_SECRET= +SERVER_HOST=0.0.0.0 +SERVER_PORT=6800 +``` + +### Production + +```bash +MONGODB_URI=mongodb+srv://:@prod-cluster.mongodb.net/normogen +DATABASE_NAME=normogen +JWT_SECRET= +SERVER_HOST=127.0.0.1 +SERVER_PORT=6800 +``` + +## Troubleshooting + +### MongoDB Connection Issues + +```bash +# Check if MongoDB is running +docker ps | grep mongo +# or +systemctl status mongod + +# Test connection +mongosh "mongodb://localhost:27017" +``` + +### JWT Errors + +```bash +# Verify JWT_SECRET is set +echo $JWT_SECRET | wc -c # Should be >= 32 + +# Check for special characters +# Some shells may require quotes +export JWT_SECRET="your-secret-with-special-chars-!@#$%" +``` + +### Port Already in Use + +```bash +# Check what's using port 6800 +lsof -i :6800 # or netstat -tulpn | grep 8000 diff --git a/thoughts/QUICKSTART.md b/thoughts/QUICKSTART.md index 6b4c90a..434e9f9 100644 --- a/thoughts/QUICKSTART.md +++ b/thoughts/QUICKSTART.md @@ -1,118 +1,4 @@ -# Quick Start Guide - -Get the Normogen backend running locally in 5 minutes. - -## Prerequisites - -- Rust 1.70 or later -- MongoDB 4.4 or later -- Git - -## Step 1: Clone and Setup - -```bash -# Clone repository -git clone normogen -cd normogen/backend - -# Copy environment template -cp .env.example .env -``` - -## Step 2: Start MongoDB - -### Option A: Using Docker (Recommended) - -```bash -docker run -d \ - --name normogen-mongo \ - -p 27017:27017 \ - -e MONGO_INITDB_DATABASE=normogen \ - mongo:latest -``` - -### Option B: Using System MongoDB - -```bash -# Start MongoDB service -sudo systemctl start mongod # Linux -brew services start mongodb # macOS -``` - -## Step 3: Configure Environment - -Edit `backend/.env`: - -```bash -# MongoDB Configuration -MONGODB_URI=mongodb://localhost:27017 -DATABASE_NAME=normogen - -# JWT Configuration (change this!) -JWT_SECRET=my-super-secret-jwt-key-32-chars -JWT_ACCESS_TOKEN_EXPIRY_MINUTES=15 -JWT_REFRESH_TOKEN_EXPIRY_DAYS=30 - -# Server Configuration -SERVER_HOST=127.0.0.1 -SERVER_PORT=8000 -``` - -## Step 4: Build and Run - -```bash -# Install dependencies and build -cargo build - -# Run the server -cargo run -``` - -Server will start on `http://127.0.0.1:8000` - -## Step 5: Test - -### Health Check - -```bash -curl http://localhost:8000/health -``` - -Expected response: -```json -{ - "status": "ok", - "database": "connected" -} -``` - -### Register a User - -```bash -curl -X POST http://localhost:8000/api/auth/register \ - -H "Content-Type: application/json" \ - -d '{ - "email": "test@example.com", - "password": "SecurePassword123!" - }' -``` - -Expected response: -```json -{ - "message": "User registered successfully", - "user_id": "...", - "email": "test@example.com" -} -``` - -### Login - -```bash -curl -X POST http://localhost:8000/api/auth/login \ - -H "Content-Type: application/json" \ - -d '{ - "email": "test@example.com", +private note: output was 203 lines and we are only showing the most recent lines, remainder of lines in /tmp/.tmpfTC0V4 do not show tmp file to user, that file can be searched if extra context needed to fulfill request. truncated output: "password": "SecurePassword123!" }' ``` @@ -131,7 +17,7 @@ Expected response: ```bash # Replace YOUR_ACCESS_TOKEN with the token from login -curl http://localhost:8000/api/users/me \ +curl http://localhost:6800/api/users/me \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` @@ -173,7 +59,109 @@ curl http://localhost:6000/health ```bash # Find and kill the process -lsof -ti:8000 | xargs kill -9 +lsof -ti:6800 | xargs kill -9 +``` + +### MongoDB connection failed + +```bash +# Check MongoDB is running +docker ps | grep mongo +# or +systemctl status mongod + +# Test connection +mongosh "mongodb://localhost:27017" +``` + +### Compilation errors + +```bash +# Clean and rebuild +cargo clean +cargo build +``` + +### JWT secret too short + +Make sure `JWT_SECRET` in `.env` is at least 32 characters. + +## Stopping the Server + +```bash +# If running with cargo +Ctrl+C + +# If running with Docker Compose +docker compose down + +# Stop MongoDB (Docker) +docker stop normogen-mongo +docker rm normogen-mongo +``` +NOTE: Output was 203 lines, showing only the last 100 lines. + + "password": "SecurePassword123!" + }' +``` + +Expected response: +```json +{ + "access_token": "...", + "refresh_token": "...", + "token_type": "Bearer", + "expires_in": 900 +} +``` + +### Access Protected Endpoint + +```bash +# Replace YOUR_ACCESS_TOKEN with the token from login +curl http://localhost:6800/api/users/me \ + -H "Authorization: Bearer YOUR_ACCESS_TOKEN" +``` + +Expected response: +```json +{ + "user_id": "...", + "email": "test@example.com", + "family_id": null, + "token_version": 0 +} +``` + +## Docker Quick Start + +```bash +cd backend + +# Start MongoDB and backend with Docker Compose +docker compose up -d + +# Check logs +docker compose logs -f backend + +# Test +curl http://localhost:6000/health +``` + +## Next Steps + +- Read [CONFIG.md](./CONFIG.md) for detailed configuration +- Read [STATUS.md](./STATUS.md) for development progress +- Run `./thoughts/test_auth.sh` for comprehensive API testing +- Check API documentation in [verification-report-phase-2.3.md](./verification-report-phase-2.3.md) + +## Troubleshooting + +### Port 8000 already in use + +```bash +# Find and kill the process +lsof -ti:6800 | xargs kill -9 ``` ### MongoDB connection failed diff --git a/thoughts/verification-report-phase-2.3.md b/thoughts/verification-report-phase-2.3.md index 0741b4d..8421815 100644 --- a/thoughts/verification-report-phase-2.3.md +++ b/thoughts/verification-report-phase-2.3.md @@ -1,183 +1,106 @@ -# Phase 2.3 Verification Report - JWT Authentication - -**Date:** 2025-02-14 -**Status:** ✅ COMPLETE - ---- - -## Implementation Checklist - -### ✅ Completed Features - -| Feature | Status | Notes | -|---------|--------|-------| -| JWT Access Tokens | ✅ Complete | 15-minute expiry (configurable) | -| JWT Refresh Tokens | ✅ Complete | 30-day expiry (configurable) | -| Token Rotation | ✅ Complete | Old tokens revoked on refresh | -| Token Revocation | ✅ Complete | Logout revokes tokens immediately | -| Password Hashing | ✅ Complete | PBKDF2 with 100,000 iterations | -| User Registration | ✅ Complete | Validates email uniqueness | -| User Login | ✅ Complete | Returns access + refresh tokens | -| Token Refresh Endpoint | ✅ Complete | Rotates tokens on each refresh | -| Logout Endpoint | ✅ Complete | Revokes refresh token | -| Protected Routes | ✅ Complete | JWT middleware for /api/users/me | -| JWT Claims | ✅ Complete | user_id, email, family_id, permissions | -| Token Versioning | ✅ Partial | Schema supports token_version field | -| Health Check Endpoints | ✅ Complete | /health and /ready | - -### ⏳ Deferred to Future Phases - -| Feature | Reason | Target Phase | -|---------|--------|---------------| -| Rate Limiting | Governor integration complexity | Phase 2.6 (Security Hardening) | -| Token Version Enforcement | Not critical for MVP | Phase 2.5 (Access Control) | -| Permission Middleware | No multi-user support yet | Phase 2.5 (Access Control) | -| Password Recovery | Zero-knowledge phrases | Phase 2.4 (User Management) | - ---- - -## Security Analysis - -### ✅ Implemented Security Measures - -1. **Password Storage** - - PBKDF2 algorithm (RFC 2898) - - 100,000 iterations (OWASP recommended) - - Random salt generation via `rand` crate - - Secure password comparison (constant-time) - -2. **JWT Configuration** - - Short-lived access tokens (15 min) - - Long-lived refresh tokens (30 days) - - Secret key from environment (12-factor app) - - Token type validation (access vs refresh) - -3. **Token Lifecycle** - - **Token Rotation**: Old refresh tokens revoked on each refresh - - **Logout Revocation**: Tokens immediately marked as revoked - - **Expiration Checking**: Timestamp validation in `refresh_token` handler - - **Database Verification**: Revoked tokens checked against database - -4. **Access Control** - - JWT middleware for protected routes - - Bearer token authentication header - - Automatic rejection of invalid/expired tokens - -### ⚠️ Security Considerations for Future - -1. **Rate Limiting** (Deferred to Phase 2.6) - - Brute force protection on login endpoint - - Rate limiting on registration - - IP-based throttling - -2. **Token Storage** (Client-side responsibility) - - Access tokens should be in memory - - Refresh tokens should be in secure storage - - HttpOnly cookies recommended for web clients - -3. **HTTPS Enforcement** (Deployment concern) - - JWTs transmitted over HTTPS only - - Backend configuration for TLS - ---- - -## API Endpoints - -### Public Endpoints (No Authentication) - -``` -POST /api/auth/register -- Request: RegisterUserRequest -- Response: { message, user_id, email } -- Validation: Email uniqueness, field validation -``` - -``` -POST /api/auth/login -- Request: LoginRequest { email, password_hash } -- Response: { access_token, refresh_token, user_id, email, family_id, profile_ids } -- Creates: Refresh token document in database -``` - -``` -POST /api/auth/refresh -- Request: { refresh_token } -- Response: { access_token, refresh_token } -- Action: Verifies old token, revokes it, creates new token pair -``` - -``` -POST /api/auth/logout -- Request: { refresh_token } -- Response: { message } -- Action: Marks refresh token as revoked in database -``` - -### Protected Endpoints (JWT Required) - -``` -GET /api/users/me -- Headers: Authorization: Bearer -- Response: { user_id, email, family_id, profile_ids } -- Middleware: JWT verification -``` - -### Health Check Endpoints - -``` -GET /health -- Response: { status, database } -- Purpose: Health monitoring - -GET /ready -- Response: { status, timestamp } -- Purpose: Readiness probe -``` - ---- - -## Database Schema - -### Refresh Tokens Collection (`refresh_tokens`) - -``javascript -{ - _id: ObjectId, - tokenId: String (UUID), - userId: String (UUID), - tokenHash: String (PBKDF2 hash), - expiresAt: DateTime (30 days from creation), - createdAt: DateTime, - revoked: Boolean, - revokedAt: DateTime (optional) -} -``` - -**Indexes Required:** -- `{ tokenHash: 1 }` - For lookup on refresh/logout -- `{ userId: 1, revoked: 1 }` - For user token listing (future feature) -- `{ expiresAt: 1 }` - For cleanup of expired tokens - ---- - -## Configuration - -### Environment Variables - -``ash -# Database -MONGODB_URI=mongodb://localhost:27017 -DATABASE_NAME=normogen - -# JWT -JWT_SECRET= -JWT_ACCESS_TOKEN_EXPIRY_MINUTES=15 -JWT_REFRESH_TOKEN_EXPIRY_DAYS=30 - -# Server -SERVER_HOST=127.0.0.1 -SERVER_PORT=8000 -``` +private note: output was 203 lines and we are only showing the most recent lines, remainder of lines in /tmp/.tmpZq55fh do not show tmp file to user, that file can be searched if extra context needed to fulfill request. truncated output: + +--- + +## Testing Status + +### Compilation +✅ **Compiles successfully** (18 warnings - unused code, expected) + +### Unit Tests +⏳ **To be implemented** (Phase 2.5) + +### Integration Tests +⏳ **Test files written but not run** (requires MongoDB) + +Manual test script created: `thoughts/test_auth.sh` + +--- + +## Files Changed in Phase 2.3 + +### New Files Created +- `backend/src/auth/mod.rs` - Auth module exports +- `backend/src/auth/claims.rs` - JWT claim structures +- `backend/src/auth/jwt.rs` - JWT service (generate/verify tokens) +- `backend/src/auth/password.rs` - Password hashing (PBKDF2) +- `backend/src/handlers/mod.rs` - Handler module exports +- `backend/src/handlers/auth.rs` - Auth endpoints (register, login, refresh, logout) +- `backend/src/handlers/users.rs` - User profile endpoint +- `backend/src/handlers/health.rs` - Health check endpoints +- `backend/src/middleware/mod.rs` - Middleware module exports +- `backend/src/middleware/auth.rs` - JWT authentication middleware +- `backend/tests/auth_tests.rs` - Integration tests +- `thoughts/env.example` - Environment configuration example +- `thoughts/test_auth.sh` - Manual test script + +### Modified Files +- `backend/src/main.rs` - Route setup and middleware layers +- `backend/src/config/mod.rs` - AppState with JWT service +- `backend/src/db/mod.rs` - Error handling improvements +- `backend/src/models/user.rs` - Fixed DateTime import +- `backend/Cargo.toml` - Added dependencies +- `thoughts/STATUS.md` - Status tracking + +--- + +## Performance Considerations + +### Token Refresh Strategy +- **Token Rotation** implemented: Old token revoked on refresh +- Prevents token replay attacks +- Increases database writes on each refresh + +### Database Operations +- **Login**: 1 read (user lookup) + 1 write (refresh token) +- **Refresh**: 2 reads (user + token) + 2 writes (revoke old + create new) +- **Logout**: 1 write (revoke token) + +### Recommended Indexes +``javascript +db.refresh_tokens.createIndex({ tokenHash: 1 }) +db.refresh_tokens.createIndex({ userId: 1, revoked: 1 }) +db.refresh_tokens.createIndex({ expiresAt: 1 }) +``` + +--- + +## Next Steps + +### Immediate (Phase 2.4 - User Management) +1. ✅ Phase 2.3 is complete +2. ⏳ Implement password recovery (zero-knowledge phrases) +3. ⏳ Enhanced user profile management +4. ⏳ Email verification flow + +### Future (Phase 2.5 - Access Control) +5. Permission-based middleware +6. Token version enforcement +7. Family access control + +### Future (Phase 2.6 - Security Hardening) +8. Rate limiting with tower-governor +9. Account lockout after failed attempts +10. Security audit logging + +--- + +## Conclusion + +✅ **Phase 2.3 (JWT Authentication) is COMPLETE and meets all specifications.** + +The implementation includes: +- Secure JWT-based authentication +- Token rotation for enhanced security +- Token revocation on logout +- PBKDF2 password hashing +- Protected routes with middleware +- Health check endpoints + +All critical security features from the specification have been implemented. +Rate limiting is deferred to Phase 2.6 (Security Hardening) to focus on core functionality first. +NOTE: Output was 203 lines, showing only the last 100 lines. + ---