30 lines
1.3 KiB
TypeScript
30 lines
1.3 KiB
TypeScript
import { discoverAndValidateOIDCIssuerWellKnown } from 'matrix-js-sdk';
|
|||
|
|
import { Session } from '../app/state/sessions';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Best-effort revoke the OIDC access + refresh tokens at the issuer's revocation
|
||
|
|
* endpoint during logout. Tolerant of any failure — logout proceeds regardless
|
||
|
|
* (the local session is cleared by the caller either way).
|
||
|
|
*/
|
||
|
|
export const revokeOidcTokens = async (session: Session): Promise<void> => {
|
||
|
|
if (!session.oidc) return;
|
||
|
|
try {
|
||
|
|
const config = await discoverAndValidateOIDCIssuerWellKnown(session.oidc.issuer);
|
||
|
|
const endpoint = config.revocation_endpoint;
|
||
|
|
if (!endpoint) return;
|
||
|
|
const { clientId } = session.oidc;
|
||
|
|
const revoke = (token: string, hint: string): Promise<Response> =>
|
||
|
|
fetch(endpoint, {
|
||
|
|
method: 'POST',
|
||
|
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||
|
|
body: new URLSearchParams({ token, token_type_hint: hint, client_id: clientId }),
|
||
|
|
});
|
||
|
|
const requests: Promise<Response>[] = [];
|
||
|
|
if (session.refreshToken) requests.push(revoke(session.refreshToken, 'refresh_token'));
|
||
|
|
if (session.accessToken) requests.push(revoke(session.accessToken, 'access_token'));
|
||
|
|
await Promise.allSettled(requests);
|
||
|
|
} catch {
|
||
|
|
/* issuer unreachable / no revocation endpoint — ignore */
|
||
|
|
}
|
||
|
|
};
|