diff --git a/src/server/auth/handlers/authorize.test.ts b/src/server/auth/handlers/authorize.test.ts index 2742d1e5..438db6a6 100644 --- a/src/server/auth/handlers/authorize.test.ts +++ b/src/server/auth/handlers/authorize.test.ts @@ -277,7 +277,7 @@ describe('Authorization Handler', () => { }); describe('Resource parameter validation', () => { - it('accepts valid resource parameter', async () => { + it('propagates resource parameter', async () => { const mockProviderWithResource = jest.spyOn(mockProvider, 'authorize'); const response = await supertest(app) @@ -302,100 +302,6 @@ describe('Authorization Handler', () => { expect.any(Object) ); }); - - it('rejects invalid resource parameter (non-URL)', async () => { - const response = await supertest(app) - .get('/authorize') - .query({ - client_id: 'valid-client', - redirect_uri: 'https://example.com/callback', - response_type: 'code', - code_challenge: 'challenge123', - code_challenge_method: 'S256', - resource: 'not-a-url' - }); - - expect(response.status).toBe(302); - const location = new URL(response.header.location); - expect(location.searchParams.get('error')).toBe('invalid_request'); - expect(location.searchParams.get('error_description')).toContain('resource'); - }); - - it('handles authorization without resource parameter', async () => { - const mockProviderWithoutResource = jest.spyOn(mockProvider, 'authorize'); - - const response = await supertest(app) - .get('/authorize') - .query({ - client_id: 'valid-client', - redirect_uri: 'https://example.com/callback', - response_type: 'code', - code_challenge: 'challenge123', - code_challenge_method: 'S256' - }); - - expect(response.status).toBe(302); - expect(mockProviderWithoutResource).toHaveBeenCalledWith( - validClient, - expect.objectContaining({ - resource: undefined, - redirectUri: 'https://example.com/callback', - codeChallenge: 'challenge123' - }), - expect.any(Object) - ); - }); - - it('passes multiple resources if provided', async () => { - const mockProviderWithResources = jest.spyOn(mockProvider, 'authorize'); - - const response = await supertest(app) - .get('/authorize') - .query({ - client_id: 'valid-client', - redirect_uri: 'https://example.com/callback', - response_type: 'code', - code_challenge: 'challenge123', - code_challenge_method: 'S256', - resource: 'https://api1.example.com/resource', - state: 'test-state' - }); - - expect(response.status).toBe(302); - expect(mockProviderWithResources).toHaveBeenCalledWith( - validClient, - expect.objectContaining({ - resource: new URL('https://api1.example.com/resource'), - state: 'test-state' - }), - expect.any(Object) - ); - }); - - it('validates resource parameter in POST requests', async () => { - const mockProviderPost = jest.spyOn(mockProvider, 'authorize'); - - const response = await supertest(app) - .post('/authorize') - .type('form') - .send({ - client_id: 'valid-client', - redirect_uri: 'https://example.com/callback', - response_type: 'code', - code_challenge: 'challenge123', - code_challenge_method: 'S256', - resource: 'https://api.example.com/resource' - }); - - expect(response.status).toBe(302); - expect(mockProviderPost).toHaveBeenCalledWith( - validClient, - expect.objectContaining({ - resource: new URL('https://api.example.com/resource') - }), - expect.any(Object) - ); - }); }); describe('Successful authorization', () => { diff --git a/src/server/auth/middleware/bearerAuth.test.ts b/src/server/auth/middleware/bearerAuth.test.ts index 665ef926..cf1a9359 100644 --- a/src/server/auth/middleware/bearerAuth.test.ts +++ b/src/server/auth/middleware/bearerAuth.test.ts @@ -3,7 +3,6 @@ import { requireBearerAuth } from "./bearerAuth.js"; import { AuthInfo } from "../types.js"; import { InsufficientScopeError, InvalidTokenError, OAuthError, ServerError } from "../errors.js"; import { OAuthTokenVerifier } from "../provider.js"; -import { LATEST_PROTOCOL_VERSION, DEFAULT_NEGOTIATED_PROTOCOL_VERSION } from '../../../types.js'; // Mock verifier const mockVerifyAccessToken = jest.fn(); @@ -43,13 +42,12 @@ describe("requireBearerAuth middleware", () => { mockRequest.headers = { authorization: "Bearer valid-token", - 'mcp-protocol-version': LATEST_PROTOCOL_VERSION, }; const middleware = requireBearerAuth({ verifier: mockVerifier }); await middleware(mockRequest as Request, mockResponse as Response, nextFunction); - expect(mockVerifyAccessToken).toHaveBeenCalledWith("valid-token", LATEST_PROTOCOL_VERSION); + expect(mockVerifyAccessToken).toHaveBeenCalledWith("valid-token"); expect(mockRequest.auth).toEqual(validAuthInfo); expect(nextFunction).toHaveBeenCalled(); expect(mockResponse.status).not.toHaveBeenCalled(); @@ -89,13 +87,12 @@ describe("requireBearerAuth middleware", () => { mockRequest.headers = { authorization: "Bearer expired-token", - 'mcp-protocol-version': LATEST_PROTOCOL_VERSION, }; const middleware = requireBearerAuth({ verifier: mockVerifier }); await middleware(mockRequest as Request, mockResponse as Response, nextFunction); - expect(mockVerifyAccessToken).toHaveBeenCalledWith("expired-token", LATEST_PROTOCOL_VERSION); + expect(mockVerifyAccessToken).toHaveBeenCalledWith("expired-token"); expect(mockResponse.status).toHaveBeenCalledWith(401); expect(mockResponse.set).toHaveBeenCalledWith( "WWW-Authenticate", @@ -118,13 +115,12 @@ describe("requireBearerAuth middleware", () => { mockRequest.headers = { authorization: "Bearer valid-token", - 'mcp-protocol-version': LATEST_PROTOCOL_VERSION, }; const middleware = requireBearerAuth({ verifier: mockVerifier }); await middleware(mockRequest as Request, mockResponse as Response, nextFunction); - expect(mockVerifyAccessToken).toHaveBeenCalledWith("valid-token", LATEST_PROTOCOL_VERSION); + expect(mockVerifyAccessToken).toHaveBeenCalledWith("valid-token"); expect(mockRequest.auth).toEqual(nonExpiredAuthInfo); expect(nextFunction).toHaveBeenCalled(); expect(mockResponse.status).not.toHaveBeenCalled(); @@ -141,7 +137,6 @@ describe("requireBearerAuth middleware", () => { mockRequest.headers = { authorization: "Bearer valid-token", - 'mcp-protocol-version': LATEST_PROTOCOL_VERSION, }; const middleware = requireBearerAuth({ @@ -151,7 +146,7 @@ describe("requireBearerAuth middleware", () => { await middleware(mockRequest as Request, mockResponse as Response, nextFunction); - expect(mockVerifyAccessToken).toHaveBeenCalledWith("valid-token", LATEST_PROTOCOL_VERSION); + expect(mockVerifyAccessToken).toHaveBeenCalledWith("valid-token"); expect(mockResponse.status).toHaveBeenCalledWith(403); expect(mockResponse.set).toHaveBeenCalledWith( "WWW-Authenticate", @@ -173,7 +168,6 @@ describe("requireBearerAuth middleware", () => { mockRequest.headers = { authorization: "Bearer valid-token", - 'mcp-protocol-version': LATEST_PROTOCOL_VERSION, }; const middleware = requireBearerAuth({ @@ -183,7 +177,7 @@ describe("requireBearerAuth middleware", () => { await middleware(mockRequest as Request, mockResponse as Response, nextFunction); - expect(mockVerifyAccessToken).toHaveBeenCalledWith("valid-token", LATEST_PROTOCOL_VERSION); + expect(mockVerifyAccessToken).toHaveBeenCalledWith("valid-token"); expect(mockRequest.auth).toEqual(authInfo); expect(nextFunction).toHaveBeenCalled(); expect(mockResponse.status).not.toHaveBeenCalled(); @@ -232,7 +226,6 @@ describe("requireBearerAuth middleware", () => { it("should return 401 when token verification fails with InvalidTokenError", async () => { mockRequest.headers = { authorization: "Bearer invalid-token", - 'mcp-protocol-version': LATEST_PROTOCOL_VERSION, }; mockVerifyAccessToken.mockRejectedValue(new InvalidTokenError("Token expired")); @@ -240,7 +233,7 @@ describe("requireBearerAuth middleware", () => { const middleware = requireBearerAuth({ verifier: mockVerifier }); await middleware(mockRequest as Request, mockResponse as Response, nextFunction); - expect(mockVerifyAccessToken).toHaveBeenCalledWith("invalid-token", LATEST_PROTOCOL_VERSION); + expect(mockVerifyAccessToken).toHaveBeenCalledWith("invalid-token"); expect(mockResponse.status).toHaveBeenCalledWith(401); expect(mockResponse.set).toHaveBeenCalledWith( "WWW-Authenticate", @@ -255,7 +248,6 @@ describe("requireBearerAuth middleware", () => { it("should return 403 when access token has insufficient scopes", async () => { mockRequest.headers = { authorization: "Bearer valid-token", - 'mcp-protocol-version': LATEST_PROTOCOL_VERSION, }; mockVerifyAccessToken.mockRejectedValue(new InsufficientScopeError("Required scopes: read, write")); @@ -263,7 +255,7 @@ describe("requireBearerAuth middleware", () => { const middleware = requireBearerAuth({ verifier: mockVerifier }); await middleware(mockRequest as Request, mockResponse as Response, nextFunction); - expect(mockVerifyAccessToken).toHaveBeenCalledWith("valid-token", LATEST_PROTOCOL_VERSION); + expect(mockVerifyAccessToken).toHaveBeenCalledWith("valid-token"); expect(mockResponse.status).toHaveBeenCalledWith(403); expect(mockResponse.set).toHaveBeenCalledWith( "WWW-Authenticate", @@ -278,7 +270,6 @@ describe("requireBearerAuth middleware", () => { it("should return 500 when a ServerError occurs", async () => { mockRequest.headers = { authorization: "Bearer valid-token", - 'mcp-protocol-version': LATEST_PROTOCOL_VERSION, }; mockVerifyAccessToken.mockRejectedValue(new ServerError("Internal server issue")); @@ -286,7 +277,7 @@ describe("requireBearerAuth middleware", () => { const middleware = requireBearerAuth({ verifier: mockVerifier }); await middleware(mockRequest as Request, mockResponse as Response, nextFunction); - expect(mockVerifyAccessToken).toHaveBeenCalledWith("valid-token", LATEST_PROTOCOL_VERSION); + expect(mockVerifyAccessToken).toHaveBeenCalledWith("valid-token"); expect(mockResponse.status).toHaveBeenCalledWith(500); expect(mockResponse.json).toHaveBeenCalledWith( expect.objectContaining({ error: "server_error", error_description: "Internal server issue" }) @@ -297,7 +288,6 @@ describe("requireBearerAuth middleware", () => { it("should return 400 for generic OAuthError", async () => { mockRequest.headers = { authorization: "Bearer valid-token", - 'mcp-protocol-version': LATEST_PROTOCOL_VERSION, }; mockVerifyAccessToken.mockRejectedValue(new OAuthError("custom_error", "Some OAuth error")); @@ -305,7 +295,7 @@ describe("requireBearerAuth middleware", () => { const middleware = requireBearerAuth({ verifier: mockVerifier }); await middleware(mockRequest as Request, mockResponse as Response, nextFunction); - expect(mockVerifyAccessToken).toHaveBeenCalledWith("valid-token", LATEST_PROTOCOL_VERSION); + expect(mockVerifyAccessToken).toHaveBeenCalledWith("valid-token"); expect(mockResponse.status).toHaveBeenCalledWith(400); expect(mockResponse.json).toHaveBeenCalledWith( expect.objectContaining({ error: "custom_error", error_description: "Some OAuth error" }) @@ -316,7 +306,6 @@ describe("requireBearerAuth middleware", () => { it("should return 500 when unexpected error occurs", async () => { mockRequest.headers = { authorization: "Bearer valid-token", - 'mcp-protocol-version': LATEST_PROTOCOL_VERSION, }; mockVerifyAccessToken.mockRejectedValue(new Error("Unexpected error")); @@ -324,7 +313,7 @@ describe("requireBearerAuth middleware", () => { const middleware = requireBearerAuth({ verifier: mockVerifier }); await middleware(mockRequest as Request, mockResponse as Response, nextFunction); - expect(mockVerifyAccessToken).toHaveBeenCalledWith("valid-token", LATEST_PROTOCOL_VERSION); + expect(mockVerifyAccessToken).toHaveBeenCalledWith("valid-token"); expect(mockResponse.status).toHaveBeenCalledWith(500); expect(mockResponse.json).toHaveBeenCalledWith( expect.objectContaining({ error: "server_error", error_description: "Internal Server Error" })