Commit Graph

170 Commits

Author SHA1 Message Date
c7142ca6a5 fix: Update password reset form to accept 8-character alphanumeric codes
Critical fix for password reset flow. The frontend form was still configured
for 6-digit numeric codes while the backend was updated to use 8-character
alphanumeric codes.

Changes:
- Updated maxlength from 6 to 8 characters
- Changed pattern from [0-9]{6} to [0-9A-Za-z]{8}
- Updated placeholder from "000000" to "ABC123XY"
- Changed label from "6-Digit Code" to "Reset Code"
- Updated help text to say "8-character code"
- Added uppercase styling for better UX
- Changed button validation from code.length !== 6 to !== 8

This ensures users can enter the full reset code sent via email.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 18:21:49 -05:00
df92ebefb8 fix: Use direct process.env access for email configuration
Simplified email configuration to always use process.env directly instead of
Nuxt runtime config. This ensures Docker environment variables are properly
read at runtime rather than being baked in at build time.

Changes:
- Removed Nuxt runtime config dependency from getEmailConfig()
- Always read EMAIL_* environment variables directly from process.env
- Added comprehensive debug logging to diagnose configuration issues
- Updated nuxt.config.ts with better documentation of runtime config behavior

This ensures environment variables set in docker-compose.yml are properly
used by the application at runtime.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 18:16:35 -05:00
47b4a14c4b fix: Ensure email configuration from environment variables is properly used
Fixed an issue where SMTP configuration would fall back to defaults despite
environment variables being set in docker-compose.yml. The email utility now
properly accesses runtime configuration by accepting the H3 event context.

Changes:
- Created getEmailConfig() helper with dual-strategy config access
- Pass event context from API handlers to email functions
- Added fallback to direct process.env access for reliability
- Added debug logging to diagnose configuration issues in production

This ensures Office365 and other SMTP providers work correctly when configured
via environment variables.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 18:11:13 -05:00
a689bee58b fix: Align status badges in user management table
Changes:
- Add items-start to status column flex container
- Ensures status badges (Active, Locked, Failed attempts) align to the left
- Consistent with Role badge alignment above
- Improves visual consistency in the table layout

Before: Status badges were centered/stretched in the column
After: Status badges are left-aligned like other badges

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 18:02:56 -05:00
3e6d479ea6 refactor: Use Docker Compose managed volume with project prefix
Changes:
- docker-compose.yml: Change from external volume to managed volume
  - Volume name: nlcc-data → data
  - Docker Compose auto-prefixes: nlcc-itinerary_data
  - Remove external: true flag
  - Volume created automatically on first up

- README.md: Update all volume references
  - Installation: Remove manual volume creation step
  - Volume name: nlcc-data → nlcc-itinerary_data
  - Add note about automatic creation
  - Update all backup/restore/inspect commands

Benefits:
- No manual volume creation required
- Docker Compose manages lifecycle automatically
- Project-scoped volume naming (nlcc-itinerary_data)
- Cleaner deployment process (one less step)
- Volume automatically created on docker-compose up
- Consistent with Docker Compose best practices

The volume will be created as "nlcc-itinerary_data" where:
- nlcc-itinerary = project directory name
- data = volume name defined in docker-compose.yml

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 17:57:25 -05:00
85c2aeb353 chore: Replace specific domain with generic example URL
Changes:
- docker-compose.yml: https://nlcc.rydertech.ushttps://church.example.com
- Dockerfile: https://nlcc.rydertech.ushttps://church.example.com
- README.md: https://nlcc.rydertech.ushttps://church.example.com

Rationale:
- Makes the repository more generic and reusable
- Users won't be confused by site-specific URLs
- Follows standard documentation practices using example.com
- Clearer that SITE_URL needs to be customized for each deployment

The example.com domain is reserved by IANA for documentation purposes,
making it the perfect choice for configuration templates.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 17:48:16 -05:00
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
d7ee2251a0 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>
2025-11-05 17:43:11 -05:00
2ff493d804 feat: Implement comprehensive security hardening
Security Improvements:
- Auto-generate AUTH_SECRET and admin credentials on first launch
  - Cryptographically secure random generation
  - Stored in database for persistence
  - Logged once to container logs for admin retrieval

- Implement CSRF protection with double-submit cookie pattern
  - Three-way validation: cookie, header, and session database
  - Automatic client-side injection via plugin
  - Server middleware for automatic validation
  - Zero frontend code changes required

- Add session fixation prevention with automatic invalidation
  - Regenerate sessions on password changes
  - Keep current session active, invalidate others on profile password change
  - Invalidate ALL sessions on forgot-password reset
  - Invalidate ALL sessions on admin password reset

- Upgrade password reset codes to 8-char alphanumeric
  - Increased from 1M to 1.8 trillion combinations
  - Uses crypto.randomInt() for cryptographic randomness
  - Excluded confusing characters (I, O) for better UX
  - Case-insensitive verification

- Implement dual-layer account lockout
  - IP-based rate limiting (existing)
  - Per-account lockout: 10 attempts = 30 min lock
  - Automatic unlock after expiration
  - Admin manual unlock via UI
  - Visual status indicators in users table

Database Changes:
- Add csrf_token column to sessions table
- Add failed_login_attempts and locked_until columns to users table
- Add settings table for persistent AUTH_SECRET storage
- All migrations backward-compatible with try-catch

