Files
gitea-mirror/src/lib/sso/oidc-config.test.ts
2025-10-26 07:49:42 +05:30

76 lines
3.5 KiB
TypeScript

import { describe, expect, it } from "bun:test";
import { normalizeOidcProviderConfig, OidcConfigError } from "./oidc-config";
const issuer = "https://auth.example.com";
describe("normalizeOidcProviderConfig", () => {
it("returns provided endpoints when complete", async () => {
const result = await normalizeOidcProviderConfig(issuer, {
clientId: "client",
clientSecret: "secret",
authorizationEndpoint: "https://auth.example.com/auth",
tokenEndpoint: "https://auth.example.com/token",
jwksEndpoint: "https://auth.example.com/jwks",
userInfoEndpoint: "https://auth.example.com/userinfo",
scopes: ["openid", "email"],
pkce: false,
}, async () => {
throw new Error("fetch should not be called when endpoints are provided");
});
expect(result.oidcConfig.authorizationEndpoint).toBe("https://auth.example.com/auth");
expect(result.oidcConfig.tokenEndpoint).toBe("https://auth.example.com/token");
expect(result.oidcConfig.jwksEndpoint).toBe("https://auth.example.com/jwks");
expect(result.oidcConfig.userInfoEndpoint).toBe("https://auth.example.com/userinfo");
expect(result.oidcConfig.scopes).toEqual(["openid", "email"]);
expect(result.oidcConfig.pkce).toBe(false);
expect(result.oidcConfig.discoveryEndpoint).toBe("https://auth.example.com/.well-known/openid-configuration");
});
it("derives missing fields from discovery", async () => {
const fetchMock = async () =>
new Response(JSON.stringify({
authorization_endpoint: "https://auth.example.com/auth",
token_endpoint: "https://auth.example.com/token",
jwks_uri: "https://auth.example.com/jwks",
userinfo_endpoint: "https://auth.example.com/userinfo",
scopes_supported: ["openid", "email", "profile"],
}));
const result = await normalizeOidcProviderConfig(issuer, {
clientId: "client",
clientSecret: "secret",
}, fetchMock);
expect(result.oidcConfig.authorizationEndpoint).toBe("https://auth.example.com/auth");
expect(result.oidcConfig.tokenEndpoint).toBe("https://auth.example.com/token");
expect(result.oidcConfig.jwksEndpoint).toBe("https://auth.example.com/jwks");
expect(result.oidcConfig.userInfoEndpoint).toBe("https://auth.example.com/userinfo");
expect(result.oidcConfig.scopes).toEqual(["openid", "email", "profile"]);
expect(result.oidcConfig.discoveryEndpoint).toBe("https://auth.example.com/.well-known/openid-configuration");
});
it("preserves trailing slash issuers when building discovery endpoints", async () => {
const trailingIssuer = "https://auth.example.com/application/o/example/";
const requestedUrls: string[] = [];
const fetchMock: typeof fetch = async (url) => {
requestedUrls.push(typeof url === "string" ? url : url.url);
return new Response(JSON.stringify({
authorization_endpoint: "https://auth.example.com/application/o/example/auth",
token_endpoint: "https://auth.example.com/application/o/example/token",
}));
};
const result = await normalizeOidcProviderConfig(trailingIssuer, {}, fetchMock);
expect(requestedUrls[0]).toBe("https://auth.example.com/application/o/example/.well-known/openid-configuration");
expect(result.oidcConfig.discoveryEndpoint).toBe("https://auth.example.com/application/o/example/.well-known/openid-configuration");
});
it("throws for invalid issuer URL", async () => {
await expect(
normalizeOidcProviderConfig("not-a-url", {}),
).rejects.toBeInstanceOf(OidcConfigError);
});
});