feat: add dark mode functionality and improve navigation system

- Add complete dark mode system with theme context and toggle
- Implement dark mode toggle component in navigation menu
- Add client-side routing with SSR-safe signal handling
- Fix language selector styling for better dark mode compatibility
- Add documentation system with mdBook integration
- Improve navigation menu with proper external/internal link handling
- Add comprehensive project documentation and configuration
- Enhance theme system with localStorage persistence
- Fix arena panic issues during server-side rendering
- Add proper TypeScript configuration and build optimizations

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Jesús Pérex 2025-07-11 20:53:20 +01:00
parent 03550c29a4
commit 2f0f807331
317 changed files with 50080 additions and 355 deletions

View File

@ -0,0 +1,38 @@
{
"permissions": {
"allow": [
"Bash(curl:*)",
"Bash(cargo:*)",
"Bash(pkill:*)",
"Bash(RUST_LOG=debug leptos serve watch)",
"Bash(RUST_LOG=debug cargo leptos watch)",
"Bash(rm:*)",
"Bash(sqlite3:*)",
"Bash(lsof:*)",
"Bash(RUST_LOG=info cargo leptos watch)",
"Bash(RUST_LOG=info ./target/debug/server)",
"Bash(env)",
"Bash(cat:*)",
"Bash(grep:*)",
"Bash(ENVIRONMENT=development cargo run --bin server)",
"Bash(ls:*)",
"Bash(CONFIG_FILE=config.dev.toml cargo run --bin server)",
"Bash(git checkout:*)",
"Bash(CONFIG_FILE=/Users/Akasha/Development/rustelo/template/config.dev.toml cargo run --bin server)",
"Bash(ENVIRONMENT=development CONFIG_FILE=config.dev.toml cargo run --bin server)",
"Bash(find:*)",
"Bash(ln:*)",
"Bash(cp:*)",
"Bash(npm run build:css:*)",
"Bash(killall:*)",
"Bash(true)",
"Bash(mv:*)",
"Bash(LEPTOS_OUTPUT_NAME=website cargo leptos build)",
"Bash(LEPTOS_OUTPUT_NAME=website cargo leptos serve --hot-reload)",
"Bash(pgrep:*)",
"Bash(./scripts/link-pkg-files.sh:*)",
"Bash(LEPTOS_OUTPUT_NAME=website cargo run --bin server)"
],
"deny": []
}
}

88
.env.example Normal file
View File

@ -0,0 +1,88 @@
# Server Configuration
# Copy this file to .env and modify the values as needed
# Root Path Configuration
# Base directory for all relative paths in the configuration
# If not set, defaults to current working directory
ROOT_PATH=.
# Server Protocol (http or https)
SERVER_PROTOCOL=http
# Server Host
SERVER_HOST=127.0.0.1
# Server Port
SERVER_PORT=3030
# TLS Configuration (only used when SERVER_PROTOCOL=https)
# Path to TLS certificate file
TLS_CERT_PATH=./certs/cert.pem
# Path to TLS private key file
TLS_KEY_PATH=./certs/key.pem
# Environment (development, production, dev, prod)
ENVIRONMENT=development
# Log Level (error, warn, info, debug, trace)
LOG_LEVEL=info
# Reload Port (for development)
RELOAD_PORT=3031
# Static Files Directory
STATIC_DIR=target/site
# Assets Directory
ASSETS_DIR=public
# Site Package Directory
SITE_PKG_DIR=pkg
# CORS Configuration
CORS_ALLOWED_ORIGINS=http://localhost:3030,http://127.0.0.1:3030
# Session Configuration
SESSION_SECRET=your-session-secret-key-change-this-in-production
# Database Configuration (if using a database)
# DATABASE_URL=postgresql://user:password@localhost/dbname
# Redis Configuration (if using Redis)
# REDIS_URL=redis://localhost:6379
# JWT Configuration
JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
JWT_ISSUER=rustelo-auth
JWT_ACCESS_TOKEN_EXPIRES_IN=15
JWT_REFRESH_TOKEN_EXPIRES_IN=7
# OAuth Configuration
OAUTH_REDIRECT_BASE_URL=http://localhost:3030/auth/callback
# Google OAuth (optional)
# GOOGLE_CLIENT_ID=your-google-client-id
# GOOGLE_CLIENT_SECRET=your-google-client-secret
# GitHub OAuth (optional)
# GITHUB_CLIENT_ID=your-github-client-id
# GITHUB_CLIENT_SECRET=your-github-client-secret
# Discord OAuth (optional)
# DISCORD_CLIENT_ID=your-discord-client-id
# DISCORD_CLIENT_SECRET=your-discord-client-secret
# Microsoft OAuth (optional)
# MICROSOFT_CLIENT_ID=your-microsoft-client-id
# MICROSOFT_CLIENT_SECRET=your-microsoft-client-secret
# MICROSOFT_TENANT_ID=common
# External API Configuration
# API_BASE_URL=https://api.example.com
# API_KEY=your-api-key
# Feature Flags
ENABLE_METRICS=false
ENABLE_HEALTH_CHECK=true
ENABLE_COMPRESSION=true

View File

