Add authentication, user management, and database migration features
- Implement OAuth 2.0 and PAT authentication methods - Add user management, roles, and profile functionality - Add database migrations and admin user scripts - Update services for authentication and user settings - Add protected routes and permission hooks - Update documentation for authentication and database access
This commit is contained in:
141
docs/AUTHENTICATION-ENV-VARS.md
Normal file
141
docs/AUTHENTICATION-ENV-VARS.md
Normal file
@@ -0,0 +1,141 @@
|
||||
# Authentication System Environment Variables
|
||||
|
||||
This document describes the new environment variables required for the authentication and authorization system.
|
||||
|
||||
## Application Branding
|
||||
|
||||
```env
|
||||
# Application name displayed throughout the UI
|
||||
APP_NAME=CMDB Insight
|
||||
|
||||
# Application tagline/subtitle displayed in header and login pages
|
||||
APP_TAGLINE=Management console for Jira Assets
|
||||
|
||||
# Copyright text displayed in the footer (use {year} as placeholder for current year)
|
||||
APP_COPYRIGHT=© {year} Zuyderland Medisch Centrum
|
||||
```
|
||||
|
||||
**Note:** The `{year}` placeholder in `APP_COPYRIGHT` will be automatically replaced with the current year. If not set, defaults to `© {current_year} Zuyderland Medisch Centrum`.
|
||||
|
||||
## Email Configuration (Nodemailer)
|
||||
|
||||
```env
|
||||
# SMTP Configuration
|
||||
SMTP_HOST=smtp.example.com
|
||||
SMTP_PORT=587
|
||||
SMTP_SECURE=false
|
||||
SMTP_USER=your-email@example.com
|
||||
SMTP_PASSWORD=your-password
|
||||
SMTP_FROM=noreply@example.com
|
||||
```
|
||||
|
||||
## Encryption
|
||||
|
||||
```env
|
||||
# Encryption Key (32 bytes, base64 encoded)
|
||||
# Generate with: openssl rand -base64 32
|
||||
ENCRYPTION_KEY=your-32-byte-encryption-key-base64
|
||||
```
|
||||
|
||||
## Local Authentication
|
||||
|
||||
```env
|
||||
# Enable local authentication (email/password)
|
||||
LOCAL_AUTH_ENABLED=true
|
||||
|
||||
# Allow public registration (optional, default: false)
|
||||
REGISTRATION_ENABLED=false
|
||||
```
|
||||
|
||||
## Password Requirements
|
||||
|
||||
```env
|
||||
# Password minimum length
|
||||
PASSWORD_MIN_LENGTH=8
|
||||
|
||||
# Password complexity requirements
|
||||
PASSWORD_REQUIRE_UPPERCASE=true
|
||||
PASSWORD_REQUIRE_LOWERCASE=true
|
||||
PASSWORD_REQUIRE_NUMBER=true
|
||||
PASSWORD_REQUIRE_SPECIAL=false
|
||||
```
|
||||
|
||||
## Session Configuration
|
||||
|
||||
```env
|
||||
# Session duration in hours
|
||||
SESSION_DURATION_HOURS=24
|
||||
```
|
||||
|
||||
## Initial Admin User
|
||||
|
||||
```env
|
||||
# Create initial administrator user (optional)
|
||||
ADMIN_EMAIL=admin@example.com
|
||||
ADMIN_PASSWORD=SecurePassword123!
|
||||
ADMIN_USERNAME=admin
|
||||
ADMIN_DISPLAY_NAME=Administrator
|
||||
```
|
||||
|
||||
## Complete Example
|
||||
|
||||
```env
|
||||
# Email Configuration
|
||||
SMTP_HOST=smtp.gmail.com
|
||||
SMTP_PORT=587
|
||||
SMTP_SECURE=false
|
||||
SMTP_USER=your-email@gmail.com
|
||||
SMTP_PASSWORD=your-app-password
|
||||
SMTP_FROM=noreply@example.com
|
||||
|
||||
# Encryption
|
||||
ENCRYPTION_KEY=$(openssl rand -base64 32)
|
||||
|
||||
# Local Auth
|
||||
LOCAL_AUTH_ENABLED=true
|
||||
REGISTRATION_ENABLED=false
|
||||
|
||||
# Password Requirements
|
||||
PASSWORD_MIN_LENGTH=8
|
||||
PASSWORD_REQUIRE_UPPERCASE=true
|
||||
PASSWORD_REQUIRE_LOWERCASE=true
|
||||
PASSWORD_REQUIRE_NUMBER=true
|
||||
PASSWORD_REQUIRE_SPECIAL=false
|
||||
|
||||
# Session
|
||||
SESSION_DURATION_HOURS=24
|
||||
|
||||
# Initial Admin
|
||||
ADMIN_EMAIL=admin@example.com
|
||||
ADMIN_PASSWORD=ChangeMe123!
|
||||
ADMIN_USERNAME=admin
|
||||
ADMIN_DISPLAY_NAME=Administrator
|
||||
```
|
||||
|
||||
## Important Notes
|
||||
|
||||
### User-Specific Configuration (REMOVED from ENV)
|
||||
|
||||
The following environment variables have been **REMOVED** from the codebase and are **NOT** configurable via environment variables:
|
||||
|
||||
- `JIRA_PAT`: **Configure in User Settings > Jira PAT**
|
||||
- `ANTHROPIC_API_KEY`: **Configure in User Settings > AI Settings**
|
||||
- `OPENAI_API_KEY`: **Configure in User Settings > AI Settings**
|
||||
- `TAVILY_API_KEY`: **Configure in User Settings > AI Settings**
|
||||
|
||||
**These are now user-specific settings only.** Each user must configure their own API keys in their profile settings. This provides:
|
||||
- Better security (keys not in shared config files)
|
||||
- Per-user API key management
|
||||
- Individual rate limiting per user
|
||||
- Better audit trails
|
||||
- Encrypted storage in the database
|
||||
|
||||
### Required Configuration
|
||||
|
||||
- `SESSION_SECRET`: Should be a secure random string in production (generate with `openssl rand -base64 32`)
|
||||
- `ENCRYPTION_KEY`: Must be exactly 32 bytes when base64 decoded (generate with `openssl rand -base64 32`)
|
||||
- `JIRA_SCHEMA_ID`: Required for Jira Assets integration
|
||||
|
||||
### Application Branding
|
||||
|
||||
- The `{year}` placeholder in `APP_COPYRIGHT` will be automatically replaced with the current year
|
||||
119
docs/AUTHENTICATION-IMPLEMENTATION-STATUS.md
Normal file
119
docs/AUTHENTICATION-IMPLEMENTATION-STATUS.md
Normal file
@@ -0,0 +1,119 @@
|
||||
# Authentication System Implementation Status
|
||||
|
||||
## ✅ Completed Features
|
||||
|
||||
### Backend
|
||||
- ✅ Database schema with users, roles, permissions, sessions, user_settings, email_tokens tables
|
||||
- ✅ User service (CRUD, password hashing, email verification, password reset)
|
||||
- ✅ Role service (dynamic role and permission management)
|
||||
- ✅ Auth service (local auth + OAuth with database-backed sessions)
|
||||
- ✅ Email service (Nodemailer with SMTP)
|
||||
- ✅ Encryption service (AES-256-GCM for sensitive data)
|
||||
- ✅ User settings service (Jira PAT, AI features, API keys)
|
||||
- ✅ Authorization middleware (requireAuth, requireRole, requirePermission)
|
||||
- ✅ All API routes protected with authentication
|
||||
- ✅ Auth routes (login, logout, password reset, email verification, invitations)
|
||||
- ✅ User management routes (admin only)
|
||||
- ✅ Role management routes
|
||||
- ✅ User settings routes
|
||||
- ✅ Profile routes
|
||||
|
||||
### Frontend
|
||||
- ✅ Auth store extended with roles, permissions, local auth support
|
||||
- ✅ Permission hooks (useHasPermission, useHasRole, usePermissions)
|
||||
- ✅ ProtectedRoute component
|
||||
- ✅ Login component (local login + OAuth choice)
|
||||
- ✅ ForgotPassword component
|
||||
- ✅ ResetPassword component
|
||||
- ✅ AcceptInvitation component
|
||||
- ✅ UserManagement component (admin)
|
||||
- ✅ RoleManagement component (admin)
|
||||
- ✅ UserSettings component
|
||||
- ✅ Profile component
|
||||
- ✅ UserMenu with logout and profile/settings links
|
||||
- ✅ Feature gating based on permissions
|
||||
|
||||
## 🔧 Configuration Required
|
||||
|
||||
### Environment Variables
|
||||
|
||||
**Required for local authentication:**
|
||||
```env
|
||||
LOCAL_AUTH_ENABLED=true
|
||||
```
|
||||
|
||||
**Required for email functionality:**
|
||||
```env
|
||||
SMTP_HOST=smtp.example.com
|
||||
SMTP_PORT=587
|
||||
SMTP_SECURE=false
|
||||
SMTP_USER=your-email@example.com
|
||||
SMTP_PASSWORD=your-password
|
||||
SMTP_FROM=noreply@example.com
|
||||
```
|
||||
|
||||
**Required for encryption:**
|
||||
```env
|
||||
ENCRYPTION_KEY=your-32-byte-encryption-key-base64
|
||||
```
|
||||
|
||||
**Optional - Initial admin user:**
|
||||
```env
|
||||
ADMIN_EMAIL=admin@example.com
|
||||
ADMIN_PASSWORD=SecurePassword123!
|
||||
ADMIN_USERNAME=admin
|
||||
ADMIN_DISPLAY_NAME=Administrator
|
||||
```
|
||||
|
||||
**Password requirements:**
|
||||
```env
|
||||
PASSWORD_MIN_LENGTH=8
|
||||
PASSWORD_REQUIRE_UPPERCASE=true
|
||||
PASSWORD_REQUIRE_LOWERCASE=true
|
||||
PASSWORD_REQUIRE_NUMBER=true
|
||||
PASSWORD_REQUIRE_SPECIAL=false
|
||||
```
|
||||
|
||||
**Session duration:**
|
||||
```env
|
||||
SESSION_DURATION_HOURS=24
|
||||
```
|
||||
|
||||
## 📝 Notes
|
||||
|
||||
### JIRA_AUTH Settings
|
||||
- `JIRA_PAT` can be removed from global env - users configure their own PAT in settings
|
||||
- `JIRA_OAUTH_CLIENT_ID` and `JIRA_OAUTH_CLIENT_SECRET` are still needed for OAuth flow
|
||||
- `JIRA_HOST` and `JIRA_SCHEMA_ID` are still needed (infrastructure settings)
|
||||
|
||||
### AI API Keys
|
||||
- `ANTHROPIC_API_KEY` can be removed from global env - users configure their own keys
|
||||
- `OPENAI_API_KEY` can be removed from global env - users configure their own keys
|
||||
- `TAVILY_API_KEY` can be removed from global env - users configure their own keys
|
||||
- These are now stored per-user in the `user_settings` table (encrypted)
|
||||
|
||||
### Authentication Flow
|
||||
1. On first run, migrations create database tables
|
||||
2. If `ADMIN_EMAIL` and `ADMIN_PASSWORD` are set, initial admin user is created
|
||||
3. Once users exist, authentication is automatically required
|
||||
4. Users can log in with email/password (local auth) or OAuth (if configured)
|
||||
5. User menu shows logged-in user with links to Profile and Settings
|
||||
6. Logout is available for all authenticated users
|
||||
|
||||
## 🚀 Next Steps
|
||||
|
||||
1. Set `LOCAL_AUTH_ENABLED=true` in environment
|
||||
2. Configure SMTP settings for email functionality
|
||||
3. Generate encryption key: `openssl rand -base64 32`
|
||||
4. Set initial admin credentials (optional)
|
||||
5. Run the application - migrations will run automatically
|
||||
6. Log in with admin account
|
||||
7. Create additional users via User Management
|
||||
8. Configure roles and permissions as needed
|
||||
|
||||
## ⚠️ Important
|
||||
|
||||
- Once users exist in the database, authentication is **automatically required**
|
||||
- Service account mode only works if no users exist AND local auth is not enabled
|
||||
- All API routes are protected - unauthenticated requests return 401
|
||||
- User-specific settings (Jira PAT, AI keys) are encrypted at rest
|
||||
142
docs/DATABASE-ACCESS.md
Normal file
142
docs/DATABASE-ACCESS.md
Normal file
@@ -0,0 +1,142 @@
|
||||
# Database Access Guide
|
||||
|
||||
This guide shows you how to easily access and view records in the PostgreSQL database.
|
||||
|
||||
## Quick Access
|
||||
|
||||
### Option 1: Using the Script (Easiest)
|
||||
|
||||
```bash
|
||||
# Connect using psql
|
||||
./scripts/open-database.sh psql
|
||||
|
||||
# Or via Docker
|
||||
./scripts/open-database.sh docker
|
||||
|
||||
# Or get connection string for GUI tools
|
||||
./scripts/open-database.sh url
|
||||
```
|
||||
|
||||
### Option 2: Direct psql Command
|
||||
|
||||
```bash
|
||||
# If PostgreSQL is running locally
|
||||
PGPASSWORD=cmdb-dev psql -h localhost -p 5432 -U cmdb -d cmdb
|
||||
```
|
||||
|
||||
### Option 3: Via Docker
|
||||
|
||||
```bash
|
||||
# Connect to PostgreSQL container
|
||||
docker exec -it $(docker ps | grep postgres | awk '{print $1}') psql -U cmdb -d cmdb
|
||||
```
|
||||
|
||||
## Connection Details
|
||||
|
||||
From `docker-compose.yml`:
|
||||
- **Host**: localhost (or `postgres` if connecting from Docker network)
|
||||
- **Port**: 5432
|
||||
- **Database**: cmdb
|
||||
- **User**: cmdb
|
||||
- **Password**: cmdb-dev
|
||||
|
||||
**Connection String:**
|
||||
```
|
||||
postgresql://cmdb:cmdb-dev@localhost:5432/cmdb
|
||||
```
|
||||
|
||||
## GUI Tools
|
||||
|
||||
### pgAdmin (Free, Web-based)
|
||||
1. Download from: https://www.pgadmin.org/download/
|
||||
2. Add new server with connection details above
|
||||
3. Browse tables and run queries
|
||||
|
||||
### DBeaver (Free, Cross-platform)
|
||||
1. Download from: https://dbeaver.io/download/
|
||||
2. Create new PostgreSQL connection
|
||||
3. Use connection string or individual fields
|
||||
|
||||
### TablePlus (macOS, Paid but has free tier)
|
||||
1. Download from: https://tableplus.com/
|
||||
2. Create new PostgreSQL connection
|
||||
3. Enter connection details
|
||||
|
||||
### DataGrip (JetBrains, Paid)
|
||||
1. Part of JetBrains IDEs or standalone
|
||||
2. Create new PostgreSQL data source
|
||||
3. Use connection string
|
||||
|
||||
## Useful SQL Commands
|
||||
|
||||
Once connected, try these commands:
|
||||
|
||||
```sql
|
||||
-- List all tables
|
||||
\dt
|
||||
|
||||
-- Describe a table structure
|
||||
\d users
|
||||
\d classifications
|
||||
\d cache_objects
|
||||
|
||||
-- View all users
|
||||
SELECT * FROM users;
|
||||
|
||||
-- View classifications
|
||||
SELECT * FROM classifications ORDER BY created_at DESC LIMIT 10;
|
||||
|
||||
-- View cached objects
|
||||
SELECT object_key, object_type, updated_at FROM cache_objects ORDER BY updated_at DESC LIMIT 20;
|
||||
|
||||
-- Count records per table
|
||||
SELECT
|
||||
'users' as table_name, COUNT(*) as count FROM users
|
||||
UNION ALL
|
||||
SELECT
|
||||
'classifications', COUNT(*) FROM classifications
|
||||
UNION ALL
|
||||
SELECT
|
||||
'cache_objects', COUNT(*) FROM cache_objects;
|
||||
|
||||
-- View user settings
|
||||
SELECT u.username, u.email, us.ai_provider, us.ai_enabled
|
||||
FROM users u
|
||||
LEFT JOIN user_settings us ON u.id = us.user_id;
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
If you're using environment variables instead of Docker:
|
||||
|
||||
```bash
|
||||
# Check your .env file for:
|
||||
DATABASE_URL=postgresql://cmdb:cmdb-dev@localhost:5432/cmdb
|
||||
# or
|
||||
DATABASE_TYPE=postgres
|
||||
DATABASE_HOST=localhost
|
||||
DATABASE_PORT=5432
|
||||
DATABASE_NAME=cmdb
|
||||
DATABASE_USER=cmdb
|
||||
DATABASE_PASSWORD=cmdb-dev
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Database not running
|
||||
```bash
|
||||
# Start PostgreSQL container
|
||||
docker-compose up -d postgres
|
||||
|
||||
# Check if it's running
|
||||
docker ps | grep postgres
|
||||
```
|
||||
|
||||
### Connection refused
|
||||
- Make sure PostgreSQL container is running
|
||||
- Check if port 5432 is already in use
|
||||
- Verify connection details match docker-compose.yml
|
||||
|
||||
### Permission denied
|
||||
- Verify username and password match docker-compose.yml
|
||||
- Check if user has access to the database
|
||||
1061
docs/NORMALIZED-DATABASE-IMPLEMENTATION-PLAN.md
Normal file
1061
docs/NORMALIZED-DATABASE-IMPLEMENTATION-PLAN.md
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user