feat(auth): include authentication in workspace and tht diagnostics
This commit is contained in:
@@ -4,6 +4,7 @@ import {
|
||||
createOidcProtocol,
|
||||
OidcIssuerMismatchError,
|
||||
OidcJwksUnavailableError,
|
||||
OidcDeviceFlowUnavailableError,
|
||||
OidcProtocolError,
|
||||
OidcProviderUnavailableError,
|
||||
} from "../src/auth/oidc-client.js";
|
||||
@@ -36,6 +37,7 @@ function protocol(options: {
|
||||
seen?: URL[];
|
||||
discoveryResponse?: (init?: RequestInit) => Response | Promise<Response>;
|
||||
tokenResponse?: (init?: RequestInit) => Response | Promise<Response>;
|
||||
deviceResponse?: (init?: RequestInit) => Response | Promise<Response>;
|
||||
jwksResponse?: (init?: RequestInit) => Response | Promise<Response>;
|
||||
httpTimeoutMs?: number;
|
||||
jwksTimeoutMs?: number;
|
||||
@@ -71,6 +73,16 @@ function protocol(options: {
|
||||
});
|
||||
}
|
||||
if (url.pathname === "/jwks") return options.jwksResponse ? await options.jwksResponse(init) : Response.json({ keys: [jwk] });
|
||||
if (url.pathname === "/device") {
|
||||
if (options.deviceResponse) return await options.deviceResponse(init);
|
||||
return Response.json({
|
||||
device_code: "device-code-must-not-be-persisted",
|
||||
user_code: "ABCD-EFGH",
|
||||
verification_uri: `${issuer}/device`,
|
||||
expires_in: 60,
|
||||
interval: 1,
|
||||
});
|
||||
}
|
||||
if (url.pathname === "/token") {
|
||||
if (options.tokenResponse) return await options.tokenResponse(init);
|
||||
return Response.json({
|
||||
@@ -131,6 +143,33 @@ test("uses HTTPS discovery, Authorization Code, and PKCE S256 without external n
|
||||
expect(seen.map((url) => url.origin)).toEqual([issuer, issuer, issuer]);
|
||||
});
|
||||
|
||||
test("uses a validated bounded OIDC device flow and returns only a verified direct-group identity", async () => {
|
||||
const seen: URL[] = [];
|
||||
const subject = protocol({
|
||||
seen,
|
||||
discoveryMetadata: { device_authorization_endpoint: `${issuer}/device` },
|
||||
});
|
||||
const presented: Array<[string, string]> = [];
|
||||
|
||||
await expect(subject.verifyDeviceFlow!(new AbortController().signal, (uri, code) => {
|
||||
presented.push([uri, code]);
|
||||
})).resolves.toMatchObject({
|
||||
issuer,
|
||||
subject: "user-123",
|
||||
groups: ["TOT Users", "Unmapped group"],
|
||||
});
|
||||
|
||||
expect(presented).toEqual([[`${issuer}/device`, "ABCD-EFGH"]]);
|
||||
expect(seen.map((url) => url.pathname)).toEqual([
|
||||
"/.well-known/openid-configuration", "/device", "/token", "/jwks",
|
||||
]);
|
||||
});
|
||||
|
||||
test("refuses device flow when discovery has no safe device authorization endpoint", async () => {
|
||||
await expect(protocol().verifyDeviceFlow!(new AbortController().signal, () => undefined))
|
||||
.rejects.toBeInstanceOf(OidcDeviceFlowUnavailableError);
|
||||
});
|
||||
|
||||
test("rejects a hanging discovery request at the provider transport deadline", async () => {
|
||||
let aborted = false;
|
||||
const subject = protocol({
|
||||
|
||||
Reference in New Issue
Block a user