diff --git a/web/src/lib/route.ts b/web/src/lib/route.ts index 734be99402..1846f29796 100644 --- a/web/src/lib/route.ts +++ b/web/src/lib/route.ts @@ -152,4 +152,13 @@ export const Route = { // queues queues: () => '/admin/queues', viewQueue: ({ name }: { name: QueueName }) => `/admin/queues/${asQueueSlug(name)}`, + + // continue helper for ensuring same-origin URLs + continue: (url: string | null, fallback: string) => { + if (!url || !url.startsWith('/') || url.startsWith('//')) { + return fallback; + } + + return url; + }, }; diff --git a/web/src/routes/auth/login/+page.ts b/web/src/routes/auth/login/+page.ts index 03a053fcd5..dceb340505 100644 --- a/web/src/routes/auth/login/+page.ts +++ b/web/src/routes/auth/login/+page.ts @@ -8,7 +8,8 @@ import type { PageLoad } from './$types'; export const load = (async ({ parent, url }) => { await parent(); - const continueUrl = url.searchParams.get('continue') || Route.photos(); + const continueUrl = Route.continue(url.searchParams.get('continue'), Route.photos()); + if (authManager.authenticated) { redirect(307, continueUrl); } diff --git a/web/src/routes/auth/pin-prompt/+page.svelte b/web/src/routes/auth/pin-prompt/+page.svelte index d6648889a8..fff02e054f 100644 --- a/web/src/routes/auth/pin-prompt/+page.svelte +++ b/web/src/routes/auth/pin-prompt/+page.svelte @@ -30,7 +30,7 @@ await new Promise((resolve) => setTimeout(resolve, 1000)); - await goto(data.continueUrl); + await goto(Route.continue(data.continueUrl, Route.photos())); } catch (error) { handleError(error, $t('wrong_pin_code')); isBadPinCode = true;