@ -35,7 +35,7 @@ web-sys = { version = "0.3.77" , features = ["Clipboard", "Window", "Navigator",
regex = "1.11.1" regex = "1.11.1"
tracing = "0.1" tracing = "0.1"
tracing-subscriber = "0.3" tracing-subscriber = "0.3"
toml = "0.8" toml = "0.9"
fluent = "0.17" fluent = "0.17"
fluent-bundle = "0.16" fluent-bundle = "0.16"
unic-langid = "0.9" unic-langid = "0.9"
@ -52,6 +52,8 @@ site-root = "target/site"
# The site-root relative folder where all compiled output (JS, WASM and CSS) is written # The site-root relative folder where all compiled output (JS, WASM and CSS) is written
# Defaults to pkg # Defaults to pkg
site-pkg-dir = "pkg" site-pkg-dir = "pkg"
# Add hash to JS/WASM files for cache busting
hash-files = true
# The tailwind input file. Not needed if tailwind-input-file is not set # The tailwind input file. Not needed if tailwind-input-file is not set
# Optional, Activates the tailwind build # Optional, Activates the tailwind build
#tailwind-input-file = "input.css" #tailwind-input-file = "input.css"
@ -59,7 +61,7 @@ site-pkg-dir = "pkg"
# [Optional] Files in the asset-dir will be copied to the site-root directory # [Optional] Files in the asset-dir will be copied to the site-root directory
assets-dir = "public" assets-dir = "public"
# The IP and port (ex: 127.0.0.1:3000) where the server serves the content. Use it in your server setup. # The IP and port (ex: 127.0.0.1:3000) where the server serves the content. Use it in your server setup.
site-addr = "127.0.0.1:3030" site-addr = "0.0.0.0:3030"
# The port to use for automatic reload monitoring # The port to use for automatic reload monitoring
reload-port = 3031 reload-port = 3031

View File

@ -180,7 +180,7 @@ ENABLE_CONTENT_DB=true
ENABLE_TLS=false ENABLE_TLS=false
# Database (choose one) # Database (choose one)
DATABASE_URL=sqlite:database.db # SQLite (simple) DATABASE_URL=sqlite://database.db # SQLite (simple)
# DATABASE_URL=postgresql://user:pass@localhost:5432/db # PostgreSQL (production) # DATABASE_URL=postgresql://user:pass@localhost:5432/db # PostgreSQL (production)
# Logging # Logging

View File

@ -403,7 +403,7 @@ The application automatically detects your database type from the connection URL
DATABASE_URL=postgresql://user:pass@localhost/db DATABASE_URL=postgresql://user:pass@localhost/db
# SQLite # SQLite
DATABASE_URL=sqlite:data/app.db DATABASE_URL=sqlite://data/app.db
``` ```
### Migration System ### Migration System

8
TODO.md Normal file
View File

@ -0,0 +1,8 @@
- [X] Configuration builder
- [X] Admin Dashboard
- [ ] User profile manager
- [ ] Remove python script are in docs ?
- [ ] Add file upload capabilities** for media management?
- [ ] **Enhance the dashboard** with content analytics?
- [ ] **Show how to configure** the content sources (DB vs Files vs Both)?

85
book.toml Normal file
View File

@ -0,0 +1,85 @@
[book]
title = "Rustelo Documentation"
description = "A comprehensive guide to building web applications with Rustelo - a modular Rust web application template"
authors = ["Rustelo Contributors"]
language = "en"
multilingual = false
src = "book"
book = "_book"
[rust]
edition = "2021"
[build]
build-dir = "_book"
create-missing = true
preprocess = ["links", "index"]
use-default-preprocessors = true
[preprocessor.links]
# Process relative links and convert them to proper mdBook links
[preprocessor.index]
# Generate index pages automatically
[output.html]
default-theme = "light"
preferred-dark-theme = "navy"
smart-punctuation = true
mathjax-support = false
copy-fonts = true
edit-url-template = "https://github.com/yourusername/rustelo/edit/main/book/{path}"
site-url = "/docs/"
cname = ""
git-repository-url = "https://github.com/yourusername/rustelo"
git-repository-icon = "fa-github"
# Logo configuration
# additional-css = ["theme/custom.css"]
# additional-js = ["theme/custom.js"]
[output.html.print]
enable = true
page-break = true
[output.html.search]
enable = true
limit-results = 30
teaser-word-count = 30
use-boolean-and = true
boost-title = 2
boost-hierarchy = 1
boost-paragraph = 1
expand = true
heading-split-level = 3
[output.html.redirect]
# Add redirects for moved pages if needed
[output.html.fold]
enable = false
level = 0
[output.html.playground]
runnable = true
copyable = true
copy-js = true
line-numbers = false
editable = false
# [output.linkcheck]
# # Check for broken links
# optional = true
# follow-web-links = false
# traverse-parent-directories = false
# exclude = [ "private" ]
# # Temporarily disabled due to broken links
# Optional: Generate PDF output
# [output.pdf]
# enable = true
# Optional: Generate EPUB output
# [output.epub]
# enable = true

176
book/SUMMARY.md Normal file
View File

@ -0,0 +1,176 @@
# Summary
[Introduction](./introduction.md)
# Getting Started
- [What is Rustelo?](./getting-started/what-is-rustelo.md)
- [Quick Installation](./getting-started/installation.md)
- [First Run & Setup](./getting-started/first-run.md)
- [First App](./getting-started/first-app.md)
- [Basic Configuration](./getting-started/configuration.md)
# For End Users
## Using the Application
- [User Interface Guide](./users/interface.md)
- [User Registration & Login](./users/authentication.md)
- [Managing Your Profile](./users/profile.md)
- [Content Publishing](./users/content.md)
- [File & Media Management](./users/media.md)
## Features & Functionality
- [Authentication & Security](./users/features/auth.md)
- [Content Management](./users/features/content.md)
- [Email & Notifications](./users/features/email.md)
- [Search & Discovery](./users/features/search.md)
- [Mobile Experience](./users/features/mobile.md)
## Administration
- [Admin Dashboard](./users/admin/dashboard.md)
- [User Management](./users/admin/users.md)
- [Content Moderation](./users/admin/content.md)
- [System Settings](./users/admin/settings.md)
- [Monitoring & Analytics](./users/admin/monitoring.md)
# For Developers
## Development Setup
- [Development Environment](./developers/setup/environment.md)
- [Project Structure](./developers/setup/structure.md)
- [Build System & Tools](./developers/setup/build.md)
- [Development Workflow](./developers/setup/workflow.md)
## Architecture
- [System Overview](./developers/architecture/overview.md)
- [Frontend Architecture](./developers/architecture/frontend.md)
- [Backend Architecture](./developers/architecture/backend.md)
- [Database Design](./developers/architecture/database.md)
- [Security Model](./developers/architecture/security.md)
## Core Components
- [Components Overview](./developers/components/README.md)
- [Authentication System](./developers/components/auth.md)
- [Content Management](./developers/components/content.md)
- [Email System](./developers/components/email.md)
- [Template Engine](./developers/components/templates.md)
- [Configuration System](./developers/components/config.md)
## Feature Development
- [Adding New Features](./developers/features/adding-features.md)
- [Feature Flags & Modules](./developers/features/feature-flags.md)
- [Database Migrations](./developers/features/migrations.md)
- [API Endpoints](./developers/features/api-endpoints.md)
- [Frontend Components](./developers/features/frontend-components.md)
## Brand & Design
- [Logo Usage Guide](./developers/brand/logo-usage.md)
## Testing
- [Testing Strategy](./developers/testing/strategy.md)
- [Unit Testing](./developers/testing/unit.md)
- [Integration Testing](./developers/testing/integration.md)
- [End-to-End Testing](./developers/testing/e2e.md)
- [Performance Testing](./developers/testing/performance.md)
# Configuration
- [Configuration Overview](./configuration/README.md)
- [Environment Variables](./configuration/environment.md)
- [Configuration Files](./configuration/files.md)
- [Features Configuration](./configuration/features.md)
- [Database Configuration](./configuration/database.md)
- [Security Settings](./configuration/security.md)
- [Performance Tuning](./configuration/performance.md)
# Deployment
- [Production Setup](./deployment/production.md)
- [Docker Deployment](./deployment/docker.md)
- [Cloud Platforms](./deployment/cloud.md)
- [SSL/TLS Configuration](./deployment/ssl.md)
- [Monitoring & Logging](./deployment/monitoring.md)
- [Backup & Recovery](./deployment/backup.md)
# API Reference
- [REST API Overview](./api/overview.md)
- [Authentication Endpoints](./api/auth.md)
- [Content Management API](./api/content.md)
- [User Management API](./api/users.md)
- [Email & Notifications API](./api/email.md)
- [Error Handling](./api/errors.md)
- [Rate Limiting](./api/rate-limiting.md)
# Security
- [Security Overview](./security/overview.md)
- [Authentication & Authorization](./security/auth.md)
- [Data Protection](./security/data-protection.md)
- [CSRF & XSS Prevention](./security/web-security.md)
- [TLS & Encryption](./security/encryption.md)
- [Security Best Practices](./security/best-practices.md)
# Performance
- [Performance Overview](./performance/overview.md)
- [Database Optimization](./performance/database.md)
- [Caching Strategies](./performance/caching.md)
- [Frontend Optimization](./performance/frontend.md)
- [Memory Management](./performance/memory.md)
- [Profiling & Monitoring](./performance/monitoring.md)
# Troubleshooting
- [Common Issues](./troubleshooting/common.md)
- [Installation Problems](./troubleshooting/installation.md)
- [Authentication Issues](./troubleshooting/auth.md)
- [Database Problems](./troubleshooting/database.md)
- [Performance Issues](./troubleshooting/performance.md)
- [Build & Development Issues](./troubleshooting/development.md)
- [Getting Help & Support](./troubleshooting/support.md)
# Advanced Topics
- [Custom Features & Extensions](./advanced/extensions.md)
- [Plugin Development](./advanced/plugins.md)
- [Theme Customization](./advanced/themes.md)
- [Integration Examples](./advanced/integrations.md)
- [Scaling & High Availability](./advanced/scaling.md)
- [Migration Strategies](./advanced/migrations.md)
# Contributing
- [Contributing Guidelines](./contributing/guidelines.md)
- [Development Setup](./contributing/setup.md)
- [Code Standards](./contributing/standards.md)
- [Testing Guidelines](./contributing/testing.md)
- [Documentation Guidelines](./contributing/docs.md)
- [Release Process](./contributing/releases.md)
# Reference
- [Configuration Options](./reference/config.md)
- [Environment Variables](./reference/env-vars.md)
- [CLI Commands](./reference/cli.md)
- [Database Schema](./reference/schema.md)
- [Error Codes](./reference/error-codes.md)
- [Feature Matrix](./reference/features.md)
- [System Requirements](./reference/requirements.md)
- [FAQ](./reference/faq.md)
- [Configuration Migration Guide](./reference/config-migration.md)
- [Environment Migration Guide](./reference/env-migration.md)
- [Feature Migration Guide](./reference/feature-migration.md)
---
[Glossary](./glossary.md)

View File

View File

View File

View File

@ -0,0 +1 @@
# Custom Features & Extensions

View File

View File

@ -0,0 +1 @@
# Migration Strategies

View File

1
book/advanced/plugins.md Normal file
View File

@ -0,0 +1 @@
# Plugin Development

1
book/advanced/scaling.md Normal file
View File

@ -0,0 +1 @@
# Scaling & High Availability

1
book/advanced/themes.md Normal file
View File

@ -0,0 +1 @@
# Theme Customization

0
book/api/auth.md Normal file
View File

0
book/api/content.md Normal file
View File

1
book/api/email.md Normal file
View File

@ -0,0 +1 @@
# Email & Notifications API

0
book/api/errors.md Normal file
View File

0
book/api/overview.md Normal file
View File

View File

1
book/api/users.md Normal file
View File

@ -0,0 +1 @@
# User Management API

View File

View File

@ -0,0 +1,51 @@
# Environment Variables Reference
This document lists all environment variables used by Rustelo.
## Core Variables
| Variable | Description | Default | Required |
|----------|-------------|---------|----------|
| `SERVER_HOST` | Server bind address | `127.0.0.1` | No |
| `SERVER_PORT` | Server port | `3030` | No |
| `SERVER_PROTOCOL` | Protocol (http/https) | `http` | No |
| `ENVIRONMENT` | Environment (DEV/PROD) | `DEV` | No |
| `LOG_LEVEL` | Log level | `info` | No |
## Database Variables (auth, content-db features)
| Variable | Description | Default | Required |
|----------|-------------|---------|----------|
| `DATABASE_URL` | Database connection URL | - | Yes |
| `DATABASE_MAX_CONNECTIONS` | Maximum connections | `10` | No |
| `DATABASE_MIN_CONNECTIONS` | Minimum connections | `1` | No |
## Authentication Variables (auth feature)
| Variable | Description | Default | Required |
|----------|-------------|---------|----------|
| `JWT_SECRET` | JWT signing secret | - | Yes |
| `JWT_EXPIRATION_HOURS` | JWT expiration | `24` | No |
| `GOOGLE_CLIENT_ID` | Google OAuth client ID | - | No |
| `GOOGLE_CLIENT_SECRET` | Google OAuth secret | - | No |
| `GITHUB_CLIENT_ID` | GitHub OAuth client ID | - | No |
| `GITHUB_CLIENT_SECRET` | GitHub OAuth secret | - | No |
## TLS Variables (tls feature)
| Variable | Description | Default | Required |
|----------|-------------|---------|----------|
| `TLS_CERT_PATH` | TLS certificate path | - | Yes |
| `TLS_KEY_PATH` | TLS private key path | - | Yes |
## Email Variables (email feature)
| Variable | Description | Default | Required |
|----------|-------------|---------|----------|
| `EMAIL_PROVIDER` | Email provider | `console` | No |
| `EMAIL_FROM_ADDRESS` | Default from address | - | Yes |
| `EMAIL_FROM_NAME` | Default from name | - | No |
| `SMTP_HOST` | SMTP server host | - | Conditional |
| `SMTP_PORT` | SMTP server port | `587` | Conditional |
| `SMTP_USERNAME` | SMTP username | - | Conditional |
| `SMTP_PASSWORD` | SMTP password | - | Conditional |

0
book/appendices/faq.md Normal file
View File

View File

@ -0,0 +1,38 @@
# Feature Matrix
This matrix shows which features are available in different configurations.
| Feature | Minimal | Auth | Content | Email | TLS | Full |
|---------|---------|------|---------|-------|-----|------|
| Static Files | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Routing | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Security Headers | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| JWT Auth | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ |
| OAuth2 | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ |
| 2FA/TOTP | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ |
| Database Content | ❌ | ❌ | ✅ | ❌ | ❌ | ✅ |
| Markdown Rendering | ❌ | ❌ | ✅ | ❌ | ❌ | ✅ |
| Email System | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ |
| HTTPS/TLS | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |
## Build Commands
```bash
# Minimal
cargo build --no-default-features
# Authentication only
cargo build --no-default-features --features "auth"
# Content management only
cargo build --no-default-features --features "content-db"
# Email only
cargo build --no-default-features --features "email"
# TLS only
cargo build --no-default-features --features "tls"
# Full featured
cargo build --features "auth,content-db,email,tls"
```

View File

View File

@ -0,0 +1,424 @@
# Rustelo Configuration
Welcome to the Rustelo Configuration documentation! This comprehensive guide covers all aspects of configuring your Rustelo application for different environments and use cases.
## 📋 Configuration Overview
Rustelo uses a powerful, modular configuration system that allows you to:
- **Environment-specific configurations** - Different settings for dev, staging, production
- **Feature-based configuration** - Enable/disable features as needed
- **Secure secret management** - Environment variables for sensitive data
- **Modular composition** - Build configurations from reusable components
- **Runtime validation** - Ensure configurations are valid before startup
## 🎯 Quick Start
### Basic Configuration
```bash
# Build development configuration
./config/scripts/build-config.sh dev
# Build production configuration
./config/scripts/build-config.sh prod config.prod.toml
# View configuration status
./config/scripts/debug-manage.sh status
```
### Environment Variables
```bash
# Create .env file
cat > .env << EOF
DATABASE_URL=sqlite//:app.db
SESSION_SECRET=your-session-secret
JWT_SECRET=your-jwt-secret
EOF
# Load environment
source .env
```
## 📖 Configuration Guides
### Core Configuration
- **[Database Configuration](./database.md)** - Database connections, migrations, and pooling
- **[Environment Variables](./environment.md)** - Managing secrets and environment-specific settings
- **[Security Configuration](./security.md)** - Authentication, authorization, and security settings
- **[Performance Configuration](./performance.md)** - Optimization and performance tuning
### Advanced Configuration
- **[Feature Configuration](./features.md)** - Enable/disable application features
- **[Configuration Files](./files.md)** - Understanding configuration file structure
- **[Configuration Files](./files.md)** - Understanding configuration file structure
- **[Security Configuration](./security.md)** - Security settings and best practices
## 🏗️ Configuration Architecture
### File Structure
```
config/
├── base/ # Base configurations
│ ├── dev.toml # Development base
│ ├── prod.toml # Production base
│ └── example.toml # Example/documentation
├── features/ # Feature-specific configs
│ ├── auth/ # Authentication features
│ ├── content/ # Content management
│ ├── email/ # Email system
│ ├── metrics/ # Monitoring & metrics
│ └── tls/ # TLS/SSL configuration
└── scripts/ # Configuration tools
├── build-config.sh # Build configurations
├── debug-manage.sh # Debug and management
└── validate-config.sh # Validation tools
```
### Configuration Layers
1. **Base Configuration** - Core application settings
2. **Feature Configuration** - Feature-specific settings
3. **Environment Variables** - Runtime secrets and overrides
4. **Command Line Arguments** - Runtime parameter overrides
## 🔧 Configuration Types
### Application Configuration
```toml
[app]
name = "My Rustelo App"
version = "1.0.0"
environment = "development"
debug = true
[server]
host = "127.0.0.1"
port = 3030
workers = 4
```
### Database Configuration
```toml
[database]
url = "${DATABASE_URL}"
max_connections = 10
min_connections = 2
connect_timeout = 30
idle_timeout = 300
```
### Feature Configuration
```toml
[features]
auth = true
content_db = true
email = false
metrics = true
tls = false
```
### Security Configuration
```toml
[security]
session_secret = "${SESSION_SECRET}"
jwt_secret = "${JWT_SECRET}"
csrf_protection = true
rate_limiting = true
secure_cookies = true
```
## 🌍 Environment Management
### Development Environment
```bash
# Development configuration
DATABASE_URL=sqlite//:dev.db
SESSION_SECRET=dev-session-secret
LOG_LEVEL=debug
ENABLE_HOT_RELOAD=true
```
### Production Environment
```bash
# Production configuration
DATABASE_URL=postgresql://user:pass@host:5432/db
SESSION_SECRET=secure-random-secret
LOG_LEVEL=info
ENABLE_HOT_RELOAD=false
DOMAIN=myapp.com
```
### Staging Environment
```bash
# Staging configuration
DATABASE_URL=postgresql://user:pass@staging-host:5432/db
SESSION_SECRET=staging-secret
LOG_LEVEL=info
ENABLE_DEBUG=false
```
## 🔐 Secret Management
### Environment Variables
```bash
# Required secrets
export SESSION_SECRET=$(openssl rand -base64 32)
export JWT_SECRET=$(openssl rand -base64 32)
export DATABASE_URL="postgresql://user:pass@host:5432/db"
# Optional secrets
export SMTP_PASSWORD="your-smtp-password"
export OAUTH_CLIENT_SECRET="your-oauth-secret"
```
### Secret Management Tools
```bash
# Generate secure secrets
./config/scripts/generate-secrets.sh
# Encrypt/decrypt configuration
./config/scripts/encrypt-config.sh
./config/scripts/decrypt-config.sh
# Validate secrets
./config/scripts/validate-secrets.sh
```
## 🎛️ Feature Management
### Enabling Features
```toml
[features]
# Authentication system
auth = true
# Content management
content_db = true
# Email functionality
email = true
# Monitoring and metrics
metrics = true
# TLS/SSL support
tls = true
```
### Feature Dependencies
```toml
[features.auth]
enabled = true
dependencies = ["crypto", "database"]
[features.content_db]
enabled = true
dependencies = ["database", "auth"]
[features.email]
enabled = false
dependencies = ["auth"]
```
## 🚀 Configuration Best Practices
### Development Best Practices
- Use SQLite for development databases
- Enable debug logging
- Use relaxed security settings
- Enable hot reloading
- Use local file storage
### Production Best Practices
- Use PostgreSQL for production databases
- Enable minimal logging
- Use strict security settings
- Disable debug features
- Use cloud storage services
### Security Best Practices
- Never commit secrets to version control
- Use environment variables for sensitive data
- Rotate secrets regularly
- Use strong encryption keys
- Enable HTTPS in production
## 📊 Configuration Validation
### Validation Scripts
```bash
# Validate current configuration
./config/scripts/validate-config.sh
# Validate specific environment
./config/scripts/validate-config.sh prod
# Check configuration completeness
./config/scripts/check-config.sh
```
### Schema Validation
```toml
[validation]
strict_mode = true
required_fields = ["database.url", "security.session_secret"]
allowed_environments = ["dev", "staging", "prod"]
```
## 🔄 Configuration Updates
### Runtime Updates
```bash
# Reload configuration (if supported)
kill -HUP $(pidof rustelo-server)
# Update feature flags
./config/scripts/update-features.sh --enable email
# Apply configuration changes
./config/scripts/apply-config.sh
```
### Configuration Deployment
```bash
# Deploy configuration to staging
./config/scripts/deploy-config.sh staging
# Deploy configuration to production
./config/scripts/deploy-config.sh prod
# Rollback configuration
./config/scripts/rollback-config.sh
```
## 🧪 Testing Configuration
### Configuration Tests
```bash
# Test configuration validity
just config-test
# Test feature configurations
just config-test-features
# Test environment configurations
just config-test-env prod
```
### Integration Tests
```bash
# Test configuration integration
cargo test --test config_integration
# Test feature integration
cargo test --test feature_integration
```
## 🔍 Troubleshooting
### Common Issues
#### Configuration Not Found
```bash
# Check configuration file exists
ls -la config.toml
# Rebuild configuration
./config/scripts/build-config.sh dev
```
#### Environment Variables Missing
```bash
# Check environment variables
env | grep -E "(DATABASE_URL|SESSION_SECRET|JWT_SECRET)"
# Load environment file
source .env
```
#### Feature Configuration Conflicts
```bash
# Check feature dependencies
./config/scripts/debug-manage.sh check-features
# Resolve conflicts
./config/scripts/resolve-conflicts.sh
```
### Debug Tools
```bash
# Debug configuration
./config/scripts/debug-manage.sh debug
# Show configuration tree
./config/scripts/debug-manage.sh tree
# Validate configuration
./config/scripts/debug-manage.sh validate
```
## 📚 Configuration Examples
### Minimal Configuration
```toml
[app]
name = "My App"
environment = "development"
[database]
url = "sqlite://app.db"
[features]
auth = true
```
### Full-Featured Configuration
```toml
[app]
name = "Production App"
environment = "production"
debug = false
[server]
host = "0.0.0.0"
port = 443
workers = 8
[database]
url = "${DATABASE_URL}"
max_connections = 20
ssl_mode = "require"
[features]
auth = true
content_db = true
email = true
metrics = true
tls = true
[security]
session_secret = "${SESSION_SECRET}"
jwt_secret = "${JWT_SECRET}"
csrf_protection = true
rate_limiting = true
secure_cookies = true
```
## 🎯 Next Steps
1. **[Database Configuration](./database.md)** - Set up your database
2. **[Environment Variables](./environment.md)** - Configure environment-specific settings
3. **[Security Configuration](./security.md)** - Secure your application
4. **[Feature Configuration](./features.md)** - Enable the features you need
5. **[Performance Configuration](./performance.md)** - Optimize for production
## 🆘 Getting Help
- **[Common Issues](../troubleshooting/common.md)** - Solutions to common problems
- **[Configuration Files Guide](./files.md)** - Understanding configuration structure
- **[Environment Guide](./environment.md)** - Environment variable management
- **Community Support** - Discord, GitHub Issues, Stack Overflow
---
**Master your Rustelo configuration!** 🦀⚙️

View File

@ -0,0 +1,343 @@
# Database Configuration
<div align="center">
<img src="../../logos/rustelo_dev-logo-h.svg" alt="RUSTELO" width="300" />
</div>
This guide covers how to configure and use databases in RUSTELO. The application supports both **PostgreSQL** and **SQLite** databases through SQLx's unified interface, with automatic database type detection based on the connection URL.
## Quick Start
### SQLite (Recommended for Development)
```toml
[database]
url = "sqlite://database.db"
```
### PostgreSQL (Recommended for Production)
```toml
[database]
url = "postgresql://username:password@localhost:5432/database_name"
```
## Database URL Formats
### SQLite URLs
- `sqlite://database.db` - Relative path to database file
- `sqlite:///path/to/database.db` - Absolute path to database file
- `sqlite::memory:` - In-memory database (testing only)
### PostgreSQL URLs
- `postgresql://user:password@host:port/database`
- `postgres://user:password@host:port/database`
## Environment Variables
You can override the database URL using environment variables:
```bash
export DATABASE_URL="sqlite//:my_database.db"
# or
export DATABASE_URL="postgresql://user:pass@localhost:5432/mydb"
```
## Database-Specific Features
### SQLite
- **Pros:**
- Zero configuration setup
- Single file database
- Perfect for development and testing
- No separate server process required
- ACID compliant
- **Cons:**
- Limited concurrent writes
- No network access
- Fewer advanced features
- File-based storage
### PostgreSQL
- **Pros:**
- Full ACID compliance
- Excellent concurrent access
- Advanced features (JSONB, arrays, etc.)
- Network accessible
- Production-ready scalability
- **Cons:**
- Requires PostgreSQL server
- More complex setup
- Resource overhead
## Configuration Examples
### Development Configuration
```toml
# config.dev.toml
[database]
url = "sqlite://dev_database.db"
max_connections = 5
min_connections = 1
connect_timeout = 30
idle_timeout = 300
max_lifetime = 1800
```
### Production Configuration
```toml
# config.prod.toml
[database]
url = "postgresql://prod_user:${DATABASE_PASSWORD}@db.example.com:5432/prod_database"
max_connections = 20
min_connections = 5
connect_timeout = 30
idle_timeout = 600
max_lifetime = 3600
```
## Connection Pool Settings
| Setting | Description | SQLite | PostgreSQL |
|---------|-------------|--------|------------|
| `max_connections` | Maximum pool size | 1 (recommended) | 10-50 |
| `min_connections` | Minimum pool size | 1 | 1-5 |
| `connect_timeout` | Connection timeout (seconds) | 30 | 30 |
| `idle_timeout` | Idle connection timeout (seconds) | 300 | 600 |
| `max_lifetime` | Maximum connection lifetime (seconds) | 1800 | 3600 |
## Database Setup
### SQLite Setup
No setup required! The database file will be created automatically when the application starts.
### PostgreSQL Setup
#### Using Docker
```bash
# Start PostgreSQL container
docker run -d \
--name postgres \
-e POSTGRES_PASSWORD=password \
-e POSTGRES_DB=myapp \
-p 5432:5432 \
postgres:15
# Connect to database
docker exec -it postgres psql -U postgres -d myapp
```
#### Using Local Installation
**macOS (Homebrew):**
```bash
brew install postgresql
brew services start postgresql
createdb myapp
```
**Ubuntu/Debian:**
```bash
sudo apt-get install postgresql postgresql-contrib
sudo systemctl start postgresql
sudo -u postgres createdb myapp
```
## Migration Support
The application automatically creates the necessary tables for both database types:
### SQLite Tables
- Uses `TEXT` for IDs (UUID format)
- Uses `DATETIME` for timestamps
- Uses `TEXT` for JSON storage
- Uses `BOOLEAN` for boolean values
### PostgreSQL Tables
- Uses `UUID` for IDs with `gen_random_uuid()`
- Uses `TIMESTAMPTZ` for timestamps
- Uses `JSONB` for JSON storage
- Uses `BOOLEAN` for boolean values
## Switching Between Databases
You can switch between databases by simply changing the `DATABASE_URL`:
```bash
# Switch to SQLite
export DATABASE_URL="sqlite://database.db"
# Switch to PostgreSQL
export DATABASE_URL="postgresql://user:pass@localhost:5432/mydb"
```
The application will automatically:
1. Detect the database type
2. Use appropriate SQL syntax
3. Create compatible table schemas
4. Handle data type differences
## Performance Considerations
### SQLite
- **Best for:**
- Single-user applications
- Development and testing
- Small to medium datasets
- Read-heavy workloads
- **Optimization tips:**
- Use WAL mode: `PRAGMA journal_mode=WAL`
- Set appropriate timeout: `PRAGMA busy_timeout=5000`
- Use transactions for bulk operations
### PostgreSQL
- **Best for:**
- Multi-user applications
- Production environments
- Large datasets
- High concurrency requirements
- **Optimization tips:**
- Configure appropriate connection pool size
- Use indexes on frequently queried columns
- Monitor and tune PostgreSQL configuration
- Use connection pooling (PgBouncer) for high traffic
## Troubleshooting
### Common SQLite Issues
- **Database locked**: Check for long-running transactions
- **File permissions**: Ensure write access to database file and directory
- **Disk space**: Verify sufficient disk space for database growth
### Common PostgreSQL Issues
- **Connection refused**: Check PostgreSQL server status
- **Authentication failed**: Verify username/password and pg_hba.conf
- **Too many connections**: Adjust max_connections or use connection pooling
### Debug Connection Issues
```bash
# Test SQLite connection
sqlite3 database.db "SELECT 1;"
# Test PostgreSQL connection
psql "postgresql://user:pass@localhost:5432/mydb" -c "SELECT 1;"
```
## Environment-Specific Configuration
### Development
```bash
# .env.development
DATABASE_URL=sqlite://dev_database.db
```
### Testing
```bash
# .env.test
DATABASE_URL=sqlite::memory:
```
### Production
```bash
# .env.production
DATABASE_URL=postgresql://user:${DATABASE_PASSWORD}@db.internal:5432/prod_db
```
## Security Considerations
### SQLite Security
- Protect database file permissions (600 or 640)
- Backup database files securely
- Consider encryption for sensitive data
### PostgreSQL Security
- Use strong passwords
- Enable SSL/TLS connections
- Restrict network access
- Regular security updates
- Use connection pooling with authentication
## Backup and Recovery
### SQLite Backup
```bash
# Simple file copy
cp database.db database_backup.db
# Using SQLite backup command
sqlite3 database.db ".backup database_backup.db"
```
### PostgreSQL Backup
```bash
# Database dump
pg_dump myapp > myapp_backup.sql
# Restore from dump
psql myapp < myapp_backup.sql
```
## Monitoring and Maintenance
### SQLite Maintenance
```sql
-- Analyze database
ANALYZE;
-- Vacuum database
VACUUM;
-- Check integrity
PRAGMA integrity_check;
```
### PostgreSQL Maintenance
```sql
-- Analyze tables
ANALYZE;
-- Vacuum tables
VACUUM;
-- Check database size
SELECT pg_size_pretty(pg_database_size('myapp'));
```
## Best Practices
1. **Use environment variables** for database URLs in production
2. **Configure appropriate connection pools** based on your workload
3. **Monitor database performance** and adjust settings as needed
4. **Regular backups** are essential for production databases
5. **Test migrations** on both database types if supporting both
6. **Use transactions** for data consistency
7. **Index frequently queried columns** for better performance
8. **Monitor connection pool usage** to prevent exhaustion
## Feature Compatibility Matrix
| Feature | SQLite | PostgreSQL |
|---------|--------|------------|
| ACID Transactions | ✅ | ✅ |
| Concurrent Reads | ✅ | ✅ |
| Concurrent Writes | ⚠️ Limited | ✅ |
| JSON Support | ✅ (TEXT) | ✅ (JSONB) |
| Full-text Search | ✅ (FTS) | ✅ (Built-in) |
| Network Access | ❌ | ✅ |
| Replication | ❌ | ✅ |
| Partitioning | ❌ | ✅ |
| Custom Functions | ✅ | ✅ |
| Triggers | ✅ | ✅ |
| Views | ✅ | ✅ |
| Stored Procedures | ❌ | ✅ |
## Next Steps
- [Database Migrations](../developers/features/migrations.md)
- [Performance Optimization](../performance/database.md)
- [Security Best Practices](../security/data-protection.md)
- [Backup Strategies](../deployment/backup.md)
This guide should help you choose and configure the right database for your needs. Both options are fully supported and the application will work seamlessly with either choice.

View File

@ -0,0 +1,543 @@
# Environment Variables
Rustelo uses environment variables to configure sensitive settings, deployment-specific values, and runtime parameters. This approach ensures that secrets are kept separate from the codebase while allowing flexible configuration across different environments.
## Overview
Environment variables in Rustelo are used for:
- **Sensitive Information**: Database credentials, API keys, secrets
- **Environment-Specific Settings**: URLs, domains, feature flags
- **Runtime Configuration**: Debug modes, logging levels, performance tuning
- **Third-Party Integration**: External service configuration
## Variable Categories
### Core System Variables
#### `RUSTELO_ENV`
- **Description**: Application environment
- **Values**: `development`, `production`, `staging`, `test`
- **Default**: `development`
- **Example**: `RUSTELO_ENV=production`
#### `RUSTELO_CONFIG_FILE`
- **Description**: Path to configuration file
- **Default**: `config.toml`
- **Example**: `RUSTELO_CONFIG_FILE=/etc/rustelo/config.prod.toml`
#### `RUSTELO_LOG_LEVEL`
- **Description**: Global log level override
- **Values**: `error`, `warn`, `info`, `debug`, `trace`
- **Default**: From config file
- **Example**: `RUSTELO_LOG_LEVEL=info`
### Database Configuration
#### `DATABASE_URL`
- **Description**: Database connection string
- **Required**: Yes (production)
- **Format**: `postgresql://user:password@host:port/database`
- **Example**: `DATABASE_URL=postgresql://rustelo:password@localhost:5432/rustelo_prod`
#### `DATABASE_MAX_CONNECTIONS`
- **Description**: Maximum database connections
- **Default**: From config file
- **Example**: `DATABASE_MAX_CONNECTIONS=20`
#### `DATABASE_SSL_MODE`
- **Description**: Database SSL mode
- **Values**: `disable`, `allow`, `prefer`, `require`
- **Default**: `prefer`
- **Example**: `DATABASE_SSL_MODE=require`
### Authentication & Security
#### `SESSION_SECRET`
- **Description**: Session encryption secret
- **Required**: Yes
- **Min Length**: 32 characters
- **Example**: `SESSION_SECRET=your-very-long-and-secure-session-secret-here`
#### `JWT_SECRET`
- **Description**: JWT signing secret
- **Required**: Yes (if JWT enabled)
- **Min Length**: 32 characters
- **Example**: `JWT_SECRET=your-jwt-signing-secret-here`
#### `ENCRYPTION_KEY`
- **Description**: Application-level encryption key
- **Required**: Yes (if encryption enabled)
- **Length**: 32 bytes (base64 encoded)
- **Example**: `ENCRYPTION_KEY=your-base64-encoded-encryption-key`
#### `CSRF_SECRET`
- **Description**: CSRF protection secret
- **Required**: No (auto-generated if not provided)
- **Example**: `CSRF_SECRET=your-csrf-secret-here`
### Email Configuration
#### `SMTP_HOST`
- **Description**: SMTP server hostname
- **Required**: Yes (if email enabled)
- **Example**: `SMTP_HOST=smtp.gmail.com`
#### `SMTP_PORT`
- **Description**: SMTP server port
- **Default**: `587`
- **Example**: `SMTP_PORT=587`
#### `SMTP_USERNAME`
- **Description**: SMTP authentication username
- **Required**: Yes (if SMTP auth enabled)
- **Example**: `SMTP_USERNAME=your-app@gmail.com`
#### `SMTP_PASSWORD`
- **Description**: SMTP authentication password
- **Required**: Yes (if SMTP auth enabled)
- **Example**: `SMTP_PASSWORD=your-app-password`
#### `FROM_EMAIL`
- **Description**: Default sender email address
- **Required**: Yes (if email enabled)
- **Example**: `FROM_EMAIL=noreply@yourapp.com`
#### `FROM_NAME`
- **Description**: Default sender name
- **Default**: Application name
- **Example**: `FROM_NAME=Your App Name`
### Web Server Configuration
#### `RUSTELO_HOST`
- **Description**: Server bind address
- **Default**: `127.0.0.1` (dev), `0.0.0.0` (prod)
- **Example**: `RUSTELO_HOST=0.0.0.0`
#### `RUSTELO_PORT`
- **Description**: Server port
- **Default**: `3030`
- **Example**: `RUSTELO_PORT=8080`
#### `RUSTELO_WORKERS`
- **Description**: Number of worker threads
- **Default**: CPU core count
- **Example**: `RUSTELO_WORKERS=4`
#### `DOMAIN`
- **Description**: Application domain for cookies and CORS
- **Required**: Yes (production)
- **Example**: `DOMAIN=yourapp.com`
#### `FRONTEND_URL`
- **Description**: Frontend application URL
- **Required**: Yes (if separate frontend)
- **Example**: `FRONTEND_URL=https://app.yourapp.com`
### Redis Configuration
#### `REDIS_URL`
- **Description**: Redis connection string
- **Required**: Yes (if Redis enabled)
- **Example**: `REDIS_URL=redis://localhost:6379`
#### `REDIS_PASSWORD`
- **Description**: Redis authentication password
- **Required**: No (if Redis auth disabled)
- **Example**: `REDIS_PASSWORD=your-redis-password`
#### `REDIS_DATABASE`
- **Description**: Redis database number
- **Default**: `0`
- **Example**: `REDIS_DATABASE=1`
### SSL/TLS Configuration
#### `TLS_CERT_FILE`
- **Description**: Path to TLS certificate file
- **Required**: Yes (if HTTPS enabled)
- **Example**: `TLS_CERT_FILE=/etc/ssl/certs/yourapp.crt`
#### `TLS_KEY_FILE`
- **Description**: Path to TLS private key file
- **Required**: Yes (if HTTPS enabled)
- **Example**: `TLS_KEY_FILE=/etc/ssl/private/yourapp.key`
#### `TLS_CA_FILE`
- **Description**: Path to TLS CA certificate file
- **Required**: No
- **Example**: `TLS_CA_FILE=/etc/ssl/certs/ca-certificates.crt`
### External Services
#### `OAUTH_GOOGLE_CLIENT_ID`
- **Description**: Google OAuth client ID
- **Required**: Yes (if Google OAuth enabled)
- **Example**: `OAUTH_GOOGLE_CLIENT_ID=your-google-client-id`
#### `OAUTH_GOOGLE_CLIENT_SECRET`
- **Description**: Google OAuth client secret
- **Required**: Yes (if Google OAuth enabled)
- **Example**: `OAUTH_GOOGLE_CLIENT_SECRET=your-google-client-secret`
#### `OAUTH_GITHUB_CLIENT_ID`
- **Description**: GitHub OAuth client ID
- **Required**: Yes (if GitHub OAuth enabled)
- **Example**: `OAUTH_GITHUB_CLIENT_ID=your-github-client-id`
#### `OAUTH_GITHUB_CLIENT_SECRET`
- **Description**: GitHub OAuth client secret
- **Required**: Yes (if GitHub OAuth enabled)
- **Example**: `OAUTH_GITHUB_CLIENT_SECRET=your-github-client-secret`
### Monitoring & Observability
#### `PROMETHEUS_ENDPOINT`
- **Description**: Prometheus metrics endpoint
- **Default**: `/metrics`
- **Example**: `PROMETHEUS_ENDPOINT=/prometheus`
#### `JAEGER_ENDPOINT`
- **Description**: Jaeger tracing endpoint
- **Required**: No
- **Example**: `JAEGER_ENDPOINT=http://localhost:14268/api/traces`
#### `SENTRY_DSN`
- **Description**: Sentry error reporting DSN
- **Required**: No
- **Example**: `SENTRY_DSN=https://your-sentry-dsn@sentry.io/project-id`
### Development & Debug
#### `RUST_LOG`
- **Description**: Rust logging configuration
- **Default**: `info`
- **Example**: `RUST_LOG=rustelo=debug,sqlx=info`
#### `RUST_BACKTRACE`
- **Description**: Enable Rust backtraces
- **Values**: `0`, `1`, `full`
- **Default**: `0`
- **Example**: `RUST_BACKTRACE=1`
#### `RUSTELO_DEBUG`
- **Description**: Enable debug mode
- **Values**: `true`, `false`
- **Default**: `false`
- **Example**: `RUSTELO_DEBUG=true`
#### `RUSTELO_MOCK_EXTERNAL`
- **Description**: Mock external services
- **Values**: `true`, `false`
- **Default**: `false`
- **Example**: `RUSTELO_MOCK_EXTERNAL=true`
## Environment-Specific Configuration
### Development Environment
```bash
# Core settings
RUSTELO_ENV=development
RUSTELO_LOG_LEVEL=debug
RUSTELO_DEBUG=true
# Database
DATABASE_URL=sqlite//:dev_database.db
# Authentication
SESSION_SECRET=dev-session-secret-change-in-production
JWT_SECRET=dev-jwt-secret-change-in-production
# Email (console output)
SMTP_HOST=localhost
SMTP_PORT=1025
FROM_EMAIL=dev@localhost
# Features
RUSTELO_MOCK_EXTERNAL=true
```
### Production Environment
```bash
# Core settings
RUSTELO_ENV=production
RUSTELO_LOG_LEVEL=info
RUSTELO_DEBUG=false
# Server
RUSTELO_HOST=0.0.0.0
RUSTELO_PORT=443
DOMAIN=yourapp.com
FRONTEND_URL=https://yourapp.com
# Database
DATABASE_URL=postgresql://rustelo:password@db-server:5432/rustelo_prod
DATABASE_MAX_CONNECTIONS=20
DATABASE_SSL_MODE=require
# Authentication
SESSION_SECRET=your-production-session-secret-64-chars-long
JWT_SECRET=your-production-jwt-secret-64-chars-long
ENCRYPTION_KEY=your-base64-encoded-encryption-key
# Email
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USERNAME=your-app@gmail.com
SMTP_PASSWORD=your-app-password
FROM_EMAIL=noreply@yourapp.com
FROM_NAME=Your App
# Redis
REDIS_URL=redis://redis-server:6379
REDIS_PASSWORD=your-redis-password
# TLS
TLS_CERT_FILE=/etc/ssl/certs/yourapp.crt
TLS_KEY_FILE=/etc/ssl/private/yourapp.key
# OAuth
OAUTH_GOOGLE_CLIENT_ID=your-google-client-id
OAUTH_GOOGLE_CLIENT_SECRET=your-google-client-secret
# Monitoring
SENTRY_DSN=https://your-sentry-dsn@sentry.io/project-id
```
### Staging Environment
```bash
# Core settings
RUSTELO_ENV=staging
RUSTELO_LOG_LEVEL=info
RUSTELO_DEBUG=true
# Server
RUSTELO_HOST=0.0.0.0
RUSTELO_PORT=443
DOMAIN=staging.yourapp.com
FRONTEND_URL=https://staging.yourapp.com
# Database
DATABASE_URL=postgresql://rustelo:password@staging-db:5432/rustelo_staging
DATABASE_MAX_CONNECTIONS=10
DATABASE_SSL_MODE=prefer
# Authentication (use staging secrets)
SESSION_SECRET=staging-session-secret-64-chars-long
JWT_SECRET=staging-jwt-secret-64-chars-long
# Email (test configuration)
SMTP_HOST=smtp.mailtrap.io
SMTP_PORT=2525
SMTP_USERNAME=your-mailtrap-username
SMTP_PASSWORD=your-mailtrap-password
FROM_EMAIL=staging@yourapp.com
```
## Environment File Management
### `.env` Files
Create environment-specific `.env` files:
```bash
# .env.development
RUSTELO_ENV=development
DATABASE_URL=sqlite:dev_database.db
SESSION_SECRET=dev-session-secret
JWT_SECRET=dev-jwt-secret
# .env.production
RUSTELO_ENV=production
DATABASE_URL=postgresql://user:pass@host:5432/db
SESSION_SECRET=prod-session-secret
JWT_SECRET=prod-jwt-secret
# .env.staging
RUSTELO_ENV=staging
DATABASE_URL=postgresql://user:pass@staging-host:5432/db
SESSION_SECRET=staging-session-secret
JWT_SECRET=staging-jwt-secret
```
### Loading Environment Files
```bash
# Load development environment
source .env.development
# Load production environment
source .env.production
# Load with dotenv (if using dotenv tool)
dotenv -f .env.production -- ./rustelo-server
```
## Docker Configuration
### Docker Compose
```yaml
# docker-compose.yml
version: '3.8'
services:
app:
build: .
environment:
- RUSTELO_ENV=production
- DATABASE_URL=postgresql://rustelo:password@db:5432/rustelo
- SESSION_SECRET=your-session-secret
- JWT_SECRET=your-jwt-secret
- REDIS_URL=redis://redis:6379
env_file:
- .env.production
depends_on:
- db
- redis
db:
image: postgres:15
environment:
- POSTGRES_DB=rustelo
- POSTGRES_USER=rustelo
- POSTGRES_PASSWORD=password
redis:
image: redis:7-alpine
command: redis-server --requirepass your-redis-password
```
### Dockerfile
```dockerfile
FROM rust:1.70 as builder
WORKDIR /app
COPY . .
RUN cargo build --release
FROM debian:bookworm-slim
# Install runtime dependencies
RUN apt-get update && apt-get install -y \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
COPY --from=builder /app/target/release/rustelo-server /usr/local/bin/
COPY --from=builder /app/config.prod.toml /etc/rustelo/config.toml
# Environment variables can be set here or passed at runtime
ENV RUSTELO_ENV=production
ENV RUSTELO_CONFIG_FILE=/etc/rustelo/config.toml
EXPOSE 3030
CMD ["rustelo-server"]
```
## Security Best Practices
### Secret Management
1. **Use Strong Secrets**
- Minimum 32 characters for session secrets
- Use cryptographically secure random generators
- Rotate secrets regularly
2. **Environment Separation**
- Never use production secrets in development
- Use different secrets for each environment
- Store secrets in secure vaults (HashiCorp Vault, AWS Secrets Manager)
3. **Access Control**
- Limit access to environment variables
- Use least privilege principle
- Audit secret access
### Example Secret Generation
```bash
# Generate secure session secret
openssl rand -base64 64
# Generate JWT secret
openssl rand -base64 64
# Generate encryption key
openssl rand -base64 32
# Generate CSRF secret
openssl rand -base64 32
```
## Validation and Testing
### Variable Validation
```bash
# Check required variables
./scripts/check-env.sh production
# Validate configuration
./config/scripts/build-config.sh prod --validate-only
```
### Testing Configuration
```bash
# Test with environment variables
RUSTELO_ENV=test DATABASE_URL=sqlite::memory: cargo test
# Test configuration loading
./rustelo-server --check-config
```
## Troubleshooting
### Common Issues
1. **Missing Environment Variables**
```bash
# Check if variables are set
env | grep RUSTELO
env | grep DATABASE_URL
```
2. **Invalid Variable Format**
```bash
# Validate database URL format
echo $DATABASE_URL | grep -E "^postgresql://"
```
3. **Permission Issues**
```bash
# Check file permissions for certificates
ls -la /etc/ssl/certs/yourapp.crt
```
### Debug Environment Loading
```bash
# Enable debug logging
RUST_LOG=rustelo=debug ./rustelo-server
# Show loaded configuration
./rustelo-server --show-config
```
## Migration Guide
When updating environment variables:
1. **Add new variables** to all environments
2. **Update documentation** with new requirements
3. **Provide default values** where possible
4. **Test thoroughly** in staging before production
5. **Update deployment scripts** and Docker configurations
For detailed migration instructions, see the [Environment Migration Guide](../reference/env-migration.md).

View File

@ -0,0 +1,617 @@
# Features Configuration
Rustelo's modular feature system allows you to enable, disable, and configure individual features based on your application's needs. This chapter covers how to configure features, understand their dependencies, and optimize your application by selecting the right combination of features.
## Overview
Features in Rustelo are:
- **Modular**: Each feature can be enabled/disabled independently
- **Configurable**: Features have their own configuration settings
- **Environment-Aware**: Different settings for development, staging, and production
- **Dependency-Aware**: Features can depend on other features
- **Performance-Optimized**: Unused features don't impact performance
## Feature System Architecture
```
features/
├── auth/ # Authentication & Authorization
│ ├── dev.toml # Development settings
│ ├── prod.toml # Production settings
│ └── example.toml # Example configuration
├── content/ # Content Management
├── email/ # Email System
├── metrics/ # Monitoring & Metrics
├── tls/ # SSL/TLS Security
├── rbac/ # Role-Based Access Control
└── cache/ # Caching System
```
## Core Features
### Authentication Feature
The authentication feature provides user authentication, session management, and security controls.
#### Configuration
```toml
[features]
auth = true
[auth.jwt]
secret = "${JWT_SECRET}"
expiration = 3600 # Token expiration in seconds
refresh_token_expiration = 604800 # Refresh token expiration (7 days)
algorithm = "HS256" # JWT algorithm
issuer = "rustelo-app" # JWT issuer
audience = "rustelo-users" # JWT audience
[auth.password]
min_length = 8 # Minimum password length
require_uppercase = true # Require uppercase letters
require_lowercase = true # Require lowercase letters
require_numbers = true # Require numbers
require_special_chars = true # Require special characters
max_age_days = 90 # Password expiration in days
history_count = 5 # Number of previous passwords to remember
[auth.security]
max_login_attempts = 5 # Maximum failed login attempts
lockout_duration = 900 # Account lockout duration in seconds
session_timeout = 1800 # Session timeout in seconds
require_email_verification = true # Require email verification
password_reset_timeout = 3600 # Password reset token timeout
[auth.two_factor]
enabled = true # Enable 2FA
backup_codes_count = 10 # Number of backup codes
totp_issuer = "Rustelo App" # TOTP issuer name
totp_digits = 6 # TOTP code length
totp_period = 30 # TOTP time period in seconds
[auth.sessions]
cleanup_interval = 3600 # Session cleanup interval in seconds
max_concurrent_sessions = 3 # Maximum concurrent sessions per user
remember_me_duration = 2592000 # Remember me duration (30 days)
```
#### Environment-Specific Settings
**Development:**
```toml
[auth.password]
min_length = 6
require_uppercase = false
require_special_chars = false
[auth.security]
max_login_attempts = 10
require_email_verification = false
```
**Production:**
```toml
[auth.password]
min_length = 12
require_uppercase = true
require_special_chars = true
[auth.security]
max_login_attempts = 3
require_email_verification = true
```
### Content Management Feature
The content feature provides content creation, editing, and management capabilities.
#### Configuration
```toml
[features]
content = true
[content]
enabled = true
content_dir = "content" # Content storage directory
cache_enabled = true # Enable content caching
cache_ttl = 3600 # Cache TTL in seconds
max_file_size = 10485760 # Maximum file size (10MB)
allowed_file_types = [ # Allowed file extensions
"md", "txt", "html", "css", "js", "json", "toml", "yaml"
]
[content.markdown]
enabled = true # Enable Markdown processing
syntax_highlighting = true # Enable code syntax highlighting
math_support = false # Enable LaTeX math rendering
table_of_contents = true # Generate table of contents
auto_links = true # Automatically link URLs
[content.media]
enabled = true # Enable media uploads
max_image_size = 5242880 # Maximum image size (5MB)
max_video_size = 52428800 # Maximum video size (50MB)
image_processing = true # Enable image processing
thumbnail_generation = true # Generate thumbnails
allowed_image_types = ["jpg", "jpeg", "png", "gif", "webp"]
allowed_video_types = ["mp4", "webm", "ogg"]
[content.versioning]
enabled = false # Enable content versioning
max_versions = 10 # Maximum versions to keep
auto_save_interval = 60 # Auto-save interval in seconds
[content.publishing]
draft_mode = true # Enable draft mode
scheduled_publishing = true # Enable scheduled publishing
approval_workflow = false # Require approval for publishing
```
### Email System Feature
The email feature provides email sending, templating, and queue management.
#### Configuration
```toml
[features]
email = true
[email]
enabled = true
provider = "smtp" # Email provider: smtp, sendgrid, console
from_email = "${FROM_EMAIL}" # Default sender email
from_name = "${FROM_NAME}" # Default sender name
reply_to = "" # Reply-to address
templates_dir = "templates/email" # Email templates directory
queue_enabled = true # Enable email queue
max_retries = 3 # Maximum retry attempts
retry_delay = 300 # Retry delay in seconds
[email.smtp]
host = "${SMTP_HOST}" # SMTP server host
port = 587 # SMTP server port
username = "${SMTP_USERNAME}" # SMTP username
password = "${SMTP_PASSWORD}" # SMTP password
use_tls = true # Use TLS encryption
use_starttls = true # Use STARTTLS
timeout = 30 # Connection timeout in seconds
[email.sendgrid]
api_key = "${SENDGRID_API_KEY}" # SendGrid API key
endpoint = "https://api.sendgrid.com/v3/mail/send" # SendGrid endpoint
[email.templates]
cache_enabled = true # Cache compiled templates
cache_ttl = 3600 # Template cache TTL
default_language = "en" # Default template language
```
### Metrics & Monitoring Feature
The metrics feature provides application monitoring, performance tracking, and observability.
#### Configuration
```toml
[features]
metrics = true
[metrics]
enabled = true
endpoint = "/metrics" # Metrics endpoint path
collect_interval = 15 # Collection interval in seconds
retention_days = 30 # Metrics retention period
[metrics.prometheus]
enabled = true # Enable Prometheus metrics
namespace = "rustelo" # Metrics namespace
subsystem = "app" # Metrics subsystem
labels = { version = "1.0.0", environment = "production" }
[metrics.system]
enabled = true # Collect system metrics
cpu_usage = true # Monitor CPU usage
memory_usage = true # Monitor memory usage
disk_usage = true # Monitor disk usage
network_usage = true # Monitor network usage
[metrics.application]
enabled = true # Collect application metrics
request_metrics = true # HTTP request metrics
database_metrics = true # Database query metrics
cache_metrics = true # Cache hit/miss metrics
error_metrics = true # Error rate metrics
[metrics.custom]
enabled = true # Enable custom metrics
business_metrics = true # Business-specific metrics
user_metrics = true # User activity metrics
```
### TLS/SSL Security Feature
The TLS feature provides SSL/TLS encryption, certificate management, and security headers.
#### Configuration
```toml
[features]
tls = true
[tls]
enabled = true
cert_file = "${TLS_CERT_FILE}" # Certificate file path
key_file = "${TLS_KEY_FILE}" # Private key file path
ca_file = "${TLS_CA_FILE}" # CA certificate file path
protocols = ["TLSv1.2", "TLSv1.3"] # Supported TLS protocols
ciphers = [ # Allowed cipher suites
"TLS_AES_256_GCM_SHA384",
"TLS_CHACHA20_POLY1305_SHA256",
"TLS_AES_128_GCM_SHA256"
]
[tls.security]
force_https = true # Force HTTPS redirects
hsts_enabled = true # Enable HSTS
hsts_max_age = 31536000 # HSTS max age (1 year)
hsts_include_subdomains = true # Include subdomains in HSTS
hsts_preload = true # Enable HSTS preload
[tls.certificates]
auto_renewal = true # Enable automatic certificate renewal
renewal_threshold = 2592000 # Renewal threshold (30 days)
acme_enabled = false # Enable ACME/Let's Encrypt
acme_directory = "https://acme-v02.api.letsencrypt.org/directory"
```
### Role-Based Access Control (RBAC)
The RBAC feature provides fine-grained access control, permissions, and role management.
#### Configuration
```toml
[features]
rbac = true
[rbac]
enabled = true
default_role = "user" # Default role for new users
admin_role = "admin" # Administrator role name
super_admin_role = "super_admin" # Super administrator role
[rbac.permissions]
hierarchical = true # Enable hierarchical permissions
inheritance = true # Enable permission inheritance
caching = true # Cache permission checks
cache_ttl = 300 # Permission cache TTL
[rbac.roles]
dynamic_roles = true # Enable dynamic role creation
role_templates = true # Enable role templates
role_expiration = false # Enable role expiration
[rbac.audit]
enabled = true # Enable audit logging
log_level = "info" # Audit log level
retention_days = 90 # Audit log retention period
```
### Caching System Feature
The caching feature provides multi-level caching for improved performance.
#### Configuration
```toml
[features]
cache = true
[cache]
enabled = true
default_ttl = 3600 # Default cache TTL in seconds
max_memory_size = 134217728 # Maximum memory cache size (128MB)
cleanup_interval = 300 # Cache cleanup interval in seconds
[cache.memory]
enabled = true # Enable in-memory caching
max_entries = 10000 # Maximum cache entries
eviction_policy = "lru" # Eviction policy: lru, lfu, random
[cache.redis]
enabled = false # Enable Redis caching
url = "${REDIS_URL}" # Redis connection URL
database = 0 # Redis database number
key_prefix = "rustelo:" # Cache key prefix
compression = true # Enable compression
[cache.file]
enabled = false # Enable file-based caching
cache_dir = "cache" # Cache directory
max_file_size = 1048576 # Maximum file size (1MB)
```
## Feature Dependencies
Some features depend on others. The system automatically handles these dependencies:
```toml
# Feature dependency matrix
[feature_dependencies]
rbac = ["auth"] # RBAC requires authentication
content = ["auth"] # Content management requires authentication
email = [] # Email has no dependencies
metrics = [] # Metrics has no dependencies
tls = [] # TLS has no dependencies
cache = [] # Cache has no dependencies
```
## Feature Flags
Feature flags allow runtime control of features:
```toml
[feature_flags]
auth_enabled = true
content_enabled = true
email_enabled = true
metrics_enabled = true
tls_enabled = true
rbac_enabled = false
cache_enabled = true
# Conditional features
[feature_flags.conditional]
oauth_enabled = false # Enable OAuth (requires auth)
two_factor_enabled = true # Enable 2FA (requires auth)
file_uploads_enabled = true # Enable file uploads (requires content)
```
## Environment-Specific Feature Configuration
### Development Environment
```toml
[features]
auth = true
content = true
email = true
metrics = true
tls = false
rbac = false
cache = true
[feature_flags]
debug_mode = true
mock_external_services = true
verbose_logging = true
```
### Production Environment
```toml
[features]
auth = true
content = true
email = true
metrics = true
tls = true
rbac = true
cache = true
[feature_flags]
debug_mode = false
mock_external_services = false
verbose_logging = false
performance_monitoring = true
```
## Performance Optimization
### Feature-Based Optimization
```toml
[optimization]
lazy_loading = true # Lazy load features
compile_time_optimization = true # Optimize at compile time
runtime_checks = false # Disable runtime feature checks in production
[optimization.features]
auth = { priority = "high", preload = true }
content = { priority = "medium", preload = false }
email = { priority = "low", preload = false }
metrics = { priority = "low", preload = false }
```
### Resource Management
```toml
[resource_limits]
max_memory_per_feature = 67108864 # 64MB per feature
max_cpu_per_feature = 10 # 10% CPU per feature
max_connections_per_feature = 100 # 100 connections per feature
```
## Feature Testing
### Test Configuration
```toml
[testing]
features_under_test = ["auth", "content"]
mock_dependencies = true
integration_tests = true
performance_tests = false
[testing.auth]
test_users = 1000
test_sessions = 100
test_roles = 10
[testing.content]
test_documents = 500
test_media_files = 100
test_versions = 5
```
## Creating Custom Features
### Feature Structure
```
features/my_feature/
├── dev.toml # Development configuration
├── prod.toml # Production configuration
├── example.toml # Example configuration
└── README.md # Feature documentation
```
### Example Custom Feature
```toml
# features/my_feature/dev.toml
[features]
my_feature = true
[my_feature]
enabled = true
debug_mode = true
api_endpoint = "http://localhost:8080"
timeout = 30
retry_count = 3
[my_feature.settings]
option1 = "value1"
option2 = 42
option3 = true
```
## Feature Management Commands
### Using Configuration Scripts
```bash
# List available features
./config/scripts/manage-config.sh list-features
# Enable a feature
./config/scripts/manage-config.sh enable-feature auth
# Disable a feature
./config/scripts/manage-config.sh disable-feature rbac
# Check feature dependencies
./config/scripts/manage-config.sh check-dependencies
# Validate feature configuration
./config/scripts/manage-config.sh validate-features
```
### Runtime Feature Management
```bash
# Check feature status
curl http://localhost:3030/admin/features
# Enable feature at runtime (if supported)
curl -X POST http://localhost:3030/admin/features/auth/enable
# Disable feature at runtime (if supported)
curl -X POST http://localhost:3030/admin/features/auth/disable
```
## Best Practices
### 1. Feature Selection
- **Start Small**: Begin with essential features only
- **Add Gradually**: Enable additional features as needed
- **Monitor Impact**: Watch performance metrics when adding features
- **Document Changes**: Keep track of feature changes and their impact
### 2. Configuration Management
- **Environment Consistency**: Use consistent feature sets across environments
- **Version Control**: Track feature configuration changes
- **Testing**: Test feature combinations thoroughly
- **Rollback Plan**: Have a plan for disabling problematic features
### 3. Performance Considerations
- **Resource Usage**: Monitor resource usage per feature
- **Startup Time**: Consider impact on application startup
- **Memory Usage**: Track memory consumption of enabled features
- **Database Impact**: Monitor database performance with features enabled
### 4. Security Considerations
- **Feature Isolation**: Ensure features don't interfere with each other
- **Access Control**: Implement proper access controls for feature management
- **Audit Logging**: Log feature changes and access
- **Security Testing**: Test security implications of feature combinations
## Troubleshooting
### Common Issues
1. **Feature Not Loading**
```bash
# Check feature configuration
./config/scripts/manage-config.sh validate-features
# Check feature dependencies
./config/scripts/manage-config.sh check-dependencies
```
2. **Performance Issues**
```bash
# Monitor feature resource usage
curl http://localhost:3030/metrics | grep feature_
# Check feature startup time
grep "feature.*initialized" logs/app.log
```
3. **Configuration Conflicts**
```bash
# Compare feature configurations
./config/scripts/manage-config.sh diff-features dev prod
```
### Debug Mode
Enable debug mode for detailed feature information:
```bash
RUSTELO_DEBUG=true FEATURE_DEBUG=true ./rustelo-server
```
## Migration Guide
When updating feature configurations:
1. **Backup Current Configuration**
```bash
./config/scripts/manage-config.sh backup-features
```
2. **Test New Configuration**
```bash
./config/scripts/manage-config.sh test-features
```
3. **Gradual Rollout**
- Update staging environment first
- Monitor for issues
- Update production environment
4. **Rollback if Needed**
```bash
./config/scripts/manage-config.sh restore-features backup-file
```
For detailed migration instructions, see the [Feature Migration Guide](../reference/feature-migration.md).

467
book/configuration/files.md Normal file
View File

@ -0,0 +1,467 @@
# Configuration Files
Rustelo uses a modular configuration system that separates concerns by features and environments. This system allows for flexible configuration management across different deployment scenarios while maintaining clear separation between base settings and feature-specific configurations.
## Overview
The configuration system consists of:
- **Base Configurations**: Core settings that apply to all features
- **Feature Configurations**: Settings specific to individual features
- **Environment-Specific Settings**: Optimized configurations for different environments
- **Configuration Management Scripts**: Tools for building, validating, and managing configurations
## Configuration Structure
```
config/
├── base/ # Base configurations
│ ├── dev.toml # Development base settings
│ ├── prod.toml # Production base settings
│ └── example.toml # Example/template base settings
├── features/ # Feature-specific configurations
│ ├── auth/ # Authentication feature
│ ├── email/ # Email feature
│ ├── tls/ # TLS/SSL feature
│ ├── content/ # Content management feature
│ └── metrics/ # Metrics and monitoring feature
├── scripts/ # Configuration management scripts
├── examples/ # Example configurations
└── README.md # Configuration documentation
```
## Base Configuration Files
Base configurations contain core settings that apply to all features:
### `base/dev.toml` - Development Environment
```toml
# Server Configuration
[server]
protocol = "http"
host = "127.0.0.1"
port = 3030
environment = "development"
log_level = "debug"
# Database Configuration
[database]
url = "sqlite//:dev_database.db"
max_connections = 5
enable_logging = true
# Session Management
[session]
secret = "dev-session-secret"
cookie_secure = false
max_age = 7200
# Security Settings (relaxed for development)
[security]
enable_csrf = false
rate_limit_requests = 1000
bcrypt_cost = 10
```
### `base/prod.toml` - Production Environment
```toml
# Server Configuration
[server]
protocol = "https"
host = "0.0.0.0"
port = 443
environment = "production"
log_level = "info"
# Database Configuration
[database]
url = "${DATABASE_URL}"
max_connections = 20
ssl_mode = "require"
# Session Management
[session]
secret = "${SESSION_SECRET}"
cookie_secure = true
max_age = 1800
# Security Settings (strict for production)
[security]
enable_csrf = true
rate_limit_requests = 100
bcrypt_cost = 12
```
## Feature Configuration Files
Feature configurations contain settings specific to individual features:
### Authentication Feature (`features/auth/`)
#### `features/auth/dev.toml`
```toml
[features]
auth = true
[auth.jwt]
secret = "dev-jwt-secret"
expiration = 86400
algorithm = "HS256"
[auth.password]
min_length = 6
require_uppercase = false
require_numbers = true
[auth.security]
max_login_attempts = 10
lockout_duration = 300
```
#### `features/auth/prod.toml`
```toml
[features]
auth = true
[auth.jwt]
secret = "${JWT_SECRET}"
expiration = 1800
algorithm = "HS256"
[auth.password]
min_length = 12
require_uppercase = true
require_numbers = true
require_special_chars = true
[auth.security]
max_login_attempts = 5
lockout_duration = 900
```
### Email Feature (`features/email/`)
#### `features/email/dev.toml`
```toml
[features]
email = true
[email]
provider = "console"
from_email = "dev@localhost"
templates_dir = "templates/email"
[email.smtp]
host = "localhost"
port = 1025
use_tls = false
```
#### `features/email/prod.toml`
```toml
[features]
email = true
[email]
provider = "smtp"
from_email = "${FROM_EMAIL}"
templates_dir = "templates/email"
[email.smtp]
host = "${SMTP_HOST}"
port = 587
username = "${SMTP_USERNAME}"
password = "${SMTP_PASSWORD}"
use_tls = true
```
## Environment Variables
Configuration files support environment variable substitution using `${VARIABLE_NAME}` syntax:
### Required Environment Variables
#### Development
- `DATABASE_URL` (optional, defaults to SQLite)
- `SESSION_SECRET` (optional, uses dev default)
#### Production
- `DATABASE_URL` (required)
- `SESSION_SECRET` (required)
- `JWT_SECRET` (required)
- `SMTP_HOST` (required if email enabled)
- `SMTP_USERNAME` (required if email enabled)
- `SMTP_PASSWORD` (required if email enabled)
- `FROM_EMAIL` (required if email enabled)
- `FRONTEND_URL` (required for CORS)
- `DOMAIN` (required for cookies)
### Environment Variable Examples
```bash
# Development
export DATABASE_URL="postgresql://user:password@localhost/rustelo_dev"
export SESSION_SECRET="your-session-secret-here"
# Production
export DATABASE_URL="postgresql://user:password@prod-db/rustelo"
export SESSION_SECRET="your-production-session-secret"
export JWT_SECRET="your-jwt-secret"
export SMTP_HOST="smtp.gmail.com"
export SMTP_USERNAME="your-app@gmail.com"
export SMTP_PASSWORD="your-app-password"
export FROM_EMAIL="noreply@yourapp.com"
export FRONTEND_URL="https://yourapp.com"
export DOMAIN="yourapp.com"
```
## Configuration Building
### Using Build Scripts
The configuration system includes scripts for building complete configuration files:
#### Shell Script
```bash
# Build development configuration
./config/scripts/build-config.sh dev
# Build production configuration
./config/scripts/build-config.sh prod config.prod.toml
# Build with validation only
CONFIG_VALIDATE_ONLY=1 ./config/scripts/build-config.sh dev
```
#### Python Script
```bash
# Build development configuration
./config/scripts/build-config.sh dev
# Build production configuration
./config/scripts/build-config.sh prod config.prod.toml
# Validate only
CONFIG_VALIDATE_ONLY=1 ./config/scripts/build-config.sh dev
```
### Management Script
The management script provides comprehensive configuration operations:
```bash
# Build configurations
./config/scripts/manage-config.sh build dev
./config/scripts/manage-config.sh build prod config.prod.toml
# Validate configurations
./config/scripts/manage-config.sh validate dev
# List features and environments
./config/scripts/manage-config.sh list-features
./config/scripts/manage-config.sh list-environments
# Compare configurations
./config/scripts/manage-config.sh diff dev prod
# Create backups
./config/scripts/manage-config.sh backup prod
```
## Configuration Validation
The system includes built-in validation for:
### Syntax Validation
- **TOML Syntax**: Ensures valid TOML structure
- **Type Checking**: Validates that values are of expected types
- **Required Fields**: Checks for presence of essential configuration sections
### Semantic Validation
- **Port Ranges**: Validates that ports are within valid ranges (1-65535)
- **Protocol Values**: Ensures protocols are valid (http, https)
- **Connection Limits**: Validates database connection pool settings
- **Feature Dependencies**: Checks that required features are enabled
### Security Validation
- **Secret Length**: Validates that secrets meet minimum length requirements
- **Password Policies**: Ensures password policies are configured securely
- **TLS Settings**: Validates SSL/TLS configuration for production
## Configuration Examples
### Complete Development Configuration
```toml
# Base settings
[server]
protocol = "http"
host = "127.0.0.1"
port = 3030
environment = "development"
[database]
url = "sqlite//:dev_database.db"
max_connections = 5
# Feature: Authentication
[features]
auth = true
[auth.jwt]
secret = "dev-jwt-secret"
expiration = 86400
# Feature: Email
[features]
email = true
[email]
provider = "console"
from_email = "dev@localhost"
# Build Information
[build_info]
environment = "dev"
build_time = "2024-01-01T12:00:00Z"
features = ["auth", "email"]
```
### Complete Production Configuration
```toml
# Base settings
[server]
protocol = "https"
host = "0.0.0.0"
port = 443
environment = "production"
[database]
url = "${DATABASE_URL}"
max_connections = 20
ssl_mode = "require"
# Feature: Authentication
[features]
auth = true
[auth.jwt]
secret = "${JWT_SECRET}"
expiration = 1800
[auth.password]
min_length = 12
require_uppercase = true
require_numbers = true
require_special_chars = true
# Feature: Email
[features]
email = true
[email]
provider = "smtp"
from_email = "${FROM_EMAIL}"
[email.smtp]
host = "${SMTP_HOST}"
port = 587
username = "${SMTP_USERNAME}"
password = "${SMTP_PASSWORD}"
use_tls = true
# Build Information
[build_info]
environment = "prod"
build_time = "2024-01-01T12:00:00Z"
features = ["auth", "email"]
```
## Best Practices
### 1. Environment-Specific Optimization
- **Development**: Prioritize developer experience and debugging
- **Production**: Prioritize security, performance, and reliability
- **Staging**: Mirror production settings with relaxed security for testing
### 2. Feature Independence
- Keep feature configurations independent of each other
- Use feature flags to enable/disable functionality
- Provide sensible defaults for all settings
### 3. Security
- Never commit sensitive values to version control
- Use environment variables for all secrets
- Implement proper validation for security-critical settings
- Use strong defaults for production environments
### 4. Documentation
- Document all configuration options in example files
- Provide clear descriptions for complex settings
- Include units and ranges for numeric values
- Maintain migration guides for configuration changes
## Troubleshooting
### Common Issues
1. **Invalid TOML Syntax**
```bash
# Validate syntax
./config/scripts/manage-config.sh validate dev
```
2. **Missing Environment Variables**
```bash
# Check required variables
env | grep -E "(DATABASE_URL|SESSION_SECRET|JWT_SECRET)"
```
3. **Feature Conflicts**
```bash
# Compare configurations
./config/scripts/manage-config.sh diff dev prod
```
### Debug Mode
Enable debug output for detailed information:
```bash
CONFIG_DEBUG=1 ./config/scripts/build-config.sh dev
```
### Validation Only
Validate configurations without building:
```bash
./config/scripts/manage-config.sh validate dev
CONFIG_VALIDATE_ONLY=1 ./config/scripts/build-config.sh prod
```
## Migration Guide
When upgrading configurations:
1. **Backup existing configurations**
2. **Update base configurations** for new settings
3. **Update feature configurations** as needed
4. **Test in development** before deploying to production
5. **Validate configurations** using the build scripts
6. **Update environment variables** if required
For detailed migration instructions, see the [Configuration Migration Guide](../reference/config-migration.md).

View File

@ -0,0 +1,532 @@
# Performance Configuration
Rustelo provides extensive performance tuning options to optimize your application for different workloads and deployment scenarios. This chapter covers how to configure performance-related settings, optimize resource usage, and monitor application performance.
## Overview
Performance optimization in Rustelo covers:
- **Server Configuration**: Worker threads, connection limits, and request handling
- **Database Optimization**: Connection pooling, query optimization, and caching
- **Memory Management**: Heap size, garbage collection, and memory pools
- **Caching Systems**: Multi-level caching strategies and cache invalidation
- **Asset Optimization**: Static file serving, compression, and CDN integration
- **Monitoring & Profiling**: Performance metrics and bottleneck identification
## Server Performance Configuration
### Worker Thread Configuration
```toml
[server.performance]
workers = 8 # Number of worker threads (default: CPU cores)
worker_max_blocking_threads = 32 # Max blocking threads per worker
worker_thread_stack_size = 2097152 # Stack size per thread (2MB)
worker_thread_keep_alive = 60 # Keep-alive time for idle threads
max_connections = 10000 # Maximum concurrent connections
connection_timeout = 30 # Connection timeout in seconds
keep_alive_timeout = 65 # Keep-alive timeout
```
### Request Handling
```toml
[server.requests]
max_request_size = 52428800 # 50MB max request size
max_header_size = 32768 # 32KB max header size
max_uri_length = 8192 # 8KB max URI length
request_timeout = 30 # Request timeout in seconds
slow_request_threshold = 1000 # Log slow requests over 1 second
max_concurrent_requests = 1000 # Max concurrent requests
```
### Connection Management
```toml
[server.connections]
tcp_nodelay = true # Disable Nagle's algorithm
tcp_keepalive = true # Enable TCP keepalive
keepalive_time = 7200 # Keepalive time (2 hours)
keepalive_interval = 75 # Keepalive probe interval
keepalive_probes = 9 # Number of keepalive probes
reuse_port = true # Enable SO_REUSEPORT
backlog = 1024 # Listen backlog queue size
```
## Database Performance Configuration
### Connection Pool Optimization
```toml
[database.performance]
max_connections = 20 # Maximum pool size
min_connections = 5 # Minimum pool size
acquire_timeout = 30 # Connection acquire timeout
idle_timeout = 600 # Idle connection timeout
max_lifetime = 1800 # Maximum connection lifetime
test_before_acquire = false # Test connections before use
```
### Query Optimization
```toml
[database.queries]
statement_timeout = 30000 # Query timeout in milliseconds
slow_query_threshold = 1000 # Log slow queries over 1 second
enable_query_cache = true # Enable query result caching
query_cache_size = 134217728 # Query cache size (128MB)
query_cache_ttl = 300 # Query cache TTL in seconds
prepared_statement_cache_size = 256 # Prepared statement cache size
```
### Database-Specific Optimizations
#### PostgreSQL
```toml
[database.postgresql]
shared_buffers = "256MB" # Shared buffer size
effective_cache_size = "1GB" # Effective cache size
work_mem = "4MB" # Work memory per query
maintenance_work_mem = "64MB" # Maintenance work memory
checkpoint_completion_target = 0.7 # Checkpoint completion target
wal_buffers = "16MB" # WAL buffer size
default_statistics_target = 100 # Statistics target
random_page_cost = 1.1 # Random page cost
```
#### SQLite
```toml
[database.sqlite]
journal_mode = "WAL" # Write-Ahead Logging
synchronous = "NORMAL" # Synchronous mode
cache_size = 10000 # Page cache size
temp_store = "memory" # Temporary storage in memory
mmap_size = 268435456 # Memory-mapped I/O size (256MB)
page_size = 4096 # Page size in bytes
```
## Memory Management
### Heap Configuration
```toml
[memory]
initial_heap_size = 134217728 # Initial heap size (128MB)
max_heap_size = 2147483648 # Maximum heap size (2GB)
gc_threshold = 0.75 # GC threshold (75% of heap)
gc_trigger_interval = 60 # GC trigger interval in seconds
```
### Memory Pools
```toml
[memory.pools]
buffer_pool_size = 67108864 # Buffer pool size (64MB)
string_pool_size = 16777216 # String pool size (16MB)
object_pool_size = 33554432 # Object pool size (32MB)
connection_pool_memory = 8388608 # Connection pool memory (8MB)
```
### Memory Monitoring
```toml
[memory.monitoring]
track_allocations = true # Track memory allocations
memory_usage_threshold = 0.8 # Alert when memory usage > 80%
enable_memory_profiling = false # Enable memory profiling (dev only)
memory_leak_detection = true # Enable memory leak detection
```
## Caching Configuration
### Multi-Level Caching
```toml
[cache]
enabled = true
default_ttl = 3600 # Default cache TTL (1 hour)
max_memory_size = 268435456 # Max memory cache size (256MB)
cleanup_interval = 300 # Cache cleanup interval (5 minutes)
compression_enabled = true # Enable cache compression
compression_threshold = 1024 # Compress items larger than 1KB
```
### L1 Cache (In-Memory)
```toml
[cache.l1]
enabled = true
max_entries = 10000 # Maximum cache entries
eviction_policy = "lru" # Eviction policy: lru, lfu, fifo
segment_count = 16 # Number of cache segments
expire_after_write = 3600 # Expire after write (1 hour)
expire_after_access = 1800 # Expire after access (30 minutes)
```
### L2 Cache (Redis)
```toml
[cache.l2]
enabled = true
redis_url = "${REDIS_URL}"
database = 0 # Redis database number
key_prefix = "rustelo:" # Cache key prefix
connection_pool_size = 10 # Redis connection pool size
connection_timeout = 5 # Redis connection timeout
command_timeout = 5 # Redis command timeout
```
### Application-Level Caching
```toml
[cache.application]
page_cache_enabled = true # Enable page caching
page_cache_ttl = 1800 # Page cache TTL (30 minutes)
api_cache_enabled = true # Enable API response caching
api_cache_ttl = 300 # API cache TTL (5 minutes)
template_cache_enabled = true # Enable template caching
static_file_cache_enabled = true # Enable static file caching
```
## Asset Optimization
### Static File Serving
```toml
[assets]
serve_static_files = true # Serve static files
static_file_cache_control = "public, max-age=31536000" # 1 year cache
enable_etag = true # Enable ETag headers
enable_last_modified = true # Enable Last-Modified headers
enable_range_requests = true # Enable range requests
```
### Compression
```toml
[assets.compression]
enabled = true
algorithms = ["gzip", "deflate", "br"] # Compression algorithms
compression_level = 6 # Compression level (1-9)
min_file_size = 1024 # Minimum file size to compress
compress_types = [ # MIME types to compress
"text/html",
"text/css",
"text/javascript",
"application/javascript",
"application/json",
"text/xml",
"application/xml"
]
```
### CDN Integration
```toml
[assets.cdn]
enabled = false # Enable CDN
cdn_url = "https://cdn.example.com" # CDN base URL
cdn_paths = ["/static", "/assets"] # Paths to serve from CDN
cache_bust_enabled = true # Enable cache busting
cache_bust_strategy = "timestamp" # Strategy: timestamp, hash, version
```
## Performance Monitoring
### Metrics Collection
```toml
[performance.metrics]
enabled = true
collection_interval = 15 # Metrics collection interval (seconds)
retention_period = 2592000 # Metrics retention (30 days)
high_resolution_metrics = true # Enable high-resolution metrics
```
### Response Time Monitoring
```toml
[performance.response_times]
track_percentiles = true # Track response time percentiles
percentiles = [50, 75, 90, 95, 99, 99.9] # Percentiles to track
slow_request_threshold = 1000 # Slow request threshold (1 second)
very_slow_request_threshold = 5000 # Very slow request threshold (5 seconds)
```
### Resource Monitoring
```toml
[performance.resources]
monitor_cpu = true # Monitor CPU usage
monitor_memory = true # Monitor memory usage
monitor_disk = true # Monitor disk I/O
monitor_network = true # Monitor network I/O
monitor_connections = true # Monitor connection count
```
## Profiling Configuration
### CPU Profiling
```toml
[profiling.cpu]
enabled = false # Enable CPU profiling (dev/staging only)
sampling_interval = 10000 # Sampling interval in microseconds
profile_duration = 60 # Profile duration in seconds
output_format = "flamegraph" # Output format: flamegraph, callgrind
```
### Memory Profiling
```toml
[profiling.memory]
enabled = false # Enable memory profiling (dev/staging only)
track_allocations = true # Track individual allocations
heap_profiling = true # Enable heap profiling
leak_detection = true # Enable memory leak detection
```
### Database Profiling
```toml
[profiling.database]
enabled = false # Enable database profiling
log_all_queries = false # Log all database queries
log_slow_queries = true # Log slow queries only
explain_slow_queries = true # Add EXPLAIN to slow queries
query_plan_cache = true # Cache query execution plans
```
## Environment-Specific Performance
### Development Environment
```toml
[performance.development]
optimize_for_development = true # Enable development optimizations
hot_reload_enabled = true # Enable hot reloading
debug_mode = true # Enable debug mode
profiling_enabled = true # Enable profiling
reduced_caching = true # Reduce caching for development
```
### Production Environment
```toml
[performance.production]
optimize_for_production = true # Enable production optimizations
aggressive_caching = true # Enable aggressive caching
connection_pooling = true # Enable connection pooling
jit_compilation = true # Enable JIT compilation
gc_optimization = true # Enable garbage collection optimization
```
## Load Testing Configuration
### Test Parameters
```toml
[load_testing]
max_virtual_users = 1000 # Maximum virtual users
ramp_up_time = 60 # Ramp-up time in seconds
test_duration = 300 # Test duration in seconds
think_time = 1 # Think time between requests
```
### Performance Targets
```toml
[load_testing.targets]
response_time_p95 = 500 # 95th percentile response time (ms)
response_time_p99 = 1000 # 99th percentile response time (ms)
throughput_rps = 1000 # Requests per second
error_rate_threshold = 0.01 # Maximum error rate (1%)
cpu_usage_threshold = 0.8 # Maximum CPU usage (80%)
memory_usage_threshold = 0.8 # Maximum memory usage (80%)
```
## Performance Optimization Strategies
### Database Optimization
```toml
[optimization.database]
enable_query_optimization = true
index_optimization = true
query_caching = true
connection_pooling = true
read_replicas = false
database_sharding = false
```
### Application Optimization
```toml
[optimization.application]
lazy_loading = true # Enable lazy loading
async_processing = true # Enable async processing
batch_operations = true # Enable batch operations
response_streaming = true # Enable response streaming
request_coalescing = true # Enable request coalescing
```
### System Optimization
```toml
[optimization.system]
kernel_bypass = false # Enable kernel bypass (advanced)
numa_awareness = true # Enable NUMA awareness
cpu_affinity = false # Enable CPU affinity
disk_io_optimization = true # Enable disk I/O optimization
network_optimization = true # Enable network optimization
```
## Monitoring and Alerting
### Performance Alerts
```toml
[alerts.performance]
enabled = true
response_time_threshold = 2000 # Response time alert threshold (2 seconds)
throughput_threshold = 100 # Throughput alert threshold (100 RPS)
error_rate_threshold = 0.05 # Error rate alert threshold (5%)
memory_usage_threshold = 0.9 # Memory usage alert threshold (90%)
cpu_usage_threshold = 0.9 # CPU usage alert threshold (90%)
```
### Health Checks
```toml
[health_checks]
enabled = true
check_interval = 30 # Health check interval (seconds)
timeout = 5 # Health check timeout (seconds)
failure_threshold = 3 # Consecutive failures before alert
```
## Benchmarking Configuration
### Benchmark Settings
```toml
[benchmarking]
enabled = false # Enable benchmarking
benchmark_duration = 60 # Benchmark duration (seconds)
warmup_duration = 10 # Warmup duration (seconds)
concurrency_levels = [1, 10, 100, 1000] # Concurrency levels to test
```
### Performance Baselines
```toml
[benchmarking.baselines]
response_time_baseline = 100 # Response time baseline (ms)
throughput_baseline = 1000 # Throughput baseline (RPS)
memory_baseline = 134217728 # Memory baseline (128MB)
cpu_baseline = 0.5 # CPU baseline (50%)
```
## Troubleshooting Performance Issues
### Common Performance Problems
1. **High Response Times**
- Check database query performance
- Review caching configuration
- Monitor resource usage
- Analyze request patterns
2. **Memory Issues**
- Monitor memory usage patterns
- Check for memory leaks
- Review garbage collection settings
- Optimize memory allocation
3. **CPU Bottlenecks**
- Profile CPU usage
- Check for inefficient algorithms
- Review worker thread configuration
- Optimize hot code paths
4. **Database Performance**
- Analyze slow queries
- Check connection pool settings
- Review database configuration
- Optimize indexes
### Performance Debugging
```toml
[debugging.performance]
enable_detailed_logging = true # Enable detailed performance logging
request_tracing = true # Enable request tracing
sql_query_logging = true # Enable SQL query logging
memory_tracking = true # Enable memory tracking
cpu_profiling = true # Enable CPU profiling
```
## Best Practices
### Performance Optimization Guidelines
1. **Measure Before Optimizing**
- Establish performance baselines
- Use profiling tools
- Monitor key metrics
- Identify bottlenecks
2. **Optimize Incrementally**
- Make small, measurable changes
- Test each optimization
- Monitor impact
- Rollback if necessary
3. **Cache Strategically**
- Cache frequently accessed data
- Use appropriate cache levels
- Implement cache invalidation
- Monitor cache hit rates
4. **Database Optimization**
- Use appropriate indexes
- Optimize query structure
- Configure connection pooling
- Monitor slow queries
### Performance Testing
```toml
[testing.performance]
automated_testing = true # Enable automated performance testing
regression_testing = true # Enable performance regression testing
load_testing = true # Enable load testing
stress_testing = true # Enable stress testing
```
## Performance Checklist
### Pre-Production Performance Review
- [ ] Database queries optimized
- [ ] Appropriate indexes created
- [ ] Connection pooling configured
- [ ] Caching strategy implemented
- [ ] Static assets optimized
- [ ] Compression enabled
- [ ] Memory limits configured
- [ ] Worker threads optimized
- [ ] Performance monitoring enabled
- [ ] Load testing completed
- [ ] Performance baselines established
- [ ] Alerting configured
## Next Steps
- [Database Optimization](../performance/database.md)
- [Caching Strategies](../performance/caching.md)
- [Frontend Optimization](../performance/frontend.md)
- [Memory Management](../performance/memory.md)
- [Monitoring & Profiling](../performance/monitoring.md)

View File

@ -0,0 +1,605 @@
# Security Configuration
Rustelo provides comprehensive security features to protect your application and user data. This chapter covers how to configure authentication, authorization, encryption, and other security measures to ensure your application meets security best practices.
## Overview
Rustelo's security system includes:
- **Authentication**: User identity verification and session management
- **Authorization**: Role-based access control (RBAC) and permissions
- **Encryption**: Data protection at rest and in transit
- **Input Validation**: Protection against injection attacks
- **Security Headers**: HTTP security headers and CSP
- **Rate Limiting**: Protection against abuse and DoS attacks
- **Audit Logging**: Security event tracking and monitoring
## Authentication Configuration
### Basic Authentication Settings
```toml
[auth]
enabled = true
require_authentication = true
default_session_timeout = 1800 # 30 minutes
max_session_duration = 28800 # 8 hours
session_cleanup_interval = 300 # 5 minutes
[auth.password]
min_length = 12
max_length = 128
require_uppercase = true
require_lowercase = true
require_numbers = true
require_special_chars = true
forbidden_passwords = [
"password", "123456", "admin", "root"
]
password_history_count = 5
password_expiry_days = 90
```
### JWT Configuration
```toml
[auth.jwt]
secret = "${JWT_SECRET}"
algorithm = "HS256"
issuer = "rustelo-app"
audience = ["rustelo-users"]
access_token_expiry = 900 # 15 minutes
refresh_token_expiry = 86400 # 24 hours
require_exp = true
require_iat = true
require_nbf = true
clock_skew = 60 # Allow 60 seconds clock skew
```
### Session Management
```toml
[auth.sessions]
cookie_name = "rustelo_session"
cookie_secure = true # HTTPS only
cookie_http_only = true # No JavaScript access
cookie_same_site = "Strict"
cookie_path = "/"
cookie_domain = "" # Current domain only
session_regeneration = true # Regenerate session ID on login
concurrent_sessions = 3 # Max concurrent sessions per user
```
### Account Security
```toml
[auth.security]
max_login_attempts = 5
lockout_duration = 900 # 15 minutes
progressive_lockout = true # Increase lockout time on repeated failures
require_email_verification = true
email_verification_expiry = 86400 # 24 hours
password_reset_expiry = 3600 # 1 hour
```
## Two-Factor Authentication
### TOTP Configuration
```toml
[auth.two_factor]
enabled = true
required_for_admin = true
backup_codes_count = 10
backup_codes_length = 8
[auth.two_factor.totp]
issuer = "Rustelo App"
algorithm = "SHA1"
digits = 6
period = 30
window = 1 # Allow 1 step before/after current time
```
### SMS Configuration
```toml
[auth.two_factor.sms]
enabled = false
provider = "twilio" # twilio, aws_sns
verification_code_length = 6
verification_code_expiry = 300 # 5 minutes
rate_limit = 5 # Max 5 SMS per hour per user
[auth.two_factor.sms.twilio]
account_sid = "${TWILIO_ACCOUNT_SID}"
auth_token = "${TWILIO_AUTH_TOKEN}"
from_number = "${TWILIO_FROM_NUMBER}"
```
## Authorization & RBAC
### Role-Based Access Control
```toml
[rbac]
enabled = true
default_role = "user"
admin_role = "admin"
super_admin_role = "super_admin"
guest_role = "guest"
[rbac.permissions]
hierarchical = true # Roles inherit permissions from parent roles
cache_enabled = true
cache_ttl = 300 # 5 minutes
audit_enabled = true
[rbac.roles]
user = {
permissions = ["read_own_profile", "update_own_profile"],
inherits_from = ["guest"]
}
moderator = {
permissions = ["moderate_content", "view_reports"],
inherits_from = ["user"]
}
admin = {
permissions = ["manage_users", "manage_content", "view_logs"],
inherits_from = ["moderator"]
}
super_admin = {
permissions = ["*"],
inherits_from = []
}
```
### Resource-Based Permissions
```toml
[rbac.resources]
users = ["create", "read", "update", "delete"]
content = ["create", "read", "update", "delete", "publish"]
reports = ["create", "read", "update", "delete", "resolve"]
logs = ["read", "export"]
settings = ["read", "update"]
```
## Encryption Configuration
### Data Encryption
```toml
[encryption]
enabled = true
algorithm = "AES-256-GCM"
key_derivation = "PBKDF2"
key_derivation_iterations = 100000
salt_length = 32
[encryption.at_rest]
enabled = true
encrypt_sensitive_fields = true
sensitive_fields = [
"password", "email", "phone", "ssn", "credit_card"
]
[encryption.in_transit]
min_tls_version = "1.2"
cipher_suites = [
"TLS_AES_256_GCM_SHA384",
"TLS_CHACHA20_POLY1305_SHA256",
"TLS_AES_128_GCM_SHA256"
]
```
### Key Management
```toml
[encryption.keys]
rotation_enabled = true
rotation_interval = 2592000 # 30 days
key_backup_enabled = true
key_backup_location = "${KEY_BACKUP_PATH}"
master_key = "${MASTER_ENCRYPTION_KEY}"
```
## Input Validation & Sanitization
### General Validation
```toml
[security.validation]
enabled = true
strict_mode = true
max_request_size = 10485760 # 10MB
max_field_length = 1000
max_array_length = 100
max_nesting_depth = 10
[security.validation.email]
allow_plus_addressing = true
allow_internationalized = true
require_verification = true
blocked_domains = ["tempmail.com", "10minutemail.com"]
```
### SQL Injection Prevention
```toml
[security.sql_injection]
use_prepared_statements = true
validate_input_types = true
escape_special_characters = true
log_suspicious_queries = true
```
### XSS Prevention
```toml
[security.xss]
enabled = true
auto_escape_html = true
content_security_policy = true
sanitize_user_input = true
allowed_html_tags = ["b", "i", "u", "em", "strong", "a"]
allowed_attributes = ["href", "title", "alt"]
```
## Security Headers
### HTTP Security Headers
```toml
[security.headers]
enabled = true
[security.headers.hsts]
enabled = true
max_age = 31536000 # 1 year
include_subdomains = true
preload = true
[security.headers.csp]
enabled = true
default_src = ["'self'"]
script_src = ["'self'", "'unsafe-inline'"]
style_src = ["'self'", "'unsafe-inline'"]
img_src = ["'self'", "data:", "https:"]
connect_src = ["'self'"]
font_src = ["'self'"]
object_src = ["'none'"]
frame_ancestors = ["'none'"]
base_uri = ["'self'"]
form_action = ["'self'"]
[security.headers.other]
x_content_type_options = "nosniff"
x_frame_options = "DENY"
x_xss_protection = "1; mode=block"
referrer_policy = "strict-origin-when-cross-origin"
permissions_policy = "geolocation=(), microphone=(), camera=()"
```
## Rate Limiting
### API Rate Limiting
```toml
[security.rate_limiting]
enabled = true
storage = "memory" # memory, redis, database
cleanup_interval = 3600 # 1 hour
[security.rate_limiting.global]
requests_per_minute = 100
burst_limit = 10
[security.rate_limiting.per_user]
requests_per_minute = 60
burst_limit = 5
[security.rate_limiting.endpoints]
"/api/auth/login" = { requests_per_minute = 5, burst_limit = 2 }
"/api/auth/register" = { requests_per_minute = 3, burst_limit = 1 }
"/api/password/reset" = { requests_per_minute = 2, burst_limit = 1 }
"/api/upload" = { requests_per_minute = 10, burst_limit = 3 }
```
### DDoS Protection
```toml
[security.ddos]
enabled = true
max_connections_per_ip = 10
connection_timeout = 30
slow_loris_protection = true
```
## CSRF Protection
```toml
[security.csrf]
enabled = true
token_name = "csrf_token"
header_name = "X-CSRF-Token"
cookie_name = "csrf_cookie"
token_length = 32
double_submit_cookie = true
same_site_cookie = "Strict"
```
## File Upload Security
```toml
[security.uploads]
enabled = true
max_file_size = 10485760 # 10MB
max_files_per_request = 5
allowed_extensions = [
"jpg", "jpeg", "png", "gif", "webp",
"pdf", "doc", "docx", "txt", "csv"
]
scan_for_viruses = true
quarantine_suspicious_files = true
```
## Audit Logging
### Security Event Logging
```toml
[security.audit]
enabled = true
log_level = "info"
log_format = "json"
log_file = "/var/log/rustelo/security.log"
max_log_size = 104857600 # 100MB
max_log_files = 10
log_retention_days = 90
[security.audit.events]
login_success = true
login_failure = true
logout = true
password_change = true
password_reset = true
account_lockout = true
permission_denied = true
data_access = true
data_modification = true
admin_actions = true
```
### Compliance Logging
```toml
[security.compliance]
gdpr_logging = true
hipaa_logging = false
pci_logging = false
sox_logging = false
```
## Environment-Specific Security
### Development Environment
```toml
[security.development]
relaxed_cors = true
debug_headers = true
disable_https_redirect = true
allow_http_cookies = true
verbose_error_messages = true
```
### Production Environment
```toml
[security.production]
strict_mode = true
hide_server_info = true
disable_debug_endpoints = true
require_https = true
enable_monitoring = true
```
## SSL/TLS Configuration
### Certificate Management
```toml
[security.tls]
enabled = true
cert_file = "${TLS_CERT_FILE}"
key_file = "${TLS_KEY_FILE}"
ca_file = "${TLS_CA_FILE}"
protocols = ["TLSv1.2", "TLSv1.3"]
prefer_server_ciphers = true
[security.tls.auto_renewal]
enabled = true
provider = "lets_encrypt"
renewal_threshold = 2592000 # 30 days
notification_email = "${ADMIN_EMAIL}"
```
## Security Monitoring
### Intrusion Detection
```toml
[security.monitoring]
enabled = true
failed_login_threshold = 10
suspicious_activity_threshold = 5
alert_admin = true
auto_block_suspicious_ips = true
block_duration = 3600 # 1 hour
```
### Security Metrics
```toml
[security.metrics]
enabled = true
track_login_attempts = true
track_permission_denials = true
track_rate_limit_hits = true
track_security_violations = true
```
## Best Practices Configuration
### Password Security
```toml
[security.passwords]
use_bcrypt = true
bcrypt_cost = 12
require_password_confirmation = true
prevent_password_reuse = true
password_strength_meter = true
```
### API Security
```toml
[security.api]
require_authentication = true
require_https = true
validate_content_type = true
rate_limit_enabled = true
cors_enabled = true
cors_allow_credentials = false
```
## Security Testing
### Penetration Testing
```toml
[security.testing]
enable_security_tests = true
sql_injection_tests = true
xss_tests = true
csrf_tests = true
authentication_tests = true
authorization_tests = true
```
## Incident Response
### Security Incident Configuration
```toml
[security.incident_response]
enabled = true
auto_lockout_on_breach = true
notify_admin_on_incident = true
incident_log_file = "/var/log/rustelo/incidents.log"
emergency_contact = "${SECURITY_CONTACT}"
```
## Compliance Frameworks
### GDPR Compliance
```toml
[security.gdpr]
enabled = true
data_retention_days = 2555 # 7 years
anonymize_on_deletion = true
consent_tracking = true
data_export_enabled = true
```
### OWASP Configuration
```toml
[security.owasp]
top_10_protection = true
injection_prevention = true
broken_authentication_prevention = true
sensitive_data_exposure_prevention = true
xml_external_entities_prevention = true
broken_access_control_prevention = true
security_misconfiguration_prevention = true
cross_site_scripting_prevention = true
insecure_deserialization_prevention = true
known_vulnerabilities_prevention = true
insufficient_logging_prevention = true
```
## Security Checklist
### Pre-Deployment Security Checks
- [ ] Strong authentication configured
- [ ] HTTPS enabled and enforced
- [ ] Security headers implemented
- [ ] Input validation enabled
- [ ] Rate limiting configured
- [ ] Audit logging enabled
- [ ] File upload restrictions in place
- [ ] Database security configured
- [ ] Regular security updates scheduled
- [ ] Backup and recovery procedures tested
- [ ] Incident response plan documented
- [ ] Security monitoring enabled
- [ ] Penetration testing completed
- [ ] Compliance requirements met
## Troubleshooting
### Common Security Issues
1. **Authentication Failures**
- Check password policies
- Verify JWT configuration
- Review session settings
2. **Authorization Issues**
- Validate RBAC configuration
- Check permission inheritance
- Review role assignments
3. **SSL/TLS Problems**
- Verify certificate validity
- Check cipher suite compatibility
- Validate TLS version settings
4. **Rate Limiting Issues**
- Monitor rate limit logs
- Adjust limits based on usage
- Check for IP blocking
### Security Debugging
```bash
# Enable security debug logging
RUST_LOG=rustelo::security=debug ./rustelo-server
# Check security headers
curl -I https://yourapp.com
# Test authentication
curl -X POST https://yourapp.com/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"test","password":"test"}'
```
## Security Resources
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
- [NIST Cybersecurity Framework](https://www.nist.gov/cyberframework)
- [Mozilla Security Guidelines](https://infosec.mozilla.org/guidelines/)
- [Rust Security Guidelines](https://doc.rust-lang.org/nomicon/security.html)
## Next Steps
- [Authentication System](../developers/components/auth.md)
- [Performance Optimization](../performance/overview.md)
- [Monitoring & Logging](../deployment/monitoring.md)
- [Security Best Practices](../security/best-practices.md)

View File

View File

View File

@ -0,0 +1 @@
# Contributing Guidelines

View File

@ -0,0 +1 @@
# Release Process

View File

View File

View File

View File

View File

@ -0,0 +1,332 @@
# Database Configuration Guide
This application supports both **PostgreSQL** and **SQLite** databases through SQLx's unified interface. The database type is automatically detected based on the connection URL.
## Quick Start
### SQLite (Recommended for Development)
```toml
[database]
url = "sqlite//:database.db"
```
### PostgreSQL (Recommended for Production)
```toml
[database]
url = "postgresql://username:password@localhost:5432/database_name"
```
## Database URL Formats
### SQLite URLs
- `sqlite//:database.db` - Relative path to database file
- `sqlite:///path/to/database.db` - Absolute path to database file
- `sqlite::memory:` - In-memory database (testing only)
### PostgreSQL URLs
- `postgresql://user:password@host:port/database`
- `postgres://user:password@host:port/database`
## Environment Variables
You can override the database URL using environment variables:
```bash
export DATABASE_URL="sqlite//:my_database.db"
# or
export DATABASE_URL="postgresql://user:pass@localhost:5432/mydb"
```
## Database-Specific Features
### SQLite
- **Pros:**
- Zero configuration setup
- Single file database
- Perfect for development and testing
- No separate server process required
- ACID compliant
- **Cons:**
- Limited concurrent writes
- No network access
- Fewer advanced features
- File-based storage
### PostgreSQL
- **Pros:**
- Full ACID compliance
- Excellent concurrent access
- Advanced features (JSONB, arrays, etc.)
- Network accessible
- Production-ready scalability
- **Cons:**
- Requires PostgreSQL server
- More complex setup
- Resource overhead
## Configuration Examples
### Development Configuration
```toml
# config.dev.toml
[database]
url = "sqlite//:dev_database.db"
max_connections = 5
min_connections = 1
connect_timeout = 30
idle_timeout = 300
max_lifetime = 1800
```
### Production Configuration
```toml
# config.prod.toml
[database]
url = "postgresql://prod_user:${DATABASE_PASSWORD}@db.example.com:5432/prod_database"
max_connections = 20
min_connections = 5
connect_timeout = 30
idle_timeout = 600
max_lifetime = 3600
```
## Connection Pool Settings
| Setting | Description | SQLite | PostgreSQL |
|---------|-------------|--------|------------|
| `max_connections` | Maximum pool size | 1 (recommended) | 10-50 |
| `min_connections` | Minimum pool size | 1 | 1-5 |
| `connect_timeout` | Connection timeout (seconds) | 30 | 30 |
| `idle_timeout` | Idle connection timeout (seconds) | 300 | 600 |
| `max_lifetime` | Maximum connection lifetime (seconds) | 1800 | 3600 |
## Database Setup
### SQLite Setup
No setup required! The database file will be created automatically when the application starts.
### PostgreSQL Setup
#### Using Docker
```bash
# Start PostgreSQL container
docker run -d \
--name postgres \
-e POSTGRES_PASSWORD=password \
-e POSTGRES_DB=myapp \
-p 5432:5432 \
postgres:15
# Connect to database
docker exec -it postgres psql -U postgres -d myapp
```
#### Using Local Installation
**macOS (Homebrew):**
```bash
brew install postgresql
brew services start postgresql
createdb myapp
```
**Ubuntu/Debian:**
```bash
sudo apt-get install postgresql postgresql-contrib
sudo systemctl start postgresql
sudo -u postgres createdb myapp
```
## Migration Support
The application automatically creates the necessary tables for both database types:
### SQLite Tables
- Uses `TEXT` for IDs (UUID format)
- Uses `DATETIME` for timestamps
- Uses `TEXT` for JSON storage
- Uses `BOOLEAN` for boolean values
### PostgreSQL Tables
- Uses `UUID` for IDs with `gen_random_uuid()`
- Uses `TIMESTAMPTZ` for timestamps
- Uses `JSONB` for JSON storage
- Uses `BOOLEAN` for boolean values
## Switching Between Databases
You can switch between databases by simply changing the `DATABASE_URL`:
```bash
# Switch to SQLite
export DATABASE_URL="sqlite//:database.db"
# Switch to PostgreSQL
export DATABASE_URL="postgresql://user:pass@localhost:5432/mydb"
```
The application will automatically:
1. Detect the database type
2. Use appropriate SQL syntax
3. Create compatible table schemas
4. Handle data type differences
## Performance Considerations
### SQLite
- **Best for:**
- Single-user applications
- Development and testing
- Small to medium datasets
- Read-heavy workloads
- **Optimization tips:**
- Use WAL mode: `PRAGMA journal_mode=WAL`
- Set appropriate timeout: `PRAGMA busy_timeout=5000`
- Use transactions for bulk operations
### PostgreSQL
- **Best for:**
- Multi-user applications
- Production environments
- Large datasets
- High concurrency requirements
- **Optimization tips:**
- Configure appropriate connection pool size
- Use indexes on frequently queried columns
- Monitor and tune PostgreSQL configuration
- Use connection pooling (PgBouncer) for high traffic
## Troubleshooting
### Common SQLite Issues
- **Database locked**: Check for long-running transactions
- **File permissions**: Ensure write access to database file and directory
- **Disk space**: Verify sufficient disk space for database growth
### Common PostgreSQL Issues
- **Connection refused**: Check PostgreSQL server status
- **Authentication failed**: Verify username/password and pg_hba.conf
- **Too many connections**: Adjust max_connections or use connection pooling
### Debug Connection Issues
```bash
# Test SQLite connection
sqlite3 database.db "SELECT 1;"
# Test PostgreSQL connection
psql "postgresql://user:pass@localhost:5432/mydb" -c "SELECT 1;"
```
## Environment-Specific Configuration
### Development
```bash
# .env.development
DATABASE_URL=sqlite//:dev_database.db
```
### Testing
```bash
# .env.test
DATABASE_URL=sqlite//::memory:
```
### Production
```bash
# .env.production
DATABASE_URL=postgresql://user:${DATABASE_PASSWORD}@db.internal:5432/prod_db
```
## Security Considerations
### SQLite Security
- Protect database file permissions (600 or 640)
- Backup database files securely
- Consider encryption for sensitive data
### PostgreSQL Security
- Use strong passwords
- Enable SSL/TLS connections
- Restrict network access
- Regular security updates
- Use connection pooling with authentication
## Backup and Recovery
### SQLite Backup
```bash
# Simple file copy
cp database.db database_backup.db
# Using SQLite backup command
sqlite3 database.db ".backup database_backup.db"
```
### PostgreSQL Backup
```bash
# Database dump
pg_dump myapp > myapp_backup.sql
# Restore from dump
psql myapp < myapp_backup.sql
```
## Monitoring and Maintenance
### SQLite Maintenance
```sql
-- Analyze database
ANALYZE;
-- Vacuum database
VACUUM;
-- Check integrity
PRAGMA integrity_check;
```
### PostgreSQL Maintenance
```sql
-- Analyze tables
ANALYZE;
-- Vacuum tables
VACUUM;
-- Check database size
SELECT pg_size_pretty(pg_database_size('myapp'));
```
## Best Practices
1. **Use environment variables** for database URLs in production
2. **Configure appropriate connection pools** based on your workload
3. **Monitor database performance** and adjust settings as needed
4. **Regular backups** are essential for production databases
5. **Test migrations** on both database types if supporting both
6. **Use transactions** for data consistency
7. **Index frequently queried columns** for better performance
8. **Monitor connection pool usage** to prevent exhaustion
## Feature Compatibility Matrix
| Feature | SQLite | PostgreSQL |
|---------|--------|------------|
| ACID Transactions | ✅ | ✅ |
| Concurrent Reads | ✅ | ✅ |
| Concurrent Writes | ⚠️ Limited | ✅ |
| JSON Support | ✅ (TEXT) | ✅ (JSONB) |
| Full-text Search | ✅ (FTS) | ✅ (Built-in) |
| Network Access | ❌ | ✅ |
| Replication | ❌ | ✅ |
| Partitioning | ❌ | ✅ |
| Custom Functions | ✅ | ✅ |
| Triggers | ✅ | ✅ |
| Views | ✅ | ✅ |
| Stored Procedures | ❌ | ✅ |
This guide should help you choose and configure the right database for your needs. Both options are fully supported and the application will work seamlessly with either choice.

View File

View File

View File

0
book/database/sqlite.md Normal file
View File

View File

@ -0,0 +1 @@
# Backup & Recovery

1
book/deployment/cloud.md Normal file
View File

@ -0,0 +1 @@
# Cloud Platforms

View File

View File

View File

View File

View File

1
book/deployment/ssl.md Normal file
View File

@ -0,0 +1 @@
# SSL/TLS Configuration

View File

@ -0,0 +1 @@
# Backend Architecture

View File

@ -0,0 +1 @@
# Database Design

View File

@ -0,0 +1 @@
# Frontend Architecture

View File

@ -0,0 +1 @@
# System Overview

View File

@ -0,0 +1 @@
# Security Model

View File

@ -0,0 +1,329 @@
# Logo Usage Guide
The Rustelo project includes a comprehensive logo system designed to work across different contexts and themes. This guide explains how to properly use the logos in your applications and documentation.
## Logo Assets
The logo system includes the following variants:
### Available Logo Files
| File | Usage | Context |
|------|-------|---------|
| `rustelo_dev-logo-h.svg` | Horizontal logo for normal/light themes | Primary horizontal logo |
| `rustelo_dev-logo-b-h.svg` | Horizontal logo for dark themes | Dark theme horizontal logo |
| `rustelo_dev-logo-v.svg` | Vertical logo for normal/light themes | Primary vertical logo |
| `rustelo_dev-logo-b-v.svg` | Vertical logo for dark themes | Dark theme vertical logo |
| `rustelo-imag.svg` | Logo image without text | Icon/favicon usage |
### Logo Locations
- **Source**: `logos/` directory (original assets)
- **Public**: `public/logos/` directory (web-accessible assets)
- **Documentation**: Referenced in mdBook via `../logos/` path
## Usage Guidelines
### 1. Web Application Usage
#### Navigation Logo
```rust
use crate::components::NavbarLogo;
// In your navigation component
view! {
<nav class="navigation">
<NavbarLogo size="small".to_string() />
// ... other nav items
</nav>
}
```
#### Brand Header
```rust
use crate::components::BrandHeader;
// For page headers
view! {
<BrandHeader
title="RUSTELO".to_string()
subtitle="Modular Rust Web Application Template".to_string()
logo_size="large".to_string()
class="justify-center".to_string()
/>
}
```
#### Standalone Logo
```rust
use crate::components::Logo;
// Basic logo usage
view! {
<Logo
orientation="horizontal".to_string()
size="medium".to_string()
show_text={true}
class="my-custom-class".to_string()
/>
}
```
### 2. Documentation Usage
#### Markdown Files
```markdown
<!-- In README.md or other markdown files -->
<div align="center">
<img src="logos/rustelo_dev-logo-h.svg" alt="RUSTELO" width="300" />
# Your Page Title
</div>
```
#### mdBook Pages
```markdown
<!-- In book pages -->
<div align="center">
<img src="../logos/rustelo_dev-logo-h.svg" alt="RUSTELO" width="400" />
</div>
# Welcome to Rustelo
```
### 3. Size Guidelines
#### Component Sizes
- **small**: 32px height (navbar usage)
- **medium**: 48px height (standard usage)
- **large**: 64px height (headers)
- **xlarge**: 80px height (hero sections)
#### Documentation Sizes
- **Small**: 150-200px width
- **Medium**: 250-300px width
- **Large**: 350-400px width
### 4. Responsive Usage
The logo components automatically adapt to different screen sizes:
```rust
// Mobile-responsive logo
view! {
<Logo
orientation="horizontal".to_string()
size="medium".to_string()
show_text={true}
class="w-full max-w-xs sm:max-w-sm md:max-w-md".to_string()
/>
}
```
## Theme Integration
### Automatic Theme Detection
The logo components automatically detect the current theme and switch between light and dark variants:
```rust
// This automatically uses the appropriate variant
view! {
<Logo
orientation="horizontal".to_string()
size="medium".to_string()
show_text={true}
/>
}
```
### Manual Theme Selection
For static contexts (like documentation), choose the appropriate variant:
- **Light backgrounds**: Use `rustelo_dev-logo-h.svg` or `rustelo_dev-logo-v.svg`
- **Dark backgrounds**: Use `rustelo_dev-logo-b-h.svg` or `rustelo_dev-logo-b-v.svg`
## Best Practices
### DO
✅ Use the horizontal logo for navigation bars and headers
✅ Use the vertical logo for sidebar or narrow layouts
✅ Use the image-only logo for favicons and small icons
✅ Maintain proper contrast with background colors
✅ Use consistent sizing within the same context
✅ Include proper alt text: "RUSTELO"
### DON'T
❌ Stretch or distort the logo proportions
❌ Use light logos on light backgrounds
❌ Use dark logos on dark backgrounds
❌ Make the logo too small to read (minimum 24px height)
❌ Use low-quality or pixelated versions
## Component API Reference
### Logo Component
```rust
#[component]
pub fn Logo(
#[prop(default = "horizontal".to_string())] orientation: String,
#[prop(default = "normal".to_string())] size: String,
#[prop(default = true)] show_text: bool,
#[prop(default = "".to_string())] class: String,
) -> impl IntoView
```
**Parameters:**
- `orientation`: "horizontal" | "vertical"
- `size`: "small" | "medium" | "large" | "xlarge"
- `show_text`: true (full logo) | false (image only)
- `class`: Additional CSS classes
### LogoLink Component
```rust
#[component]
pub fn LogoLink(
#[prop(default = "horizontal".to_string())] orientation: String,
#[prop(default = "normal".to_string())] size: String,
#[prop(default = true)] show_text: bool,
#[prop(default = "".to_string())] class: String,
#[prop(default = "/".to_string())] href: String,
) -> impl IntoView
```
**Additional Parameters:**
- `href`: Link destination (default: "/")
### BrandHeader Component
```rust
#[component]
pub fn BrandHeader(
#[prop(default = "RUSTELO".to_string())] title: String,
#[prop(default = "".to_string())] subtitle: String,
#[prop(default = "medium".to_string())] logo_size: String,
#[prop(default = "".to_string())] class: String,
) -> impl IntoView
```
**Parameters:**
- `title`: Main brand title
- `subtitle`: Optional subtitle text
- `logo_size`: Logo size variant
- `class`: Additional CSS classes
### NavbarLogo Component
```rust
#[component]
pub fn NavbarLogo(
#[prop(default = "small".to_string())] size: String,
#[prop(default = "".to_string())] class: String,
) -> impl IntoView
```
**Parameters:**
- `size`: Logo size (optimized for navbar)
- `class`: Additional CSS classes
## Usage Examples
### Hero Section
```rust
view! {
<section class="hero">
<BrandHeader
title="RUSTELO".to_string()
subtitle="Build fast, secure web applications with Rust".to_string()
logo_size="xlarge".to_string()
class="text-center".to_string()
/>
</section>
}
```
### Sidebar
```rust
view! {
<aside class="sidebar">
<Logo
orientation="vertical".to_string()
size="medium".to_string()
show_text={true}
class="mb-4".to_string()
/>
</aside>
}
```
### Footer
```rust
view! {
<footer class="footer">
<Logo
orientation="horizontal".to_string()
size="small".to_string()
show_text={false}
class="opacity-60".to_string()
/>
</footer>
}
```
## Troubleshooting
### Logo Not Displaying
1. **Check file paths**: Ensure logos are copied to `public/logos/`
2. **Verify imports**: Make sure components are properly imported
3. **Theme detection**: Confirm theme context is available
### Theme Switching Issues
1. **Theme provider**: Ensure `ThemeProvider` is properly configured
2. **CSS classes**: Check that theme-specific CSS is loaded
3. **JavaScript**: Verify theme switching JavaScript is working
### Performance Optimization
1. **SVG optimization**: Use optimized SVG files
2. **Lazy loading**: Add `loading="lazy"` for non-critical logos
3. **Caching**: Ensure proper cache headers for logo assets
## File Structure
```
template/
├── logos/ # Source logo files
│ ├── rustelo_dev-logo-h.svg
│ ├── rustelo_dev-logo-b-h.svg
│ ├── rustelo_dev-logo-v.svg
│ ├── rustelo_dev-logo-b-v.svg
│ └── rustelo-imag.svg
├── public/
│ └── logos/ # Web-accessible logo files
│ ├── rustelo_dev-logo-h.svg
│ ├── rustelo_dev-logo-b-h.svg
│ ├── rustelo_dev-logo-v.svg
│ ├── rustelo_dev-logo-b-v.svg
│ └── rustelo-imag.svg
└── client/src/components/
└── Logo.rs # Logo components
```
## Contributing
When adding new logo variants or updating existing ones:
1. Update both `logos/` and `public/logos/` directories
2. Test with both light and dark themes
3. Verify responsive behavior
4. Update this documentation
5. Test in all supported browsers
For questions or issues with logo usage, please refer to the [GitHub Issues](https://github.com/yourusername/rustelo/issues) page.

View File

@ -0,0 +1,303 @@
# Rustelo Components
Welcome to the Rustelo Components documentation! This section covers all the built-in components and utilities available in the Rustelo framework.
## 📦 Available Components
### Authentication Components
- **[Authentication System](./auth.md)** - User authentication, JWT tokens, and session management
- Login/Register forms
- Password reset functionality
- User profile management
- Role-based access control
### Content Management
- **[Content System](./content.md)** - Content creation, editing, and management
- Markdown rendering
- File uploads and media management
- Content versioning
- Search functionality
### Email System
- **[Email Components](./email.md)** - Email sending and template management
- SMTP configuration
- Email templates
- Queue management
- Notification system
### Configuration
- **[Configuration System](./config.md)** - Application configuration management
- Environment-based configs
- Feature toggles
- Runtime configuration
- Validation and schema
### Templates & UI
- **[Template System](./templates.md)** - UI templates and components
- Responsive layouts
- Theme system
- Component library
- Style utilities
## 🎯 Component Architecture
Rustelo follows a modular component architecture where each component is:
- **Self-contained** - Each component manages its own state and dependencies
- **Configurable** - Components can be enabled/disabled via features
- **Extensible** - Easy to customize and extend for your needs
- **Well-documented** - Complete API documentation and examples
## 🚀 Getting Started
### Enable Components
Components are enabled through Cargo features:
```toml
[dependencies]
server = { path = "../server", features = ["auth", "content-db", "email"] }
```
### Basic Usage
```rust
use rustelo::components::{Auth, Content, Email};
// Initialize components
let auth = Auth::new(config.auth)?;
let content = Content::new(config.content)?;
let email = Email::new(config.email)?;
```
## 📋 Component Status
| Component | Status | Features | Documentation |
|-----------|--------|----------|---------------|
| Authentication | ✅ Complete | `auth` | [View](./auth.md) |
| Content Management | ✅ Complete | `content-db` | [View](./content.md) |
| Email System | ✅ Complete | `email` | [View](./email.md) |
| Configuration | ✅ Complete | Always enabled | [View](./config.md) |
| Templates | ✅ Complete | Always enabled | [View](./templates.md) |
## 🔧 Component Development
### Creating Custom Components
```rust
use rustelo::Component;
pub struct MyComponent {
config: MyConfig,
}
impl Component for MyComponent {
type Config = MyConfig;
fn new(config: Self::Config) -> Result<Self, Error> {
Ok(Self { config })
}
fn initialize(&mut self) -> Result<(), Error> {
// Initialize component
Ok(())
}
}
```
### Component Lifecycle
1. **Configuration** - Load component configuration
2. **Initialization** - Set up component state
3. **Registration** - Register routes and handlers
4. **Runtime** - Handle requests and events
5. **Cleanup** - Graceful shutdown
## 🎨 Frontend Components
### Leptos Components
```rust
use leptos::*;
use rustelo::components::*;
#[component]
pub fn App() -> impl IntoView {
view! {
<AuthProvider>
<ContentProvider>
<Router>
<Routes>
<Route path="/" view=HomePage/>
<Route path="/login" view=LoginPage/>
<Route path="/dashboard" view=DashboardPage/>
</Routes>
</Router>
</ContentProvider>
</AuthProvider>
}
}
```
### Styling Components
```rust
use rustelo::ui::*;
#[component]
pub fn MyPage() -> impl IntoView {
view! {
<Page title="My Page">
<Card>
<CardHeader>
<h2>"Welcome"</h2>
</CardHeader>
<CardBody>
<p>"Content goes here"</p>
</CardBody>
</Card>
</Page>
}
}
```
## 🔍 Component APIs
### Authentication API
```rust
// Check if user is authenticated
let is_authenticated = auth.is_authenticated(&request)?;
// Get current user
let user = auth.get_current_user(&request)?;
// Login user
let token = auth.login(&credentials)?;
```
### Content API
```rust
// Create content
let content = content_manager.create(CreateContentRequest {
title: "My Article".to_string(),
body: "Article content...".to_string(),
content_type: ContentType::Article,
})?;
// Get content
let content = content_manager.get_by_id(content_id)?;
```
### Email API
```rust
// Send email
email_service.send(SendEmailRequest {
to: "user@example.com".to_string(),
subject: "Welcome!".to_string(),
template: "welcome".to_string(),
data: serde_json::json!({
"name": "John Doe"
}),
})?;
```
## 📊 Performance Considerations
### Component Optimization
- **Lazy Loading** - Components are initialized only when needed
- **Caching** - Built-in caching for frequently accessed data
- **Connection Pooling** - Efficient database and external service connections
- **Async Operations** - Non-blocking I/O operations
### Resource Management
```rust
// Components automatically manage resources
impl Drop for MyComponent {
fn drop(&mut self) {
// Cleanup resources
self.cleanup();
}
}
```
## 🧪 Testing Components
### Unit Tests
```rust
#[cfg(test)]
mod tests {
use super::*;
use rustelo::testing::*;
#[tokio::test]
async fn test_auth_component() {
let config = test_config();
let auth = Auth::new(config.auth).unwrap();
// Test authentication
assert!(auth.is_authenticated(&test_request()).is_ok());
}
}
```
### Integration Tests
```rust
#[tokio::test]
async fn test_component_integration() {
let app = test_app().await;
// Test component interactions
let response = app.post("/api/auth/login")
.json(&login_request())
.send()
.await?;
assert_eq!(response.status(), 200);
}
```
## 🔐 Security
### Security Best Practices
- **Input Validation** - All inputs are validated and sanitized
- **Authentication** - Secure token-based authentication
- **Authorization** - Role-based access control
- **CSRF Protection** - Built-in CSRF token validation
- **Rate Limiting** - Configurable rate limiting
### Security Configuration
```toml
[security]
csrf_protection = true
rate_limiting = true
secure_cookies = true
https_only = true
```
## 📚 Next Steps
1. **[Authentication Guide](./auth.md)** - Set up user authentication
2. **[Content Management](./content.md)** - Manage application content
3. **[Email System](./email.md)** - Configure email functionality
4. **[Configuration](./config.md)** - Understand configuration options
5. **[Templates](./templates.md)** - Customize UI templates
## 🆘 Getting Help
- **[Common Issues](../../troubleshooting/common.md)** - Solutions to common problems
- **[API Reference](../../api/overview.md)** - Complete API documentation
- **[Examples](../../advanced/integrations.md)** - Real-world examples
- **Community Support** - Discord, GitHub Issues, Stack Overflow
---
**Happy building with Rustelo components!** 🦀✨

View File

@ -0,0 +1 @@
# Authentication System

View File

@ -0,0 +1 @@
# Configuration System

View File

@ -0,0 +1 @@
# Content Management

View File

@ -0,0 +1,766 @@
# Email System
<div align="center">
<img src="../../../logos/rustelo_dev-logo-h.svg" alt="RUSTELO" width="300" />
</div>
This guide covers RUSTELO's comprehensive email system, including setup, configuration, usage, and best practices for integrating email functionality into your application.
## Overview
The RUSTELO email system provides a complete solution for sending emails from your web application with support for multiple providers, template-based emails, form submissions, and both server-side and client-side integration.
### Architecture
- **Email Service**: Core service that handles email sending
- **Providers**: Pluggable email providers (SMTP, SendGrid, Console)
- **Templates**: Handlebars-based email templates
- **Forms**: Ready-to-use contact and support form components
- **API**: REST endpoints for email operations
## Features
✨ **Multiple Providers**
- SMTP (Gmail, Outlook, custom servers)
- SendGrid API
- Console output (development)
📧 **Template System**
- Handlebars templates
- HTML and text versions
- Custom helpers
- Variable substitution
🔧 **Form Integration**
- Contact forms
- Support forms with priorities
- Custom form handling
🛡️ **Security**
- Input validation
- Rate limiting
- CSRF protection
- Secure configuration
🎨 **Rich Components**
- React/Leptos form components
- Real-time validation
- Error handling
- Success feedback
## Quick Start
### 1. Enable Email Feature
Make sure the email feature is enabled in your `Cargo.toml`:
```toml
[features]
default = ["email"]
email = ["lettre", "handlebars", "urlencoding"]
```
### 2. Basic Configuration
Add email configuration to your `config.toml`:
```toml
[email]
enabled = true
provider = "console" # Start with console for development
from_email = "noreply@yourapp.com"
from_name = "Your App"
template_dir = "templates/email"
```
### 3. Create Template Directory
```bash
mkdir -p templates/email/html
mkdir -p templates/email/text
```
### 4. Start Using
```rust
// Send a simple email
let result = email_service.send_simple_email(
"user@example.com",
"Welcome!",
"Thank you for signing up!"
).await?;
// Send a contact form
let result = email_service.send_contact_form(
"John Doe",
"john@example.com",
"Question about pricing",
"I'd like to know more about your pricing plans.",
"admin@yourapp.com"
).await?;
```
## Configuration
### Email Configuration Options
```toml
[email]
# Basic settings
enabled = true
provider = "smtp" # "smtp", "sendgrid", "console"
from_email = "noreply@yourapp.com"
from_name = "Your App Name"
template_dir = "templates/email"
# SMTP settings (when provider = "smtp")
smtp_host = "smtp.gmail.com"
smtp_port = 587
smtp_username = "your-email@gmail.com"
smtp_password = "@encrypted_smtp_password"
smtp_use_tls = false
smtp_use_starttls = true
# SendGrid settings (when provider = "sendgrid")
sendgrid_api_key = "@encrypted_sendgrid_api_key"
sendgrid_endpoint = "https://api.sendgrid.com/v3/mail/send"
```
### Environment-Specific Configuration
```toml
# Development
[environments.development]
email.provider = "console"
email.enabled = true
# Production
[environments.production]
email.provider = "sendgrid"
email.sendgrid_api_key = "@encrypted_sendgrid_api_key"
email.enabled = true
```
## Email Providers
### Console Provider
Perfect for development and testing. Prints emails to the console.
```toml
[email]
provider = "console"
```
**Features:**
- No external dependencies
- Immediate feedback
- Safe for development
### SMTP Provider
Use any SMTP server including Gmail, Outlook, or custom servers.
```toml
[email]
provider = "smtp"
smtp_host = "smtp.gmail.com"
smtp_port = 587
smtp_username = "your-email@gmail.com"
smtp_password = "@encrypted_smtp_password"
smtp_use_starttls = true
```
**Common SMTP Configurations:**
**Gmail:**
```toml
smtp_host = "smtp.gmail.com"
smtp_port = 587
smtp_use_starttls = true
# Requires App Password (not regular password)
```
**Outlook:**
```toml
smtp_host = "smtp-mail.outlook.com"
smtp_port = 587
smtp_use_starttls = true
```
**Custom SMTP:**
```toml
smtp_host = "mail.yourserver.com"
smtp_port = 587
smtp_use_starttls = true
```
### SendGrid Provider
Use SendGrid's API for reliable email delivery.
```toml
[email]
provider = "sendgrid"
sendgrid_api_key = "@encrypted_sendgrid_api_key"
```
**Features:**
- High deliverability
- Built-in analytics
- Bounce handling
- Reliable service
## Templates
### Template Structure
```
templates/email/
├── html/
│ ├── contact.hbs
│ ├── support.hbs
│ ├── welcome.hbs
│ └── notification.hbs
└── text/
├── contact.hbs
├── support.hbs
├── welcome.hbs
└── notification.hbs
```
### Template Naming
- `contact.hbs` - Contact form emails
- `support.hbs` - Support form emails
- `welcome.hbs` - Welcome/registration emails
- `notification.hbs` - General notifications
### Handlebars Helpers
Built-in helpers for common email tasks:
- `{{format_date}}` - Format dates
- `{{format_currency}}` - Format money
- `{{upper}}` - Uppercase text
- `{{lower}}` - Lowercase text
- `{{capitalize}}` - Capitalize words
### Example Template
**templates/email/html/contact.hbs:**
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Contact Form Submission</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
.header { background-color: #f8f9fa; padding: 20px; border-radius: 8px; }
.content { margin: 20px 0; }
.footer { color: #666; font-size: 12px; }
</style>
</head>
<body>
<div class="header">
<h1>New Contact Form Submission</h1>
</div>
<div class="content">
<p><strong>Name:</strong> {{name}}</p>
<p><strong>Email:</strong> {{email}}</p>
<p><strong>Subject:</strong> {{subject}}</p>
<p><strong>Message:</strong></p>
<p>{{message}}</p>
</div>
<div class="footer">
<p>Sent at {{format_date timestamp}}</p>
</div>
</body>
</html>
```
**templates/email/text/contact.hbs:**
```text
New Contact Form Submission
Name: {{name}}
Email: {{email}}
Subject: {{subject}}
Message:
{{message}}
Sent at {{format_date timestamp}}
```
## API Endpoints
### GET /api/email/status
Check email system status.
**Response:**
```json
{
"enabled": true,
"provider": "smtp",
"configured": true,
"templates": ["contact", "support", "welcome", "notification"]
}
```
### POST /api/email/contact
Send a contact form email.
**Request:**
```json
{
"name": "John Doe",
"email": "john@example.com",
"subject": "Question about pricing",
"message": "I'd like to know more about your pricing plans.",
"recipient": "admin@yourapp.com"
}
```
**Response:**
```json
{
"message": "Email sent successfully",
"message_id": "abc123def456",
"status": "sent"
}
```
### POST /api/email/support
Send a support form email with priority.
**Request:**
```json
{
"name": "Jane Smith",
"email": "jane@example.com",
"subject": "Technical Issue",
"message": "Having trouble with login functionality.",
"priority": "high",
"category": "technical",
"recipient": "support@yourapp.com"
}
```
### POST /api/email/send
Send a template-based email.
**Request:**
```json
{
"to": "user@example.com",
"subject": "Welcome to Our Platform",
"template": "welcome",
"template_data": {
"user_name": "John Doe",
"activation_link": "https://yourapp.com/activate/token123"
}
}
```
### POST /api/email/notification
Send a notification email.
**Request:**
```json
{
"to": "user@example.com",
"title": "Important Update",
"message": "Your account has been updated successfully.",
"content": "Additional details about the update..."
}
```
## Client Components
### ContactForm Component
```rust
#[component]
pub fn ContactForm() -> impl IntoView {
let (form_data, set_form_data) = create_signal(ContactFormData::default());
let (is_submitting, set_is_submitting) = create_signal(false);
let (message, set_message) = create_signal(String::new());
let submit_form = create_action(move |data: &ContactFormData| {
let data = data.clone();
async move {
set_is_submitting(true);
let result = send_contact_form(data).await;
set_is_submitting(false);
match result {
Ok(_) => set_message("Thank you for your message! We'll get back to you soon.".to_string()),
Err(e) => set_message(format!("Error sending message: {}", e)),
}
}
});
view! {
<div class="contact-form">
<h2>"Contact Us"</h2>
<form on:submit=move |ev| {
ev.prevent_default();
submit_form.dispatch(form_data.get());
}>
<div class="form-group">
<label for="name">"Name"</label>
<input
type="text"
id="name"
required
on:input=move |ev| {
set_form_data.update(|data| data.name = event_target_value(&ev));
}
/>
</div>
<div class="form-group">
<label for="email">"Email"</label>
<input
type="email"
id="email"
required
on:input=move |ev| {
set_form_data.update(|data| data.email = event_target_value(&ev));
}
/>
</div>
<div class="form-group">
<label for="subject">"Subject"</label>
<input
type="text"
id="subject"
required
on:input=move |ev| {
set_form_data.update(|data| data.subject = event_target_value(&ev));
}
/>
</div>
<div class="form-group">
<label for="message">"Message"</label>
<textarea
id="message"
required
on:input=move |ev| {
set_form_data.update(|data| data.message = event_target_value(&ev));
}
></textarea>
</div>
<button type="submit" disabled=move || is_submitting.get()>
{move || if is_submitting.get() { "Sending..." } else { "Send Message" }}
</button>
</form>
<Show when=move || !message.get().is_empty()>
<div class="message">{move || message.get()}</div>
</Show>
</div>
}
}
```
### SupportForm Component
```rust
#[component]
pub fn SupportForm() -> impl IntoView {
let (form_data, set_form_data) = create_signal(SupportFormData::default());
let (is_submitting, set_is_submitting) = create_signal(false);
let (message, set_message) = create_signal(String::new());
let submit_form = create_action(move |data: &SupportFormData| {
let data = data.clone();
async move {
set_is_submitting(true);
let result = send_support_form(data).await;
set_is_submitting(false);
match result {
Ok(_) => set_message("Support ticket submitted successfully!".to_string()),
Err(e) => set_message(format!("Error submitting ticket: {}", e)),
}
}
});
view! {
<div class="support-form">
<h2>"Support Request"</h2>
<form on:submit=move |ev| {
ev.prevent_default();
submit_form.dispatch(form_data.get());
}>
// Similar form fields with priority selector
<div class="form-group">
<label for="priority">"Priority"</label>
<select
id="priority"
on:change=move |ev| {
set_form_data.update(|data| data.priority = event_target_value(&ev));
}
>
<option value="low">"Low"</option>
<option value="medium">"Medium"</option>
<option value="high">"High"</option>
<option value="urgent">"Urgent"</option>
</select>
</div>
<button type="submit" disabled=move || is_submitting.get()>
{move || if is_submitting.get() { "Submitting..." } else { "Submit Ticket" }}
</button>
</form>
</div>
}
}
```
## Server Usage
### Basic Email Sending
```rust
use server::email::{EmailService, EmailConfig};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = EmailConfig::from_file("config.toml")?;
let email_service = EmailService::new(config).await?;
// Send simple email
email_service.send_simple_email(
"user@example.com",
"Welcome!",
"Thank you for signing up!"
).await?;
Ok(())
}
```
### Template-Based Emails
```rust
use std::collections::HashMap;
#[server(SendWelcomeEmail, "/api/email/welcome")]
pub async fn send_welcome_email(
email: String,
name: String,
activation_token: String,
) -> Result<String, ServerFnError> {
let email_service = get_email_service().await?;
let mut template_data = HashMap::new();
template_data.insert("user_name".to_string(), name);
template_data.insert("activation_link".to_string(),
format!("https://yourapp.com/activate/{}", activation_token));
email_service.send_template_email(
&email,
"Welcome to Our Platform",
"welcome",
template_data
).await?;
Ok("Welcome email sent successfully".to_string())
}
```
### Form Handling
```rust
#[server(HandleContactForm, "/api/email/contact")]
pub async fn handle_contact_form(
name: String,
email: String,
subject: String,
message: String,
) -> Result<String, ServerFnError> {
let email_service = get_email_service().await?;
// Validate input
if name.is_empty() || email.is_empty() || message.is_empty() {
return Err(ServerFnError::ServerError("All fields are required".to_string()));
}
// Send email
email_service.send_contact_form(
&name,
&email,
&subject,
&message,
"admin@yourapp.com"
).await?;
Ok("Contact form submitted successfully".to_string())
}
```
## Environment Variables
### Common Variables
```bash
# SMTP Configuration
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USERNAME=your-email@gmail.com
SMTP_PASSWORD=your-app-password
SMTP_USE_STARTTLS=true
# SendGrid Configuration
SENDGRID_API_KEY=your-sendgrid-api-key
# Email Settings
EMAIL_FROM=noreply@yourapp.com
EMAIL_FROM_NAME="Your App"
```
### Using in Configuration
```toml
[email]
smtp_username = "${SMTP_USERNAME}"
smtp_password = "@encrypted_smtp_password"
sendgrid_api_key = "@encrypted_sendgrid_api_key"
from_email = "${EMAIL_FROM}"
```
## Security Considerations
### 1. Credential Management
Always encrypt sensitive credentials:
```bash
# Encrypt SMTP password
cargo run --bin config_crypto_tool encrypt "your-smtp-password"
# Encrypt SendGrid API key
cargo run --bin config_crypto_tool encrypt "your-sendgrid-api-key"
```
### 2. Input Validation
Always validate email inputs:
```rust
use validator::{Validate, ValidationError};
#[derive(Validate)]
struct ContactFormData {
#[validate(length(min = 1, message = "Name is required"))]
name: String,
#[validate(email(message = "Invalid email address"))]
email: String,
#[validate(length(min = 1, max = 1000, message = "Message must be between 1 and 1000 characters"))]
message: String,
}
```
### 3. Rate Limiting
Implement rate limiting for email endpoints:
```rust
use tower_governor::{governor::GovernorLayer, GovernorConfigBuilder};
// Limit to 5 emails per minute per IP
let governor_config = GovernorConfigBuilder::default()
.per_minute(5)
.burst_size(2)
.finish()
.unwrap();
let governor_layer = GovernorLayer {
config: Arc::new(governor_config),
};
```
### 4. CSRF Protection
Enable CSRF protection for email forms:
```rust
use axum_csrf::{CsrfConfig, CsrfLayer};
let csrf_config = CsrfConfig::default();
let csrf_layer = CsrfLayer::new(csrf_config);
```
## Troubleshooting
### Common Issues
**Email not sending:**
- Check provider configuration
- Verify credentials
- Check network connectivity
- Review email service logs
**Template not found:**
- Verify template directory path
- Check template file naming
- Ensure HTML and text versions exist
**Authentication failed:**
- For Gmail: Use App Password, not regular password
- For other providers: Check username/password
- Verify server and port settings
**Rate limiting:**
- Check provider limits
- Implement proper rate limiting
- Consider using queues for bulk emails
### Debug Mode
Enable debug logging to troubleshoot issues:
```toml
[logging]
level = "debug"
[email]
enabled = true
debug = true
```
## Best Practices
1. **Use encrypted configuration** for sensitive credentials
2. **Implement proper validation** for all email inputs
3. **Use rate limiting** to prevent abuse
4. **Provide both HTML and text** versions of templates
5. **Test with console provider** during development
6. **Monitor email delivery** in production
7. **Handle errors gracefully** with user-friendly messages
8. **Use meaningful subject lines** and sender names
## Next Steps
- [API Reference](../../api/email.md)
- [Security Best Practices](../../security/best-practices.md)
- [Configuration Guide](../../configuration/files.md)
- [Deployment Guide](../../deployment/production.md)
The email system provides a robust foundation for all your application's communication needs while maintaining security and reliability.

View File

@ -0,0 +1 @@
# Template Engine

View File

@ -0,0 +1 @@
# Adding New Features

View File

@ -0,0 +1 @@
# API Endpoints

View File

@ -0,0 +1 @@
# Feature Flags & Modules

View File

@ -0,0 +1 @@
# Frontend Components

View File

@ -0,0 +1,867 @@
# Database Migrations
<div align="center">
<img src="../../../logos/rustelo_dev-logo-h.svg" alt="RUSTELO" width="300" />
</div>
This guide covers database migrations in RUSTELO, including the database-agnostic migration system and how to migrate from legacy PostgreSQL-only code to the new multi-database architecture.
## Overview
RUSTELO has been upgraded to use a **database-agnostic architecture** that supports both PostgreSQL and SQLite. This guide covers:
- Database migration patterns and best practices
- Migrating from PostgreSQL-only to database-agnostic code
- Writing database-specific migration files
- Handling data type differences between databases
- Testing migration strategies
## Migration Architecture
### Before (Legacy PostgreSQL-Only)
```rust
// Direct PostgreSQL dependency
use sqlx::PgPool;
// Repository tied to PostgreSQL
pub struct AuthRepository {
pool: PgPool,
}
impl AuthRepository {
pub fn new(pool: PgPool) -> Self {
Self { pool }
}
pub async fn find_user(&self, id: Uuid) -> Result<Option<User>> {
sqlx::query_as!(User, "SELECT * FROM users WHERE id = $1", id)
.fetch_optional(&self.pool)
.await
}
}
```
### After (Database-Agnostic)
```rust
// Database-agnostic abstractions
use crate::database::{DatabaseConnection, DatabaseType};
// Repository works with any database
pub struct AuthRepository {
database: DatabaseConnection,
}
impl AuthRepository {
pub fn new(database: DatabaseConnection) -> Self {
Self { database }
}
pub async fn find_user(&self, id: Uuid) -> Result<Option<User>> {
match self.database.database_type() {
DatabaseType::PostgreSQL => self.find_user_postgres(id).await,
DatabaseType::SQLite => self.find_user_sqlite(id).await,
}
}
async fn find_user_postgres(&self, id: Uuid) -> Result<Option<User>> {
let row = self.database
.fetch_optional(
"SELECT * FROM users WHERE id = $1",
&[id.into()],
)
.await?;
if let Some(row) = row {
Ok(Some(User {
id: row.get_uuid("id")?,
email: row.get_string("email")?,
username: row.get_string("username")?,
created_at: row.get_datetime("created_at")?,
}))
} else {
Ok(None)
}
}
async fn find_user_sqlite(&self, id: Uuid) -> Result<Option<User>> {
let row = self.database
.fetch_optional(
"SELECT * FROM users WHERE id = ?",
&[id.to_string().into()],
)
.await?;
if let Some(row) = row {
Ok(Some(User {
id: row.get_uuid("id")?,
email: row.get_string("email")?,
username: row.get_string("username")?,
created_at: row.get_datetime("created_at")?,
}))
} else {
Ok(None)
}
}
}
```
## Migration Steps
### 1. Update Repository Constructors
**Before:**
```rust
let auth_repository = Arc::new(AuthRepository::new(pool.clone()));
```
**After:**
```rust
// For the new database-agnostic repositories
let auth_repository = Arc::new(database::auth::AuthRepository::new(database.clone()));
// Or create from pool
let auth_repository = Arc::new(database::auth::AuthRepository::from_pool(&database_pool));
```
### 2. Replace Direct SQL Queries
**Before:**
```rust
pub async fn create_user(&self, user: &User) -> Result<()> {
sqlx::query!(
"INSERT INTO users (id, email, username) VALUES ($1, $2, $3)",
user.id,
user.email,
user.username
)
.execute(&self.pool)
.await?;
Ok(())
}
```
**After:**
```rust
pub async fn create_user(&self, user: &User) -> Result<()> {
match self.database.database_type() {
DatabaseType::PostgreSQL => self.create_user_postgres(user).await,
DatabaseType::SQLite => self.create_user_sqlite(user).await,
}
}
async fn create_user_postgres(&self, user: &User) -> Result<()> {
self.database
.execute(
"INSERT INTO users (id, email, username) VALUES ($1, $2, $3)",
&[
user.id.into(),
user.email.clone().into(),
user.username.clone().into(),
],
)
.await?;
Ok(())
}
async fn create_user_sqlite(&self, user: &User) -> Result<()> {
self.database
.execute(
"INSERT INTO users (id, email, username) VALUES (?, ?, ?)",
&[
user.id.to_string().into(),
user.email.clone().into(),
user.username.clone().into(),
],
)
.await?;
Ok(())
}
```
### 3. Update Row Processing
**Before:**
```rust
let row = sqlx::query_as::<_, UserRow>("SELECT * FROM users WHERE id = $1")
.bind(id)
.fetch_optional(&self.pool)
.await?;
```
**After:**
```rust
let row = self.database
.fetch_optional(
"SELECT * FROM users WHERE id = $1", // PostgreSQL
&[id.into()],
)
.await?;
if let Some(row) = row {
let user = User {
id: row.get_uuid("id")?,
email: row.get_string("email")?,
username: row.get_string("username")?,
created_at: row.get_datetime("created_at")?,
};
}
```
### 4. Database Initialization
**Before:**
```rust
let pool = PgPool::connect(&database_url).await?;
let auth_repository = AuthRepository::new(pool);
```
**After:**
```rust
let database_config = DatabaseConfig {
url: database_url.to_string(),
max_connections: 10,
min_connections: 1,
connect_timeout: Duration::from_secs(30),
idle_timeout: Duration::from_secs(600),
max_lifetime: Duration::from_secs(3600),
};
let database_pool = DatabasePool::new(&database_config).await?;
let database = Database::new(database_pool.clone());
let auth_repository = database::auth::AuthRepository::new(database.create_connection());
```
## Database-Specific Considerations
### PostgreSQL vs SQLite Differences
| Feature | PostgreSQL | SQLite |
|---------|------------|--------|
| **Parameter Binding** | `$1, $2, $3` | `?, ?, ?` |
| **UUID Storage** | Native `UUID` type | `TEXT` (string) |
| **Timestamps** | `TIMESTAMP WITH TIME ZONE` | `TEXT` (ISO 8601) |
| **JSON** | `JSONB` | `TEXT` (JSON string) |
| **Arrays** | Native arrays | `TEXT` (JSON array) |
| **Boolean** | `BOOLEAN` | `INTEGER` (0/1) |
### Handling Data Type Differences
```rust
// UUID handling
match self.database.database_type() {
DatabaseType::PostgreSQL => {
// PostgreSQL stores UUIDs natively
params.push(user_id.into());
}
DatabaseType::SQLite => {
// SQLite stores UUIDs as strings
params.push(user_id.to_string().into());
}
}
// Timestamp handling
match self.database.database_type() {
DatabaseType::PostgreSQL => {
// PostgreSQL stores timestamps natively
params.push(created_at.into());
}
DatabaseType::SQLite => {
// SQLite stores timestamps as ISO strings
params.push(created_at.to_rfc3339().into());
}
}
// JSON handling
match self.database.database_type() {
DatabaseType::PostgreSQL => {
// PostgreSQL supports native JSONB
params.push(serde_json::to_value(&data)?.into());
}
DatabaseType::SQLite => {
// SQLite stores JSON as text
params.push(serde_json::to_string(&data)?.into());
}
}
```
## Database Migration Files
### Migration File Structure
```
migrations/
├── 001_create_users/
│ ├── up_postgres.sql
│ ├── down_postgres.sql
│ ├── up_sqlite.sql
│ └── down_sqlite.sql
├── 002_add_2fa_support/
│ ├── up_postgres.sql
│ ├── down_postgres.sql
│ ├── up_sqlite.sql
│ └── down_sqlite.sql
└── 003_create_posts/
├── up_postgres.sql
├── down_postgres.sql
├── up_sqlite.sql
└── down_sqlite.sql
```
### Example Migration Files
**PostgreSQL Migration (001_create_users/up_postgres.sql):**
```sql
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
email VARCHAR(255) UNIQUE NOT NULL,
username VARCHAR(100) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
email_verified BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_username ON users(username);
```
**SQLite Migration (001_create_users/up_sqlite.sql):**
```sql
CREATE TABLE users (
id TEXT PRIMARY KEY,
email TEXT UNIQUE NOT NULL,
username TEXT UNIQUE NOT NULL,
password_hash TEXT NOT NULL,
email_verified INTEGER DEFAULT 0,
created_at TEXT DEFAULT (datetime('now')),
updated_at TEXT DEFAULT (datetime('now'))
);
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_username ON users(username);
```
### Running Migrations
```bash
# Run migrations for PostgreSQL
cargo run --bin migrate -- --database-url "postgresql://user:pass@localhost/db"
# Run migrations for SQLite
cargo run --bin migrate -- --database-url "sqlite//:database.db"
# Roll back migrations
cargo run --bin migrate -- --database-url "sqlite//:database.db" --rollback
# Check migration status
cargo run --bin migrate -- --database-url "sqlite//:database.db" --status
```
## Migration Patterns
### Pattern 1: Simple Repository Migration
```rust
// Old
pub struct MyRepository {
pool: PgPool,
}
// New
pub struct MyRepository {
database: DatabaseConnection,
}
impl MyRepository {
pub fn new(database: DatabaseConnection) -> Self {
Self { database }
}
// Add convenience constructor
pub fn from_pool(pool: &DatabasePool) -> Self {
let connection = DatabaseConnection::from_pool(pool);
Self::new(connection)
}
}
```
### Pattern 2: Complex Query Migration
```rust
// Old
pub async fn complex_query(&self) -> Result<Vec<Item>> {
sqlx::query_as!(
Item,
r#"
SELECT i.*, u.username
FROM items i
JOIN users u ON i.user_id = u.id
WHERE i.created_at > $1
ORDER BY i.created_at DESC
"#,
since
)
.fetch_all(&self.pool)
.await
}
// New
pub async fn complex_query(&self, since: DateTime<Utc>) -> Result<Vec<Item>> {
match self.database.database_type() {
DatabaseType::PostgreSQL => self.complex_query_postgres(since).await,
DatabaseType::SQLite => self.complex_query_sqlite(since).await,
}
}
async fn complex_query_postgres(&self, since: DateTime<Utc>) -> Result<Vec<Item>> {
let rows = self.database
.fetch_all(
r#"
SELECT i.id, i.name, i.user_id, i.created_at, u.username
FROM items i
JOIN users u ON i.user_id = u.id
WHERE i.created_at > $1
ORDER BY i.created_at DESC
"#,
&[since.into()],
)
.await?;
self.rows_to_items(rows)
}
async fn complex_query_sqlite(&self, since: DateTime<Utc>) -> Result<Vec<Item>> {
let rows = self.database
.fetch_all(
r#"
SELECT i.id, i.name, i.user_id, i.created_at, u.username
FROM items i
JOIN users u ON i.user_id = u.id
WHERE i.created_at > ?
ORDER BY i.created_at DESC
"#,
&[since.to_rfc3339().into()],
)
.await?;
self.rows_to_items(rows)
}
fn rows_to_items(&self, rows: Vec<DatabaseRow>) -> Result<Vec<Item>> {
let mut items = Vec::new();
for row in rows {
items.push(Item {
id: row.get_uuid("id")?,
name: row.get_string("name")?,
user_id: row.get_uuid("user_id")?,
username: row.get_string("username")?,
created_at: row.get_datetime("created_at")?,
});
}
Ok(items)
}
```
### Pattern 3: Transaction Handling
```rust
pub async fn create_user_with_profile(&self, user: &User, profile: &Profile) -> Result<()> {
match self.database.database_type() {
DatabaseType::PostgreSQL => {
self.create_user_with_profile_postgres(user, profile).await
}
DatabaseType::SQLite => {
self.create_user_with_profile_sqlite(user, profile).await
}
}
}
async fn create_user_with_profile_postgres(&self, user: &User, profile: &Profile) -> Result<()> {
let mut tx = self.database.begin().await?;
// Create user
tx.execute(
"INSERT INTO users (id, email, username) VALUES ($1, $2, $3)",
&[user.id.into(), user.email.clone().into(), user.username.clone().into()],
).await?;
// Create profile
tx.execute(
"INSERT INTO profiles (user_id, first_name, last_name) VALUES ($1, $2, $3)",
&[profile.user_id.into(), profile.first_name.clone().into(), profile.last_name.clone().into()],
).await?;
tx.commit().await?;
Ok(())
}
async fn create_user_with_profile_sqlite(&self, user: &User, profile: &Profile) -> Result<()> {
let mut tx = self.database.begin().await?;
// Create user
tx.execute(
"INSERT INTO users (id, email, username) VALUES (?, ?, ?)",
&[user.id.to_string().into(), user.email.clone().into(), user.username.clone().into()],
).await?;
// Create profile
tx.execute(
"INSERT INTO profiles (user_id, first_name, last_name) VALUES (?, ?, ?)",
&[profile.user_id.to_string().into(), profile.first_name.clone().into(), profile.last_name.clone().into()],
).await?;
tx.commit().await?;
Ok(())
}
```
## Migration Checklist
### Code Migration
- [ ] Replace `PgPool` with `DatabaseConnection`
- [ ] Update repository constructors
- [ ] Split database operations into database-specific methods
- [ ] Handle parameter binding differences (`$1` vs `?`)
- [ ] Handle data type differences (UUID, timestamps, etc.)
- [ ] Update imports to use new database modules
- [ ] Add convenience constructors (`from_pool`)
- [ ] Update error handling
### Database Migration Files
- [ ] Create separate migration files for PostgreSQL (`*_postgres.sql`)
- [ ] Create separate migration files for SQLite (`*_sqlite.sql`)
- [ ] Update migration runner configuration
- [ ] Test migrations on both database types
- [ ] Add rollback migrations
- [ ] Document migration dependencies
### Configuration
- [ ] Update environment variables
- [ ] Test with different database URLs
- [ ] Update deployment scripts
- [ ] Update documentation
- [ ] Configure connection pooling
- [ ] Set appropriate timeouts
### Testing
- [ ] Update unit tests to use new abstractions
- [ ] Add integration tests for both database types
- [ ] Test migration path from old to new architecture
- [ ] Performance testing on both databases
- [ ] Test rollback scenarios
- [ ] Add database-specific test fixtures
## Troubleshooting
### Common Issues and Solutions
#### 1. UUID Conversion Errors
**Problem:** SQLite doesn't support UUID natively
**Solution:** Convert UUIDs to strings for SQLite
```rust
match self.database.database_type() {
DatabaseType::PostgreSQL => params.push(uuid.into()),
DatabaseType::SQLite => params.push(uuid.to_string().into()),
}
```
#### 2. Parameter Binding Mismatch
**Problem:** Using PostgreSQL syntax (`$1`) with SQLite
**Solution:** Use database-specific query strings
```rust
let query = match self.database.database_type() {
DatabaseType::PostgreSQL => "SELECT * FROM users WHERE id = $1",
DatabaseType::SQLite => "SELECT * FROM users WHERE id = ?",
};
```
#### 3. Migration File Not Found
**Problem:** Missing database-specific migration files
**Solution:** Ensure both `*_postgres.sql` and `*_sqlite.sql` files exist
#### 4. Type Conversion Errors
**Problem:** Data type mismatches between databases
**Solution:** Use the `DatabaseRow` trait methods consistently
```rust
// Always use the trait methods
let user_id = row.get_uuid("user_id")?; // Handles conversion automatically
let created_at = row.get_datetime("created_at")?; // Handles conversion automatically
```
#### 5. Connection Pool Issues
**Problem:** Connection pool exhaustion or configuration issues
**Solution:** Properly configure connection pool settings
```rust
let database_config = DatabaseConfig {
url: database_url.to_string(),
max_connections: 10,
min_connections: 1,
connect_timeout: Duration::from_secs(30),
idle_timeout: Duration::from_secs(600),
max_lifetime: Duration::from_secs(3600),
};
```
## Best Practices
### 1. Database-Agnostic Design
- Write repositories that work with both databases
- Use the database abstraction layer consistently
- Avoid database-specific features when possible
- Test with both databases regularly
### 2. Migration Strategy
- Migrate one module at a time
- Test thoroughly with both database types
- Keep the old code until migration is complete
- Document the migration process
### 3. Performance Considerations
- PostgreSQL: Better for complex queries and large datasets
- SQLite: Better for simple queries and small datasets
- Use appropriate database features for your use case
- Monitor query performance on both databases
### 4. Testing Strategy
- Test all code paths with both databases
- Use SQLite for fast unit tests
- Use PostgreSQL for integration tests
- Test migration rollbacks
- Use database-specific test fixtures
### 5. Error Handling
- Handle database-specific errors appropriately
- Use consistent error types across databases
- Log database operations for debugging
- Provide meaningful error messages
## Example: Complete Repository Migration
Here's a complete example of migrating a repository from PostgreSQL-only to database-agnostic:
### Before (PostgreSQL-Only)
```rust
use sqlx::PgPool;
use uuid::Uuid;
use chrono::{DateTime, Utc};
pub struct PostRepository {
pool: PgPool,
}
impl PostRepository {
pub fn new(pool: PgPool) -> Self {
Self { pool }
}
pub async fn create_post(&self, post: &Post) -> Result<()> {
sqlx::query!(
"INSERT INTO posts (id, title, content, author_id, published) VALUES ($1, $2, $3, $4, $5)",
post.id,
post.title,
post.content,
post.author_id,
post.published
)
.execute(&self.pool)
.await?;
Ok(())
}
pub async fn find_post(&self, id: Uuid) -> Result<Option<Post>> {
let row = sqlx::query_as!(
Post,
"SELECT id, title, content, author_id, published, created_at FROM posts WHERE id = $1",
id
)
.fetch_optional(&self.pool)
.await?;
Ok(row)
}
pub async fn find_posts_by_author(&self, author_id: Uuid) -> Result<Vec<Post>> {
let rows = sqlx::query_as!(
Post,
"SELECT id, title, content, author_id, published, created_at FROM posts WHERE author_id = $1 ORDER BY created_at DESC",
author_id
)
.fetch_all(&self.pool)
.await?;
Ok(rows)
}
}
```
### After (Database-Agnostic)
```rust
use crate::database::{DatabaseConnection, DatabaseType, DatabaseRow};
use uuid::Uuid;
use chrono::{DateTime, Utc};
pub struct PostRepository {
database: DatabaseConnection,
}
impl PostRepository {
pub fn new(database: DatabaseConnection) -> Self {
Self { database }
}
pub fn from_pool(pool: &crate::database::DatabasePool) -> Self {
let connection = DatabaseConnection::from_pool(pool);
Self::new(connection)
}
pub async fn create_post(&self, post: &Post) -> Result<()> {
match self.database.database_type() {
DatabaseType::PostgreSQL => self.create_post_postgres(post).await,
DatabaseType::SQLite => self.create_post_sqlite(post).await,
}
}
async fn create_post_postgres(&self, post: &Post) -> Result<()> {
self.database
.execute(
"INSERT INTO posts (id, title, content, author_id, published) VALUES ($1, $2, $3, $4, $5)",
&[
post.id.into(),
post.title.clone().into(),
post.content.clone().into(),
post.author_id.into(),
post.published.into(),
],
)
.await?;
Ok(())
}
async fn create_post_sqlite(&self, post: &Post) -> Result<()> {
self.database
.execute(
"INSERT INTO posts (id, title, content, author_id, published) VALUES (?, ?, ?, ?, ?)",
&[
post.id.to_string().into(),
post.title.clone().into(),
post.content.clone().into(),
post.author_id.to_string().into(),
(post.published as i32).into(),
],
)
.await?;
Ok(())
}
pub async fn find_post(&self, id: Uuid) -> Result<Option<Post>> {
match self.database.database_type() {
DatabaseType::PostgreSQL => self.find_post_postgres(id).await,
DatabaseType::SQLite => self.find_post_sqlite(id).await,
}
}
async fn find_post_postgres(&self, id: Uuid) -> Result<Option<Post>> {
let row = self
.database
.fetch_optional(
"SELECT id, title, content, author_id, published, created_at FROM posts WHERE id = $1",
&[id.into()],
)
.await?;
self.row_to_post(row)
}
async fn find_post_sqlite(&self, id: Uuid) -> Result<Option<Post>> {
let row = self
.database
.fetch_optional(
"SELECT id, title, content, author_id, published, created_at FROM posts WHERE id = ?",
&[id.to_string().into()],
)
.await?;
self.row_to_post(row)
}
pub async fn find_posts_by_author(&self, author_id: Uuid) -> Result<Vec<Post>> {
match self.database.database_type() {
DatabaseType::PostgreSQL => self.find_posts_by_author_postgres(author_id).await,
DatabaseType::SQLite => self.find_posts_by_author_sqlite(author_id).await,
}
}
async fn find_posts_by_author_postgres(&self, author_id: Uuid) -> Result<Vec<Post>> {
let rows = self
.database
.fetch_all(
"SELECT id, title, content, author_id, published, created_at FROM posts WHERE author_id = $1 ORDER BY created_at DESC",
&[author_id.into()],
)
.await?;
self.rows_to_posts(rows)
}
async fn find_posts_by_author_sqlite(&self, author_id: Uuid) -> Result<Vec<Post>> {
let rows = self
.database
.fetch_all(
"SELECT id, title, content, author_id, published, created_at FROM posts WHERE author_id = ? ORDER BY created_at DESC",
&[author_id.to_string().into()],
)
.await?;
self.rows_to_posts(rows)
}
fn row_to_post(&self, row: Option<DatabaseRow>) -> Result<Option<Post>> {
if let Some(row) = row {
Ok(Some(Post {
id: row.get_uuid("id")?,
title: row.get_string("title")?,
content: row.get_string("content")?,
author_id: row.get_uuid("author_id")?,
published: row.get_bool("published")?,
created_at: row.get_datetime("created_at")?,
}))
} else {
Ok(None)
}
}
fn rows_to_posts(&self, rows: Vec<DatabaseRow>) -> Result<Vec<Post>> {
let mut posts = Vec::new();
for row in rows {
posts.push(Post {
id: row.get_uuid("id")?,
title: row.get_string("title")?,
content: row.get_string("content")?,
author_id: row.get_uuid("author_id")?,
published: row.get_bool("published")?,
created_at: row.get_datetime("created_at")?,
});
}
Ok(posts)
}
}
```
## Next Steps
- [Database Configuration](../../configuration/database.md)
- [Performance Optimization](../../performance/database.md)
- [Testing Strategies](../testing/strategy.md)
- [Deployment Guide](../../deployment/production.md)
This migration guide provides a comprehensive approach to transitioning from PostgreSQL-only to database-agnostic architecture while maintaining functionality and performance across both database systems.

View File

@ -0,0 +1 @@
# Build System & Tools

View File

@ -0,0 +1 @@
# Development Environment

View File

@ -0,0 +1 @@
# Project Structure

View File

@ -0,0 +1 @@
# Development Workflow

View File

@ -0,0 +1 @@
# End-to-End Testing

View File

@ -0,0 +1 @@
# Integration Testing

View File

@ -0,0 +1 @@
# Performance Testing

View File

@ -0,0 +1 @@
# Testing Strategy

View File

@ -0,0 +1 @@
# Unit Testing

View File

View File

View File

View File

View File

View File

361
book/features/auth/2fa.md Normal file
View File

@ -0,0 +1,361 @@
# Two-Factor Authentication (2FA) Implementation
<div align="center">
<img src="../logos/rustelo_dev-logo-h.svg" alt="RUSTELO" width="300" />
</div>
This document describes the implementation of Time-based One-Time Password (TOTP) two-factor authentication in the Rustelo application.
## Overview
The 2FA implementation provides an additional layer of security for user accounts by requiring a second form of authentication beyond username and password. This implementation uses TOTP (Time-based One-Time Password) compatible with popular authenticator apps like Google Authenticator, Authy, and Microsoft Authenticator.
## Features
- **TOTP Authentication**: Standards-compliant TOTP implementation (RFC 6238)
- **QR Code Generation**: Automatic QR code generation for easy setup
- **Backup Codes**: Recovery codes for account access if authenticator device is lost
- **Rate Limiting**: Protection against brute force attacks
- **Audit Trail**: Logging of 2FA attempts for security monitoring
- **Graceful Degradation**: Existing users can continue using the system without 2FA until they opt-in
## Architecture
### Backend Components
#### Database Schema
- `user_2fa`: Stores TOTP secrets and configuration
- `user_2fa_recovery_codes`: Individual recovery codes for better tracking
- `user_2fa_attempts`: Audit trail of authentication attempts
- `users`: Extended with `two_factor_required` flag
- `sessions`: Extended with `two_factor_verified` flag
#### Core Services
- `TwoFactorService`: Main 2FA business logic
- `AuthService`: Extended to handle 2FA login flow
- `AuthRepository`: Database operations for user management
#### API Endpoints
- `POST /api/auth/login`: First step login (returns 2FA requirement)
- `POST /api/auth/login/2fa`: Second step login with 2FA code
- `POST /api/auth/2fa/setup`: Initialize 2FA setup
- `POST /api/auth/2fa/verify`: Verify and enable 2FA
- `GET /api/auth/2fa/status`: Get current 2FA status
- `POST /api/auth/2fa/disable`: Disable 2FA
- `POST /api/auth/2fa/backup-codes`: Generate new backup codes
### Frontend Components
#### React Components
- `TwoFactorSetup`: Complete 2FA setup flow
- `TwoFactorLoginForm`: 2FA code input during login
- `TwoFactorLoginPage`: Full page 2FA login
- `GenerateBackupCodesComponent`: Backup code management
- `DisableTwoFactorComponent`: 2FA disabling interface
#### Auth Context
- Extended `AuthContext` to handle 2FA states
- `requires_2fa` flag to track 2FA requirement
- `pending_2fa_email` to store email during 2FA flow
## Setup Process
### 1. User Initiates 2FA Setup
```rust
POST /api/auth/2fa/setup
{
"password": "current_password"
}
```
### 2. Server Response
```json
{
"success": true,
"data": {
"secret": "BASE32_ENCODED_SECRET",
"qr_code_url": "data:image/svg+xml;base64,QR_CODE_DATA",
"backup_codes": ["12345678", "87654321", ...]
}
}
```
### 3. User Scans QR Code
- User scans QR code with authenticator app
- Alternatively, manually enters the secret key
### 4. User Verifies Setup
```rust
POST /api/auth/2fa/verify
{
"code": "123456"
}
```
### 5. 2FA Enabled
- TOTP verification successful
- 2FA is now enabled for the account
- Backup codes are active
## Login Flow
### 1. Standard Login
```rust
POST /api/auth/login
{
"email": "user@example.com",
"password": "password",
"remember_me": false
}
```
### 2. 2FA Required Response
```json
{
"success": true,
"data": {
"user": { ... },
"access_token": "",
"requires_2fa": true
}
}
```
### 3. 2FA Code Submission
```rust
POST /api/auth/login/2fa
{
"email": "user@example.com",
"code": "123456",
"remember_me": false
}
```
### 4. Complete Authentication
```json
{
"success": true,
"data": {
"user": { ... },
"access_token": "JWT_TOKEN",
"refresh_token": "REFRESH_TOKEN",
"requires_2fa": false
}
}
```
## Security Features
### Rate Limiting
- Maximum 5 failed attempts per 15-minute window
- Prevents brute force attacks on 2FA codes
### Backup Codes
- 8-digit recovery codes
- Hashed storage in database
- Single-use only
- Can be regenerated
### Audit Trail
- All 2FA attempts are logged
- Includes IP address, user agent, and timestamp
- Distinguishes between TOTP and backup code usage
### Secret Management
- TOTP secrets are Base32 encoded
- Secrets are unique per user
- Secrets are generated using cryptographically secure random number generation
## Configuration
### Environment Variables
```env
# Database connection
DATABASE_URL=postgresql://localhost/rustelo_dev
# JWT configuration
JWT_SECRET=your_jwt_secret_key
JWT_EXPIRATION=3600
# Application settings
APP_NAME=Rustelo
ISSUER_NAME=Rustelo Authentication
```
### Dependencies
```toml
[dependencies]
# 2FA specific
totp-rs = "5.6"
qrcode = { version = "0.15", features = ["svg"] }
base32 = "0.5"
sha2 = "0.10"
base64 = "0.22"
```
## Usage Examples
### Enable 2FA for a User
```rust
// Setup 2FA
let request = Setup2FARequest {
password: "user_password".to_string(),
};
let response = auth_service.setup_2fa(user_id, request).await?;
// Verify and enable
let verify_request = Verify2FARequest {
code: "123456".to_string(),
};
auth_service.verify_2fa_setup(user_id, verify_request, None, None).await?;
```
### Login with 2FA
```rust
// First step: regular login
let login_request = LoginCredentials {
email: "user@example.com".to_string(),
password: "password".to_string(),
remember_me: false,
};
let response = auth_service.login(login_request, None).await?;
if response.requires_2fa {
// Second step: 2FA verification
let twofa_request = Login2FARequest {
email: "user@example.com".to_string(),
code: "123456".to_string(),
remember_me: false,
};
let final_response = auth_service.login_with_2fa(twofa_request, None, None, None).await?;
}
```
## Testing
### Unit Tests
```rust
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_2fa_setup() {
let service = TwoFactorService::new(pool, "Test".to_string(), "Test".to_string());
let response = service.setup_2fa(user_id, "user@test.com", request).await;
assert!(response.is_ok());
}
#[tokio::test]
async fn test_totp_verification() {
// Test TOTP code verification
let service = TwoFactorService::new(pool, "Test".to_string(), "Test".to_string());
let result = service.verify_2fa_for_login(user_id, "123456", None, None).await;
// Assert based on test conditions
}
}
```
### Integration Tests
```rust
#[tokio::test]
async fn test_full_2fa_flow() {
// Test complete 2FA setup and login flow
// 1. Setup 2FA
// 2. Verify setup
// 3. Login with 2FA
// 4. Verify successful authentication
}
```
## Migration Guide
### Database Migration
```sql
-- Run migration 002_add_2fa_support.sql
-- This adds all necessary 2FA tables and columns
```
### Existing Users
- Existing users can continue using the system without 2FA
- 2FA is opt-in for existing users
- `two_factor_enabled` field defaults to `false`
### Deployment Steps
1. Deploy database migration
2. Deploy backend code with 2FA support
3. Deploy frontend code with 2FA components
4. Update documentation and user guides
## Troubleshooting
### Common Issues
#### QR Code Not Displaying
- Check that SVG rendering is enabled
- Verify QR code generation dependencies
- Check browser console for errors
#### Invalid 2FA Code
- Ensure device time is synchronized
- Verify secret key entry
- Check for typos in manual entry
#### Backup Code Not Working
- Verify code hasn't been used before
- Check for typing errors
- Ensure user has remaining backup codes
### Debug Commands
```bash
# Check 2FA status for user
psql -d rustelo_dev -c "SELECT * FROM user_2fa WHERE user_id = 'USER_ID';"
# View recent 2FA attempts
psql -d rustelo_dev -c "SELECT * FROM user_2fa_attempts WHERE user_id = 'USER_ID' ORDER BY created_at DESC LIMIT 10;"
# Check backup codes
psql -d rustelo_dev -c "SELECT code_hash, used_at FROM user_2fa_recovery_codes WHERE user_id = 'USER_ID';"
```
## Security Considerations
### Best Practices
- Use HTTPS in production
- Implement proper session management
- Regular security audits
- Monitor 2FA attempt logs
- User education on 2FA security
### Compliance
- TOTP implementation follows RFC 6238
- Backup codes follow industry best practices
- Audit logging supports compliance requirements
## Future Enhancements
### Planned Features
- SMS-based 2FA as alternative
- Hardware security key support (WebAuthn)
- Admin-enforced 2FA policies
- Bulk 2FA management for organizations
- Advanced reporting and analytics
### Performance Optimizations
- Caching of 2FA status
- Async processing of audit logs
- Database query optimization
- CDN for QR code generation
## Support
For issues or questions regarding 2FA implementation:
1. Check this documentation
2. Review server logs
3. Check database state
4. Contact development team
---
Last Updated: 2024-01-XX
Version: 1.0.0

View File

View File

View File

View File

View File

View File

View File

View File

View File

Some files were not shown because too many files have changed in this diff Show More