Commit Graph

399 Commits

Author SHA1 Message Date
Paul Nothaft 3ccb8154eb fix: correct storage path resolution in multiple files (#96)
Fixed inconsistent storage path fallbacks that caused 500 errors when
serving thumbnails. The paths were using '../../storage' (2 levels up)
instead of '../../../storage' (3 levels up) when STORAGE_PATH env var
is not set.

Affected files:
- backend/src/routes/gallery.js
- backend/src/services/photoService.js
- backend/src/services/eventService.js
2026-01-17 14:01:29 +01:00
Paul Nothaft 691e3aba09 fix: add allow_user_uploads to gallery API responses
The gallery /photos and /info endpoints were not returning the
allow_user_uploads field, causing the upload button to never show
in the frontend since the value was always undefined/false.
2026-01-16 15:15:09 +01:00
Paul Nothaft 2a2c23d116 fix: mobile upload button visibility in gallery
- Remove hidden sm:block wrapper hiding upload button on mobile for Grid layout
- Add upload button to GallerySidebar using existing allowUploads/onUploadClick props
- Ensures upload button is visible in both header and sidebar on all devices

Closes #113
2026-01-16 14:49:37 +01:00
Paul Nothaft 2151147f2d feat: add optional event date and expiration settings
Add global settings to make event_date and expiration optional when
creating galleries. This supports non-event use cases like portraits,
corporate shoots, etc.

New features:
- Settings toggles in Settings → Event Creation tab
- "Require event date" checkbox with warning about random URL identifiers
- "Require expiration date" checkbox with warning about manual archiving
- Galleries without date use random hex suffix in slug (e.g. portrait-smith-a1b2c3)
- Galleries without expiration never expire (stay active until archived)

Backend changes:
- New migration for settings and nullable columns
- Conditional validation based on settings
- Updated slug generation with random suffix fallback
- Updated expiration checker to skip null expires_at
- Updated gallery access control for null expiration

Frontend changes:
- New checkboxes in EventsTab with warnings
- Conditional event date field (shows optional label)
- No Expiration message when expiration disabled
- Updated types for nullable event_date and expires_at

Closes #118
2026-01-16 09:39:32 +01:00
Paul Nothaft 3e69579f5a docs: add API_URL environment variable to .env.example files
Document the API_URL environment variable that is used for constructing
URLs for assets (logos, images) in email notifications. Without this
setting, the system defaults to http://localhost:3001 which causes
broken images in production emails.

Added to both root and backend .env.example files with clear
documentation about its purpose and importance.
2026-01-16 09:39:32 +01:00
Paul Nothaft 808ed1d2f1 fix: checkbox and toggle settings not persisting after page refresh
PostgreSQL's json column type returns parsed values directly (boolean
false instead of string "false"). The backend code used a truthy check
which failed for boolean false values, causing null to be returned
instead of the actual false value.

Changed condition from `if (setting.setting_value)` to explicit null
check `if (setting.setting_value !== null && setting.setting_value !== undefined)`
and added handling for already-parsed json column values.

Fixes #117
2026-01-16 09:39:32 +01:00
Paul Nothaft b40e085d28 Merge pull request #116 from the-luap/release-please--branches--beta
Build and Push Docker Images / build-backend (push) Failing after 3m18s
Build and Push Docker Images / build-frontend (push) Failing after 3m15s
Build and Push Docker Images / summary (push) Successful in 3s
chore(beta): release 3.1.0-beta.0
v3.1.0-beta.0
2026-01-15 15:04:17 -05:00
github-actions[bot] d603567e21 chore(beta): release 3.1.0-beta.0 2026-01-15 20:03:57 +00:00
Paul Nothaft c6fdd38e84 Merge pull request #115 from the-luap/fix/codeql-v4-upgrade
feat: pre-generated watermarks and mobile upload button improvements
2026-01-15 15:03:25 -05:00
Paul Nothaft ae181cf92f fix: show upload button in mobile topbar instead of sidebar
The upload button was hidden in the sidebar on mobile devices, requiring
users to open the menu to find it. Now it appears directly in the topbar
for easy access on all screen sizes.

- Remove !isMobile condition from header upload button
- Add responsive text (short on mobile, full on desktop)
- Remove duplicate upload button from sidebar

Fixes #113
2026-01-15 21:00:17 +01:00
Paul Nothaft 1be974afbb feat: pre-generate watermarks for instant lightbox loading
Previously watermarks were applied on-the-fly when viewing photos in the
lightbox, causing 1+ minute load times for high-resolution images.

This change pre-generates watermarked versions during upload and when
watermark settings change, enabling instant image loading (~50-100ms).

