@frontmcp/testing 0.6.1 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/fixtures/index.mjs +2377 -0
- package/esm/index.mjs +4768 -0
- package/esm/matchers/index.mjs +646 -0
- package/esm/package.json +127 -0
- package/esm/playwright/index.mjs +19 -0
- package/esm/setup.mjs +680 -0
- package/fixtures/index.js +2418 -0
- package/index.js +4866 -0
- package/jest-preset.js +3 -3
- package/matchers/index.js +673 -0
- package/package.json +51 -23
- package/playwright/index.js +46 -0
- package/setup.js +651 -0
- package/src/assertions/index.js +0 -18
- package/src/assertions/index.js.map +0 -1
- package/src/assertions/mcp-assertions.js +0 -220
- package/src/assertions/mcp-assertions.js.map +0 -1
- package/src/auth/auth-headers.js +0 -62
- package/src/auth/auth-headers.js.map +0 -1
- package/src/auth/index.js +0 -15
- package/src/auth/index.js.map +0 -1
- package/src/auth/mock-api-server.js +0 -200
- package/src/auth/mock-api-server.js.map +0 -1
- package/src/auth/mock-oauth-server.js +0 -253
- package/src/auth/mock-oauth-server.js.map +0 -1
- package/src/auth/token-factory.js +0 -181
- package/src/auth/token-factory.js.map +0 -1
- package/src/auth/user-fixtures.js +0 -92
- package/src/auth/user-fixtures.js.map +0 -1
- package/src/client/index.js +0 -12
- package/src/client/index.js.map +0 -1
- package/src/client/mcp-test-client.builder.js +0 -163
- package/src/client/mcp-test-client.builder.js.map +0 -1
- package/src/client/mcp-test-client.js +0 -937
- package/src/client/mcp-test-client.js.map +0 -1
- package/src/client/mcp-test-client.types.js +0 -16
- package/src/client/mcp-test-client.types.js.map +0 -1
- package/src/errors/index.js +0 -85
- package/src/errors/index.js.map +0 -1
- package/src/example-tools/index.js +0 -40
- package/src/example-tools/index.js.map +0 -1
- package/src/example-tools/tool-configs.js +0 -222
- package/src/example-tools/tool-configs.js.map +0 -1
- package/src/expect.js +0 -31
- package/src/expect.js.map +0 -1
- package/src/fixtures/fixture-types.js +0 -7
- package/src/fixtures/fixture-types.js.map +0 -1
- package/src/fixtures/index.js +0 -16
- package/src/fixtures/index.js.map +0 -1
- package/src/fixtures/test-fixture.js +0 -311
- package/src/fixtures/test-fixture.js.map +0 -1
- package/src/http-mock/http-mock.js +0 -544
- package/src/http-mock/http-mock.js.map +0 -1
- package/src/http-mock/http-mock.types.js +0 -10
- package/src/http-mock/http-mock.types.js.map +0 -1
- package/src/http-mock/index.js +0 -11
- package/src/http-mock/index.js.map +0 -1
- package/src/index.js +0 -167
- package/src/index.js.map +0 -1
- package/src/interceptor/index.js +0 -15
- package/src/interceptor/index.js.map +0 -1
- package/src/interceptor/interceptor-chain.js +0 -207
- package/src/interceptor/interceptor-chain.js.map +0 -1
- package/src/interceptor/interceptor.types.js +0 -7
- package/src/interceptor/interceptor.types.js.map +0 -1
- package/src/interceptor/mock-registry.js +0 -189
- package/src/interceptor/mock-registry.js.map +0 -1
- package/src/matchers/index.js +0 -12
- package/src/matchers/index.js.map +0 -1
- package/src/matchers/matcher-types.js +0 -10
- package/src/matchers/matcher-types.js.map +0 -1
- package/src/matchers/mcp-matchers.js +0 -395
- package/src/matchers/mcp-matchers.js.map +0 -1
- package/src/platform/index.js +0 -47
- package/src/platform/index.js.map +0 -1
- package/src/platform/platform-client-info.js +0 -155
- package/src/platform/platform-client-info.js.map +0 -1
- package/src/platform/platform-types.js +0 -110
- package/src/platform/platform-types.js.map +0 -1
- package/src/playwright/index.js +0 -49
- package/src/playwright/index.js.map +0 -1
- package/src/server/index.js +0 -10
- package/src/server/index.js.map +0 -1
- package/src/server/test-server.js +0 -341
- package/src/server/test-server.js.map +0 -1
- package/src/setup.js +0 -30
- package/src/setup.js.map +0 -1
- package/src/transport/index.js +0 -10
- package/src/transport/index.js.map +0 -1
- package/src/transport/streamable-http.transport.js +0 -438
- package/src/transport/streamable-http.transport.js.map +0 -1
- package/src/transport/transport.interface.js +0 -7
- package/src/transport/transport.interface.js.map +0 -1
- package/src/ui/index.js +0 -23
- package/src/ui/index.js.map +0 -1
- package/src/ui/ui-assertions.js +0 -367
- package/src/ui/ui-assertions.js.map +0 -1
- package/src/ui/ui-matchers.js +0 -493
- package/src/ui/ui-matchers.js.map +0 -1
- /package/{src/assertions → assertions}/index.d.ts +0 -0
- /package/{src/assertions → assertions}/mcp-assertions.d.ts +0 -0
- /package/{src/auth → auth}/auth-headers.d.ts +0 -0
- /package/{src/auth → auth}/index.d.ts +0 -0
- /package/{src/auth → auth}/mock-api-server.d.ts +0 -0
- /package/{src/auth → auth}/mock-oauth-server.d.ts +0 -0
- /package/{src/auth → auth}/token-factory.d.ts +0 -0
- /package/{src/auth → auth}/user-fixtures.d.ts +0 -0
- /package/{src/client → client}/index.d.ts +0 -0
- /package/{src/client → client}/mcp-test-client.builder.d.ts +0 -0
- /package/{src/client → client}/mcp-test-client.d.ts +0 -0
- /package/{src/client → client}/mcp-test-client.types.d.ts +0 -0
- /package/{src/errors → errors}/index.d.ts +0 -0
- /package/{src/example-tools → example-tools}/index.d.ts +0 -0
- /package/{src/example-tools → example-tools}/tool-configs.d.ts +0 -0
- /package/{src/expect.d.ts → expect.d.ts} +0 -0
- /package/{src/fixtures → fixtures}/fixture-types.d.ts +0 -0
- /package/{src/fixtures → fixtures}/index.d.ts +0 -0
- /package/{src/fixtures → fixtures}/test-fixture.d.ts +0 -0
- /package/{src/http-mock → http-mock}/http-mock.d.ts +0 -0
- /package/{src/http-mock → http-mock}/http-mock.types.d.ts +0 -0
- /package/{src/http-mock → http-mock}/index.d.ts +0 -0
- /package/{src/index.d.ts → index.d.ts} +0 -0
- /package/{src/interceptor → interceptor}/index.d.ts +0 -0
- /package/{src/interceptor → interceptor}/interceptor-chain.d.ts +0 -0
- /package/{src/interceptor → interceptor}/interceptor.types.d.ts +0 -0
- /package/{src/interceptor → interceptor}/mock-registry.d.ts +0 -0
- /package/{src/matchers → matchers}/index.d.ts +0 -0
- /package/{src/matchers → matchers}/matcher-types.d.ts +0 -0
- /package/{src/matchers → matchers}/mcp-matchers.d.ts +0 -0
- /package/{src/platform → platform}/index.d.ts +0 -0
- /package/{src/platform → platform}/platform-client-info.d.ts +0 -0
- /package/{src/platform → platform}/platform-types.d.ts +0 -0
- /package/{src/playwright → playwright}/index.d.ts +0 -0
- /package/{src/server → server}/index.d.ts +0 -0
- /package/{src/server → server}/test-server.d.ts +0 -0
- /package/{src/setup.d.ts → setup.d.ts} +0 -0
- /package/{src/transport → transport}/index.d.ts +0 -0
- /package/{src/transport → transport}/streamable-http.transport.d.ts +0 -0
- /package/{src/transport → transport}/transport.interface.d.ts +0 -0
- /package/{src/ui → ui}/index.d.ts +0 -0
- /package/{src/ui → ui}/ui-assertions.d.ts +0 -0
- /package/{src/ui → ui}/ui-matchers.d.ts +0 -0
|
@@ -1,253 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @file mock-oauth-server.ts
|
|
4
|
-
* @description Mock OAuth server for testing transparent auth mode
|
|
5
|
-
*
|
|
6
|
-
* This module provides a mock OAuth/OIDC server that serves:
|
|
7
|
-
* - JWKS endpoint for token verification
|
|
8
|
-
* - OAuth metadata endpoint (optional)
|
|
9
|
-
* - Token endpoint for anonymous tokens (optional)
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* ```typescript
|
|
13
|
-
* import { MockOAuthServer, TestTokenFactory } from '@frontmcp/testing';
|
|
14
|
-
*
|
|
15
|
-
* const tokenFactory = new TestTokenFactory();
|
|
16
|
-
* const oauthServer = new MockOAuthServer(tokenFactory);
|
|
17
|
-
*
|
|
18
|
-
* // Start the mock server
|
|
19
|
-
* await oauthServer.start();
|
|
20
|
-
*
|
|
21
|
-
* // Configure your MCP server to use this mock
|
|
22
|
-
* // IDP_PROVIDER_URL = oauthServer.baseUrl
|
|
23
|
-
*
|
|
24
|
-
* // Create tokens using the same factory
|
|
25
|
-
* const token = await tokenFactory.createTestToken({ sub: 'user-123' });
|
|
26
|
-
*
|
|
27
|
-
* // Stop when done
|
|
28
|
-
* await oauthServer.stop();
|
|
29
|
-
* ```
|
|
30
|
-
*/
|
|
31
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
|
-
exports.MockOAuthServer = void 0;
|
|
33
|
-
const http_1 = require("http");
|
|
34
|
-
// ═══════════════════════════════════════════════════════════════════
|
|
35
|
-
// MOCK OAUTH SERVER
|
|
36
|
-
// ═══════════════════════════════════════════════════════════════════
|
|
37
|
-
/**
|
|
38
|
-
* Mock OAuth/OIDC server for testing transparent auth mode
|
|
39
|
-
*
|
|
40
|
-
* Serves JWKS from a TestTokenFactory so that MCP servers can
|
|
41
|
-
* validate test tokens without connecting to a real IdP.
|
|
42
|
-
*/
|
|
43
|
-
class MockOAuthServer {
|
|
44
|
-
tokenFactory;
|
|
45
|
-
options;
|
|
46
|
-
server = null;
|
|
47
|
-
_info = null;
|
|
48
|
-
connections = new Set();
|
|
49
|
-
constructor(tokenFactory, options = {}) {
|
|
50
|
-
this.tokenFactory = tokenFactory;
|
|
51
|
-
this.options = options;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Start the mock OAuth server
|
|
55
|
-
*/
|
|
56
|
-
async start() {
|
|
57
|
-
if (this.server) {
|
|
58
|
-
throw new Error('Mock OAuth server is already running');
|
|
59
|
-
}
|
|
60
|
-
const port = this.options.port ?? 0; // 0 = random available port
|
|
61
|
-
return new Promise((resolve, reject) => {
|
|
62
|
-
const server = (0, http_1.createServer)(this.handleRequest.bind(this));
|
|
63
|
-
this.server = server;
|
|
64
|
-
// Track connections for proper cleanup
|
|
65
|
-
server.on('connection', (socket) => {
|
|
66
|
-
this.connections.add(socket);
|
|
67
|
-
socket.on('close', () => this.connections.delete(socket));
|
|
68
|
-
});
|
|
69
|
-
server.on('error', (err) => {
|
|
70
|
-
this.log(`Server error: ${err.message}`);
|
|
71
|
-
reject(err);
|
|
72
|
-
});
|
|
73
|
-
server.listen(port, () => {
|
|
74
|
-
const address = server.address();
|
|
75
|
-
if (!address || typeof address === 'string') {
|
|
76
|
-
reject(new Error('Failed to get server address'));
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
const actualPort = address.port;
|
|
80
|
-
const issuer = this.options.issuer ?? `http://localhost:${actualPort}`;
|
|
81
|
-
this._info = {
|
|
82
|
-
baseUrl: `http://localhost:${actualPort}`,
|
|
83
|
-
port: actualPort,
|
|
84
|
-
issuer,
|
|
85
|
-
jwksUrl: `http://localhost:${actualPort}/.well-known/jwks.json`,
|
|
86
|
-
};
|
|
87
|
-
this.log(`Mock OAuth server started at ${this._info.baseUrl}`);
|
|
88
|
-
resolve(this._info);
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Stop the mock OAuth server
|
|
94
|
-
*/
|
|
95
|
-
async stop() {
|
|
96
|
-
const server = this.server;
|
|
97
|
-
if (!server) {
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
// Destroy all active connections to allow server.close() to complete
|
|
101
|
-
for (const socket of this.connections) {
|
|
102
|
-
socket.destroy();
|
|
103
|
-
}
|
|
104
|
-
this.connections.clear();
|
|
105
|
-
return new Promise((resolve, reject) => {
|
|
106
|
-
server.close((err) => {
|
|
107
|
-
if (err) {
|
|
108
|
-
reject(err);
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
this.server = null;
|
|
112
|
-
this._info = null;
|
|
113
|
-
this.log('Mock OAuth server stopped');
|
|
114
|
-
resolve();
|
|
115
|
-
}
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Get server info
|
|
121
|
-
*/
|
|
122
|
-
get info() {
|
|
123
|
-
if (!this._info) {
|
|
124
|
-
throw new Error('Mock OAuth server is not running');
|
|
125
|
-
}
|
|
126
|
-
return this._info;
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Get the token factory (for creating tokens)
|
|
130
|
-
*/
|
|
131
|
-
getTokenFactory() {
|
|
132
|
-
return this.tokenFactory;
|
|
133
|
-
}
|
|
134
|
-
// ═══════════════════════════════════════════════════════════════════
|
|
135
|
-
// PRIVATE
|
|
136
|
-
// ═══════════════════════════════════════════════════════════════════
|
|
137
|
-
async handleRequest(req, res) {
|
|
138
|
-
const url = req.url ?? '/';
|
|
139
|
-
this.log(`${req.method} ${url}`);
|
|
140
|
-
// CORS headers
|
|
141
|
-
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
142
|
-
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
|
143
|
-
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
|
|
144
|
-
if (req.method === 'OPTIONS') {
|
|
145
|
-
res.writeHead(204);
|
|
146
|
-
res.end();
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
try {
|
|
150
|
-
if (url === '/.well-known/jwks.json' || url === '/.well-known/jwks') {
|
|
151
|
-
await this.handleJwks(req, res);
|
|
152
|
-
}
|
|
153
|
-
else if (url === '/.well-known/openid-configuration') {
|
|
154
|
-
await this.handleOidcConfig(req, res);
|
|
155
|
-
}
|
|
156
|
-
else if (url === '/.well-known/oauth-authorization-server') {
|
|
157
|
-
await this.handleOAuthMetadata(req, res);
|
|
158
|
-
}
|
|
159
|
-
else if (url === '/oauth/token') {
|
|
160
|
-
await this.handleTokenEndpoint(req, res);
|
|
161
|
-
}
|
|
162
|
-
else {
|
|
163
|
-
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
164
|
-
res.end(JSON.stringify({ error: 'not_found', error_description: 'Endpoint not found' }));
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
catch (error) {
|
|
168
|
-
this.log(`Error handling request: ${error}`);
|
|
169
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
170
|
-
res.end(JSON.stringify({ error: 'server_error', error_description: 'Internal server error' }));
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
async handleJwks(_req, res) {
|
|
174
|
-
const jwks = await this.tokenFactory.getPublicJwks();
|
|
175
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
176
|
-
res.end(JSON.stringify(jwks));
|
|
177
|
-
this.log('Served JWKS');
|
|
178
|
-
}
|
|
179
|
-
async handleOidcConfig(_req, res) {
|
|
180
|
-
const issuer = this._info?.issuer ?? 'http://localhost';
|
|
181
|
-
const config = {
|
|
182
|
-
issuer,
|
|
183
|
-
authorization_endpoint: `${issuer}/oauth/authorize`,
|
|
184
|
-
token_endpoint: `${issuer}/oauth/token`,
|
|
185
|
-
jwks_uri: `${issuer}/.well-known/jwks.json`,
|
|
186
|
-
response_types_supported: ['code', 'token'],
|
|
187
|
-
subject_types_supported: ['public'],
|
|
188
|
-
id_token_signing_alg_values_supported: ['RS256'],
|
|
189
|
-
scopes_supported: ['openid', 'profile', 'email'],
|
|
190
|
-
token_endpoint_auth_methods_supported: ['client_secret_basic', 'client_secret_post', 'none'],
|
|
191
|
-
claims_supported: ['sub', 'iss', 'aud', 'exp', 'iat', 'email', 'name'],
|
|
192
|
-
grant_types_supported: ['authorization_code', 'refresh_token', 'client_credentials', 'anonymous'],
|
|
193
|
-
};
|
|
194
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
195
|
-
res.end(JSON.stringify(config));
|
|
196
|
-
this.log('Served OIDC configuration');
|
|
197
|
-
}
|
|
198
|
-
async handleOAuthMetadata(_req, res) {
|
|
199
|
-
const issuer = this._info?.issuer ?? 'http://localhost';
|
|
200
|
-
const metadata = {
|
|
201
|
-
issuer,
|
|
202
|
-
authorization_endpoint: `${issuer}/oauth/authorize`,
|
|
203
|
-
token_endpoint: `${issuer}/oauth/token`,
|
|
204
|
-
jwks_uri: `${issuer}/.well-known/jwks.json`,
|
|
205
|
-
response_types_supported: ['code', 'token'],
|
|
206
|
-
grant_types_supported: ['authorization_code', 'refresh_token', 'client_credentials', 'anonymous'],
|
|
207
|
-
token_endpoint_auth_methods_supported: ['client_secret_basic', 'client_secret_post', 'none'],
|
|
208
|
-
scopes_supported: ['openid', 'profile', 'email', 'anonymous'],
|
|
209
|
-
};
|
|
210
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
211
|
-
res.end(JSON.stringify(metadata));
|
|
212
|
-
this.log('Served OAuth metadata');
|
|
213
|
-
}
|
|
214
|
-
async handleTokenEndpoint(req, res) {
|
|
215
|
-
// Parse request body
|
|
216
|
-
const body = await this.readBody(req);
|
|
217
|
-
const params = new URLSearchParams(body);
|
|
218
|
-
const grantType = params.get('grant_type');
|
|
219
|
-
if (grantType === 'anonymous') {
|
|
220
|
-
// Issue an anonymous token
|
|
221
|
-
const token = await this.tokenFactory.createAnonymousToken();
|
|
222
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
223
|
-
res.end(JSON.stringify({
|
|
224
|
-
access_token: token,
|
|
225
|
-
token_type: 'Bearer',
|
|
226
|
-
expires_in: 3600,
|
|
227
|
-
}));
|
|
228
|
-
this.log('Issued anonymous token');
|
|
229
|
-
}
|
|
230
|
-
else {
|
|
231
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
232
|
-
res.end(JSON.stringify({
|
|
233
|
-
error: 'unsupported_grant_type',
|
|
234
|
-
error_description: 'Only anonymous grant type is supported in mock server',
|
|
235
|
-
}));
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
readBody(req) {
|
|
239
|
-
return new Promise((resolve, reject) => {
|
|
240
|
-
const chunks = [];
|
|
241
|
-
req.on('data', (chunk) => chunks.push(chunk));
|
|
242
|
-
req.on('end', () => resolve(Buffer.concat(chunks).toString()));
|
|
243
|
-
req.on('error', reject);
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
log(message) {
|
|
247
|
-
if (this.options.debug) {
|
|
248
|
-
console.log(`[MockOAuthServer] ${message}`);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
exports.MockOAuthServer = MockOAuthServer;
|
|
253
|
-
//# sourceMappingURL=mock-oauth-server.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mock-oauth-server.js","sourceRoot":"","sources":["../../../src/auth/mock-oauth-server.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @file mock-oauth-server.ts\n * @description Mock OAuth server for testing transparent auth mode\n *\n * This module provides a mock OAuth/OIDC server that serves:\n * - JWKS endpoint for token verification\n * - OAuth metadata endpoint (optional)\n * - Token endpoint for anonymous tokens (optional)\n *\n * @example\n * ```typescript\n * import { MockOAuthServer, TestTokenFactory } from '@frontmcp/testing';\n *\n * const tokenFactory = new TestTokenFactory();\n * const oauthServer = new MockOAuthServer(tokenFactory);\n *\n * // Start the mock server\n * await oauthServer.start();\n *\n * // Configure your MCP server to use this mock\n * // IDP_PROVIDER_URL = oauthServer.baseUrl\n *\n * // Create tokens using the same factory\n * const token = await tokenFactory.createTestToken({ sub: 'user-123' });\n *\n * // Stop when done\n * await oauthServer.stop();\n * ```\n */\n\nimport { createServer, Server, IncomingMessage, ServerResponse } from 'http';\nimport type { TestTokenFactory } from './token-factory';\n\n// ═══════════════════════════════════════════════════════════════════\n// TYPES\n// ═══════════════════════════════════════════════════════════════════\n\nexport interface MockOAuthServerOptions {\n /** Port to listen on (default: random available port) */\n port?: number;\n /** Issuer URL (default: http://localhost:{port}) */\n issuer?: string;\n /** Enable debug logging */\n debug?: boolean;\n}\n\nexport interface MockOAuthServerInfo {\n /** Base URL of the server */\n baseUrl: string;\n /** Port the server is listening on */\n port: number;\n /** Issuer URL */\n issuer: string;\n /** JWKS endpoint URL */\n jwksUrl: string;\n}\n\n// ═══════════════════════════════════════════════════════════════════\n// MOCK OAUTH SERVER\n// ═══════════════════════════════════════════════════════════════════\n\n/**\n * Mock OAuth/OIDC server for testing transparent auth mode\n *\n * Serves JWKS from a TestTokenFactory so that MCP servers can\n * validate test tokens without connecting to a real IdP.\n */\nexport class MockOAuthServer {\n private readonly tokenFactory: TestTokenFactory;\n private readonly options: MockOAuthServerOptions;\n private server: Server | null = null;\n private _info: MockOAuthServerInfo | null = null;\n private connections: Set<import('net').Socket> = new Set();\n\n constructor(tokenFactory: TestTokenFactory, options: MockOAuthServerOptions = {}) {\n this.tokenFactory = tokenFactory;\n this.options = options;\n }\n\n /**\n * Start the mock OAuth server\n */\n async start(): Promise<MockOAuthServerInfo> {\n if (this.server) {\n throw new Error('Mock OAuth server is already running');\n }\n\n const port = this.options.port ?? 0; // 0 = random available port\n\n return new Promise((resolve, reject) => {\n const server = createServer(this.handleRequest.bind(this));\n this.server = server;\n\n // Track connections for proper cleanup\n server.on('connection', (socket) => {\n this.connections.add(socket);\n socket.on('close', () => this.connections.delete(socket));\n });\n\n server.on('error', (err) => {\n this.log(`Server error: ${err.message}`);\n reject(err);\n });\n\n server.listen(port, () => {\n const address = server.address();\n if (!address || typeof address === 'string') {\n reject(new Error('Failed to get server address'));\n return;\n }\n\n const actualPort = address.port;\n const issuer = this.options.issuer ?? `http://localhost:${actualPort}`;\n\n this._info = {\n baseUrl: `http://localhost:${actualPort}`,\n port: actualPort,\n issuer,\n jwksUrl: `http://localhost:${actualPort}/.well-known/jwks.json`,\n };\n\n this.log(`Mock OAuth server started at ${this._info.baseUrl}`);\n resolve(this._info);\n });\n });\n }\n\n /**\n * Stop the mock OAuth server\n */\n async stop(): Promise<void> {\n const server = this.server;\n if (!server) {\n return;\n }\n\n // Destroy all active connections to allow server.close() to complete\n for (const socket of this.connections) {\n socket.destroy();\n }\n this.connections.clear();\n\n return new Promise((resolve, reject) => {\n server.close((err) => {\n if (err) {\n reject(err);\n } else {\n this.server = null;\n this._info = null;\n this.log('Mock OAuth server stopped');\n resolve();\n }\n });\n });\n }\n\n /**\n * Get server info\n */\n get info(): MockOAuthServerInfo {\n if (!this._info) {\n throw new Error('Mock OAuth server is not running');\n }\n return this._info;\n }\n\n /**\n * Get the token factory (for creating tokens)\n */\n getTokenFactory(): TestTokenFactory {\n return this.tokenFactory;\n }\n\n // ═══════════════════════════════════════════════════════════════════\n // PRIVATE\n // ═══════════════════════════════════════════════════════════════════\n\n private async handleRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const url = req.url ?? '/';\n this.log(`${req.method} ${url}`);\n\n // CORS headers\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n try {\n if (url === '/.well-known/jwks.json' || url === '/.well-known/jwks') {\n await this.handleJwks(req, res);\n } else if (url === '/.well-known/openid-configuration') {\n await this.handleOidcConfig(req, res);\n } else if (url === '/.well-known/oauth-authorization-server') {\n await this.handleOAuthMetadata(req, res);\n } else if (url === '/oauth/token') {\n await this.handleTokenEndpoint(req, res);\n } else {\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'not_found', error_description: 'Endpoint not found' }));\n }\n } catch (error) {\n this.log(`Error handling request: ${error}`);\n res.writeHead(500, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'server_error', error_description: 'Internal server error' }));\n }\n }\n\n private async handleJwks(_req: IncomingMessage, res: ServerResponse): Promise<void> {\n const jwks = await this.tokenFactory.getPublicJwks();\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(jwks));\n this.log('Served JWKS');\n }\n\n private async handleOidcConfig(_req: IncomingMessage, res: ServerResponse): Promise<void> {\n const issuer = this._info?.issuer ?? 'http://localhost';\n const config = {\n issuer,\n authorization_endpoint: `${issuer}/oauth/authorize`,\n token_endpoint: `${issuer}/oauth/token`,\n jwks_uri: `${issuer}/.well-known/jwks.json`,\n response_types_supported: ['code', 'token'],\n subject_types_supported: ['public'],\n id_token_signing_alg_values_supported: ['RS256'],\n scopes_supported: ['openid', 'profile', 'email'],\n token_endpoint_auth_methods_supported: ['client_secret_basic', 'client_secret_post', 'none'],\n claims_supported: ['sub', 'iss', 'aud', 'exp', 'iat', 'email', 'name'],\n grant_types_supported: ['authorization_code', 'refresh_token', 'client_credentials', 'anonymous'],\n };\n\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(config));\n this.log('Served OIDC configuration');\n }\n\n private async handleOAuthMetadata(_req: IncomingMessage, res: ServerResponse): Promise<void> {\n const issuer = this._info?.issuer ?? 'http://localhost';\n const metadata = {\n issuer,\n authorization_endpoint: `${issuer}/oauth/authorize`,\n token_endpoint: `${issuer}/oauth/token`,\n jwks_uri: `${issuer}/.well-known/jwks.json`,\n response_types_supported: ['code', 'token'],\n grant_types_supported: ['authorization_code', 'refresh_token', 'client_credentials', 'anonymous'],\n token_endpoint_auth_methods_supported: ['client_secret_basic', 'client_secret_post', 'none'],\n scopes_supported: ['openid', 'profile', 'email', 'anonymous'],\n };\n\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(metadata));\n this.log('Served OAuth metadata');\n }\n\n private async handleTokenEndpoint(req: IncomingMessage, res: ServerResponse): Promise<void> {\n // Parse request body\n const body = await this.readBody(req);\n const params = new URLSearchParams(body);\n const grantType = params.get('grant_type');\n\n if (grantType === 'anonymous') {\n // Issue an anonymous token\n const token = await this.tokenFactory.createAnonymousToken();\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(\n JSON.stringify({\n access_token: token,\n token_type: 'Bearer',\n expires_in: 3600,\n }),\n );\n this.log('Issued anonymous token');\n } else {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(\n JSON.stringify({\n error: 'unsupported_grant_type',\n error_description: 'Only anonymous grant type is supported in mock server',\n }),\n );\n }\n }\n\n private readBody(req: IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on('data', (chunk) => chunks.push(chunk));\n req.on('end', () => resolve(Buffer.concat(chunks).toString()));\n req.on('error', reject);\n });\n }\n\n private log(message: string): void {\n if (this.options.debug) {\n console.log(`[MockOAuthServer] ${message}`);\n }\n }\n}\n"]}
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @file token-factory.ts
|
|
4
|
-
* @description JWT token factory for testing authentication
|
|
5
|
-
*/
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.TestTokenFactory = void 0;
|
|
8
|
-
const jose_1 = require("jose");
|
|
9
|
-
// ═══════════════════════════════════════════════════════════════════
|
|
10
|
-
// TOKEN FACTORY CLASS
|
|
11
|
-
// ═══════════════════════════════════════════════════════════════════
|
|
12
|
-
/**
|
|
13
|
-
* Factory for creating JWT tokens for testing
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* ```typescript
|
|
17
|
-
* const factory = new TestTokenFactory();
|
|
18
|
-
*
|
|
19
|
-
* // Create a token with claims
|
|
20
|
-
* const token = await factory.createTestToken({
|
|
21
|
-
* sub: 'user-123',
|
|
22
|
-
* scopes: ['read', 'write'],
|
|
23
|
-
* });
|
|
24
|
-
*
|
|
25
|
-
* // Create convenience tokens
|
|
26
|
-
* const adminToken = await factory.createAdminToken();
|
|
27
|
-
* const userToken = await factory.createUserToken();
|
|
28
|
-
* ```
|
|
29
|
-
*/
|
|
30
|
-
class TestTokenFactory {
|
|
31
|
-
issuer;
|
|
32
|
-
audience;
|
|
33
|
-
privateKey = null;
|
|
34
|
-
publicKey = null;
|
|
35
|
-
jwk = null;
|
|
36
|
-
keyId;
|
|
37
|
-
constructor(options = {}) {
|
|
38
|
-
this.issuer = options.issuer ?? 'https://test.frontmcp.local';
|
|
39
|
-
this.audience = options.audience ?? 'frontmcp-test';
|
|
40
|
-
this.keyId = `test-key-${Date.now()}`;
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Initialize the key pair (called automatically on first use)
|
|
44
|
-
*/
|
|
45
|
-
async ensureKeys() {
|
|
46
|
-
if (this.privateKey && this.publicKey)
|
|
47
|
-
return;
|
|
48
|
-
// Generate RSA key pair
|
|
49
|
-
const { publicKey, privateKey } = await (0, jose_1.generateKeyPair)('RS256', {
|
|
50
|
-
extractable: true,
|
|
51
|
-
});
|
|
52
|
-
this.privateKey = privateKey;
|
|
53
|
-
this.publicKey = publicKey;
|
|
54
|
-
// Export public key as JWK
|
|
55
|
-
this.jwk = await (0, jose_1.exportJWK)(publicKey);
|
|
56
|
-
this.jwk.kid = this.keyId;
|
|
57
|
-
this.jwk.use = 'sig';
|
|
58
|
-
this.jwk.alg = 'RS256';
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Create a JWT token with the specified claims
|
|
62
|
-
*/
|
|
63
|
-
async createTestToken(options) {
|
|
64
|
-
await this.ensureKeys();
|
|
65
|
-
const now = Math.floor(Date.now() / 1000);
|
|
66
|
-
const exp = options.exp ?? 3600;
|
|
67
|
-
const payload = {
|
|
68
|
-
iss: options.iss ?? this.issuer,
|
|
69
|
-
sub: options.sub,
|
|
70
|
-
aud: options.aud ?? this.audience,
|
|
71
|
-
iat: now,
|
|
72
|
-
exp: now + exp,
|
|
73
|
-
scope: options.scopes?.join(' '),
|
|
74
|
-
...options.claims,
|
|
75
|
-
};
|
|
76
|
-
const token = await new jose_1.SignJWT(payload)
|
|
77
|
-
.setProtectedHeader({ alg: 'RS256', kid: this.keyId })
|
|
78
|
-
.sign(this.privateKey);
|
|
79
|
-
return token;
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Create an admin token with full access
|
|
83
|
-
*/
|
|
84
|
-
async createAdminToken(sub = 'admin-001') {
|
|
85
|
-
return this.createTestToken({
|
|
86
|
-
sub,
|
|
87
|
-
scopes: ['admin:*', 'read', 'write', 'delete'],
|
|
88
|
-
claims: {
|
|
89
|
-
email: 'admin@test.local',
|
|
90
|
-
name: 'Test Admin',
|
|
91
|
-
role: 'admin',
|
|
92
|
-
},
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Create a regular user token
|
|
97
|
-
*/
|
|
98
|
-
async createUserToken(sub = 'user-001', scopes = ['read', 'write']) {
|
|
99
|
-
return this.createTestToken({
|
|
100
|
-
sub,
|
|
101
|
-
scopes,
|
|
102
|
-
claims: {
|
|
103
|
-
email: 'user@test.local',
|
|
104
|
-
name: 'Test User',
|
|
105
|
-
role: 'user',
|
|
106
|
-
},
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Create an anonymous user token
|
|
111
|
-
*/
|
|
112
|
-
async createAnonymousToken() {
|
|
113
|
-
return this.createTestToken({
|
|
114
|
-
sub: `anon:${Date.now()}`,
|
|
115
|
-
scopes: ['anonymous'],
|
|
116
|
-
claims: {
|
|
117
|
-
name: 'Anonymous',
|
|
118
|
-
role: 'anonymous',
|
|
119
|
-
},
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Create an expired token (for testing token expiration)
|
|
124
|
-
*/
|
|
125
|
-
async createExpiredToken(options) {
|
|
126
|
-
await this.ensureKeys();
|
|
127
|
-
const now = Math.floor(Date.now() / 1000);
|
|
128
|
-
const payload = {
|
|
129
|
-
iss: this.issuer,
|
|
130
|
-
sub: options.sub,
|
|
131
|
-
aud: this.audience,
|
|
132
|
-
iat: now - 7200, // 2 hours ago
|
|
133
|
-
exp: now - 3600, // Expired 1 hour ago
|
|
134
|
-
};
|
|
135
|
-
const token = await new jose_1.SignJWT(payload)
|
|
136
|
-
.setProtectedHeader({ alg: 'RS256', kid: this.keyId })
|
|
137
|
-
.sign(this.privateKey);
|
|
138
|
-
return token;
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Create a token with an invalid signature (for testing signature validation)
|
|
142
|
-
*/
|
|
143
|
-
createTokenWithInvalidSignature(options) {
|
|
144
|
-
const now = Math.floor(Date.now() / 1000);
|
|
145
|
-
// Create a fake JWT with an invalid signature
|
|
146
|
-
const header = Buffer.from(JSON.stringify({ alg: 'RS256', kid: this.keyId })).toString('base64url');
|
|
147
|
-
const payload = Buffer.from(JSON.stringify({
|
|
148
|
-
iss: this.issuer,
|
|
149
|
-
sub: options.sub,
|
|
150
|
-
aud: this.audience,
|
|
151
|
-
iat: now,
|
|
152
|
-
exp: now + 3600,
|
|
153
|
-
})).toString('base64url');
|
|
154
|
-
// Invalid signature (just random bytes)
|
|
155
|
-
const signature = Buffer.from('invalid-signature-' + Date.now()).toString('base64url');
|
|
156
|
-
return `${header}.${payload}.${signature}`;
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Get the public JWKS for verifying tokens
|
|
160
|
-
*/
|
|
161
|
-
async getPublicJwks() {
|
|
162
|
-
await this.ensureKeys();
|
|
163
|
-
return {
|
|
164
|
-
keys: [this.jwk],
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Get the issuer URL
|
|
169
|
-
*/
|
|
170
|
-
getIssuer() {
|
|
171
|
-
return this.issuer;
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Get the audience
|
|
175
|
-
*/
|
|
176
|
-
getAudience() {
|
|
177
|
-
return this.audience;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
exports.TestTokenFactory = TestTokenFactory;
|
|
181
|
-
//# sourceMappingURL=token-factory.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"token-factory.js","sourceRoot":"","sources":["../../../src/auth/token-factory.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @file token-factory.ts\n * @description JWT token factory for testing authentication\n */\n\nimport { SignJWT, generateKeyPair, exportJWK, type JWTPayload, type JWK } from 'jose';\n\n// ═══════════════════════════════════════════════════════════════════\n// TYPES\n// ═══════════════════════════════════════════════════════════════════\n\nexport interface CreateTokenOptions {\n /** Subject (user ID) - required */\n sub: string;\n /** Issuer URL */\n iss?: string;\n /** Audience */\n aud?: string | string[];\n /** OAuth scopes */\n scopes?: string[];\n /** Expiration time in seconds from now (default: 3600) */\n exp?: number;\n /** Additional custom claims */\n claims?: Record<string, unknown>;\n}\n\nexport interface TokenFactoryOptions {\n /** Default issuer URL */\n issuer?: string;\n /** Default audience */\n audience?: string;\n}\n\n// Type for crypto key\ntype CryptoKeyLike = CryptoKey | Uint8Array;\n\n// ═══════════════════════════════════════════════════════════════════\n// TOKEN FACTORY CLASS\n// ═══════════════════════════════════════════════════════════════════\n\n/**\n * Factory for creating JWT tokens for testing\n *\n * @example\n * ```typescript\n * const factory = new TestTokenFactory();\n *\n * // Create a token with claims\n * const token = await factory.createTestToken({\n * sub: 'user-123',\n * scopes: ['read', 'write'],\n * });\n *\n * // Create convenience tokens\n * const adminToken = await factory.createAdminToken();\n * const userToken = await factory.createUserToken();\n * ```\n */\nexport class TestTokenFactory {\n private readonly issuer: string;\n private readonly audience: string;\n private privateKey: CryptoKeyLike | null = null;\n private publicKey: CryptoKeyLike | null = null;\n private jwk: JWK | null = null;\n private keyId: string;\n\n constructor(options: TokenFactoryOptions = {}) {\n this.issuer = options.issuer ?? 'https://test.frontmcp.local';\n this.audience = options.audience ?? 'frontmcp-test';\n this.keyId = `test-key-${Date.now()}`;\n }\n\n /**\n * Initialize the key pair (called automatically on first use)\n */\n private async ensureKeys(): Promise<void> {\n if (this.privateKey && this.publicKey) return;\n\n // Generate RSA key pair\n const { publicKey, privateKey } = await generateKeyPair('RS256', {\n extractable: true,\n });\n\n this.privateKey = privateKey;\n this.publicKey = publicKey;\n\n // Export public key as JWK\n this.jwk = await exportJWK(publicKey);\n this.jwk.kid = this.keyId;\n this.jwk.use = 'sig';\n this.jwk.alg = 'RS256';\n }\n\n /**\n * Create a JWT token with the specified claims\n */\n async createTestToken(options: CreateTokenOptions): Promise<string> {\n await this.ensureKeys();\n\n const now = Math.floor(Date.now() / 1000);\n const exp = options.exp ?? 3600;\n\n const payload: JWTPayload = {\n iss: options.iss ?? this.issuer,\n sub: options.sub,\n aud: options.aud ?? this.audience,\n iat: now,\n exp: now + exp,\n scope: options.scopes?.join(' '),\n ...options.claims,\n };\n\n const token = await new SignJWT(payload)\n .setProtectedHeader({ alg: 'RS256', kid: this.keyId })\n .sign(this.privateKey!);\n\n return token;\n }\n\n /**\n * Create an admin token with full access\n */\n async createAdminToken(sub = 'admin-001'): Promise<string> {\n return this.createTestToken({\n sub,\n scopes: ['admin:*', 'read', 'write', 'delete'],\n claims: {\n email: 'admin@test.local',\n name: 'Test Admin',\n role: 'admin',\n },\n });\n }\n\n /**\n * Create a regular user token\n */\n async createUserToken(sub = 'user-001', scopes = ['read', 'write']): Promise<string> {\n return this.createTestToken({\n sub,\n scopes,\n claims: {\n email: 'user@test.local',\n name: 'Test User',\n role: 'user',\n },\n });\n }\n\n /**\n * Create an anonymous user token\n */\n async createAnonymousToken(): Promise<string> {\n return this.createTestToken({\n sub: `anon:${Date.now()}`,\n scopes: ['anonymous'],\n claims: {\n name: 'Anonymous',\n role: 'anonymous',\n },\n });\n }\n\n /**\n * Create an expired token (for testing token expiration)\n */\n async createExpiredToken(options: Pick<CreateTokenOptions, 'sub'>): Promise<string> {\n await this.ensureKeys();\n\n const now = Math.floor(Date.now() / 1000);\n\n const payload: JWTPayload = {\n iss: this.issuer,\n sub: options.sub,\n aud: this.audience,\n iat: now - 7200, // 2 hours ago\n exp: now - 3600, // Expired 1 hour ago\n };\n\n const token = await new SignJWT(payload)\n .setProtectedHeader({ alg: 'RS256', kid: this.keyId })\n .sign(this.privateKey!);\n\n return token;\n }\n\n /**\n * Create a token with an invalid signature (for testing signature validation)\n */\n createTokenWithInvalidSignature(options: Pick<CreateTokenOptions, 'sub'>): string {\n const now = Math.floor(Date.now() / 1000);\n\n // Create a fake JWT with an invalid signature\n const header = Buffer.from(JSON.stringify({ alg: 'RS256', kid: this.keyId })).toString('base64url');\n const payload = Buffer.from(\n JSON.stringify({\n iss: this.issuer,\n sub: options.sub,\n aud: this.audience,\n iat: now,\n exp: now + 3600,\n }),\n ).toString('base64url');\n\n // Invalid signature (just random bytes)\n const signature = Buffer.from('invalid-signature-' + Date.now()).toString('base64url');\n\n return `${header}.${payload}.${signature}`;\n }\n\n /**\n * Get the public JWKS for verifying tokens\n */\n async getPublicJwks(): Promise<{ keys: JWK[] }> {\n await this.ensureKeys();\n return {\n keys: [this.jwk!],\n };\n }\n\n /**\n * Get the issuer URL\n */\n getIssuer(): string {\n return this.issuer;\n }\n\n /**\n * Get the audience\n */\n getAudience(): string {\n return this.audience;\n }\n}\n"]}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @file user-fixtures.ts
|
|
4
|
-
* @description Pre-defined test user fixtures
|
|
5
|
-
*/
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.TestUsers = void 0;
|
|
8
|
-
exports.createTestUser = createTestUser;
|
|
9
|
-
/**
|
|
10
|
-
* Pre-defined test users for common testing scenarios
|
|
11
|
-
*/
|
|
12
|
-
exports.TestUsers = {
|
|
13
|
-
/**
|
|
14
|
-
* Admin user with full access
|
|
15
|
-
*/
|
|
16
|
-
admin: {
|
|
17
|
-
sub: 'admin-001',
|
|
18
|
-
email: 'admin@test.local',
|
|
19
|
-
name: 'Test Admin',
|
|
20
|
-
scopes: ['admin:*', 'read', 'write', 'delete'],
|
|
21
|
-
role: 'admin',
|
|
22
|
-
},
|
|
23
|
-
/**
|
|
24
|
-
* Regular user with read/write access
|
|
25
|
-
*/
|
|
26
|
-
user: {
|
|
27
|
-
sub: 'user-001',
|
|
28
|
-
email: 'user@test.local',
|
|
29
|
-
name: 'Test User',
|
|
30
|
-
scopes: ['read', 'write'],
|
|
31
|
-
role: 'user',
|
|
32
|
-
},
|
|
33
|
-
/**
|
|
34
|
-
* Read-only user
|
|
35
|
-
*/
|
|
36
|
-
readOnly: {
|
|
37
|
-
sub: 'readonly-001',
|
|
38
|
-
email: 'readonly@test.local',
|
|
39
|
-
name: 'Read Only User',
|
|
40
|
-
scopes: ['read'],
|
|
41
|
-
role: 'readonly',
|
|
42
|
-
},
|
|
43
|
-
/**
|
|
44
|
-
* Anonymous user
|
|
45
|
-
*/
|
|
46
|
-
anonymous: {
|
|
47
|
-
sub: 'anon:001',
|
|
48
|
-
name: 'Anonymous',
|
|
49
|
-
scopes: ['anonymous'],
|
|
50
|
-
role: 'anonymous',
|
|
51
|
-
},
|
|
52
|
-
/**
|
|
53
|
-
* User with no scopes (for testing access denied)
|
|
54
|
-
*/
|
|
55
|
-
noScopes: {
|
|
56
|
-
sub: 'noscopes-001',
|
|
57
|
-
email: 'noscopes@test.local',
|
|
58
|
-
name: 'No Scopes User',
|
|
59
|
-
scopes: [],
|
|
60
|
-
role: 'user',
|
|
61
|
-
},
|
|
62
|
-
/**
|
|
63
|
-
* User with only tool execution scope
|
|
64
|
-
*/
|
|
65
|
-
toolsOnly: {
|
|
66
|
-
sub: 'toolsonly-001',
|
|
67
|
-
email: 'toolsonly@test.local',
|
|
68
|
-
name: 'Tools Only User',
|
|
69
|
-
scopes: ['tools:execute'],
|
|
70
|
-
role: 'user',
|
|
71
|
-
},
|
|
72
|
-
/**
|
|
73
|
-
* User with only resource read scope
|
|
74
|
-
*/
|
|
75
|
-
resourcesOnly: {
|
|
76
|
-
sub: 'resourcesonly-001',
|
|
77
|
-
email: 'resourcesonly@test.local',
|
|
78
|
-
name: 'Resources Only User',
|
|
79
|
-
scopes: ['resources:read'],
|
|
80
|
-
role: 'user',
|
|
81
|
-
},
|
|
82
|
-
};
|
|
83
|
-
/**
|
|
84
|
-
* Create a custom test user
|
|
85
|
-
*/
|
|
86
|
-
function createTestUser(overrides) {
|
|
87
|
-
return {
|
|
88
|
-
scopes: [],
|
|
89
|
-
...overrides,
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
//# sourceMappingURL=user-fixtures.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"user-fixtures.js","sourceRoot":"","sources":["../../../src/auth/user-fixtures.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAmGH,wCAKC;AAzFD;;GAEG;AACU,QAAA,SAAS,GAAoC;IACxD;;OAEG;IACH,KAAK,EAAE;QACL,GAAG,EAAE,WAAW;QAChB,KAAK,EAAE,kBAAkB;QACzB,IAAI,EAAE,YAAY;QAClB,MAAM,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC;QAC9C,IAAI,EAAE,OAAO;KACd;IAED;;OAEG;IACH,IAAI,EAAE;QACJ,GAAG,EAAE,UAAU;QACf,KAAK,EAAE,iBAAiB;QACxB,IAAI,EAAE,WAAW;QACjB,MAAM,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;QACzB,IAAI,EAAE,MAAM;KACb;IAED;;OAEG;IACH,QAAQ,EAAE;QACR,GAAG,EAAE,cAAc;QACnB,KAAK,EAAE,qBAAqB;QAC5B,IAAI,EAAE,gBAAgB;QACtB,MAAM,EAAE,CAAC,MAAM,CAAC;QAChB,IAAI,EAAE,UAAU;KACjB;IAED;;OAEG;IACH,SAAS,EAAE;QACT,GAAG,EAAE,UAAU;QACf,IAAI,EAAE,WAAW;QACjB,MAAM,EAAE,CAAC,WAAW,CAAC;QACrB,IAAI,EAAE,WAAW;KAClB;IAED;;OAEG;IACH,QAAQ,EAAE;QACR,GAAG,EAAE,cAAc;QACnB,KAAK,EAAE,qBAAqB;QAC5B,IAAI,EAAE,gBAAgB;QACtB,MAAM,EAAE,EAAE;QACV,IAAI,EAAE,MAAM;KACb;IAED;;OAEG;IACH,SAAS,EAAE;QACT,GAAG,EAAE,eAAe;QACpB,KAAK,EAAE,sBAAsB;QAC7B,IAAI,EAAE,iBAAiB;QACvB,MAAM,EAAE,CAAC,eAAe,CAAC;QACzB,IAAI,EAAE,MAAM;KACb;IAED;;OAEG;IACH,aAAa,EAAE;QACb,GAAG,EAAE,mBAAmB;QACxB,KAAK,EAAE,0BAA0B;QACjC,IAAI,EAAE,qBAAqB;QAC3B,MAAM,EAAE,CAAC,gBAAgB,CAAC;QAC1B,IAAI,EAAE,MAAM;KACb;CACF,CAAC;AAEF;;GAEG;AACH,SAAgB,cAAc,CAAC,SAAqD;IAClF,OAAO;QACL,MAAM,EAAE,EAAE;QACV,GAAG,SAAS;KACb,CAAC;AACJ,CAAC","sourcesContent":["/**\n * @file user-fixtures.ts\n * @description Pre-defined test user fixtures\n */\n\nexport interface TestUserFixture {\n /** User subject ID */\n sub: string;\n /** User email */\n email?: string;\n /** User display name */\n name?: string;\n /** OAuth scopes */\n scopes: string[];\n /** User role */\n role?: string;\n}\n\n/**\n * Pre-defined test users for common testing scenarios\n */\nexport const TestUsers: Record<string, TestUserFixture> = {\n /**\n * Admin user with full access\n */\n admin: {\n sub: 'admin-001',\n email: 'admin@test.local',\n name: 'Test Admin',\n scopes: ['admin:*', 'read', 'write', 'delete'],\n role: 'admin',\n },\n\n /**\n * Regular user with read/write access\n */\n user: {\n sub: 'user-001',\n email: 'user@test.local',\n name: 'Test User',\n scopes: ['read', 'write'],\n role: 'user',\n },\n\n /**\n * Read-only user\n */\n readOnly: {\n sub: 'readonly-001',\n email: 'readonly@test.local',\n name: 'Read Only User',\n scopes: ['read'],\n role: 'readonly',\n },\n\n /**\n * Anonymous user\n */\n anonymous: {\n sub: 'anon:001',\n name: 'Anonymous',\n scopes: ['anonymous'],\n role: 'anonymous',\n },\n\n /**\n * User with no scopes (for testing access denied)\n */\n noScopes: {\n sub: 'noscopes-001',\n email: 'noscopes@test.local',\n name: 'No Scopes User',\n scopes: [],\n role: 'user',\n },\n\n /**\n * User with only tool execution scope\n */\n toolsOnly: {\n sub: 'toolsonly-001',\n email: 'toolsonly@test.local',\n name: 'Tools Only User',\n scopes: ['tools:execute'],\n role: 'user',\n },\n\n /**\n * User with only resource read scope\n */\n resourcesOnly: {\n sub: 'resourcesonly-001',\n email: 'resourcesonly@test.local',\n name: 'Resources Only User',\n scopes: ['resources:read'],\n role: 'user',\n },\n};\n\n/**\n * Create a custom test user\n */\nexport function createTestUser(overrides: Partial<TestUserFixture> & { sub: string }): TestUserFixture {\n return {\n scopes: [],\n ...overrides,\n };\n}\n"]}
|
package/src/client/index.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @file client/index.ts
|
|
4
|
-
* @description MCP Test Client exports
|
|
5
|
-
*/
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.McpTestClientBuilder = exports.McpTestClient = void 0;
|
|
8
|
-
var mcp_test_client_1 = require("./mcp-test-client");
|
|
9
|
-
Object.defineProperty(exports, "McpTestClient", { enumerable: true, get: function () { return mcp_test_client_1.McpTestClient; } });
|
|
10
|
-
var mcp_test_client_builder_1 = require("./mcp-test-client.builder");
|
|
11
|
-
Object.defineProperty(exports, "McpTestClientBuilder", { enumerable: true, get: function () { return mcp_test_client_builder_1.McpTestClientBuilder; } });
|
|
12
|
-
//# sourceMappingURL=index.js.map
|
package/src/client/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,qDAAkD;AAAzC,gHAAA,aAAa,OAAA;AACtB,qEAAiE;AAAxD,+HAAA,oBAAoB,OAAA","sourcesContent":["/**\n * @file client/index.ts\n * @description MCP Test Client exports\n */\n\nexport { McpTestClient } from './mcp-test-client';\nexport { McpTestClientBuilder } from './mcp-test-client.builder';\nexport type {\n McpTestClientConfig,\n McpResponse,\n McpErrorInfo,\n TestTransportType,\n TestAuthConfig,\n ToolResultWrapper,\n ResourceContentWrapper,\n PromptResultWrapper,\n LogEntry,\n LogLevel,\n RequestTrace,\n NotificationEntry,\n ProgressUpdate,\n SessionInfo,\n AuthState,\n TransportState,\n // JSON-RPC types\n JSONRPCRequest,\n JSONRPCResponse,\n // Re-exports from MCP SDK\n InitializeResult,\n ListToolsResult,\n CallToolResult,\n ListResourcesResult,\n ReadResourceResult,\n ListResourceTemplatesResult,\n ListPromptsResult,\n GetPromptResult,\n Tool,\n Resource,\n ResourceTemplate,\n Prompt,\n} from './mcp-test-client.types';\n"]}
|