feat(auth): OIDC phase 4/5/6 — token refresh, logout revocation, account link
- initMatrix.ts: import the shared Session type; when a session has a refresh token + oidc metadata, wire a LotusOidcTokenRefresher via createClient's refreshToken + tokenRefreshFunction (reactive 401 refresh). Rust crypto is unaffected (still keyed on userId/deviceId). - client/oidcTokenRefresher.ts: OidcTokenRefresher subclass that persists rotated tokens back to the fallback session. - client/oidcLogout.ts + logoutClient: best-effort revoke access+refresh tokens at the issuer's revocation_endpoint on logout (tolerant of failure). - settings/account/OidcManageAccount.tsx: MSC2965 "Manage account" deep-link, shown only when authMetadata is present (OIDC servers); mirrors OtherDevices. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
import { OidcTokenRefresher } from 'matrix-js-sdk';
|
||||
import type { IdTokenClaims } from 'oidc-client-ts';
|
||||
import { OidcSessionMeta, setFallbackSession } from '../app/state/sessions';
|
||||
|
||||
/**
|
||||
* OidcTokenRefresher that persists rotated tokens back to the fallback session,
|
||||
* so a page reload keeps the freshest access/refresh token. The matrix client
|
||||
* calls this automatically (reactively on a 401) when a refresh token is set.
|
||||
*/
|
||||
export class LotusOidcTokenRefresher extends OidcTokenRefresher {
|
||||
private readonly deviceIdRef: string;
|
||||
|
||||
private readonly userIdRef: string;
|
||||
|
||||
private readonly baseUrlRef: string;
|
||||
|
||||
private readonly oidcRef: OidcSessionMeta;
|
||||
|
||||
constructor(oidc: OidcSessionMeta, deviceId: string, userId: string, baseUrl: string) {
|
||||
super(
|
||||
oidc.issuer,
|
||||
oidc.clientId,
|
||||
oidc.redirectUri,
|
||||
deviceId,
|
||||
(oidc.idTokenClaims ?? {}) as unknown as IdTokenClaims,
|
||||
);
|
||||
this.deviceIdRef = deviceId;
|
||||
this.userIdRef = userId;
|
||||
this.baseUrlRef = baseUrl;
|
||||
this.oidcRef = oidc;
|
||||
}
|
||||
|
||||
protected async persistTokens(tokens: {
|
||||
accessToken: string;
|
||||
refreshToken?: string;
|
||||
}): Promise<void> {
|
||||
setFallbackSession(tokens.accessToken, this.deviceIdRef, this.userIdRef, this.baseUrlRef, {
|
||||
refreshToken: tokens.refreshToken,
|
||||
oidc: this.oidcRef,
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user