Introduces a full in-app notification system with three types (simple,
boolean with server-side callbacks, navigate), three scopes (user, trip,
admin), fan-out persistence per recipient, and real-time push via
WebSocket. Includes a notification bell in the navbar, dropdown, dedicated
/notifications page, and a dev-only admin tab for testing all notification
variants.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Skip loadUser() and exclude /shared/ from the 401 redirect interceptor
so unauthenticated users can open shared trip links without being
redirected to /login. Fixes#308.
toast.warn does not exist in the toast library; calling it threw an error
that was caught and displayed as "Could not connect to Immich" even when
the save succeeded. Fixes#309.
Fixes#306 — OIDC scopes were hardcoded to 'openid email profile',
causing OIDC_ADMIN_CLAIM-based role mapping to fail when the required
scope (e.g. 'groups') wasn't requested. The new OIDC_SCOPE variable
defaults to 'openid email profile groups' so group-based admin mapping
works out of the box. Variable is now documented in README, docker-compose,
.env.example, and the Helm chart values.
Allow the first-boot admin account to be configured via ADMIN_EMAIL and
ADMIN_PASSWORD environment variables. If both are set the account is created
with those credentials; otherwise the existing random-password fallback is
used. Documented across .env.example, docker-compose.yml, Helm chart
(values.yaml, secret.yaml, deployment.yaml), and CLAUDE.md.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds COOKIE_SECURE (fixes login loop on plain-HTTP setups) and the previously
undocumented OIDC_DISCOVERY_URL to .env.example, docker-compose.yml, README.md,
chart/values.yaml, chart/templates/configmap.yaml, and chart/README.md.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Auth middleware now tags its 401s with code: AUTH_REQUIRED so the
client interceptor only redirects to /login on genuine session failures,
not on upstream API errors
- Fix /albums and album sync routes using raw encrypted API key instead
of getImmichCredentials() (which decrypts it), causing Immich to reject
requests with 401
- Add toast error notifications for all Immich operations in MemoriesPanel
that previously swallowed errors silently
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
db was already imported as addonDb; the extra db named import was
unnecessary. Updated the one stray db.prepare call at line 155 to use
addonDb consistently.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- LoginPage now uses getApiErrorMessage() instead of err.message so
backend validation errors (e.g. "Password must be at least 8 characters")
are displayed instead of the generic "Request failed with status code 400"
- Add missing db import in server/src/index.ts
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add a native title tooltip to calendar day cells so hovering over a
public holiday reveals its name (and custom label if configured).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
useCallback captured tripStore at creation time (dep: [routeCalcEnabled]).
If assignments were empty on first render (trip still loading), the callback
would permanently see empty assignments and call setRoute(null) whenever
invoked — e.g. when clicking a place triggers onSelectDay → updateRouteForDay.
Fix: store tripStore in a ref updated on every render so the callback always
reads the latest assignments without needing to be recreated.
Implements a full undo history system for the Plan screen.
New hook: usePlannerHistory (client/src/hooks/usePlannerHistory.ts)
- Maintains a LIFO stack (up to 30 entries) of reversible actions
- Exposes pushUndo(label, fn), undo(), canUndo, lastActionLabel
Tracked actions:
- Assign place to day (undo: remove the assignment)
- Remove place from day (undo: re-assign at original position)
- Reorder places within a day (undo: restore previous order)
- Move place to a different day (undo: move back)
- Optimize route (undo: restore original order)
- Lock / unlock place (undo: toggle back)
- Delete place (undo: recreate place + restore all day assignments)
- Add place (undo: delete it)
- Import from GPX (undo: delete all imported places)
- Import from Google Maps list (undo: delete all imported places)
UI: Undo button (Undo2 icon) in DayPlanSidebar header. PDF, ICS and
Undo buttons all use custom instant hover tooltips instead of native
title attributes.
A toast notification confirms each undo action.
Translations: undo.* keys added to all 12 language files.
Inspector now ignores sidebar widths when window is under 900px,
preventing it from being squeezed when sidebars are visually hidden
but their width values are still set.
security: require auth for uploaded photos (GHSA-wxx3-84fc-mrx2)
GHSA-pcr3-6647-jh72 (HIGH):
- Add canAccessTrip check to all /trips/:tripId/photos and
/trips/:tripId/album-links endpoints
- Prevents authenticated users from accessing other trips' photos
GHSA-wxx3-84fc-mrx2 (LOW):
- /uploads/photos now requires JWT auth token or valid share token
- Covers and avatars remain public (needed for login/share pages)
- Files were already blocked behind auth