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:
@@ -5,6 +5,7 @@ import { MatrixId } from './MatrixId';
|
||||
import { Profile } from './Profile';
|
||||
import { ContactInformation } from './ContactInfo';
|
||||
import { IgnoredUserList } from './IgnoredUserList';
|
||||
import { OidcManageAccount } from './OidcManageAccount';
|
||||
|
||||
type AccountProps = {
|
||||
requestClose: () => void;
|
||||
@@ -32,6 +33,7 @@ export function Account({ requestClose }: AccountProps) {
|
||||
<Box direction="Column" gap="700">
|
||||
<Profile />
|
||||
<MatrixId />
|
||||
<OidcManageAccount />
|
||||
<ContactInformation />
|
||||
<IgnoredUserList />
|
||||
</Box>
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import { Box, Chip, Text } from 'folds';
|
||||
import { SequenceCard } from '../../../components/sequence-card';
|
||||
import { SequenceCardStyle } from '../styles.css';
|
||||
import { SettingTile } from '../../../components/setting-tile';
|
||||
import { useAuthMetadata } from '../../../hooks/useAuthMetadata';
|
||||
import { useAccountManagementActions } from '../../../hooks/useAccountManagement';
|
||||
import { withSearchParam } from '../../../pages/pathUtils';
|
||||
|
||||
/**
|
||||
* On OIDC/next-gen-auth servers, profile/password/sessions are managed by the
|
||||
* authentication service — surface a deep-link to its account page (MSC2965
|
||||
* account-management URL). Renders nothing on password/legacy-SSO servers, where
|
||||
* `useAuthMetadata()` is undefined.
|
||||
*/
|
||||
export function OidcManageAccount() {
|
||||
const authMetadata = useAuthMetadata();
|
||||
const accountManagementActions = useAccountManagementActions();
|
||||
|
||||
const open = useCallback(() => {
|
||||
const authUrl = authMetadata?.account_management_uri ?? authMetadata?.issuer;
|
||||
if (!authUrl) return;
|
||||
window.open(withSearchParam(authUrl, { action: accountManagementActions.profile }), '_blank');
|
||||
}, [authMetadata, accountManagementActions]);
|
||||
|
||||
if (!authMetadata) return null;
|
||||
|
||||
return (
|
||||
<Box direction="Column" gap="100">
|
||||
<Text size="L400">Account Management</Text>
|
||||
<SequenceCard
|
||||
className={SequenceCardStyle}
|
||||
variant="SurfaceVariant"
|
||||
direction="Column"
|
||||
gap="400"
|
||||
>
|
||||
<SettingTile
|
||||
title="Manage account"
|
||||
description="Your profile, password, and sessions are managed by your single sign-on provider."
|
||||
after={
|
||||
<Chip variant="Secondary" radii="Pill" onClick={open}>
|
||||
<Text size="T200">Open</Text>
|
||||
</Chip>
|
||||
}
|
||||
/>
|
||||
</SequenceCard>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user