docs: Update Dockerfile and README for security improvements
Dockerfile Changes: - Remove hardcoded AUTH_SECRET and admin credentials from build args - Add security comments explaining auto-generation behavior - Simplify environment variables to only required configurations - Document how to retrieve auto-generated credentials from logs README.md Updates: - Comprehensive security features documentation - Updated environment variables table with auto-generation info - Detailed instructions for retrieving auto-generated credentials - Added security compliance section (OWASP, NIST, best practices) - Updated project structure to reflect all new security components - Enhanced database schema documentation - Added production security recommendations checklist - Documented all implemented security features: * Auto-generated secrets * Password security (bcrypt, requirements, reset codes) * CSRF protection * Session management * Account lockout (dual-layer) * User management features All documentation now accurately reflects the enterprise-grade security implementation and simplified deployment process. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
10
Dockerfile
10
Dockerfile
@@ -16,9 +16,6 @@ RUN mkdir -p /app/data
|
|||||||
|
|
||||||
# Accept build arguments
|
# Accept build arguments
|
||||||
ARG SITE_URL=https://nlcc.rydertech.us
|
ARG SITE_URL=https://nlcc.rydertech.us
|
||||||
ARG AUTH_SECRET=change-this-secret-in-production-please
|
|
||||||
ARG ADMIN_USERNAME=admin
|
|
||||||
ARG ADMIN_PASSWORD=Admin123!
|
|
||||||
ARG EMAIL_HOST=smtp.example.com
|
ARG EMAIL_HOST=smtp.example.com
|
||||||
ARG EMAIL_PORT=587
|
ARG EMAIL_PORT=587
|
||||||
ARG EMAIL_USER=noreply@example.com
|
ARG EMAIL_USER=noreply@example.com
|
||||||
@@ -27,15 +24,16 @@ ARG EMAIL_FROM=New Life Christian Church <noreply@example.com>
|
|||||||
|
|
||||||
# Set environment variables for build
|
# Set environment variables for build
|
||||||
ENV SITE_URL=$SITE_URL
|
ENV SITE_URL=$SITE_URL
|
||||||
ENV AUTH_SECRET=$AUTH_SECRET
|
|
||||||
ENV ADMIN_USERNAME=$ADMIN_USERNAME
|
|
||||||
ENV ADMIN_PASSWORD=$ADMIN_PASSWORD
|
|
||||||
ENV EMAIL_HOST=$EMAIL_HOST
|
ENV EMAIL_HOST=$EMAIL_HOST
|
||||||
ENV EMAIL_PORT=$EMAIL_PORT
|
ENV EMAIL_PORT=$EMAIL_PORT
|
||||||
ENV EMAIL_USER=$EMAIL_USER
|
ENV EMAIL_USER=$EMAIL_USER
|
||||||
ENV EMAIL_PASSWORD=$EMAIL_PASSWORD
|
ENV EMAIL_PASSWORD=$EMAIL_PASSWORD
|
||||||
ENV EMAIL_FROM=$EMAIL_FROM
|
ENV EMAIL_FROM=$EMAIL_FROM
|
||||||
|
|
||||||
|
# Security: AUTH_SECRET and admin credentials are auto-generated on first launch
|
||||||
|
# They are stored in the database and logged once to container logs
|
||||||
|
# Use: docker logs <container-name> | grep "ADMIN CREDENTIALS" to retrieve them
|
||||||
|
|
||||||
# Build the application
|
# Build the application
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
|
|||||||
204
README.md
204
README.md
@@ -5,13 +5,17 @@ A web application for managing and displaying weekly sermons for New Life Christ
|
|||||||
## Features
|
## Features
|
||||||
|
|
||||||
- 📝 **Sermon Management**: Create and manage sermon content with a user-friendly form
|
- 📝 **Sermon Management**: Create and manage sermon content with a user-friendly form
|
||||||
- 🔐 **Authentication**: Secure admin access with login system
|
- 🔐 **Enterprise Security**: OWASP-compliant authentication with CSRF protection, session management, and account lockout
|
||||||
|
- 👥 **User Management**: Full admin panel for managing users, roles, and account security
|
||||||
|
- 🔒 **Password Security**: Bcrypt hashing, strong password requirements, and secure password reset with 8-character alphanumeric codes
|
||||||
|
- 🛡️ **Account Protection**: Dual-layer brute force protection (IP-based + per-account lockout)
|
||||||
- 📱 **QR Codes**: Generate QR codes for easy sermon sharing
|
- 📱 **QR Codes**: Generate QR codes for easy sermon sharing
|
||||||
- 📅 **Date-based URLs**: Sermons accessible via `sermon-MMDDYYYY` format
|
- 📅 **Date-based URLs**: Sermons accessible via `sermon-MMDDYYYY` format
|
||||||
- 🎨 **Modern UI**: Clean, responsive design using Tailwind CSS and Inter font
|
- 🎨 **Modern UI**: Clean, responsive design using Tailwind CSS and Inter font
|
||||||
- 📊 **Three Sections**: Bible References, Personal Appliance, and Pastor's Challenge
|
- 📊 **Three Sections**: Bible References, Personal Appliance, and Pastor's Challenge
|
||||||
- 🗂️ **Smart Organization**: Recent sermons (last 3 months) displayed by default, older sermons in dropdown
|
- 🗂️ **Smart Organization**: Recent sermons (last 3 months) displayed by default, older sermons in dropdown
|
||||||
- 🐳 **Docker Ready**: Fully containerized for easy deployment
|
- 📧 **Email Notifications**: Password reset codes and sermon notes via SMTP
|
||||||
|
- 🐳 **Docker Ready**: Fully containerized for easy deployment with auto-generated secrets
|
||||||
|
|
||||||
## Technology Stack
|
## Technology Stack
|
||||||
|
|
||||||
@@ -27,41 +31,34 @@ This application uses environment variables configured directly in `docker-compo
|
|||||||
|
|
||||||
### Environment Variables
|
### Environment Variables
|
||||||
|
|
||||||
| Variable | Description | Default |
|
| Variable | Description | Default | Required |
|
||||||
|----------|-------------|---------|
|
|----------|-------------|---------|----------|
|
||||||
| `SITE_URL` | Public URL where the app is hosted (used for QR codes) | `https://nlcc.rydertech.us` |
|
| `SITE_URL` | Public URL where the app is hosted (used for QR codes) | `https://nlcc.rydertech.us` | Yes |
|
||||||
| `AUTH_SECRET` | Secret key for authentication sessions | `change-this-secret-in-production-please` |
|
| `AUTH_SECRET` | Secret key for authentication sessions | **Auto-generated** | No |
|
||||||
| `ADMIN_USERNAME` | Initial admin login username | `admin` |
|
| `ADMIN_USERNAME` | Initial admin login username | `admin` | No |
|
||||||
| `ADMIN_PASSWORD` | Initial admin login password | `Admin123!` |
|
| `ADMIN_PASSWORD` | Initial admin login password | **Auto-generated** | No |
|
||||||
| `EMAIL_HOST` | SMTP server hostname | `smtp.example.com` |
|
| `EMAIL_HOST` | SMTP server hostname | `smtp.example.com` | Yes |
|
||||||
| `EMAIL_PORT` | SMTP server port | `587` |
|
| `EMAIL_PORT` | SMTP server port | `587` | Yes |
|
||||||
| `EMAIL_USER` | SMTP authentication username | `noreply@example.com` |
|
| `EMAIL_USER` | SMTP authentication username | `noreply@example.com` | Yes |
|
||||||
| `EMAIL_PASSWORD` | SMTP authentication password | `your-email-password` |
|
| `EMAIL_PASSWORD` | SMTP authentication password | Required | Yes |
|
||||||
| `EMAIL_FROM` | Email sender address and name | `New Life Christian Church <noreply@example.com>` |
|
| `EMAIL_FROM` | Email sender address and name | `New Life Christian Church <noreply@example.com>` | Yes |
|
||||||
|
|
||||||
|
**Security Note**: `AUTH_SECRET` and `ADMIN_PASSWORD` are now automatically generated on first launch using cryptographically secure random generation. They are stored in the database and logged once to container logs.
|
||||||
|
|
||||||
### Customizing Configuration
|
### Customizing Configuration
|
||||||
|
|
||||||
Edit `docker-compose.yml` and update the values in both the `build.args` and `environment` sections:
|
Edit `docker-compose.yml` and update the required values:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
services:
|
services:
|
||||||
nlcc-itinerary:
|
nlcc-itinerary:
|
||||||
build:
|
|
||||||
args:
|
|
||||||
- SITE_URL=https://your-church-domain.com
|
|
||||||
- AUTH_SECRET=your-secure-random-secret-here
|
|
||||||
- ADMIN_USERNAME=your-admin-username
|
|
||||||
- ADMIN_PASSWORD=your-secure-password
|
|
||||||
- EMAIL_HOST=smtp.gmail.com
|
|
||||||
- EMAIL_PORT=587
|
|
||||||
- EMAIL_USER=your-email@gmail.com
|
|
||||||
- EMAIL_PASSWORD=your-app-password
|
|
||||||
- EMAIL_FROM=Your Church Name <your-email@gmail.com>
|
|
||||||
environment:
|
environment:
|
||||||
- SITE_URL=https://your-church-domain.com
|
- SITE_URL=https://your-church-domain.com
|
||||||
- AUTH_SECRET=your-secure-random-secret-here
|
# Optional: customize admin username (default: "admin")
|
||||||
- ADMIN_USERNAME=your-admin-username
|
# - ADMIN_USERNAME=your-admin-username
|
||||||
- ADMIN_PASSWORD=your-secure-password
|
# Optional: set custom admin password (otherwise auto-generated)
|
||||||
|
# - ADMIN_PASSWORD=your-secure-password
|
||||||
|
# Email configuration (required for password resets)
|
||||||
- EMAIL_HOST=smtp.gmail.com
|
- EMAIL_HOST=smtp.gmail.com
|
||||||
- EMAIL_PORT=587
|
- EMAIL_PORT=587
|
||||||
- EMAIL_USER=your-email@gmail.com
|
- EMAIL_USER=your-email@gmail.com
|
||||||
@@ -69,10 +66,7 @@ services:
|
|||||||
- EMAIL_FROM=Your Church Name <your-email@gmail.com>
|
- EMAIL_FROM=Your Church Name <your-email@gmail.com>
|
||||||
```
|
```
|
||||||
|
|
||||||
**Generate a secure AUTH_SECRET:**
|
**Note**: `AUTH_SECRET` is no longer needed in configuration - it's automatically generated and stored in the database on first launch.
|
||||||
```bash
|
|
||||||
openssl rand -hex 32
|
|
||||||
```
|
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
@@ -90,9 +84,8 @@ cd nlcc-itinerary
|
|||||||
|
|
||||||
2. Edit `docker-compose.yml` and configure your settings:
|
2. Edit `docker-compose.yml` and configure your settings:
|
||||||
- Update `SITE_URL` to your public domain
|
- Update `SITE_URL` to your public domain
|
||||||
- Generate and set a secure `AUTH_SECRET` (use `openssl rand -hex 32`)
|
- Configure email settings (required for password resets)
|
||||||
- Set your desired `ADMIN_USERNAME` and `ADMIN_PASSWORD`
|
- Optionally set `ADMIN_USERNAME` and `ADMIN_PASSWORD` (otherwise auto-generated)
|
||||||
- Make sure to update values in BOTH `build.args` AND `environment` sections
|
|
||||||
|
|
||||||
3. Build and run with Docker Compose:
|
3. Build and run with Docker Compose:
|
||||||
```bash
|
```bash
|
||||||
@@ -105,16 +98,34 @@ The application will be available at `http://localhost:3002` (or your configured
|
|||||||
|
|
||||||
### Initial Admin Account
|
### Initial Admin Account
|
||||||
|
|
||||||
The initial admin account is created automatically on first run using the credentials specified in `docker-compose.yml`:
|
The initial admin account is created automatically on first run with secure auto-generated credentials:
|
||||||
|
|
||||||
**Default values**:
|
**Default behavior**:
|
||||||
- **Username**: admin
|
- **Username**: `admin` (can be customized with `ADMIN_USERNAME` env var)
|
||||||
- **Password**: Admin123!
|
- **Password**: **Auto-generated** (cryptographically secure 16-character password)
|
||||||
|
|
||||||
|
**Retrieving Auto-Generated Credentials**:
|
||||||
|
```bash
|
||||||
|
# View the auto-generated admin password from container logs
|
||||||
|
docker logs nlcc-itinerary 2>&1 | grep "ADMIN CREDENTIALS"
|
||||||
|
```
|
||||||
|
|
||||||
|
The output will show:
|
||||||
|
```
|
||||||
|
╔════════════════════════════════════════════════════════╗
|
||||||
|
║ 🔐 ADMIN CREDENTIALS (SAVE THESE!) ║
|
||||||
|
╠════════════════════════════════════════════════════════╣
|
||||||
|
║ Username: admin ║
|
||||||
|
║ Password: <randomly-generated-password> ║
|
||||||
|
╚════════════════════════════════════════════════════════╝
|
||||||
|
```
|
||||||
|
|
||||||
⚠️ **Important**:
|
⚠️ **Important**:
|
||||||
- Change these credentials in `docker-compose.yml` before deploying to production
|
- Credentials are logged **only once** on first startup
|
||||||
- After the first build, you can change the admin password through the user management interface
|
- Save the credentials immediately - they won't be shown again
|
||||||
- Additional users can be created through the registration page
|
- Alternatively, set `ADMIN_PASSWORD` in `docker-compose.yml` to use a custom password
|
||||||
|
- Change admin password after first login via the profile page
|
||||||
|
- Additional users and admins can be created through the user management interface
|
||||||
|
|
||||||
## Project Structure
|
## Project Structure
|
||||||
|
|
||||||
@@ -129,16 +140,27 @@ nlcc-itinerary/
|
|||||||
│ └── auth.ts
|
│ └── auth.ts
|
||||||
├── pages/ # Application pages
|
├── pages/ # Application pages
|
||||||
│ ├── index.vue # Main sermon listing
|
│ ├── index.vue # Main sermon listing
|
||||||
│ ├── login.vue # Admin login
|
│ ├── login.vue # Login page
|
||||||
|
│ ├── register.vue # User registration
|
||||||
│ ├── admin.vue # Sermon creation form
|
│ ├── admin.vue # Sermon creation form
|
||||||
|
│ ├── users.vue # User management (admin only)
|
||||||
|
│ ├── profile.vue # User profile settings
|
||||||
│ └── [slug].vue # Individual sermon page
|
│ └── [slug].vue # Individual sermon page
|
||||||
|
├── plugins/ # Nuxt plugins
|
||||||
|
│ └── csrf.client.ts # CSRF auto-injection
|
||||||
├── server/
|
├── server/
|
||||||
│ ├── api/ # API endpoints
|
│ ├── api/ # API endpoints
|
||||||
│ │ ├── auth/ # Authentication endpoints
|
│ │ ├── auth/ # Authentication endpoints
|
||||||
│ │ └── sermons/ # Sermon CRUD endpoints
|
│ │ ├── sermons/ # Sermon CRUD endpoints
|
||||||
|
│ │ ├── users/ # User management endpoints
|
||||||
|
│ │ └── profile/ # Profile management
|
||||||
|
│ ├── middleware/ # Server middleware
|
||||||
|
│ │ └── csrf.ts # CSRF validation
|
||||||
│ └── utils/ # Server utilities
|
│ └── utils/ # Server utilities
|
||||||
│ ├── database.ts # SQLite database functions
|
│ ├── database.ts # SQLite database functions
|
||||||
│ └── auth.ts # Authentication helpers
|
│ ├── auth.ts # Authentication helpers
|
||||||
|
│ ├── csrf.ts # CSRF protection utilities
|
||||||
|
│ └── email.ts # Email sending functions
|
||||||
├── logos/ # Church logos
|
├── logos/ # Church logos
|
||||||
├── Dockerfile # Docker configuration
|
├── Dockerfile # Docker configuration
|
||||||
├── docker-compose.yml # Docker Compose configuration
|
├── docker-compose.yml # Docker Compose configuration
|
||||||
@@ -181,21 +203,91 @@ The application uses SQLite with the following schema:
|
|||||||
|
|
||||||
### Users Table
|
### Users Table
|
||||||
- `id`: Primary key
|
- `id`: Primary key
|
||||||
- `username`: User's username
|
- `username`: User's username (unique)
|
||||||
- `password`: User's password (plain text - should be hashed in production)
|
- `password`: User's password (bcrypt hashed)
|
||||||
|
- `first_name`: User's first name
|
||||||
|
- `last_name`: User's last name
|
||||||
|
- `email`: User's email address
|
||||||
|
- `is_admin`: Admin flag (0 or 1)
|
||||||
|
- `failed_login_attempts`: Failed login counter
|
||||||
|
- `locked_until`: Account lock expiration timestamp
|
||||||
|
- `created_at`: Account creation timestamp
|
||||||
|
|
||||||
## Security Notes
|
### Sessions Table
|
||||||
|
- `id`: Primary key
|
||||||
|
- `token`: Session token (unique)
|
||||||
|
- `username`: Associated username
|
||||||
|
- `expires_at`: Session expiration timestamp
|
||||||
|
- `csrf_token`: CSRF token for request validation
|
||||||
|
- `created_at`: Session creation timestamp
|
||||||
|
|
||||||
⚠️ **For Production Use**:
|
### Settings Table
|
||||||
|
- `key`: Setting key (primary)
|
||||||
|
- `value`: Setting value
|
||||||
|
- `created_at`: Creation timestamp
|
||||||
|
- `updated_at`: Last update timestamp
|
||||||
|
|
||||||
1. Change the default admin credentials in your `.env` file
|
## Security Features
|
||||||
2. ✅ Password hashing is implemented using bcrypt
|
|
||||||
3. Use a strong `AUTH_SECRET` in environment variables (generate with `openssl rand -hex 32`)
|
|
||||||
4. Enable HTTPS
|
|
||||||
5. Consider implementing rate limiting
|
|
||||||
6. Add CSRF protection
|
|
||||||
|
|
||||||
**Note**: Passwords are now securely hashed using bcrypt with 10 salt rounds before being stored in the database.
|
This application implements enterprise-grade security following OWASP best practices:
|
||||||
|
|
||||||
|
### ✅ Implemented Security Features
|
||||||
|
|
||||||
|
1. **Auto-Generated Secrets**
|
||||||
|
- `AUTH_SECRET` automatically generated using cryptographic randomness
|
||||||
|
- Admin password auto-generated with 16 characters (uppercase, lowercase, numbers, symbols)
|
||||||
|
- All secrets stored securely in database
|
||||||
|
|
||||||
|
2. **Password Security**
|
||||||
|
- Bcrypt hashing with 10 salt rounds
|
||||||
|
- Strong password requirements (8+ chars, uppercase, lowercase, number/symbol)
|
||||||
|
- Secure password reset with 8-character alphanumeric codes (1.8 trillion combinations)
|
||||||
|
- Session invalidation on password changes
|
||||||
|
|
||||||
|
3. **CSRF Protection**
|
||||||
|
- Double-submit cookie pattern implementation
|
||||||
|
- Automatic token injection on all API requests
|
||||||
|
- Three-way validation (cookie, header, session database)
|
||||||
|
- Zero configuration needed in components
|
||||||
|
|
||||||
|
4. **Session Management**
|
||||||
|
- Secure session tokens with HTTP-only cookies
|
||||||
|
- Automatic session expiration (24 hours)
|
||||||
|
- Session invalidation on security events (password changes, admin resets)
|
||||||
|
- Protection against session fixation attacks
|
||||||
|
|
||||||
|
5. **Account Lockout (Dual-Layer Brute Force Protection)**
|
||||||
|
- IP-based rate limiting (existing)
|
||||||
|
- Per-account lockout: 10 failed attempts = 30 minute lock
|
||||||
|
- Automatic unlock after expiration
|
||||||
|
- Admin manual unlock capability via UI
|
||||||
|
|
||||||
|
6. **User Management**
|
||||||
|
- Role-based access control (admin/user)
|
||||||
|
- Admin dashboard for user management
|
||||||
|
- Account lock status visibility
|
||||||
|
- Password reset functionality
|
||||||
|
|
||||||
|
### 🔒 Production Recommendations
|
||||||
|
|
||||||
|
1. ✅ Strong passwords - Enforced by application
|
||||||
|
2. ✅ Password hashing - Bcrypt with salt rounds
|
||||||
|
3. ✅ CSRF protection - Implemented
|
||||||
|
4. ✅ Session security - HTTP-only cookies with expiration
|
||||||
|
5. ✅ Account lockout - Dual-layer protection
|
||||||
|
6. ✅ Secrets management - Auto-generated and stored securely
|
||||||
|
7. **Enable HTTPS** - Configure reverse proxy (nginx/Caddy)
|
||||||
|
8. **Regular backups** - Backup `/app/data` directory
|
||||||
|
9. **Email security** - Use app-specific passwords for SMTP
|
||||||
|
10. **Monitor logs** - Review failed login attempts
|
||||||
|
|
||||||
|
### 🛡️ Security Compliance
|
||||||
|
|
||||||
|
- **OWASP Top 10 2021**: Addressed broken authentication, injection, security misconfiguration
|
||||||
|
- **Password Storage**: NIST-compliant bcrypt hashing
|
||||||
|
- **CSRF Protection**: Industry-standard double-submit pattern
|
||||||
|
- **Session Security**: Secure cookie attributes and expiration
|
||||||
|
- **Brute Force Protection**: Account lockout + rate limiting
|
||||||
|
|
||||||
## Docker Commands
|
## Docker Commands
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user