minimize changes
This commit is contained in:
parent
68424ef7e6
commit
9e2a565164
2 changed files with 11 additions and 116 deletions
|
|
@ -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', () => {
|
||||
|
|
|
|||
|
|
@ -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" })
|
||||
|
|
|
|||
Loading…
Reference in a new issue