Commit Graph

92 Commits

Author SHA1 Message Date
cee37c78c4 feat: Unify navigation with hamburger menu across all screen sizes
- Renamed MobileMenu to Menu component (no longer mobile-only)
- Added 500ms debounce to prevent accidental double-tap menu toggles
- Improved click-outside detection using ref-based containment check
- Removed mobile/desktop navigation split - menu now consistent everywhere
- All pages now use single hamburger menu on both mobile and desktop
- Simplified header layouts across index, sermon, profile, admin, and users pages

This provides a cleaner, more consistent UX with the hamburger menu available
on all screen sizes. The debounce prevents the menu from closing accidentally
when navigating between pages or double-tapping.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-06 09:51:09 -05:00
1cb0a4e9a2 feat: Add consistent mobile hamburger menu across all pages
- Updated profile.vue to use MobileMenu on mobile, desktop buttons on desktop
- Updated admin.vue to use MobileMenu on mobile, desktop buttons on desktop
- Updated users.vue to use MobileMenu on mobile, desktop buttons on desktop
- All pages with header navigation now have consistent mobile UX
- Mobile menu provides clean, organized navigation with all options
- Desktop retains traditional button layout for familiarity

This ensures consistent navigation experience across the entire application,
with the hamburger menu appearing on all pages with headers when viewed
on mobile devices.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-06 09:29:34 -05:00
a8673fa255 fix: Make Register links properly navigate to registration form
- Initialize isRegistering state from URL query parameter (mode=register)
- Update URL when toggling between login/register modes for shareable links
- Remove duplicate useRoute() calls in login/register handlers
- Ensures all Register buttons throughout the app show the registration form

This fixes the issue where Register links navigated to /login?mode=register
but the login page ignored the mode parameter and showed the login form instead.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-06 09:12:11 -05:00
c7dc88cdf6 feat: Add mobile hamburger menu and Register button
Implemented comprehensive navigation improvements to make registration
more discoverable and provide a cleaner mobile experience.

## Mobile Improvements
- Created reusable MobileMenu component with hamburger icon
- Replaces cluttered button layout with clean dropdown menu
- Includes Home, Profile, Admin links, and authentication options
- Auto-closes when clicking outside or navigating
- Smooth transition animations

## Register Button Added
- Sermon page: Added Register button next to Login in notes section
- Sermon page: Added Register button in header for non-authenticated users
- Home page: Added Register button next to Login for easy discovery
- All Register links redirect to login page in register mode

## Navigation Consistency
- Home button now visible on sermon pages (desktop and mobile)
- Consistent navigation experience across all pages
- Mobile menu available on both home and sermon pages
- Better mobile UX with less header crowding

Benefits:
- Users can easily find how to register
- Cleaner mobile interface
- Consistent navigation patterns
- Better discoverability of account features

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-06 09:02:41 -05:00
287284c2fe perf: Comprehensive efficiency optimizations
Implemented all 5 critical efficiency improvements to optimize
performance, reduce resource usage, and improve scalability.

## 1. Database Indexes
- Added indexes on sermon_notes foreign keys (user_id, sermon_id)
- Added composite index on sermons (archived, date DESC)
- Added indexes on frequently queried columns across all tables
- Impact: Faster queries as data grows, better JOIN performance

## 2. Eliminated N+1 Query Pattern
- Reduced 2 API calls to 1 on home page load
- Changed from separate active/archived fetches to single call
- Filter archived sermons client-side using computed properties
- Impact: 50% reduction in HTTP requests per page load

## 3. Scheduled Database Cleanup
- Extended existing plugin to clean expired sessions hourly
- Added cleanup for expired rate limits every hour
- Added cleanup for expired password reset codes every hour
- Sermon cleanup continues to run daily based on retention policy
- Impact: Prevents database table growth, better performance

## 4. Multi-stage Docker Build
- Implemented 3-stage build: deps -> builder -> runtime
- Separated build-time and runtime dependencies
- Added non-root user (nuxt:nodejs) for security
- Integrated dumb-init for proper signal handling
- Added health check endpoint at /api/health
- Impact: Smaller image size, faster deployments, better security

## 5. HTTP Caching
- Static assets: 1 year cache (immutable)
- Logos/images: 1 year cache (immutable)
- API routes: No cache (always fresh)
- HTML pages: 10 minute cache with revalidation
- Impact: Reduced bandwidth, faster page loads, less server load

All optimizations follow best practices and maintain backward
compatibility with existing functionality.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-06 08:01:45 -05:00
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
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
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
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
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
773ea92f5d security & footer fix 2025-10-12 00:18:01 -04:00
c4674a4c85 delete profile & login redirect fixes 2025-10-12 00:05:21 -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
21b480021e Profile enhancements & greeting 2025-10-06 18:54:58 -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
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
86b8354b5c display changes 2025-10-02 11:29:06 -04:00
002302bb52 auth changes 2025-10-02 11:14:43 -04:00
b4db0461a0 Footer 2025-10-02 09:24:41 -04:00
ef4d47c4f0 Sermon dates on view page 2025-10-02 09:11:39 -04:00
a70393b375 Sermon dates 2025-10-02 09:09:02 -04:00
27fcedfcd5 Songs & dates 2025-10-02 08:59:05 -04:00
dfe3517ac6 Fix mobile layout: stack View button below dropdown on mobile devices 2025-10-02 08:45:31 -04:00
413df3dabc Fix timezone issue in individual sermon page formatDate function 2025-10-02 00:36:40 -04:00
82aaf15957 Fix timezone issue in admin page formatDate function 2025-10-02 00:33:45 -04:00
b08aeab3a4 Fix timezone issue: dates now display correctly by forcing local time interpretation 2025-10-02 00:32:54 -04:00
2d64213411 Fix hydration mismatch by wrapping sermon sections in ClientOnly 2025-10-02 00:28:47 -04:00
2bd8afe785 Align Today's Sermon with grid layout to match Upcoming Sermons 2025-10-02 00:27:46 -04:00
deb0269a67 Restructure home page: separate Today's Sermon, Upcoming Sermons, and Previous Sermons sections 2025-10-02 00:23:14 -04:00
2b5618a4da Fix sermon selection to exclude future dates - show most recent sermon up to today 2025-10-02 00:17:18 -04:00
8df6f886f3 Fix hydration mismatch by wrapping sermon heading in ClientOnly 2025-10-02 00:14:27 -04:00
3cee9fefd7 Fix home page: show archived sermons in dropdown, fix Today's Sermon heading, add View button 2025-10-02 00:12:39 -04:00
4daea87cd1 Add unarchive functionality and show archived status in admin dropdown 2025-10-02 00:05:45 -04:00
591405c66f Fix mobile layout: Edit and Archive on first row, Delete on second row 2025-10-01 23:56:39 -04:00
fd1f3c14bb Add archive button and confirmation dialogs to admin page 2025-10-01 23:52:24 -04:00
160d898d94 Make church logo clickable on all pages to navigate to home/sermons page 2025-10-01 23:41:43 -04:00