3.43.0 (2026-05-07)
Features
- add admin dark mode and SEO/robots.txt settings (9c2a0d2)
- add bulk category editing for photos (#157) (eca36c7)
- add category hero/cover photo selection (#163) (6c30e2c)
- add configurable upload batch size for reverse proxy compatibility (#208) (02a46e0)
- add COOKIE_SECURE=auto for mixed HTTPS/HTTP deployments (#298) (b1dfbe4)
- add COOKIE_SECURE=auto for mixed HTTPS/HTTP deployments (#298) (15a8ab4)
- add customizable event types with admin management (f8881d5)
- add Dutch (nl) locale and fix missing translation keys across all locales (b54a80d)
- add Dutch locale and fix missing translation keys (e32da68)
- add Gallery Premium and Gallery Story layouts (Beta) (e179def)
- add hero image focal point picker with anchor positioning (#162) (734868a)
- add justified layout modes and aspect-ratio-aware mosaic (#146) (608bbd5)
- Add justified layout modes and aspect-ratio-aware mosaic (#146) (ef2ae00)
- add justified/rows layout mode to masonry gallery (#146) (e081b56)
- add justified/rows layout mode to masonry gallery (#146) + security fixes (cd1d504)
- add optional event date and expiration settings (3079eaa)
- add optional event date and expiration settings (2151147), closes #118
- add original filename preservation and Lightroom export support (a59f414)
- add original filename preservation and Lightroom export support (9872ad3)
- add per-event custom logo upload with bug fixes (85170b8)
- add per-event hero logo customization options (0790a1d)
- add per-gallery thumbnail scale setting (#172) (#251) (ee46088)
- add photo cap per event and Portuguese (pt-BR) locale (1fa222e)
- add photo cap per event and Portuguese locale (088de43)
- add quilted layout, fix mosaic, and backfill photo dimensions (#146) (46ed1bc)
- add thumbnail settings UI to admin panel (3a30fea)
- add thumbnail settings UI to admin settings page (#206) (7d6d2f5)
- add update instructions dialog, email notifications, and capture date sorting (50c0990), closes #181
- add visual WYSIWYG email template editor (#229) (04a7ea8)
- branding: 8-token CI palette + force color mode + dark-mode consistency (8050927)
- branding: force color mode (dark or light) site-wide (5a162fc)
- branding: inline force color mode with auto-save + clearer palette help text (67d7d8d)
- branding: per-family generic fallback via meta.json (dcff451)
- branding: preview each font in its own face in the picker dropdown (b4f9b65)
- branding: self-hosted webfonts with filesystem scanner (d04bf28)
- branding: self-hosted webfonts with filesystem scanner (bac51fe)
- cms: add external URL toggle for imprint and privacy pages (b2c8161)
- cms: add per-page external URL override — backend (66423bb)
- cms: admin UI for external imprint/privacy URL (a4e3d10)
- cms: redirect legal links to external URL when configured (c5bba50)
- configurable upload batch size for reverse proxy compatibility (9b7495e)
- configurable upload batch size for reverse proxy compatibility (4243363)
- customisable 404 + gallery-not-found pages via CMS (#324) (4f77905)
- decouple hero header from gallery layouts (#158) (7b8d8bd)
- draft mode, admin branding, and workflow improvements (dc98206)
- draft mode, admin branding, and workflow improvements (40332a7)
- dynamic website title from branding settings (d29aab7)
- email: expand email palette to 8 tokens + Sync from Branding button (47b6b39)
- events: add Photos column to admin events list (#384) (d561db8)
- events: add Photos column to admin events list (#384) (ffb4318)
- events: bulk delete with password confirmation (#384) (647aea2)
- events: bulk delete with password confirmation (#384) (48d538f)
- events: prefill admin email + admin picker on event creation (3fe8e61)
- events: prefill admin email + admin picker on event creation (ee56b67)
- events: Sync from Branding button in gallery theme customizer + clarified default inheritance (bdbe7b8)
- events: tree view for external media folder picker (cdd40ac)
- events: tree view for external media folder picker (f927b09)
- frontend: dedupe /public/settings via shared usePublicSettings hook (#325) (3d4ae4d)
- gallery layouts, bulk category editing, and hero header improvements (7037106)
- gallery layouts, hero customization, bulk categories & event types (d9e00dc)
- gallery layouts, hero customization, event types, and UX improvements (#146, #155-163, #170, #171) (4280444)
- gallery: decouple header style from layout, add banner option (1f1a856)
- gallery: decouple header style from layout, add banner option (24d7277)
- gallery: decouple header style from layout, add banner option (aff29c9)
- gallery: icon-only menu, accent Download CTA (#386) (876b35b)
- gallery: icon-only menu, accent Download CTA, logo aligned (#386) (de8ad5f)
- guest selections with per-person identity (#292) (3856ba2)
- guest selections with per-person identity (#292) (ad4e5a7)
- i18n: add Brazilian Portuguese (pt-BR) locale (375f512)
- i18n: improve pt locale with pt-BR phrasings, remove duplicate pt-BR file (f25559c)
- improve gallery layouts with aspect-ratio-aware masonry and mosaic modes (#146) (aacfcd5)
- improve hero image UX and live preview (#163, #158) (d63f67a)
- multilingual email templates with translations table (8c5996e)
- multilingual email templates with translations table (f50d7c0)
- native multi-arch Docker images (Apple Silicon, ARM64 Linux) (df30618)
- native S3 storage backend (#328) + presigned download follow-up (1b717ce)
- new features and bug fixes for beta release (151e1bf)
- optional customer phone field gated by global toggle (#322) (be6cb28)
- original filename in admin UI, update dialog, and security hardening (3ea9d5b)
- original filename in admin UI, update dialog, security hardening, and bug fixes (bcf2745)
- outbound webhooks for event/photo lifecycle (#327) (c488f48)
- per-event custom logos, customizable event types, and multiple bug fixes (4c08160)
- photo visibility control with client access (#172) (4a93e4e)
- photo visibility control with client access (#172) (e1b6e43)
- pre-generate watermarks for instant lightbox loading (1be974a), closes #112
- pre-generated watermarks and mobile upload button improvements (c6fdd38)
- pre-zip download all and photo replacement by name (#312, #313) (d3f1206)
- pre-zip download all and photo replacement by name (#312, #313) (e18afd3)
- presigned download UI + S3 prefix walker auto-importer (follow-ups) (446d80a)
- public v1 API + token management + OpenAPI docs (#322) (808b15b)
- register Russian locale and add to language selector (6f95b8c)
- S3 storage + webhooks + settings dedupe + backup fixes (06d54be)
- show original filename in admin UI (#184) (0891be1)
- sort photos by capture date with configurable default sort (#283) (8805fa5)
- sort photos by capture date with configurable default sort (#283) (633d4a0)
- support Apple Silicon natively via multi-arch images (c282a72)
- theme: expand color settings to 8-token CI palette + alt button (114aab5)
- upload: async photo processing — backend (PR-B part 1) (851744c)
- upload: async photo processing — frontend (PR-B part 2) (3b827b8)
- upload: async photo processing + fix(auth): /auth/session symmetry (loop fix) (907bcf1)
- upload: two-state UI + temp dir cleanup (PR-A of async processing) (86dfcc4)
- visual WYSIWYG email template editor (703c03f)
- warn about low thumbnail resolution when selecting beta themes (ee3f6ae)
- warn about low thumbnail resolution with beta themes (aef9b4e)
- webhooks: enrich event.* payloads with customer contact + share_token (#341) (7ea4801)
- webhooks: enrich event.* payloads with customer contact + share_token (#341) (1e69d5f)
Bug Fixes
- add allow_user_uploads to gallery API responses (691e3ab)
- add lightbox loading spinner and watermark cache invalidation (050ed37)
- add STORAGE_PATH to production docker-compose (cdda709)
- address beta feedback - gallery layout fixes, Russian locale, email logo (#249) (486239a)
- address bugs and feature requests from discussion #317 (6cfff6f)
- address Shannon security assessment findings (37 vulnerabilities) (#254) (23cd9cb)
- admin photo feedback filters have no effect (#293) (9ed8a2b)
- admin: tab underlines use accent (not accent-dark) for proper highlight color (565ae45)
- apply password change fix to regular modal + longer toast delay (#263) (c63bc47)
- apply password change redirect fix to regular modal too (#263) (147dc28)
- apply sort direction in gallery and respect show_feedback_to_guests (#302, #303) (3716ff5)
- apply sort direction in gallery view and respect show_feedback_to_guests (#302, #303) (dffe057)
- auth: /auth/session must enforce session timeout symmetrically (#350 recurrence) (c8e09c2)
- auth: /auth/session must enforce session timeout symmetrically (#350 recurrence) (b106da1)
- auth: /auth/session must reject tokens that adminAuth/galleryAuth would reject (f905f7e)
- auth: /auth/session must verify issuer claim like adminAuth (#350) (83dedbc)
- auth: make /auth/session verify the issuer claim like adminAuth (#350) (88a6c6a)
- backup: cron schedule mapping + manifest format detection + bigint coerce (ab4095f)
- backup: incremental backups against S3 + jsonb stats parsing (e232f9f)
- branding: admin sidebar uses accent-dark, primary buttons follow CI token (fc2bce3)
- branding: comprehensive sweep — replace remaining primary-* legacy colors with accent tokens (578a174)
- branding: selected-state accent colors, force-mode actually flips galleries, compact color picker layout (5b410ed)
- branding: working tooltips, high-contrast selected states, gallery chrome follows accent (b19bb0c)
- checkbox and toggle settings not persisting after page refresh (808ed1d), closes #117
- cms: apply dark mode to CMS editor, public CMS, and admin modals (d2a10f6)
- cms: nl/pt/ru i18n + gate external_url in public response (08d0462)
- cms: nl/pt/ru i18n + gate external_url in public response (bce5c1f)
- correct invitation activation validation and add missing translations (991aa98), closes #129
- correct invitation email link URL path (86fa104), closes #129
- correct storage path resolution in multiple files (#96) (0e3674b)
- correct storage path resolution in multiple files (#96) (3ccb815)
- database migration restart bug, lightbox loading spinner, and watermark cache invalidation (7c58749)
- dedupe parallel admin 401 redirects to /admin/login (038e84c)
- discussion #317 issues and #318 archive crash (2f2f405)
- display welcome message in gallery and fix guest thumbnail URLs (#306, #307) (b05c36a)
- display welcome message in gallery and fix guest thumbnail URLs (#306, #307) (9323bef)
- docker compose v2 syntax and add missing ADMIN_PASSWORD to .env.example (#189) (0817443)
- docker: install system ffmpeg on Alpine, drop broken bundled binary (3ab8a64)
- docker: install system ffmpeg on Alpine, drop broken bundled binary (96818c7)
- dynamic website title from branding settings (4701edc)
- email: render conditionals, localise password placeholders, fix caller/template variable drift (0767203)
- email: render conditionals, localise password placeholders, fix caller/template variable drift (e8052ad)
- event-specific custom CSS settings not being saved (dadef81), closes #136
- events search/counters (#346), lazy gallery skeleton (#321), smooth lightbox swipe (#348) (6229b38)
- events without expiration date incorrectly shown as expired (c4f16eb)
- events: admin-set password on reset, full-URL gallery_link in all emails (0d1f82d)
- events: admin-set password on reset, full-URL gallery_link in all emails (ff50c74)
- events: coerce expires_in_days to Number before addDays (e5712d8)
- events: coerce expires_in_days to Number before addDays (db29d0e)
- events: match scrollbar to theme in external folder tree picker (bd42ee1)
- events: server-side search/pagination to remove first-100 cap (#346) (a5b20ca)
- events: show customer phone in event details view (#331) (4c73d22)
- events: stop mapping branding_logo_position onto hero_logo_position (af2b062)
- events: stop mapping branding_logo_position onto hero_logo_position (ef1c875)
- external media dimensions, theme race condition, email color customization (dfae2c2)
- floor password_changed_at when comparing against JWT iat (793e410)
- fonts: drop immutable Cache-Control to allow font replacement rollout (5703fcb)
- gallery: default controls to inline for every layout (045e9ea)
- gallery: lazy-render skeleton grid for fast loads (#321 follow-up) (d9d8137)
- gallery: preserve sidebar controlsStyle on banner migration (05dadff)
- gallery: single-finger swipe nav in mobile lightbox (#332) (4c8eba0)
- gallery: use ref for swipe-start to avoid stale-closure miss (#332) (fcddfe0)
- gallery: WCAG-safe Download button text + extract HeaderDownloadButton (#401 follow-ups) (04e928d)
- gallery: WCAG-safe Download button text + extract HeaderDownloadButton (#401 follow-ups) (0c80abd)
- guest feedback flow bugs in Masonry grid and PhotoLightbox (#292) (54badef)
- guest feedback flow bugs in Masonry grid and PhotoLightbox (#292) (77f07e9)
- handle null dates in dashboard and gallery pages (c5a8ffc)
- hero header state and preview in admin theme editor (#158) (f554f46)
- improve ghost button visibility in admin dark mode (4912e2b)
- improve password validation errors and event list UX (#170, #171) (171abb3)
- improve photo serving, category filters, and upload chunking (#155, #156, #161) (fa4c838)
- increase upload limit to 1GB and fix category filters (#155, #156) (397d33a)
- issue #203 file type validation + security CVE fixes (8017171)
- lightbox: mobile toolbar clipping + iOS safe-area + viewport-fit (#336) (42a7ae4)
- lightbox: smooth carousel swipe + drop instructional hint (#348) (743086d)
- mobile lightbox + share previews + customer phone bug triage (1e40677)
- mobile upload button not visible in gallery (#113) (cacaffa)
- mobile upload button visibility in gallery (2a2c23d), closes #113
- mobile upload button visibility in gallery (df7dbff), closes #113
- mobile upload button visibility in gallery (#113) (05a5307)
- mobile upload button visibility in gallery (#113) (6cb4342)
- nginx: proxy /fonts requests to backend (e6c03e4)
- pin npm to v10 in backend Dockerfile (ddefd3a)
- pin npm upgrade to v10 in backend Dockerfile (978e447)
- prevent backend crash on archive when admin_email is null (#318) (e4b0f96)
- prevent database migration restart failures (83a4344), closes #107
- remove non-functional watermark toggle from Feature Toggles (d4a15db)
- render minimal/none header styles, cap hero height, switch category hero images (#158, #162, #163) (bc6c48b)
- resend gallery email fails for events without password (6b3ead7), closes #137
- resolve admin invitation flow issues and improve STORAGE_PATH documentation (41bf6ff)
- resolve code quality issues and add missing i18n keys (#162, #163) (329d224)
- resolve code scanning security alerts (multer, tar, Node 22) (85a07fc)
- resolve external media dimensions, gallery theme race condition, and add email color customization (bbeedd1)
- resolve issues #194, #195, #196, #197 (33af088)
- resolve issues #194, #195, #196, #197 (5ea4ef3)
- resolve issues #194, #195, #196, #197 (33483cf)
- resolve issues #194, #195, #196, #197 (cd00bc1)
- resolve JWT iat timing issue in password change (#263) (c031b1e)
- resolve mixed light/dark mode styling in admin UI (#175) (f8c8abd)
- resolve password change redirect loop (#263) and file watcher crash (#269) (b23c51b)
- resolve password change redirect loop and file watcher crash (835bdf5), closes #269
- resolve redirect loop after mandatory password change (#263) (07fc5e6)
- resolve redirect loop after mandatory password change (#263) (3c8d344)
- respect allowed_file_types setting for upload validation (#203) (fe07a14)
- respect optional email settings in event creation (831ea6a)
- respect optional email settings in event creation (#217) (9c44a0e)
- restore aspect-ratio layouts and improve hero image quality (#180) (3974ba5)
- restore aspect-ratio layouts and improve hero image quality (#180) (5cef7fd)
- revert /api prefix in adminPhotos.js to avoid double-prefix (094276d)
- revert /api prefix in adminPhotos.js to avoid double-prefix (#307) (ceb2a09)
- security: invalidate tokens on password change, enforce session timeout, fix role update (85a60a2)
- security: invalidate tokens on password change, enforce session timeout, fix role update (f362239)
- security: resolve all npm audit vulnerabilities (4272618)
- security: resolve Docker image CVEs for code scanning alerts (cbecb93)
- security: token invalidation on password change, session timeout enforcement (0a3a537)
- security: token invalidation on password change, session timeout enforcement (7ca9631)
- set JWT iat after password_changed_at to prevent token rejection (#263) (b1d1667)
- share: OG/Twitter-card metadata for gallery share URLs (#333) (5275621)
- shorten Save button label on email template editor (7250c42)
- show upload button in mobile topbar instead of sidebar (ae181cf), closes #113
- sync backend package-lock.json for security deps (bb81fa5)
- sync backend package-lock.json with security dep updates (03e1989)
- sync header_style DB column with theme editor selections (#158) (2288309)
- sync header_style DB column with theme editor selections (#158) (a19e7c4)
- theme picker buttons no longer submit the parent form (#326) (2eead52)
- theme save without Live Preview, Branding default on new events, gallery loading flicker (#323, #321) (822be9a)
- theme-preset match loop ignores extra fields like logoUrl (#323) (b63a877)
- theme: centralise force-mode enforcement inside ThemeContext so every gallery flips (21188f4)
- theme: kill initial white frame + theme-aware skeleton tiles (#358 follow-up) (f529c9e)
- theme: kill initial white frame + theme-aware skeleton tiles (#358 follow-up) (1a530ae)
- theme: pre-React bootstrap to kill white-flash on dark galleries (#358) (07b41e6)
- theme: pre-React bootstrap to kill white-flash on dark galleries (#358) (f81a872)
- update dependencies to resolve code scanning security alerts (1f524f2)
- update docker-compose to docker compose and add ADMIN_PASSWORD to .env.example (#189) (a4c6248)
- update packages to fix security vulnerabilities (8097a0c)
- update security policy with private reporting channels (308e086)
- update security policy with private reporting channels (7f77362)
- update security policy with proper contact email and private reporting (67b0f32), closes #223
- use actual photo aspect ratios in masonry columns mode (#146) (8711f96)
- use CSS Columns for gap-free mosaic layout (#146) (821d329)
- use photo dimensions for mosaic aspect ratios (#146) (27ff51e)
- video upload media type, select all, and dimension repair (#203, #220, #180) (fc75bcd)
- video upload, select all, and dimension repair (#203, #220, #180) (a0bb080)
- wire admin photo feedback filters into grid query (#293) (d4b4dc6)
- wrap email preview with full styled header/footer template (9a6d2e8)
- wrap email preview with full styled header/footer template (fc0911a), closes #229
- wrap test email with standard email template (#252) (954a011)
Reverts
- branding: per-option font preview (defer to follow-up) (f410207)
Documentation
- add API_URL environment variable to .env.example files (3e69579)
- add Buy Me a Coffee badge + Support section (46bc894)
- add External Media Library section to deployment guide (#270) (2e1c71c)
- add External Media Library section to deployment guide (#270) (f6ca713)
- clarify file system photo import requires existing event (#269) (5295516)
- clarify file system photo import requires existing event (#269) (ee0baaf)
- emphasize importance of STORAGE_PATH in env example (3397807)
- fonts: cache rollout, stale-list note, meta.json (bd0e052)
- move documentation to docs.picpeak.app, drop in-repo copies (02ed5d4)
- move documentation to docs.picpeak.app, drop in-repo copies (0faf9b3)
- readme: add Contributors section with @Luca-Timo and @Rekoo-PS (c60ab74)
- readme: add Contributors section with @Luca-Timo and @Rekoo-PS (dbe0a30)
- rewrite README — shorter, cleaner (62643f2)
- rewrite README — shorter, cleaner, less AI-sounding (64f6061)