Files
nlcc-itinerary/README.md
Joshua Ryder 3474ca7013 refactor: Use external Docker named volume for data persistence
Changes:
- Replace bind mount (./data) with external named volume (nlcc-data)
- Volume must be created before first run: docker volume create nlcc-data
- Improves portability and follows Docker best practices
- Better separation between code and data

Benefits:
- Data persists across container rebuilds and updates
- Easier backup and restore operations
- Platform-agnostic (works same on Linux/Windows/macOS)
- Managed by Docker's volume system
- No permission issues with bind mounts

README Updates:
- Added volume creation step to installation instructions
- Documented volume management commands (create, inspect, backup, restore)
- Added backup/restore examples using alpine container
- Clarified data persistence behavior

Note: Existing deployments using ./data bind mount will need to:
1. Backup existing data: cp -r ./data ./data-backup
2. Create volume: docker volume create nlcc-data
3. Restart container: docker-compose up -d
4. Copy data to volume if needed

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 17:46:07 -05:00

349 lines
13 KiB
Markdown

# New Life Christian Church - Sermon Itinerary
A web application for managing and displaying weekly sermons for New Life Christian Church.
## Features
- 📝 **Sermon Management**: Create and manage sermon content with a user-friendly form
- 🔐 **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
- 📅 **Date-based URLs**: Sermons accessible via `sermon-MMDDYYYY` format
- 🎨 **Modern UI**: Clean, responsive design using Tailwind CSS and Inter font
- 📊 **Three Sections**: Bible References, Personal Appliance, and Pastor's Challenge
- 🗂️ **Smart Organization**: Recent sermons (last 3 months) displayed by default, older sermons in dropdown
- 📧 **Email Notifications**: Password reset codes and sermon notes via SMTP
- 🐳 **Docker Ready**: Fully containerized for easy deployment with auto-generated secrets
## Technology Stack
- **Frontend**: Nuxt 3 (Vue.js)
- **Styling**: Tailwind CSS with Inter font from Google Fonts
- **Database**: SQLite
- **QR Codes**: qrcode library
- **Deployment**: Docker & Docker Compose
## Configuration
This application uses environment variables configured directly in `docker-compose.yml`. Edit the file to customize your deployment settings.
### Environment Variables
| Variable | Description | Default | Required |
|----------|-------------|---------|----------|
| `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 | **Auto-generated** | No |
| `ADMIN_USERNAME` | Initial admin login username | `admin` | No |
| `ADMIN_PASSWORD` | Initial admin login password | **Auto-generated** | No |
| `EMAIL_HOST` | SMTP server hostname | `smtp.example.com` | Yes |
| `EMAIL_PORT` | SMTP server port | `587` | Yes |
| `EMAIL_USER` | SMTP authentication username | `noreply@example.com` | Yes |
| `EMAIL_PASSWORD` | SMTP authentication password | Required | Yes |
| `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
Edit `docker-compose.yml` and update the required values:
```yaml
services:
nlcc-itinerary:
environment:
- SITE_URL=https://your-church-domain.com
# Optional: customize admin username (default: "admin")
# - ADMIN_USERNAME=your-admin-username
# 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_PORT=587
- EMAIL_USER=your-email@gmail.com
- EMAIL_PASSWORD=your-app-password
- EMAIL_FROM=Your Church Name <your-email@gmail.com>
```
**Note**: `AUTH_SECRET` is no longer needed in configuration - it's automatically generated and stored in the database on first launch.
## Getting Started
### Prerequisites
- Docker and Docker Compose installed on your system
### Installation & Deployment
1. Clone the repository:
```bash
git clone <repository-url>
cd nlcc-itinerary
```
2. Edit `docker-compose.yml` and configure your settings:
- Update `SITE_URL` to your public domain
- Configure email settings (required for password resets)
- Optionally set `ADMIN_USERNAME` and `ADMIN_PASSWORD` (otherwise auto-generated)
3. Create the external Docker volume for data persistence:
```bash
docker volume create nlcc-data
```
4. Build and run with Docker Compose:
```bash
docker-compose up -d --build
```
The application will be available at `http://localhost:3002` (or your configured port)
**Important**: The `SITE_URL` must be set correctly for QR codes to work. This should be the public URL where your application is accessible (e.g., `https://church.example.com`).
### Initial Admin Account
The initial admin account is created automatically on first run with secure auto-generated credentials:
**Default behavior**:
- **Username**: `admin` (can be customized with `ADMIN_USERNAME` env var)
- **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**:
- Credentials are logged **only once** on first startup
- Save the credentials immediately - they won't be shown again
- 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
```
nlcc-itinerary/
├── assets/css/ # Global styles
├── components/ # Vue components
│ ├── SermonCard.vue
│ ├── QRCodeButton.vue
│ └── QRCodeModal.vue
├── middleware/ # Route middleware
│ └── auth.ts
├── pages/ # Application pages
│ ├── index.vue # Main sermon listing
│ ├── login.vue # Login page
│ ├── register.vue # User registration
│ ├── admin.vue # Sermon creation form
│ ├── users.vue # User management (admin only)
│ ├── profile.vue # User profile settings
│ └── [slug].vue # Individual sermon page
├── plugins/ # Nuxt plugins
│ └── csrf.client.ts # CSRF auto-injection
├── server/
│ ├── api/ # API endpoints
│ │ ├── auth/ # Authentication endpoints
│ │ ├── sermons/ # Sermon CRUD endpoints
│ │ ├── users/ # User management endpoints
│ │ └── profile/ # Profile management
│ ├── middleware/ # Server middleware
│ │ └── csrf.ts # CSRF validation
│ └── utils/ # Server utilities
│ ├── database.ts # SQLite database functions
│ ├── auth.ts # Authentication helpers
│ ├── csrf.ts # CSRF protection utilities
│ └── email.ts # Email sending functions
├── logos/ # Church logos
├── Dockerfile # Docker configuration
├── docker-compose.yml # Docker Compose configuration
└── nuxt.config.ts # Nuxt configuration
```
## Usage
### Creating a Sermon
1. Navigate to `/login` and sign in with admin credentials
2. You'll be redirected to `/admin`
3. Fill in the sermon details:
- **Date**: Select the sermon date (URL will be auto-generated as `sermon-MMDDYYYY`)
- **Title**: Enter the sermon title
- **Bible References**: Add one or more Bible verses (use +/- buttons)
- **Personal Appliance**: Enter personal application content
- **Pastor's Challenge**: Enter the pastor's challenge content
4. Click "Create Sermon"
### Viewing Sermons
- **Main Page** (`/`): Shows recent sermons (last 3 months) with option to view older ones
- **Individual Sermon** (`/sermon-MMDDYYYY`): Full sermon details with QR code
- **QR Code**: Click the QR code button on any sermon card or page to generate a scannable code
## Database
The application uses SQLite with the following schema:
### Sermons Table
- `id`: Primary key
- `slug`: Unique sermon identifier (e.g., sermon-09282025)
- `title`: Sermon title
- `date`: Sermon date
- `bible_references`: Newline-separated Bible verses
- `personal_appliance`: Personal application content
- `pastors_challenge`: Pastor's challenge content
- `created_at`: Timestamp
### Users Table
- `id`: Primary key
- `username`: User's username (unique)
- `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
### 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
### Settings Table
- `key`: Setting key (primary)
- `value`: Setting value
- `created_at`: Creation timestamp
- `updated_at`: Last update timestamp
## Security Features
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
```bash
# Build and start
docker-compose up -d
# View logs
docker-compose logs -f
# Stop containers
docker-compose down
# Rebuild after changes
docker-compose up -d --build
# Access container shell
docker exec -it nlcc-itinerary sh
```
## Data Persistence
The SQLite database is stored in a Docker named volume (`nlcc-data`) which is mounted to `/app/data` in the container. This ensures:
- Data persists across container restarts and rebuilds
- Better portability across different environments
- Easier backup and restore operations
- Managed by Docker volume system
**Volume Management Commands**:
```bash
# Create the volume (required before first run)
docker volume create nlcc-data
# Inspect volume location and details
docker volume inspect nlcc-data
# Backup the database
docker run --rm -v nlcc-data:/data -v $(pwd):/backup alpine tar czf /backup/nlcc-backup.tar.gz -C /data .
# Restore from backup
docker run --rm -v nlcc-data:/data -v $(pwd):/backup alpine tar xzf /backup/nlcc-backup.tar.gz -C /data
# Remove volume (WARNING: deletes all data!)
docker volume rm nlcc-data
```
## License
This project is created for New Life Christian Church.
## Support
For issues or questions, please contact the development team.