New Files:
- server/utils/csrf.ts - CSRF protection utilities
- server/middleware/csrf.ts - Automatic CSRF validation middleware
- plugins/csrf.client.ts - Automatic CSRF header injection
- server/api/users/unlock/[id].post.ts - Admin unlock endpoint

Modified Files:
- server/utils/database.ts - Core security functions and schema updates
- server/utils/email.ts - Enhanced reset code generation
- server/api/auth/login.post.ts - CSRF + account lockout logic
- server/api/auth/register.post.ts - CSRF token generation
- server/api/auth/logout.post.ts - CSRF cookie cleanup
- server/api/auth/reset-password.post.ts - Session invalidation
- server/api/auth/verify-reset-code.post.ts - Case-insensitive codes
- server/api/profile/update.put.ts - Session invalidation on password change
- server/api/users/password/[id].put.ts - Session invalidation on admin reset
- pages/users.vue - Lock status display and unlock functionality
- docker-compose.yml - Removed default credentials
- nuxt.config.ts - Support auto-generation

All changes follow OWASP best practices and are production-ready.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 17:36:31 -05:00
75b7a93bf9 Update image to use GitLab container registry
Changed image reference from local tag to GitLab container registry at
glcr.rydertech.us/ryder/nlcc-itinerary:latest

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 14:41:05 -05:00
b3eb32a688 Clean up docker-compose.yml
Removed build configuration from docker-compose.yml. The image should be built
separately using 'docker build -t nlcc-itinerary:latest .' and the compose file
now just references the pre-built image with runtime configuration.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 14:34:58 -05:00
a7e6c7725d Claude settings 2025-11-04 14:27:41 -05:00
858f214fab Keep admin on page after editing sermon
Changed behavior so that editing a sermon no longer redirects to homepage.
Instead, it shows a success message and keeps the form filled for further edits.
Creating a new sermon still redirects to homepage as before.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 14:26:30 -05:00
66172e0baa Add sermon retention policy feature
Implemented a configurable retention policy system for sermons with automatic cleanup:
- Added settings table to store retention policy configuration
- Created API endpoints for getting/setting retention policy
- Added Database Settings section to admin page with retention options (forever, 1-10 years)
- Implemented manual cleanup endpoint for on-demand deletion
- Added automated daily cleanup task via Nitro plugin
- Sermons are deleted based on their date field according to the retention policy

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 14:07:14 -05:00
587cefec41 profile deletion fixes 2025-10-12 13:14:04 -04:00
ffb72a7cbd database fix 2025-10-12 01:08:49 -04:00
a505edcae7 created by for sermons 2025-10-12 01:01:01 -04:00
e313def354 footer fixes 2025-10-12 00:42:48 -04:00
7a481f5004 layout fixes 2025-10-12 00:39:14 -04:00
e05b5a032d layout & date fixes 2025-10-12 00:35:14 -04:00
f0f7108765 layout & text fixes 2025-10-12 00:31:07 -04:00
dfdb3e0840 security fixes 2025-10-12 00:24:27 -04:00
773ea92f5d security & footer fix 2025-10-12 00:18:01 -04:00
740ff82642 delete profile fix 2025-10-12 00:10:00 -04:00
c4674a4c85 delete profile & login redirect fixes 2025-10-12 00:05:21 -04:00
056841dc5e rate-limit fixes 2025-10-07 14:19:25 -04:00
ffb721a12c more security improvements 2025-10-07 13:54:29 -04:00
329becfb08 security improvements 2025-10-07 13:39:53 -04:00
a4aca9c99d Downloaded notes filename change 2025-10-07 10:31:39 -04:00
3faec06186 Notes saving fixes 2025-10-07 09:16:27 -04:00
2f505ad7e2 email formatting 2025-10-07 09:10:37 -04:00
8afcac954c auth fixes 2025-10-07 09:02:28 -04:00
7fc1d79eeb Saving notes and username fixes 2025-10-07 08:58:38 -04:00
6b33f79737 Font size adjustment 2025-10-06 19:12:52 -04:00
99a2d7afd2 Font size adjustments 2025-10-06 19:09:06 -04:00
730803a5c1 Profile enhancements 2025-10-06 19:00:18 -04:00
c7b8735a90 Greeting fix 2025-10-06 18:56:26 -04:00
21b480021e Profile enhancements & greeting 2025-10-06 18:54:58 -04:00
49a88f6634 SSPR fix 2025-10-06 18:43:38 -04:00
ee94b7aec1 SSPR fix 2025-10-06 18:39:18 -04:00
18fe670b47 Email SSPR fixes & user management improvements 2025-10-06 18:35:34 -04:00
c127ea35f6 Self-service password reset 2025-10-06 18:26:01 -04:00
53c9ba8fd7 Styling fixes 2025-10-06 17:48:38 -04:00
067053525b Docker compose adjustments 2025-10-06 17:35:22 -04:00
ab952e0334 Mobile layout adjustments 2025-10-06 17:32:01 -04:00
966e244729 Mobile layout adjustments 2025-10-06 17:29:10 -04:00
2dbd4f6ba0 Notes! 2025-10-06 17:20:26 -04:00
291b6743c5 Login watcher 2025-10-06 17:14:54 -04:00
a50791e74c User creation and management 2025-10-06 17:04:34 -04:00
dfa857c131 encryption 2025-10-02 16:25:31 -04:00