From 8dd22ab8a31d660927366d4a8e45dd398b494c89 Mon Sep 17 00:00:00 2001 From: jubnl Date: Fri, 3 Apr 2026 17:04:18 +0200 Subject: [PATCH 1/3] fix: deselect day when closing DayDetailPanel Closing the panel via the X button now calls handleSelectDay(null), clearing selectedDayId from the Zustand store and resetting the route. Fixes #356. --- client/src/pages/TripPlannerPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/pages/TripPlannerPage.tsx b/client/src/pages/TripPlannerPage.tsx index 47918bd..c2b962c 100644 --- a/client/src/pages/TripPlannerPage.tsx +++ b/client/src/pages/TripPlannerPage.tsx @@ -717,7 +717,7 @@ export default function TripPlannerPage(): React.ReactElement | null { reservations={reservations} lat={geoPlace?.lat} lng={geoPlace?.lng} - onClose={() => setShowDayDetail(null)} + onClose={() => { setShowDayDetail(null); handleSelectDay(null) }} onAccommodationChange={loadAccommodations} leftWidth={isMobile ? 0 : (leftCollapsed ? 0 : leftWidth)} rightWidth={isMobile ? 0 : (rightCollapsed ? 0 : rightWidth)} From e0105115f4ce5325ffa126518d3c2386fb0fea7e Mon Sep 17 00:00:00 2001 From: jubnl Date: Fri, 3 Apr 2026 19:12:26 +0200 Subject: [PATCH 2/3] =?UTF-8?q?fix(immich):=20detect=20http=E2=86=92https?= =?UTF-8?q?=20redirect=20on=20test=20connection=20and=20update=20URL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a user enters an http:// Immich URL that redirects to https://, the test succeeded (GET follows redirects fine) but subsequent POST requests (e.g. photo search) broke due to method downgrade on 301/302. Now testConnection() checks resp.url against the input URL after a successful fetch. If the only difference is http→https on the same host and port, it returns a canonicalUrl so the frontend can update the input field before the user saves — ensuring the correct URL is stored. --- client/src/pages/SettingsPage.tsx | 7 ++++++- server/src/services/immichService.ts | 20 ++++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/client/src/pages/SettingsPage.tsx b/client/src/pages/SettingsPage.tsx index 6558344..d888fc4 100644 --- a/client/src/pages/SettingsPage.tsx +++ b/client/src/pages/SettingsPage.tsx @@ -176,7 +176,12 @@ export default function SettingsPage(): React.ReactElement { try { const res = await apiClient.post('/integrations/immich/test', { immich_url: immichUrl, immich_api_key: immichApiKey }) if (res.data.connected) { - toast.success(`${t('memories.connectionSuccess')} — ${res.data.user?.name || ''}`) + if (res.data.canonicalUrl) { + setImmichUrl(res.data.canonicalUrl) + toast.success(`${t('memories.connectionSuccess')} — ${res.data.user?.name || ''} (URL updated to ${res.data.canonicalUrl})`) + } else { + toast.success(`${t('memories.connectionSuccess')} — ${res.data.user?.name || ''}`) + } setImmichTestPassed(true) } else { toast.error(`${t('memories.connectionError')}: ${res.data.error}`) diff --git a/server/src/services/immichService.ts b/server/src/services/immichService.ts index 9dd3de5..6468338 100644 --- a/server/src/services/immichService.ts +++ b/server/src/services/immichService.ts @@ -69,7 +69,7 @@ export async function saveImmichSettings( export async function testConnection( immichUrl: string, immichApiKey: string -): Promise<{ connected: boolean; error?: string; user?: { name?: string; email?: string } }> { +): Promise<{ connected: boolean; error?: string; user?: { name?: string; email?: string }; canonicalUrl?: string }> { const ssrf = await checkSsrf(immichUrl); if (!ssrf.allowed) return { connected: false, error: ssrf.error ?? 'Invalid Immich URL' }; try { @@ -79,7 +79,23 @@ export async function testConnection( }); if (!resp.ok) return { connected: false, error: `HTTP ${resp.status}` }; const data = await resp.json() as { name?: string; email?: string }; - return { connected: true, user: { name: data.name, email: data.email } }; + + // Detect http → https upgrade only: same host/port, protocol changed to https + let canonicalUrl: string | undefined; + if (resp.url) { + const finalUrl = new URL(resp.url); + const inputUrl = new URL(immichUrl); + if ( + inputUrl.protocol === 'http:' && + finalUrl.protocol === 'https:' && + finalUrl.hostname === inputUrl.hostname && + finalUrl.port === inputUrl.port + ) { + canonicalUrl = finalUrl.origin; + } + } + + return { connected: true, user: { name: data.name, email: data.email }, canonicalUrl }; } catch (err: unknown) { return { connected: false, error: err instanceof Error ? err.message : 'Connection failed' }; } From 98813a9b400d21381e554ddb1ce09ed623cc4c92 Mon Sep 17 00:00:00 2001 From: jubnl Date: Fri, 3 Apr 2026 19:15:30 +0200 Subject: [PATCH 3/3] fix(helm): add ingressClassName support to Helm chart Adds `ingress.className` value and renders `ingressClassName` in the Ingress spec, allowing users to specify the ingress controller class. Closes #377. --- chart/templates/ingress.yaml | 3 +++ chart/values.yaml | 1 + 2 files changed, 4 insertions(+) diff --git a/chart/templates/ingress.yaml b/chart/templates/ingress.yaml index a13b7f4..91c4ba7 100644 --- a/chart/templates/ingress.yaml +++ b/chart/templates/ingress.yaml @@ -10,6 +10,9 @@ metadata: {{- toYaml . | nindent 4 }} {{- end }} spec: + {{- if .Values.ingress.className }} + ingressClassName: {{ .Values.ingress.className }} + {{- end }} {{- if .Values.ingress.tls }} tls: {{- toYaml .Values.ingress.tls | nindent 4 }} diff --git a/chart/values.yaml b/chart/values.yaml index 68cf274..52dfccf 100644 --- a/chart/values.yaml +++ b/chart/values.yaml @@ -97,6 +97,7 @@ resources: ingress: enabled: false + className: "" annotations: {} hosts: - host: chart-example.local