diff --git a/web/src/lib/services/photoprism.ts b/web/src/lib/services/photoprism.ts index 948ed90..4800ef1 100644 --- a/web/src/lib/services/photoprism.ts +++ b/web/src/lib/services/photoprism.ts @@ -67,6 +67,36 @@ export async function fetchSession(id: string): Promise { return data; } +/** + * After OIDC completes, PhotoPrism redirects to `siteUrl` with two cookies + * set: `auth_token` (the X-Auth-Token value) and `auth_session` (the session + * UID). If both are present, fetch the matching session and adopt it so the + * SPA picks up the OIDC-issued identity without a username/password trip. + * + * Returns the adopted session, or null when the cookies are missing or stale + * (caller treats null as "stay on /login"). + */ +export async function bootstrapSessionFromCookies(): Promise { + if (!browser) return null; + const read = (name: string): string | null => { + const m = document.cookie.match(new RegExp('(?:^|; )' + name + '=([^;]+)')); + return m ? decodeURIComponent(m[1]) : null; + }; + const token = read('auth_token'); + const sid = read('auth_session'); + if (!token || !sid) return null; + // Prime the http client so the X-Auth-Token interceptor fires. + session.accessToken = token; + try { + const resp = await fetchSession(sid); + adoptSession(resp); + return resp; + } catch { + session.accessToken = null; + return null; + } +} + export async function getConfig(): Promise { const { data } = await http.get('/config'); return data; diff --git a/web/src/lib/types/photoprism.ts b/web/src/lib/types/photoprism.ts index 6f65625..c30a398 100644 --- a/web/src/lib/types/photoprism.ts +++ b/web/src/lib/types/photoprism.ts @@ -55,6 +55,22 @@ export interface PpClientConfig { lenses?: number; countries?: number; }; + /** + * Optional extensions block. PhotoPrism reports OIDC availability and + * the per-provider login URI here so the SPA can render a "Sign in + * with " button. Empty (or `enabled:false`) when OIDC isn't + * configured. + */ + ext?: { + oidc?: { + enabled: boolean; + provider?: string; + loginUri?: string; + icon?: string; + register?: boolean; + redirect?: boolean; + }; + }; } export interface PpSessionResponse { diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index df622a5..086d220 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -1,5 +1,6 @@
@@ -71,8 +95,23 @@ {submitting ? 'Signing in…' : 'Sign in'} -

- OIDC SSO ships in M4 when the IdP is wired up. -

+ {#if oidc} +
+ +
+ or +
+
+ + + {/if}