- Add multi-administrator support with role-based access control
- Add CSS template system with Apple Liquid Glass designs
- Add CSS template selector to event editing
- Fix photo category selection and feedback button visibility (#77)
- Security hardening and Alpine base image upgrade
- Add CSS template selector to ThemeCustomizerEnhanced component
- Rename "Custom CSS" to "Event-specific Custom CSS" for clarity
- Load and save css_template_id when editing events
- Fetch CSS templates when entering edit mode on EventDetailsPage
- Pass CSS template props to ThemeEditorModal
- Add backend validation for css_template_id field
- Fix upload category selection by looking up category from database
and saving category_id to photos table (was being ignored before)
- Use category slug for filename generation during upload
- Improve Like/Comment button visibility in CarouselGalleryLayout and
PhotoLightbox with semi-transparent background and border styling
- Backend PATCH /photos/:photoId now returns updated photo object
- Photo listing now joins with photo_categories table to get actual
category name and slug instead of hardcoding based on photo.type
- Frontend service now properly returns AdminPhoto from update response
Fixes#77
## Changes
### CSS Template System
- Added CSS class hooks to gallery components for custom template targeting
- Gallery sidebar, header, footer, and photo cards can now be styled via CSS templates
- CSS variables on :root allow themes to override colors, effects, and spacing
### Gallery Component CSS Classes Added
- `.gallery-page` - Main gallery container
- `.gallery-header` - Top header bar
- `.gallery-sidebar` - Filter/download sidebar
- `.gallery-sidebar-header`, `.gallery-sidebar-title`, `.gallery-sidebar-close`
- `.gallery-sidebar-content`, `.gallery-sidebar-section`
- `.gallery-sidebar-search-input`, `.gallery-sidebar-search-icon`
- `.gallery-sidebar-backdrop` - Mobile overlay
- `.gallery-btn`, `.gallery-btn-download` - Sidebar buttons
- `.gallery-footer` - Footer section
- `.photo-card`, `.photo-grid` - Photo display elements
### CSS Templates (Database)
- Elegant Dark (id=1): Dark navy theme with light text and red accents
- Liquid Glass Light (id=2): iOS 26 frosted glass effect with gradient background
### Bug Fixes
- Fixed CSS variables not inheriting (moved from .gallery-page to :root)
- Fixed sidebar position breaking layout (removed position: relative override)
- Fixed Elegant Dark sidebar text visibility (white on white issue)
### Other Changes
- Settings page refactoring and cleanup
- i18n locale updates for new gallery features
- Vite proxy port configuration fix
- Admin auth route improvements
- CSS templates service updates
- Add safeParseDate helper to handle dates that may be strings, Date objects, or timestamps
- Replace all parseISO(event.*) calls with safeParseDate() to prevent "dateString.split is not a function" errors
- Fix Vite proxy target from port 3002 to 3001 to match backend server port
Comprehensive feature plan for filtering photos by guest feedback
(ratings, likes, favorites) and exporting selections for professional
photo editing workflows.
Export formats supported:
- TXT: Simple filename list for Lightroom filter paste
- CSV: Spreadsheet with metadata columns
- XMP: Sidecar files with ratings/labels for Lightroom/Capture One
- ZIP: Original photos with folder organization
- JSON: Structured metadata for automation
Key features:
- Admin filter UI with rating thresholds and feedback toggles
- AND/OR filter logic
- Quick presets (Guest Picks, Top Rated, Most Popular)
- Photo selection with batch actions
- XMP rating mapping (PicPeak 1-5 → XMP 1-5 + color labels)
- Background job support for large exports
- Export settings dialog with customization options
Research references:
- Adobe XMP/Lightroom metadata standards
- Capture One EIP format
- IPTC Photo Metadata Standard
- ExifTool capabilities
This document outlines the implementation plan for allowing administrators
to rename gallery events with full Option B implementation:
- Database updates (events, photos, new slug_redirects table)
- File system changes (folders and photo files)
- New API endpoint: POST /api/admin/events/:id/rename
- Frontend UI components (button, dialog, progress indicator)
- Email notification option for resending invitation
- Slug redirect support for backward compatibility
- Transaction handling with rollback mechanism
The feature includes:
- Rename button on event detail page
- Confirmation dialog with new name input
- Real-time slug preview
- Checkbox to resend invitation email
- Progress indicator during operation
- Redirect to renamed event on success
Upgrade npm to latest version in both backend and frontend Dockerfiles
to fix the command injection vulnerability in glob's CLI (CVE-2025-64756).
The vulnerability exists in npm's bundled glob package (< 10.5.0 or < 11.1.0).
Issue #66: Remove redundant picpeak-workers.service creation from setup script.
Workers (fileWatcher, expirationChecker, emailProcessor) are now started
automatically by server.js, so a separate systemd service is not needed.
The legacy service cleanup code is retained for migration purposes.
Issue #67: Ensure storage directories exist at container startup in
wait-for-db.sh. When host directories are bind-mounted in Docker, the
container's built-in directories are overridden. This fix creates the
required directory structure (events/active, events/archived, thumbnails)
before the application starts, preventing EACCES permission errors.
This commit applies essential bug fixes from main branch to ensure no
regressions occur when merging the video-support branch:
1. Increase body parser limits from 100mb to 10gb for large video uploads
- Updated express.json and express.urlencoded limits in server.js
2. Rename video migration from 047 to 048 to avoid conflict
- Main branch already has 047_add_tls_reject_unauthorized.js
- Prevents migration system from skipping one of the migrations
3. Fix category update logic with proper validation
- Add updated_at timestamp to all category updates
- Add explicit null handling for category_id
- Add parseInt with radix parameter for numeric IDs
- Add isNaN validation to prevent invalid values
- Fix event_id constraint in single photo update query
- Add parseInt to photoCount comparison for type safety
These fixes ensure all bug fixes from main branch (especially from
commit d91ab43) are preserved when the PR is merged.
- Increased max file size from 500MB to 10GB
- Created chunkedUploadService.js for managing chunked uploads
- Added chunked upload API endpoints (init, chunk, complete, status, abort)
- Added frontend chunked upload methods to photos.service.ts
- Files >100MB automatically use chunked uploads
- 10MB chunk size for reliable transfers
- Auto-cleanup of expired uploads after 24 hours
- Updated README with 10GB limit and nginx configuration example
- Added Video Support Requirements section with resource recommendations
- Noted FFmpeg is bundled via npm (no system installation required)
- Listed supported formats and max file size
- Updated roadmap to mark Video Support as implemented
This commit implements full video upload, storage, streaming, and playback functionality
for the PicPeak photo sharing platform, allowing users to upload and view videos alongside
photos in galleries.
Backend Changes:
- Added video processing dependencies (fluent-ffmpeg, @ffmpeg-installer/ffmpeg)
- Created videoProcessor.js service for video metadata extraction and thumbnail generation
- Updated photoProcessor.js to handle both images and videos
- Modified adminPhotos.js to accept video files with 500MB size limit
- Enhanced gallery.js with HTTP range request support for video streaming
- Expanded fileSecurityUtils.js with video MIME types and magic number validation
- Added database migration for video support columns (media_type, duration, codecs, dimensions)
Frontend Changes:
- Updated TypeScript types to include video metadata fields
- Created VideoPlayer.tsx component with custom controls
- Modified PhotoUpload.tsx to accept video files (.mp4, .webm, .mov, .avi)
- Updated UserPhotoUpload.tsx for guest video uploads
- Enhanced PhotoGrid.tsx with video badges and duration display
- Modified PhotoLightbox.tsx to conditionally render VideoPlayer for videos
Database Schema:
- Added media_type column ('image' | 'video')
- Added mime_type, duration, video_codec, audio_codec columns
- Added width and height columns for media dimensions
- Migrated existing photos to media_type 'image'
Features:
- Video thumbnail generation from video frames
- Streaming support with range requests for efficient playback
- Video duration display on thumbnails
- Play button indicators on video items
- Full-featured video player with playback controls
- Support for MP4, WebM, MOV, and AVI formats
This feature allows users with non-standard SMTP setups (shared hosting,
self-signed certificates) to bypass certificate validation when needed.
Changes:
- Add database migration for tls_reject_unauthorized column
- Update emailProcessor.js to pass TLS option to nodemailer
- Update adminEmail.js routes to handle the new field
- Add checkbox UI with security warning in EmailConfigPage
- Add English and German translations