feat(session): ensure dpop even with OIDC
This commit is contained in:
@@ -754,6 +754,11 @@ export interface SessionSummary {
|
||||
is_revoked: boolean;
|
||||
is_active: boolean;
|
||||
oidc_sid: string | null;
|
||||
/** `true` when this row IS the admin's currently-active session —
|
||||
* compared server-side by `dpop_jkt`. Panel uses this to warn
|
||||
* before revoking ("this will log you out"). Always `false` when
|
||||
* the admin's own session is unbound. */
|
||||
is_current: boolean;
|
||||
}
|
||||
|
||||
/** Wire response of `GET /api/admin/sessions`. */
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* routing: externals (magic-link / OIDC-only / OCM recipients) have no home
|
||||
* folder and land on the shared-with-me view.
|
||||
*/
|
||||
import { fetchMe, tryRefresh } from '$lib/api/endpoints/auth';
|
||||
import { bindDpopIfPossible, fetchMe, tryRefresh } from '$lib/api/endpoints/auth';
|
||||
import { drives } from '$lib/stores/drives.svelte';
|
||||
import type { User } from '$lib/api/types';
|
||||
import { ensureActiveUser } from '$lib/utils/localStoragePrefs';
|
||||
@@ -45,8 +45,18 @@ class SessionStore {
|
||||
if (!me && (await tryRefresh())) {
|
||||
me = await fetchMe();
|
||||
}
|
||||
if (me) this.setUser(me);
|
||||
else this.user = null;
|
||||
if (me) {
|
||||
this.setUser(me);
|
||||
// Post-redirect DPoP bind — catches OIDC / magic-link
|
||||
// flows whose server-side callback creates the session
|
||||
// UNBOUND (no way for the redirect to carry the JKT in
|
||||
// the callback body). One-shot per SPA lifetime because
|
||||
// `this.loaded` guard makes `load()` a singleton;
|
||||
// server returns 409 if the session is already bound
|
||||
// (harmless — result is swallowed). Fire-and-forget so
|
||||
// a slow IndexedDB open doesn't stall the app boot.
|
||||
void bindDpopIfPossible();
|
||||
} else this.user = null;
|
||||
} catch {
|
||||
this.user = null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user