| 1 | import { afterEach, describe, expect, it } from 'vitest';
|
| 2 | import { POST as mcpHandler } from '../api/mcp.js';
|
| 3 | import { GET as metadataHandler } from '../api/oauth-protected-resource.js';
|
| 4 |
|
| 5 | describe('hosted MCP authorization', () => {
|
| 6 | const originalIssuer = process.env.DESCOPE_MCP_ISSUER;
|
| 7 | const originalIntegrationIssuer = process.env.DESCOPE_ISSUER;
|
| 8 | afterEach(() => {
|
| 9 | if (originalIssuer === undefined) delete process.env.DESCOPE_MCP_ISSUER;
|
| 10 | else process.env.DESCOPE_MCP_ISSUER = originalIssuer;
|
| 11 | if (originalIntegrationIssuer === undefined) delete process.env.DESCOPE_ISSUER;
|
| 12 | else process.env.DESCOPE_ISSUER = originalIntegrationIssuer;
|
| 13 | });
|
| 14 |
|
| 15 | it('challenges unauthenticated remote MCP requests', async () => {
|
| 16 | const response = await mcpHandler(
|
| 17 | new Request('https://openclasp.example/mcp', {
|
| 18 | method: 'POST',
|
| 19 | headers: { 'content-type': 'application/json' },
|
| 20 | body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'tools/list' }),
|
| 21 | }),
|
| 22 | );
|
| 23 | expect(response.status).toBe(401);
|
| 24 | expect(response.headers.get('www-authenticate')).toContain(
|
| 25 | 'resource_metadata="https://openclasp.example/.well-known/oauth-protected-resource"',
|
| 26 | );
|
| 27 | });
|
| 28 |
|
| 29 | it('fails closed when the OAuth issuer is not configured', () => {
|
| 30 | delete process.env.DESCOPE_MCP_ISSUER;
|
| 31 | delete process.env.DESCOPE_ISSUER;
|
| 32 | const response = metadataHandler(
|
| 33 | new Request('https://openclasp.example/.well-known/oauth-protected-resource'),
|
| 34 | );
|
| 35 | expect(response.status).toBe(503);
|
| 36 | });
|
| 37 | });
|