feat(auth): OIDC phase 0+1 — discovery, flow detection, client config
Toward MSC3861/MSC2965 next-gen-auth login (P4-6), client-only.
- cs-api.ts: type the stable `m.authentication` well-known key + getOidcIssuer()
(stable preferred over the unstable msc2965 key; {} for non-OIDC servers).
- useParsedLoginFlows.ts: getOidcCompatibilityFlag() (MSC3824 oauth_aware_preferred
/ delegated_oidc_compatibility) as a secondary OIDC hint.
- New pages/auth/oidc/oidcConfig.ts: dynamic-registration client metadata + the
non-hash callback URL (redirect_uris can't contain a fragment).
- paths.ts: OIDC_CALLBACK_PATH.
- 8 unit tests for the pure helpers.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { getOidcIssuer, AutoDiscoveryInfo } from './cs-api';
|
||||
|
||||
const info = (extra: Record<string, unknown>): AutoDiscoveryInfo =>
|
||||
({ 'm.homeserver': { base_url: 'https://hs' }, ...extra }) as AutoDiscoveryInfo;
|
||||
|
||||
test('getOidcIssuer reads the stable m.authentication key', () => {
|
||||
assert.deepEqual(
|
||||
getOidcIssuer(info({ 'm.authentication': { issuer: 'https://i', account: 'https://a' } })),
|
||||
{ issuer: 'https://i', account: 'https://a' },
|
||||
);
|
||||
});
|
||||
|
||||
test('getOidcIssuer falls back to the unstable msc2965 key', () => {
|
||||
assert.deepEqual(
|
||||
getOidcIssuer(info({ 'org.matrix.msc2965.authentication': { issuer: 'https://u' } })),
|
||||
{ issuer: 'https://u', account: undefined },
|
||||
);
|
||||
});
|
||||
|
||||
test('getOidcIssuer prefers stable over unstable when both present', () => {
|
||||
assert.equal(
|
||||
getOidcIssuer(
|
||||
info({
|
||||
'm.authentication': { issuer: 'https://stable' },
|
||||
'org.matrix.msc2965.authentication': { issuer: 'https://unstable' },
|
||||
}),
|
||||
).issuer,
|
||||
'https://stable',
|
||||
);
|
||||
});
|
||||
|
||||
test('getOidcIssuer returns {} for non-OIDC servers', () => {
|
||||
assert.deepEqual(getOidcIssuer(info({})), {});
|
||||
assert.deepEqual(getOidcIssuer(info({ 'm.authentication': {} })), {}); // present but no issuer
|
||||
});
|
||||
Reference in New Issue
Block a user