* wip scope change * rm useless bool * fix-me: package changes for linking * negative test * negative test for multiple scopes * fix displays of warnings * wip step-up * negative test for step up auth * move warning into main request flow * clean up more checks * cleanup step-up scenario * cleanup and simplify * cleanup middleware * inline negative tests * inline the other test * refactor logging and inlining for standalone execution too * skip pending tests
79 lines
3 KiB
TypeScript
79 lines
3 KiB
TypeScript
import { authScenariosList } from './index.js';
|
|
import {
|
|
runClientAgainstScenario,
|
|
InlineClientRunner
|
|
} from './test_helpers/testClient.js';
|
|
import { runClient as goodClient } from '../../../../examples/clients/typescript/auth-test.js';
|
|
import { runClient as badPrmClient } from '../../../../examples/clients/typescript/auth-test-bad-prm.js';
|
|
import { runClient as ignoreScopeClient } from '../../../../examples/clients/typescript/auth-test-ignore-scope.js';
|
|
import { runClient as partialScopesClient } from '../../../../examples/clients/typescript/auth-test-partial-scopes.js';
|
|
import { runClient as ignore403Client } from '../../../../examples/clients/typescript/auth-test-ignore-403.js';
|
|
import { setLogLevel } from '../../../../examples/clients/typescript/helpers/logger.js';
|
|
|
|
beforeAll(() => {
|
|
setLogLevel('error');
|
|
});
|
|
|
|
const skipScenarios = new Set<string>([
|
|
// Waiting on typescript-sdk support in bearerAuth middleware to include
|
|
// scope in WWW-Authenticate header
|
|
// https://github.com/modelcontextprotocol/typescript-sdk/pull/1133
|
|
'auth/scope-from-www-authenticate',
|
|
// Waiting on typescript-sdk support for using scopes_supported from PRM
|
|
// to request scopes.
|
|
// https://github.com/modelcontextprotocol/typescript-sdk/pull/1133
|
|
'auth/scope-from-scopes-supported'
|
|
]);
|
|
|
|
describe('Client Auth Scenarios', () => {
|
|
// Generate individual test for each auth scenario
|
|
for (const scenario of authScenariosList) {
|
|
test(`${scenario.name} passes`, async () => {
|
|
if (skipScenarios.has(scenario.name)) {
|
|
// TODO: skip in a native way?
|
|
return;
|
|
}
|
|
const runner = new InlineClientRunner(goodClient);
|
|
await runClientAgainstScenario(runner, scenario.name);
|
|
});
|
|
}
|
|
});
|
|
|
|
describe('Negative tests', () => {
|
|
test('bad client requests root PRM location', async () => {
|
|
const runner = new InlineClientRunner(badPrmClient);
|
|
await runClientAgainstScenario(runner, 'auth/basic-dcr', [
|
|
'prm-priority-order'
|
|
]);
|
|
});
|
|
|
|
test('client ignores scope from WWW-Authenticate header', async () => {
|
|
const runner = new InlineClientRunner(ignoreScopeClient);
|
|
await runClientAgainstScenario(runner, 'auth/scope-from-www-authenticate', [
|
|
'scope-from-www-authenticate'
|
|
]);
|
|
});
|
|
|
|
test('client only requests subset of scopes_supported', async () => {
|
|
const runner = new InlineClientRunner(partialScopesClient);
|
|
await runClientAgainstScenario(runner, 'auth/scope-from-scopes-supported', [
|
|
'scope-from-scopes-supported'
|
|
]);
|
|
});
|
|
|
|
test('client requests scope even if scopes_supported is empty', async () => {
|
|
const runner = new InlineClientRunner(partialScopesClient);
|
|
await runClientAgainstScenario(
|
|
runner,
|
|
'auth/scope-omitted-when-undefined',
|
|
['scope-omitted-when-undefined']
|
|
);
|
|
});
|
|
|
|
test('client only responds to 401, not 403', async () => {
|
|
const runner = new InlineClientRunner(ignore403Client);
|
|
await runClientAgainstScenario(runner, 'auth/scope-step-up', [
|
|
'scope-step-up-escalation'
|
|
]);
|
|
});
|
|
});
|