[auth] OAuth protected-resource-metadata: fallback on 4xx not just 404 (#879)

Co-authored-by: adam jones <domdomegg+git@gmail.com>
This commit is contained in:
Paul Carleton 2025-08-19 15:43:09 +01:00 • committed by GitHub
commit 1f5950be01
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -212,11 +212,11 @@ describe("OAuth Authorization", () => {
expect(url.toString()).toBe("https://resource.example.com/.well-known/oauth-protected-resource/path?param=value");
});
it("falls back to root discovery when path-aware discovery returns 404", async () => {
// First call (path-aware) returns 404
it.each([400, 401, 403, 404, 410, 422, 429])("falls back to root discovery when path-aware discovery returns %d", async (statusCode) => {
// First call (path-aware) returns 4xx
mockFetch.mockResolvedValueOnce({
ok: false,
status: 404,
status: statusCode,
});
// Second call (root fallback) succeeds
@ -267,6 +267,20 @@ describe("OAuth Authorization", () => {
expect(calls.length).toBe(2);
});
it("throws error on 500 status and does not fallback", async () => {
// First call (path-aware) returns 500
mockFetch.mockResolvedValueOnce({
ok: false,
status: 500,
});
await expect(discoverOAuthProtectedResourceMetadata("https://resource.example.com/path/name"))
.rejects.toThrow();
const calls = mockFetch.mock.calls;
expect(calls.length).toBe(1); // Should not attempt fallback
});
it("does not fallback when the original URL is already at root path", async () => {
// First call (path-aware for root) returns 404
mockFetch.mockResolvedValueOnce({
@ -907,7 +921,7 @@ describe("OAuth Authorization", () => {
const metadata = await discoverAuthorizationServerMetadata("https://auth.example.com/tenant1");
expect(metadata).toBeUndefined();
// Verify that all discovery URLs were attempted
expect(mockFetch).toHaveBeenCalledTimes(8); // 4 URLs × 2 attempts each (with and without headers)
});