Commit Graph

308 Commits

Author SHA1 Message Date
Paul Nothaft 85a60a2dc7 fix(security): invalidate tokens on password change, enforce session timeout, fix role update
- Set password_changed_at when changing password via adminAuth route so
  existing JWT tokens are rejected by the auth middleware check
- Enforce session timeout on first request with unseen tokens by checking
  token iat against configured timeout (prevents bypass after server restart)
- Convert camelCase roleId/isActive to snake_case role_id/is_active in
  frontend updateUser service (fixes silent role update failures)

Resolves GHSA-rqg3-47p5-vgwg
2026-03-16 22:36:52 +01:00
github-actions[bot] b52cf1f741 chore(main): release 2.6.1 2026-03-11 19:48:05 +00:00
Paul Nothaft 28793bba68 Merge main into beta for release/beta-to-main 2026-03-11 20:12:52 +01:00
github-actions[bot] c92879fbd3 chore(main): release 2.6.0 2026-03-11 10:57:06 +00:00
Paul Nothaft fc75bcdfc3 fix: video upload media type, select all, and dimension repair (#203, #220, #180)
- Fix admin video upload missing media_type/mime_type and video processing (#203)
- Fix Gallery-Premium Select All using atomic callbacks instead of stale closure loop (#220)
- Add photo dimension repair endpoint and admin UI (#180)
- Add E2E tests for all three fixes
2026-03-11 11:50:43 +01:00
github-actions[bot] 0c98c6b453 chore(beta): release 3.17.1-beta.0 2026-03-08 14:42:28 +00:00
Paul Nothaft 831ea6a3bc Merge pull request #218 from the-luap/fix/optional-email-event-creation
fix: respect optional email settings in event creation
2026-03-08 15:42:14 +01:00
Paul Nothaft 9c44a0ebfa fix: respect optional email settings in event creation (#217)
When admin/customer emails were configured as optional in Settings >
Event Creation, the backend still rejected empty values because:

1. express-validator .optional() only skips undefined, not empty strings
   — changed to .optional({ values: 'falsy' }) so "" is treated as
   absent
2. DB columns host_email and admin_email had NOT NULL constraints
   — added migration to make them nullable
3. Email queue insert crashed on null recipient_email
   — skip queuing when no customer email is provided
2026-03-08 15:36:38 +01:00
github-actions[bot] 7d967a47ae chore(beta): release 3.17.0-beta.0 2026-03-05 21:21:48 +00:00
Paul Nothaft 9b7495e005 Merge pull request #214 from the-luap/feat/configurable-upload-batch-size
feat: configurable upload batch size for reverse proxy compatibility
2026-03-05 22:21:29 +01:00
Paul Nothaft cc4503ad28 Revert "feat: configurable upload batch size for reverse proxy compatibility" 2026-03-05 22:16:28 +01:00
Paul Nothaft 424336340b Merge pull request #210 from the-luap/feat/configurable-upload-batch-size
feat: configurable upload batch size for reverse proxy compatibility
2026-03-05 22:14:41 +01:00
Paul Nothaft 02a46e083d feat: add configurable upload batch size for reverse proxy compatibility (#208)
Users behind Cloudflare Tunnel and other reverse proxies cannot upload
batches >100MB. The upload chunking previously used a hardcoded 500MB
limit. This adds a configurable `max_upload_batch_size_mb` setting
(default 95MB) to the admin General settings, leaving headroom below
Cloudflare's 100MB limit.
2026-03-05 22:12:37 +01:00
github-actions[bot] 98fd6dd8e1 chore(beta): release 3.16.0-beta.0 2026-03-05 20:38:56 +00:00
Paul Nothaft 3a30fea862 Merge pull request #207 from the-luap/fix/github-issues-194-197-main
feat: add thumbnail settings UI to admin panel
2026-03-05 21:38:41 +01:00
Paul Nothaft 7d6d2f5688 feat: add thumbnail settings UI to admin settings page (#206)
Add a new "Thumbnails" tab in the admin settings page allowing users to
configure thumbnail dimensions, quality, format, and fit mode from the UI.
Also fix backend route column name mismatch (key/value → setting_key/setting_value)
that caused a 500 error, and add a button to regenerate all thumbnails.
2026-03-04 22:55:14 +01:00
github-actions[bot] a1d941f049 chore(beta): release 3.15.3-beta.0 2026-03-02 22:18:06 +00:00
Paul Nothaft c0301dcbf4 Merge branch 'beta' into fix/github-issues-194-197-main 2026-03-02 23:15:37 +01:00
Paul Nothaft cbecb9323c fix(security): resolve Docker image CVEs for code scanning alerts
- Upgrade nginx base from 1.27-alpine to 1.28-alpine (Alpine 3.23, OpenSSL 3.5.5)
- Upgrade npm to latest in backend production stage to fix tar, minimatch, brace-expansion CVEs
- Add brace-expansion and minimatch overrides for app-level transitive deps
- Remove incompatible body-parser v2 override (breaks Express 4 JSON parsing)
- Remove npm upgrade from builder stages (npm 11 breaks npm ci with existing lockfile)
2026-03-02 23:06:15 +01:00
Paul Nothaft 4272618b3f fix(security): resolve all npm audit vulnerabilities
Frontend (6 → 0 vulnerabilities):
- axios: update to fix DoS via __proto__ key in mergeConfig (CVE-2026-25639)
- swiper: update to fix prototype pollution (critical)
- rollup: update to fix arbitrary file write via path traversal
- minimatch: update to fix multiple ReDoS vulnerabilities
- ajv: update to fix ReDoS with $data option
- markdown-it: update to fix ReDoS

Backend (32 → 0 vulnerabilities):
- multer: update to fix DoS via incomplete cleanup and resource exhaustion
- minimatch: update to fix multiple ReDoS vulnerabilities
- Add npm overrides for transitive dependencies:
  - fast-xml-parser >=5.3.8 (fixes XSS, DoS, stack overflow via AWS SDK)
  - qs >=6.14.2 (fixes arrayLimit bypass DoS via Express)
  - tar >=7.5.8 (fixes path traversal and hardlink attacks via sqlite3)

Docker:
- Pin nginx base image to 1.27-alpine in Dockerfile.prod
- Update security comments in backend Dockerfile
- Existing apk upgrade --no-cache ensures OpenSSL/libexpat CVEs are
  patched at build time (OpenSSL 3.5.5, Alpine 3.23.3)
2026-03-02 10:36:47 +01:00
Paul Nothaft fe07a148f1 fix: respect allowed_file_types setting for upload validation (#203)
The "Allowed File Types" admin setting was stored in the database but
never actually read during upload validation. Both frontend and backend
used hardcoded MIME type lists, causing video uploads (e.g. MP4) to be
rejected even when explicitly added to the setting.

Changes:
- Add getAllowedMimeTypes() to uploadSettings service that reads the
  general_allowed_file_types DB setting and converts extensions to MIME types
- Backend admin upload route now resolves allowed types from settings
  before multer processes files (via resolveAllowedTypes middleware)
- Backend gallery upload route uses dynamic allowed types from settings
- Expose allowed_file_types in public settings API for gallery clients
- Frontend PhotoUpload and UserPhotoUpload components now derive allowed
  MIME types from settings instead of hardcoded image-only lists
- Add shared fileTypes.ts utility for extension-to-MIME conversion

Closes #203
2026-03-01 14:36:34 +01:00
github-actions[bot] 59faf73f04 chore(main): release 2.5.1 2026-02-22 21:37:40 +00:00
github-actions[bot] 3e0c4fd73e chore(beta): release 3.15.2-beta.0 2026-02-22 21:37:26 +00:00
Paul Nothaft 33483cf32d fix: resolve issues #194, #195, #196, #197
- #194: Send full date format object instead of just format string to prevent JSON parse errors
- #195: Remove non-functional forgot password link, fix README port 3005 -> 3000
- #196: Use ADMIN_PASSWORD env var in migration, update existing user in create-admin script instead of failing
- #197: Convert camelCase filter keys to snake_case in photo export to match backend PhotoFilterBuilder
2026-02-22 22:34:44 +01:00
Paul Nothaft cd00bc13d4 fix: resolve issues #194, #195, #196, #197
- #194: Send full date format object instead of just format string to prevent JSON parse errors
- #195: Remove non-functional forgot password link, fix README port 3005 -> 3000
- #196: Use ADMIN_PASSWORD env var in migration, update existing user in create-admin script instead of failing
- #197: Convert camelCase filter keys to snake_case in photo export to match backend PhotoFilterBuilder
2026-02-22 22:27:21 +01:00
github-actions[bot] f672c1daa6 chore(main): release 2.5.0 2026-02-21 19:48:43 +00:00
Paul Nothaft 888c4ab209 Merge main into beta for release/beta-to-main
Resolved conflicts in CHANGELOG.md, backend/package.json, and
frontend/package.json. Version set to 3.15.1.
2026-02-21 20:43:46 +01:00
github-actions[bot] 9045402c9a chore(beta): release 3.15.1-beta.0 2026-02-21 19:31:37 +00:00
github-actions[bot] fe9486e5fa chore(beta): release 3.15.0-beta.0 2026-02-17 19:47:41 +00:00
github-actions[bot] 6613f1b088 chore(beta): release 3.14.0-beta.0 2026-02-17 14:38:14 +00:00
Paul Nothaft 3ea9d5b121 Merge pull request #185 from the-luap/feat/new-features
feat: original filename in admin UI, update dialog, and security hardening
2026-02-17 15:37:56 +01:00
Paul Nothaft 0891be197f feat: show original filename in admin UI (#184)
Surface the existing original_filename from the database in the admin
photo grid hover overlay and photo viewer sidebar, so photographers can
correlate uploaded images with their Lightroom/disk originals. Only shown
when it differs from the system-generated filename. Gallery guests remain
unaffected.
2026-02-17 15:30:12 +01:00
Paul Nothaft 2b25d81144 security: comprehensive hardening across frontend, backend, and infrastructure
- Disable production source maps and hide nginx version
- Reduce JSON body limit from 10gb to 50mb (uploads use multer, not JSON)
- Strip database info and error details from health endpoint
- Mask reCAPTCHA secret key in admin settings API responses
- Whitelist sort/order query parameters in events and photos endpoints
- Stop reflecting arbitrary origins in static file CORS headers
- Align nginx security headers with backend Helmet CSP, remove deprecated X-XSS-Protection
- Strip EXIF metadata from generated thumbnails and hero images
- Bind postgres/redis dev ports to localhost in docker-compose configs
- Add safeExec utility (spawn with shell:false) to prevent command injection
- Convert all exec/execAsync calls in backup, restore, and database backup
  services to use safe spawn-based helpers
2026-02-16 22:33:20 +01:00
Paul Nothaft 50c09904a9 feat: add update instructions dialog, email notifications, and capture date sorting
- Add Update Instructions Dialog with environment-specific commands (Docker/Git/Standalone)
- Add email notification settings for new version alerts
- Add "Sort by Capture Date" option using EXIF metadata extraction
- Fix E2E tests by loading environment variables via dotenv
- Add test-images/ and backend/*.db to .gitignore

Closes #181
2026-02-16 16:23:57 +01:00
github-actions[bot] d239857d9a chore(beta): release 3.13.1-beta.0 2026-02-15 21:49:34 +00:00
Paul Nothaft 3974ba5de5 Merge pull request #182 from the-luap/feat/new-features
fix: restore aspect-ratio layouts and improve hero image quality (#180)
2026-02-15 22:49:20 +01:00
Paul Nothaft 5cef7fdd18 fix: restore aspect-ratio layouts and improve hero image quality (#180)
- Fix masonry/mosaic layout regression where tiles displayed uniform heights
  instead of respecting image aspect ratios. Changed from fixed 150-500px
  height constraints to dynamic constraints based on column width.

- Add hero image optimization pipeline generating 1920x1080 images for
  full-width hero sections instead of using low-quality thumbnails.

- New /hero/:photoId endpoint serves optimized hero images with watermark
  support and automatic generation/caching.

- Add hero_url field to photos API response for frontend consumption.

- Migration 069 adds hero_path column to photos table.
2026-02-15 22:43:18 +01:00
github-actions[bot] edf3a43950 chore(beta): release 3.13.0-beta.0 2026-02-06 23:35:55 +00:00
github-actions[bot] 2c35543e73 chore(beta): release 3.12.0-beta.0 2026-02-06 22:29:57 +00:00
Paul Nothaft 7c75736719 Merge pull request #176 from the-luap/feat/new-features
Feat/new features
2026-02-06 23:29:39 +01:00
Paul Nothaft 9c2a0d272a feat: add admin dark mode and SEO/robots.txt settings
Admin Dark Mode:
- Add AdminDarkModeContext with light/dark/system preference
- Update all admin components with Tailwind dark: classes
- Add dark mode toggle in admin header
- Persist preference in localStorage

SEO Settings:
- Add robots.txt configuration in Settings > SEO tab
- Block AI crawlers (GPTBot, ChatGPT-User, etc.) with toggle
- Custom robots.txt rules management
- Add RobotsMetaTags component for gallery pages
- Backend service for dynamic robots.txt generation
- Database migration for SEO settings storage

UI/UX Improvements:
- Consistent dark mode styling across all admin pages
- Update gallery components with themed CSS classes
- Fix input, card, and button styling for dark mode
2026-02-06 23:26:01 +01:00
github-actions[bot] e05fd64760 chore(beta): release 3.11.0-beta.0 2026-02-06 20:46:15 +00:00
github-actions[bot] 10ff6b118c chore(beta): release 3.10.1-beta.0 2026-02-03 16:25:51 +00:00
Paul Nothaft 2288309395 Merge pull request #166 from the-luap/feat/new-features
fix: sync header_style DB column with theme editor selections (#158)
2026-02-03 17:16:09 +01:00
Paul Nothaft a19e7c40a2 fix: sync header_style DB column with theme editor selections (#158)
The frontend never sent header_style/hero_divider_style as separate
fields when creating or updating events, so the database columns always
kept their default value of 'standard' — making the hero header
impossible to enable through the admin UI.

- Extract headerStyle/heroDividerStyle from theme config and include in
  create and update payloads (CreateEventPage, EventDetailsPage)
- Add backend fallback to extract values from color_theme JSON when not
  explicitly provided, ensuring older clients stay in sync
2026-02-03 17:12:56 +01:00
github-actions[bot] 8ddec6ed8b chore(beta): release 3.10.0-beta.0 2026-02-03 14:56:50 +00:00
Paul Nothaft d9e00dc0db Merge pull request #164 from the-luap/feat/new-features
feat: gallery layouts, hero customization, bulk categories & event types
2026-02-03 15:50:54 +01:00
Paul Nothaft 6c30e2c2ed feat: add category hero/cover photo selection (#163)
Wire up the hero_photo_id column on photo_categories that was added in
the migration but never connected. Backend routes now accept and persist
hero_photo_id on category create/update, a dedicated PUT /:id/hero
endpoint is added, and the gallery API returns hero_photo_id for each
category. Frontend EventCategoryManager shows a clickable thumbnail per
category that opens a photo picker modal. Includes EN/DE i18n keys.
2026-02-03 15:43:23 +01:00
Paul Nothaft 329d224846 fix: resolve code quality issues and add missing i18n keys (#162, #163)
Add missing i18n translations for hero image focal point picker in both
EN and DE locales. Fix lint errors across touched files: remove unused
imports/variables, replace raw buttons with shared Button component,
eliminate inline styles, extract duplicated backend validation, and
remove dead heroImagePosition type.
2026-02-03 10:53:13 +01:00
Paul Nothaft 734868abc2 feat: add hero image focal point picker with anchor positioning (#162)
Add interactive focal point picker for hero images, allowing precise
crop positioning via click or preset buttons (top/center/bottom).
Includes backend validation, migrations, and gallery rendering support.
2026-02-03 10:08:58 +01:00