- Add database migration for watermark_path tracking (061)
- Add watermarkGeneratorService for batch operations
- Extend watermarkService with save-to-disk capability
- Modify gallery endpoint to serve pre-generated files
- Add background regeneration when branding settings change
- Add npm script for migrating existing photos

Closes #112
2026-01-15 21:00:10 +01:00
Paul Nothaft d29aab7c70 feat: dynamic website title from branding settings
Update document title based on company name and tagline settings:
- Both filled: "{Company Name} - {Tagline}"
- Name only: "{Company Name}"
- Neither: "PicPeak - Photo Sharing Platform" (default)
2026-01-15 16:43:21 +01:00
Paul Nothaft 050ed37819 fix: add lightbox loading spinner and watermark cache invalidation
- Add spinning loader in lightbox while large images are loading
- Add onLoad callback to AuthenticatedImage for canvas and img modes
- Add ETag headers based on watermark settings for HTTP cache validation
- Add watermark version query param to photo/thumbnail URLs for cache busting
- Ensures images refresh when watermark settings are enabled/changed
2026-01-15 16:19:22 +01:00
Paul Nothaft 83a4344a01 fix: prevent database migration restart failures
- Move migrations table insert inside PostgreSQL transaction for atomicity
- Add PostgreSQL error codes 42701 (duplicate column), 42710 (duplicate
  object), and 23505 (unique violation) to error handling
- Make migrations 006 and 008 idempotent with column existence checks

Fixes #107
2026-01-15 15:43:13 +01:00
Paul Nothaft ce8587b24d fix: lightbox watermark loading, white label translations, and dynamic footer year
- Fix watermarked images not opening in lightbox (add /api prefix to photo URLs)
- Add i18n translations for 'White Label' and 'Hide Powered by' branding settings
- Add complete logo customization translations (EN and DE)
- Replace hardcoded © 2024 with dynamic current year in footer
- Use company name from settings in default footer text
2026-01-15 14:16:00 +01:00
Paul Nothaft ea20446a79 fix: watermark thumbnails, custom logo display, and German translations
- Fix thumbnail display when watermarks enabled globally on existing galleries
  - Backend: Apply watermarks to thumbnails at the thumbnail endpoint
  - Frontend: Remove hack that redirected thumbnails to photo endpoint
- Fix custom logo display in gallery hero sections
  - Only apply brightness/invert filter to default PicPeak logo
  - Custom logos now display as-is with drop-shadow only
- Add German translations for Event Creation and Image Protection settings
  - settings.events: Pflichtfelder, Kundenname/E-Mail erforderlich, etc.
  - settings.imageSecurity: Bildschutz, Ratenbegrenzung, Sicherheitsüberwachung
  - Protection level options in both EN and DE locales
