fix(web): adopt OIDC session from PhotoPrism's localStorage (not cookies)
PhotoPrism's /api/v1/oidc/redirect handler doesn't actually set
auth_token/auth_session cookies — it returns an HTML page that does:
setItem("pp:<storageNamespace>:session.id", <session uid>)
setItem("pp:<storageNamespace>:session.token", <X-Auth-Token value>)
setItem("pp:<storageNamespace>:session.user", <user JSON>)
setItem("pp:<storageNamespace>:session.provider", "oidc")
window.location.href = "/library/login";
The deployment's reverse proxy is expected to bounce /library/login
(and /library/*) back to `/`; the SPA then reads PhotoPrism's
storageNamespace from /api/v1/config, looks up session.id and
session.token under that prefix, and adopts the session.
Confirmed via the M0 test instance: prior to this change, server-side
sessions were created on every OIDC return (DB row present) but the
browser had no way to claim them, so the user bounced back to /login.
This commit is contained in:
@@ -19,21 +19,22 @@
|
||||
let { children } = $props();
|
||||
|
||||
// Bootstrap state: the OIDC return drops the user back on `/` with
|
||||
// PhotoPrism's auth_token/auth_session cookies set, but the SPA store
|
||||
// is empty. We try to adopt the cookie session on first mount before
|
||||
// the auth guard can punt to /login.
|
||||
// PhotoPrism's session info written to localStorage under
|
||||
// `pp:<storageNamespace>:session.*`, but the SPA store is empty. We
|
||||
// try to adopt that session on first mount before the auth guard
|
||||
// can punt to /login.
|
||||
let bootstrapped = $state(false);
|
||||
|
||||
onMount(async () => {
|
||||
if (!isAuthenticated()) {
|
||||
await bootstrapSessionFromCookies();
|
||||
await bootstrapSessionFromPhotoPrism();
|
||||
}
|
||||
bootstrapped = true;
|
||||
});
|
||||
|
||||
// Auth guard. Anything outside /login requires a session; otherwise
|
||||
// punt to the login page (which itself redirects authenticated users
|
||||
// back to /). Held until the cookie bootstrap has had a chance to run.
|
||||
// back to /). Held until the bootstrap pass has had a chance to run.
|
||||
$effect(() => {
|
||||
if (!browser || !bootstrapped) return;
|
||||
const onLogin = page.url.pathname === '/login';
|
||||
|
||||
Reference in New Issue
Block a user