feat(#413): add OIDC provider health check with 30s cache
All checks were successful
ci/woodpecker/push/api Pipeline was successful

- isOidcProviderReachable() fetches discovery URL with 2s timeout
- getAuthConfig() omits authentik when provider unreachable
- 30-second cache prevents repeated network calls

Refs #413

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jason Woltje
2026-02-16 11:20:05 -06:00
parent d2605196ac
commit 3b2356f5a0
4 changed files with 205 additions and 22 deletions

View File

@@ -126,28 +126,28 @@ describe("AuthController", () => {
});
describe("getConfig", () => {
it("should return auth config from service", () => {
it("should return auth config from service", async () => {
const mockConfig = {
providers: [
{ id: "email", name: "Email", type: "credentials" as const },
{ id: "authentik", name: "Authentik", type: "oauth" as const },
],
};
mockAuthService.getAuthConfig.mockReturnValue(mockConfig);
mockAuthService.getAuthConfig.mockResolvedValue(mockConfig);
const result = controller.getConfig();
const result = await controller.getConfig();
expect(result).toEqual(mockConfig);
expect(mockAuthService.getAuthConfig).toHaveBeenCalled();
});
it("should return correct response shape with only email provider", () => {
it("should return correct response shape with only email provider", async () => {
const mockConfig = {
providers: [{ id: "email", name: "Email", type: "credentials" as const }],
};
mockAuthService.getAuthConfig.mockReturnValue(mockConfig);
mockAuthService.getAuthConfig.mockResolvedValue(mockConfig);
const result = controller.getConfig();
const result = await controller.getConfig();
expect(result).toEqual(mockConfig);
expect(result.providers).toHaveLength(1);
@@ -158,7 +158,7 @@ describe("AuthController", () => {
});
});
it("should never leak secrets in auth config response", () => {
it("should never leak secrets in auth config response", async () => {
// Set ALL sensitive environment variables with known values
const sensitiveEnv: Record<string, string> = {
OIDC_CLIENT_SECRET: "test-client-secret",
@@ -186,9 +186,9 @@ describe("AuthController", () => {
{ id: "authentik", name: "Authentik", type: "oauth" as const },
],
};
mockAuthService.getAuthConfig.mockReturnValue(mockConfig);
mockAuthService.getAuthConfig.mockResolvedValue(mockConfig);
const result = controller.getConfig();
const result = await controller.getConfig();
const serialized = JSON.stringify(result);
// Assert no secret values leak into the serialized response