2026-01-15 13:57:22 +01:00
Paul Nothaft 1c8f686c19 Merge pull request #102 from the-luap/release-please--branches--beta
Build and Push Docker Images / build-backend (push) Failing after 3m23s
Build and Push Docker Images / build-frontend (push) Failing after 3m8s
Build and Push Docker Images / summary (push) Successful in 2s
chore(beta): release 3.0.1-beta.0
v3.0.1-beta.0
2026-01-15 06:36:13 -05:00
github-actions[bot] a0f38053d3 chore(beta): release 3.0.1-beta.0 2026-01-15 11:35:58 +00:00
Paul Nothaft cb012186d9 Merge pull request #101 from the-luap/fix/codeql-v4-upgrade
fix: CI workflow fixes for protected branches
2026-01-15 06:35:46 -05:00
Paul Nothaft fe7d45dd12 fix: use Release Please extra-files instead of sync-versions job
Remove sync-versions job that fails on protected branches.
Instead, use Release Please's extra-files feature to update
package.json versions as part of the release PR.
2026-01-15 12:32:07 +01:00
Paul Nothaft c05ae5b0b9 chore: upgrade CodeQL Action from v3 to v4
Address deprecation warning - CodeQL Action v3 will be deprecated in December 2026.
2026-01-15 12:30:25 +01:00
Paul Nothaft dab012c3d1 Merge pull request #100 from the-luap/release-please--branches--beta
Build and Push Docker Images / build-backend (push) Failing after 3m31s
Build and Push Docker Images / build-frontend (push) Failing after 3m23s
Build and Push Docker Images / summary (push) Successful in 5s
chore(beta): release 3.0.0-beta.0
v3.0.0-beta.0
2026-01-15 06:28:27 -05:00
github-actions[bot] 32492c5a91 chore(beta): release 3.0.0-beta.0 2026-01-15 11:24:18 +00:00
github-actions[bot] 2add85eccf chore: sync package.json versions to 2.3.0 2026-01-15 11:19:05 +00:00
Paul Nothaft 5edfb44776 Merge pull request #99 from the-luap/release-please--branches--main
Build and Push Docker Images / build-backend (push) Failing after 4m13s
Build and Push Docker Images / build-frontend (push) Failing after 3m30s
Build and Push Docker Images / summary (push) Successful in 3s
chore(main): release 2.3.0
v2.3.0
2026-01-15 06:18:39 -05:00
github-actions[bot] eedb0fe49c chore(main): release 2.3.0 2026-01-15 11:18:00 +00:00
Paul Nothaft 3c7dc2013f feat: beta/stable release channels with update notifications and bug fixes (#98)
feat: beta/stable release channels with update notifications and bug fixes
2026-01-15 06:17:41 -05:00
Paul Nothaft 617e778a48 feat: implement beta/stable release channels with update notifications
Add dual-channel release strategy for stable and beta releases:

Release Channels:
- Stable channel: production-ready releases (stable, latest, v2.3.0)
- Beta channel: early access features (beta, v2.3.0-beta.1)
- Configurable via PICPEAK_CHANNEL environment variable

Update Notifications:
- Admin dashboard shows available updates for configured channel
- Checks GitHub Releases API with 1-hour cache
- Can be disabled with UPDATE_CHECK_ENABLED=false

CI/CD Changes:
- New release-please-beta.yml workflow for beta prereleases
- Docker build workflow produces stable/beta tags based on branch
- Beta versions use v2.3.0-beta.1 format

New Files:
- .github/workflows/release-please-beta.yml
- release-please-config-beta.json
- .release-please-manifest-beta.json
- backend/src/services/updateCheckService.js
- frontend/src/components/admin/UpdateNotification.tsx

Modified Files:
- docker-compose.production.yml (channel selection)
- .env.example (PICPEAK_CHANNEL, UPDATE_CHECK_ENABLED)
- backend/src/routes/adminSystem.js (/updates endpoint)
- frontend components (VersionInfo, AdminDashboard)
- i18n locales (en.json, de.json)
- README.md and DEPLOYMENT_GUIDE.md (documentation)
2026-01-15 12:11:06 +01:00
Paul Nothaft e3c3c4c951 fix: gallery thumbnails not loading (404 errors) #96
The gallery thumbnail endpoint was returning 404 when thumbnail_path
was null or the file didn't exist, unlike the admin endpoint which
generates thumbnails on demand using ensureThumbnail().

- Import ensureThumbnail from imageProcessor
- Use ensureThumbnail() in gallery thumbnail route to generate
  thumbnails on demand if they don't exist
- This matches the admin endpoint behavior

Fixes #96
2026-01-15 11:22:13 +01:00
Paul Nothaft 0e3b50d1b6 fix: watermark upload JSON parsing and image quality preservation
- Fix JSON parsing error when uploading watermark logo by handling both
  JSON-stringified and raw string paths
- Ensure publicPath is JSON.stringify'd consistently when saving
- Preserve original image format (PNG/WebP/JPEG) when applying watermarks
- Use maximum quality (100) to prevent unnecessary recompression
2026-01-12 13:24:21 +01:00
Paul Nothaft bd8b885f7f fix: display new password after admin password reset
- show-admin-credentials.js --reset now displays the generated password
  instead of just saying "[NEWLY RESET - stored in database]"
- Also sets must_change_password flag to force password change on login
- Updated DEPLOYMENT_GUIDE.md and SIMPLE_SETUP.md to clarify that the
  new password is displayed in console output after reset
2026-01-12 13:23:24 +01:00
Paul Nothaft 3cdc0ea715 fix: prevent unnecessary image recompression and fix SQLite migration #95
- Skip image processing for basic/standard protection levels when no
  fingerprinting or watermarking is enabled
- Preserve original image format (PNG/WebP/JPEG) instead of always
  converting to JPEG
- Fix SQLite migration failure for fresh installations by adding
  multilingual columns to email_templates table before inserting
  admin email templates

Fixes #95
2026-01-12 13:20:39 +01:00
github-actions[bot] a2ff9eae3f chore: sync package.json versions to 2.2.4 2026-01-08 22:24:23 +00:00
Paul Nothaft 3f7631cd95 Merge pull request #93 from the-luap/release-please--branches--main
Build and Push Docker Images / build-backend (push) Failing after 3m9s
Build and Push Docker Images / build-frontend (push) Failing after 3m9s
Build and Push Docker Images / summary (push) Successful in 2s
chore(main): release 2.2.4
v2.2.4
2026-01-08 23:23:57 +01:00
github-actions[bot] 53b8764ed7 chore(main): release 2.2.4 2026-01-08 22:22:51 +00:00
Paul Nothaft 082d8ab205 fix: Docker Swarm DNS resolution and backup status display (v2.2.3)
fix: Docker Swarm DNS resolution and backup status display (v2.2.3)
2026-01-08 23:22:33 +01:00
Paul Nothaft 749100c92a fix(backup): add lastBackup alias and totalBackups for frontend compatibility
The frontend expected `status.lastBackup` but the backend was returning
`status.lastRun`. This caused the backup dashboard to show "No backup available"
even when backups existed in the history.

Added:
- `lastBackup` as alias for `lastRun`
- `totalBackups` count of completed backups
2026-01-08 23:11:48 +01:00
Paul Nothaft 3798662722 Merge pull request #91 from the-luap/release-please--branches--main
Build and Push Docker Images / build-backend (push) Failing after 3m22s
Build and Push Docker Images / build-frontend (push) Failing after 3m0s
Build and Push Docker Images / summary (push) Successful in 2s
chore(main): release 2.2.3
v2.2.3
2026-01-08 18:26:58 +01:00
github-actions[bot] fa1397cb8c chore(main): release 2.2.3 2026-01-08 17:26:11 +00:00
Paul Nothaft cc1ddfd42c fix(nginx): Add Docker DNS resolver for Swarm/dynamic service discovery (v2.2.3)
Fixes 502 Bad Gateway on root path in Docker Swarm by adding DNS resolver
  configuration (127.0.0.11) and dynamic DNS resolution for all proxy_pass 
  directives. This ensures nginx resolves backend service IPs on each request 
  rather than caching them at startup.
2026-01-08 18:25:54 +01:00
Paul Nothaft 049837f9d6 fix(nginx): add Docker DNS resolver for Swarm/dynamic service discovery
- Add resolver 127.0.0.11 directive for Docker's internal DNS
- Use variable-based proxy_pass to force per-request DNS resolution
- Fix 502 Bad Gateway error on root path in Docker Swarm deployments

The issue was that nginx caches DNS lookups at startup, but in Docker
Swarm where service IPs can change dynamically, this caused stale DNS
entries leading to 502 errors for proxied requests.

Bumps version to 2.2.3
2026-01-08 16:25:05 +01:00
Paul Nothaft 29dc2a3cf1 Merge pull request #89 from the-luap/release-please--branches--main
Build and Push Docker Images / build-backend (push) Failing after 3m26s
Build and Push Docker Images / build-frontend (push) Failing after 3m23s
Build and Push Docker Images / summary (push) Has been cancelled
chore(main): release 2.2.2
v2.2.2
2026-01-08 15:53:44 +01:00
github-actions[bot] d2cba449b0 chore(main): release 2.2.2 2026-01-08 14:51:24 +00:00
Paul Nothaft e0bd19a74d fix: Align nginx backend port for production Docker deployments (v2.2.2) (#88)
Fix 502 Bad Gateway on root path in production Docker/Traefik deployments.

  - nginx.conf: backend:3001 → backend:3000 (matches production container port)
  - docker-compose.yml: align dev environment to use port 3000
  - Bump version to 2.2.2
2026-01-08 15:51:10 +01:00
Paul Nothaft 0ab8cbde7f chore: bump version to 2.2.2
Includes fix for nginx backend port alignment (3001 → 3000) that caused
502 errors on root path in production Docker deployments.
2026-01-08 15:46:41 +01:00
Paul Nothaft 3a8d53f492 fix: align backend port to 3000 across all configurations
The production docker-compose used port 3000 internally but nginx.conf
was hardcoded to port 3001, causing 502 errors on the root path (/).

Changes:
- Update nginx.conf to use backend:3000
- Update docker-compose.yml to use PORT=3000 for consistency
- Update port mapping and healthcheck to use port 3000
2026-01-08 15:28:35 +01:00
Paul Nothaft 804a964ba0 Merge pull request #87 from the-luap/release-please--branches--main
Build and Push Docker Images / build-backend (push) Failing after 2m58s
Build and Push Docker Images / build-frontend (push) Failing after 3m4s
Build and Push Docker Images / summary (push) Has been cancelled
chore(main): release 2.2.1
v2.2.1
2026-01-08 14:01:58 +01:00
github-actions[bot] d2cd1aa933 chore(main): release 2.2.1 2026-01-08 13:01:36 +00:00
Paul Nothaft d7ecf83d32 fix: Resolve branding display issues and invitation parsing errors (v2.2.1) (#86)
Fixes #84, Fixes #85
  - Fix uploads proxy routing in nginx and vite dev server
  - Fix logo/favicon state handling in BrandingPage
  - Fix invitation API response field transformation (snake_case → camelCase)  
  - Add hide_powered_by to public settings API
  - Mark Multiple Administrators as implemented in roadmap
  - Bump version to 2.2.1
2026-01-08 14:01:21 +01:00
Paul Nothaft ebb2ce6065 Merge branch 'main' into feature/multiple-administrators 2026-01-08 13:58:41 +01:00