@enterprisestandard/esv 0.0.5-beta.20260115.1 → 0.0.5-beta.20260115.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.
@@ -0,0 +1,428 @@
1
+ /**
2
+ * SSO/OIDC endpoint handlers for the ESV mock server
3
+ *
4
+ * Implements a minimal OIDC provider for testing SSO integrations.
5
+ */
6
+ import { generateRandomString, generateUUID, getJwks, signJwt, verifyCodeChallenge } from './crypto.js';
7
+ import { createSession, deleteAuthCode, deleteRefreshToken, deleteSession, getAuthCode, getRefreshToken, getTestUser, storeAuthCode, storeRefreshToken, } from './state.js';
8
+ const ISSUER = 'http://localhost:3555/sso';
9
+ const TOKEN_EXPIRY = 3600; // 1 hour
10
+ const REFRESH_EXPIRY = 86400; // 24 hours
11
+ const CODE_EXPIRY = 300; // 5 minutes
12
+ /**
13
+ * Parse request body as URL-encoded form data
14
+ */
15
+ async function parseFormBody(req) {
16
+ return new Promise((resolve, reject) => {
17
+ let body = '';
18
+ req.on('data', (chunk) => {
19
+ body += chunk.toString();
20
+ });
21
+ req.on('end', () => {
22
+ resolve(new URLSearchParams(body));
23
+ });
24
+ req.on('error', reject);
25
+ });
26
+ }
27
+ /**
28
+ * Handle SSO requests
29
+ */
30
+ export async function handleSsoRequest(req, res, pathname) {
31
+ // Remove /sso prefix
32
+ const ssoPath = pathname.replace(/^\/sso/, '');
33
+ // GET /sso/authorize - Authorization endpoint
34
+ if (req.method === 'GET' && ssoPath === '/authorize') {
35
+ await handleAuthorize(req, res);
36
+ return;
37
+ }
38
+ // POST /sso/token - Token endpoint
39
+ if (req.method === 'POST' && ssoPath === '/token') {
40
+ await handleToken(req, res);
41
+ return;
42
+ }
43
+ // GET /sso/certs - JWKS endpoint
44
+ if (req.method === 'GET' && ssoPath === '/certs') {
45
+ handleCerts(res);
46
+ return;
47
+ }
48
+ // POST /sso/revoke - Token revocation
49
+ if (req.method === 'POST' && ssoPath === '/revoke') {
50
+ await handleRevoke(req, res);
51
+ return;
52
+ }
53
+ // GET /sso/userinfo - User info endpoint
54
+ if (req.method === 'GET' && ssoPath === '/userinfo') {
55
+ handleUserInfo(req, res);
56
+ return;
57
+ }
58
+ // GET /sso/logout - End session endpoint
59
+ if (req.method === 'GET' && ssoPath === '/logout') {
60
+ handleLogout(req, res);
61
+ return;
62
+ }
63
+ // POST /sso/logout - Back-channel logout
64
+ if (req.method === 'POST' && ssoPath === '/logout/backchannel') {
65
+ await handleBackChannelLogout(req, res);
66
+ return;
67
+ }
68
+ // GET /sso/.well-known/openid-configuration
69
+ if (req.method === 'GET' && ssoPath === '/.well-known/openid-configuration') {
70
+ handleOpenIDConfig(res);
71
+ return;
72
+ }
73
+ res.writeHead(404, { 'Content-Type': 'application/json' });
74
+ res.end(JSON.stringify({ error: 'not_found' }));
75
+ }
76
+ /**
77
+ * Authorization endpoint - issues authorization codes
78
+ *
79
+ * In a real implementation, this would show a login form.
80
+ * For testing, we auto-authenticate with the test user.
81
+ */
82
+ async function handleAuthorize(req, res) {
83
+ const url = new URL(req.url || '', `http://${req.headers.host}`);
84
+ const params = url.searchParams;
85
+ const clientId = params.get('client_id');
86
+ const redirectUri = params.get('redirect_uri');
87
+ const responseType = params.get('response_type');
88
+ const scope = params.get('scope') || 'openid';
89
+ const state = params.get('state');
90
+ const codeChallenge = params.get('code_challenge');
91
+ const codeChallengeMethod = params.get('code_challenge_method');
92
+ // Validate required parameters
93
+ if (!clientId || !redirectUri || !responseType) {
94
+ res.writeHead(400, { 'Content-Type': 'application/json' });
95
+ res.end(JSON.stringify({
96
+ error: 'invalid_request',
97
+ error_description: 'Missing required parameters',
98
+ }));
99
+ return;
100
+ }
101
+ if (responseType !== 'code') {
102
+ res.writeHead(400, { 'Content-Type': 'application/json' });
103
+ res.end(JSON.stringify({
104
+ error: 'unsupported_response_type',
105
+ error_description: 'Only code response type is supported',
106
+ }));
107
+ return;
108
+ }
109
+ // Generate authorization code
110
+ const testUser = getTestUser();
111
+ const code = generateRandomString(32);
112
+ const authCode = {
113
+ code,
114
+ userId: testUser.id,
115
+ clientId,
116
+ redirectUri,
117
+ scope,
118
+ codeChallenge: codeChallenge || undefined,
119
+ codeChallengeMethod: codeChallengeMethod || undefined,
120
+ state: state || undefined,
121
+ createdAt: new Date(),
122
+ expiresAt: new Date(Date.now() + CODE_EXPIRY * 1000),
123
+ };
124
+ storeAuthCode(authCode);
125
+ // Redirect back with code
126
+ const redirectUrl = new URL(redirectUri);
127
+ redirectUrl.searchParams.set('code', code);
128
+ if (state) {
129
+ redirectUrl.searchParams.set('state', state);
130
+ }
131
+ res.writeHead(302, { Location: redirectUrl.toString() });
132
+ res.end();
133
+ }
134
+ /**
135
+ * Token endpoint - exchanges codes for tokens or refreshes tokens
136
+ */
137
+ async function handleToken(req, res) {
138
+ const body = await parseFormBody(req);
139
+ const grantType = body.get('grant_type');
140
+ if (grantType === 'authorization_code') {
141
+ await handleAuthorizationCodeGrant(body, res);
142
+ }
143
+ else if (grantType === 'refresh_token') {
144
+ await handleRefreshTokenGrant(body, res);
145
+ }
146
+ else {
147
+ res.writeHead(400, { 'Content-Type': 'application/json' });
148
+ res.end(JSON.stringify({
149
+ error: 'unsupported_grant_type',
150
+ error_description: 'Only authorization_code and refresh_token are supported',
151
+ }));
152
+ }
153
+ }
154
+ /**
155
+ * Handle authorization code exchange
156
+ */
157
+ async function handleAuthorizationCodeGrant(body, res) {
158
+ const code = body.get('code');
159
+ const redirectUri = body.get('redirect_uri');
160
+ const codeVerifier = body.get('code_verifier');
161
+ if (!code || !redirectUri) {
162
+ res.writeHead(400, { 'Content-Type': 'application/json' });
163
+ res.end(JSON.stringify({
164
+ error: 'invalid_request',
165
+ error_description: 'Missing code or redirect_uri',
166
+ }));
167
+ return;
168
+ }
169
+ const authCode = getAuthCode(code);
170
+ if (!authCode) {
171
+ res.writeHead(400, { 'Content-Type': 'application/json' });
172
+ res.end(JSON.stringify({
173
+ error: 'invalid_grant',
174
+ error_description: 'Invalid or expired authorization code',
175
+ }));
176
+ return;
177
+ }
178
+ // Validate redirect URI
179
+ if (authCode.redirectUri !== redirectUri) {
180
+ res.writeHead(400, { 'Content-Type': 'application/json' });
181
+ res.end(JSON.stringify({
182
+ error: 'invalid_grant',
183
+ error_description: 'Redirect URI mismatch',
184
+ }));
185
+ return;
186
+ }
187
+ // Validate PKCE if present
188
+ if (authCode.codeChallenge && authCode.codeChallengeMethod === 'S256') {
189
+ if (!codeVerifier || !verifyCodeChallenge(codeVerifier, authCode.codeChallenge)) {
190
+ res.writeHead(400, { 'Content-Type': 'application/json' });
191
+ res.end(JSON.stringify({
192
+ error: 'invalid_grant',
193
+ error_description: 'Invalid code verifier',
194
+ }));
195
+ return;
196
+ }
197
+ }
198
+ // Delete used code
199
+ deleteAuthCode(code);
200
+ // Create session
201
+ const sessionId = generateUUID();
202
+ createSession({
203
+ id: sessionId,
204
+ userId: authCode.userId,
205
+ createdAt: new Date(),
206
+ lastActivityAt: new Date(),
207
+ });
208
+ // Generate tokens
209
+ const testUser = getTestUser();
210
+ const tokens = generateTokens(testUser, authCode.clientId, authCode.scope, sessionId);
211
+ res.writeHead(200, { 'Content-Type': 'application/json' });
212
+ res.end(JSON.stringify(tokens));
213
+ }
214
+ /**
215
+ * Handle refresh token grant
216
+ */
217
+ async function handleRefreshTokenGrant(body, res) {
218
+ const refreshToken = body.get('refresh_token');
219
+ if (!refreshToken) {
220
+ res.writeHead(400, { 'Content-Type': 'application/json' });
221
+ res.end(JSON.stringify({
222
+ error: 'invalid_request',
223
+ error_description: 'Missing refresh_token',
224
+ }));
225
+ return;
226
+ }
227
+ const tokenData = getRefreshToken(refreshToken);
228
+ if (!tokenData || tokenData.expiresAt < new Date()) {
229
+ res.writeHead(400, { 'Content-Type': 'application/json' });
230
+ res.end(JSON.stringify({
231
+ error: 'invalid_grant',
232
+ error_description: 'Invalid or expired refresh token',
233
+ }));
234
+ return;
235
+ }
236
+ // Delete old refresh token (rotation)
237
+ deleteRefreshToken(refreshToken);
238
+ // Generate new tokens
239
+ const testUser = getTestUser();
240
+ const tokens = generateTokens(testUser, tokenData.clientId, tokenData.scope, tokenData.sessionId);
241
+ res.writeHead(200, { 'Content-Type': 'application/json' });
242
+ res.end(JSON.stringify(tokens));
243
+ }
244
+ /**
245
+ * Generate access token, ID token, and refresh token
246
+ */
247
+ function generateTokens(user, clientId, scope, sessionId) {
248
+ const now = Math.floor(Date.now() / 1000);
249
+ // ID Token claims
250
+ const idTokenClaims = {
251
+ iss: ISSUER,
252
+ sub: user.id,
253
+ aud: clientId,
254
+ nonce: generateRandomString(16),
255
+ sid: sessionId,
256
+ auth_time: now,
257
+ email: user.email,
258
+ email_verified: true,
259
+ name: user.name,
260
+ given_name: user.givenName,
261
+ family_name: user.familyName,
262
+ preferred_username: user.userName,
263
+ picture: user.picture,
264
+ };
265
+ // Access token claims
266
+ const accessTokenClaims = {
267
+ iss: ISSUER,
268
+ sub: user.id,
269
+ aud: clientId,
270
+ scope,
271
+ sid: sessionId,
272
+ };
273
+ const idToken = signJwt(idTokenClaims, TOKEN_EXPIRY);
274
+ const accessToken = signJwt(accessTokenClaims, TOKEN_EXPIRY);
275
+ const refreshTokenValue = generateRandomString(64);
276
+ // Store refresh token
277
+ const refreshToken = {
278
+ token: refreshTokenValue,
279
+ userId: user.id,
280
+ clientId,
281
+ scope,
282
+ sessionId,
283
+ createdAt: new Date(),
284
+ expiresAt: new Date(Date.now() + REFRESH_EXPIRY * 1000),
285
+ };
286
+ storeRefreshToken(refreshToken);
287
+ return {
288
+ access_token: accessToken,
289
+ token_type: 'Bearer',
290
+ expires_in: TOKEN_EXPIRY,
291
+ refresh_token: refreshTokenValue,
292
+ refresh_expires_in: REFRESH_EXPIRY,
293
+ id_token: idToken,
294
+ scope,
295
+ session_state: sessionId,
296
+ };
297
+ }
298
+ /**
299
+ * JWKS endpoint
300
+ */
301
+ function handleCerts(res) {
302
+ const jwks = getJwks();
303
+ res.writeHead(200, { 'Content-Type': 'application/json' });
304
+ res.end(JSON.stringify(jwks));
305
+ }
306
+ /**
307
+ * Token revocation endpoint
308
+ */
309
+ async function handleRevoke(req, res) {
310
+ const body = await parseFormBody(req);
311
+ const token = body.get('token');
312
+ const tokenTypeHint = body.get('token_type_hint');
313
+ if (token) {
314
+ if (tokenTypeHint === 'refresh_token' || !tokenTypeHint) {
315
+ deleteRefreshToken(token);
316
+ }
317
+ // Access tokens are stateless, can't be revoked
318
+ }
319
+ res.writeHead(200, { 'Content-Type': 'application/json' });
320
+ res.end(JSON.stringify({ success: true }));
321
+ }
322
+ /**
323
+ * User info endpoint
324
+ */
325
+ function handleUserInfo(req, res) {
326
+ // Extract and validate token
327
+ const authHeader = req.headers.authorization;
328
+ if (!authHeader?.startsWith('Bearer ')) {
329
+ res.writeHead(401, { 'Content-Type': 'application/json' });
330
+ res.end(JSON.stringify({ error: 'invalid_token' }));
331
+ return;
332
+ }
333
+ // For simplicity, we don't validate the token here - just return test user
334
+ const user = getTestUser();
335
+ res.writeHead(200, { 'Content-Type': 'application/json' });
336
+ res.end(JSON.stringify({
337
+ sub: user.id,
338
+ email: user.email,
339
+ email_verified: true,
340
+ name: user.name,
341
+ given_name: user.givenName,
342
+ family_name: user.familyName,
343
+ preferred_username: user.userName,
344
+ picture: user.picture,
345
+ }));
346
+ }
347
+ /**
348
+ * End session / logout endpoint
349
+ */
350
+ function handleLogout(req, res) {
351
+ const url = new URL(req.url || '', `http://${req.headers.host}`);
352
+ const postLogoutRedirectUri = url.searchParams.get('post_logout_redirect_uri');
353
+ if (postLogoutRedirectUri) {
354
+ res.writeHead(302, { Location: postLogoutRedirectUri });
355
+ res.end();
356
+ }
357
+ else {
358
+ res.writeHead(200, { 'Content-Type': 'text/html' });
359
+ res.end('<html><body><h1>Logged out</h1></body></html>');
360
+ }
361
+ }
362
+ /**
363
+ * Back-channel logout endpoint
364
+ */
365
+ async function handleBackChannelLogout(req, res) {
366
+ const body = await parseFormBody(req);
367
+ const logoutToken = body.get('logout_token');
368
+ if (!logoutToken) {
369
+ res.writeHead(400, { 'Content-Type': 'application/json' });
370
+ res.end(JSON.stringify({ error: 'invalid_request', error_description: 'Missing logout_token' }));
371
+ return;
372
+ }
373
+ // Parse the logout token to get sid
374
+ try {
375
+ const parts = logoutToken.split('.');
376
+ if (parts.length >= 2) {
377
+ const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString('utf-8'));
378
+ if (payload.sid) {
379
+ deleteSession(payload.sid);
380
+ }
381
+ }
382
+ }
383
+ catch {
384
+ // Ignore parsing errors
385
+ }
386
+ res.writeHead(200, { 'Content-Type': 'application/json' });
387
+ res.end(JSON.stringify({ success: true }));
388
+ }
389
+ /**
390
+ * OpenID Configuration endpoint
391
+ */
392
+ function handleOpenIDConfig(res) {
393
+ res.writeHead(200, { 'Content-Type': 'application/json' });
394
+ res.end(JSON.stringify({
395
+ issuer: ISSUER,
396
+ authorization_endpoint: `${ISSUER}/authorize`,
397
+ token_endpoint: `${ISSUER}/token`,
398
+ userinfo_endpoint: `${ISSUER}/userinfo`,
399
+ jwks_uri: `${ISSUER}/certs`,
400
+ end_session_endpoint: `${ISSUER}/logout`,
401
+ revocation_endpoint: `${ISSUER}/revoke`,
402
+ response_types_supported: ['code'],
403
+ subject_types_supported: ['public'],
404
+ id_token_signing_alg_values_supported: ['RS256'],
405
+ scopes_supported: ['openid', 'profile', 'email'],
406
+ token_endpoint_auth_methods_supported: ['client_secret_post', 'client_secret_basic'],
407
+ claims_supported: [
408
+ 'sub',
409
+ 'iss',
410
+ 'aud',
411
+ 'exp',
412
+ 'iat',
413
+ 'nonce',
414
+ 'email',
415
+ 'email_verified',
416
+ 'name',
417
+ 'given_name',
418
+ 'family_name',
419
+ 'preferred_username',
420
+ 'picture',
421
+ 'sid',
422
+ ],
423
+ code_challenge_methods_supported: ['S256'],
424
+ backchannel_logout_supported: true,
425
+ backchannel_logout_session_supported: true,
426
+ }));
427
+ }
428
+ //# sourceMappingURL=sso.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sso.js","sourceRoot":"","sources":["../../src/server/sso.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,152 @@
1
+ /**
2
+ * In-memory state management for the ESV mock server
3
+ *
4
+ * All state resets when the server restarts.
5
+ */
6
+ // ========== State Stores ==========
7
+ // IAM Users
8
+ const users = new Map();
9
+ // IAM Groups
10
+ const groups = new Map();
11
+ // Authorization codes (short-lived)
12
+ const authCodes = new Map();
13
+ // Refresh tokens
14
+ const refreshTokens = new Map();
15
+ // Sessions
16
+ const sessions = new Map();
17
+ // Default test user for SSO
18
+ let defaultTestUser = {
19
+ id: 'test-user-001',
20
+ userName: 'testuser@example.com',
21
+ email: 'testuser@example.com',
22
+ name: 'Test User',
23
+ givenName: 'Test',
24
+ familyName: 'User',
25
+ };
26
+ // ========== User Operations ==========
27
+ export function getUsers() {
28
+ return Array.from(users.values());
29
+ }
30
+ export function getUser(id) {
31
+ return users.get(id);
32
+ }
33
+ export function createUser(user) {
34
+ const now = new Date().toISOString();
35
+ user.meta = {
36
+ resourceType: 'User',
37
+ created: now,
38
+ lastModified: now,
39
+ location: `/Users/${user.id}`,
40
+ };
41
+ users.set(user.id, user);
42
+ return user;
43
+ }
44
+ export function updateUser(id, updates) {
45
+ const user = users.get(id);
46
+ if (!user)
47
+ return undefined;
48
+ const updated = { ...user, ...updates };
49
+ if (updated.meta) {
50
+ updated.meta.lastModified = new Date().toISOString();
51
+ }
52
+ users.set(id, updated);
53
+ return updated;
54
+ }
55
+ export function deleteUser(id) {
56
+ return users.delete(id);
57
+ }
58
+ // ========== Group Operations ==========
59
+ export function getGroups() {
60
+ return Array.from(groups.values());
61
+ }
62
+ export function getGroup(id) {
63
+ return groups.get(id);
64
+ }
65
+ export function createGroup(group) {
66
+ const now = new Date().toISOString();
67
+ group.meta = {
68
+ resourceType: 'Group',
69
+ created: now,
70
+ lastModified: now,
71
+ location: `/Groups/${group.id}`,
72
+ };
73
+ groups.set(group.id, group);
74
+ return group;
75
+ }
76
+ export function updateGroup(id, updates) {
77
+ const group = groups.get(id);
78
+ if (!group)
79
+ return undefined;
80
+ const updated = { ...group, ...updates };
81
+ if (updated.meta) {
82
+ updated.meta.lastModified = new Date().toISOString();
83
+ }
84
+ groups.set(id, updated);
85
+ return updated;
86
+ }
87
+ export function deleteGroup(id) {
88
+ return groups.delete(id);
89
+ }
90
+ // ========== Auth Code Operations ==========
91
+ export function storeAuthCode(authCode) {
92
+ authCodes.set(authCode.code, authCode);
93
+ }
94
+ export function getAuthCode(code) {
95
+ return authCodes.get(code);
96
+ }
97
+ export function deleteAuthCode(code) {
98
+ return authCodes.delete(code);
99
+ }
100
+ // ========== Refresh Token Operations ==========
101
+ export function storeRefreshToken(refreshToken) {
102
+ refreshTokens.set(refreshToken.token, refreshToken);
103
+ }
104
+ export function getRefreshToken(token) {
105
+ return refreshTokens.get(token);
106
+ }
107
+ export function deleteRefreshToken(token) {
108
+ return refreshTokens.delete(token);
109
+ }
110
+ export function deleteRefreshTokensBySession(sessionId) {
111
+ for (const [token, data] of refreshTokens.entries()) {
112
+ if (data.sessionId === sessionId) {
113
+ refreshTokens.delete(token);
114
+ }
115
+ }
116
+ }
117
+ // ========== Session Operations ==========
118
+ export function createSession(session) {
119
+ sessions.set(session.id, session);
120
+ }
121
+ export function getSession(id) {
122
+ return sessions.get(id);
123
+ }
124
+ export function deleteSession(id) {
125
+ // Also delete associated refresh tokens
126
+ deleteRefreshTokensBySession(id);
127
+ return sessions.delete(id);
128
+ }
129
+ // ========== Test User Operations ==========
130
+ export function getTestUser() {
131
+ return defaultTestUser;
132
+ }
133
+ export function setTestUser(user) {
134
+ defaultTestUser = user;
135
+ }
136
+ // ========== Reset State ==========
137
+ export function resetState() {
138
+ users.clear();
139
+ groups.clear();
140
+ authCodes.clear();
141
+ refreshTokens.clear();
142
+ sessions.clear();
143
+ defaultTestUser = {
144
+ id: 'test-user-001',
145
+ userName: 'testuser@example.com',
146
+ email: 'testuser@example.com',
147
+ name: 'Test User',
148
+ givenName: 'Test',
149
+ familyName: 'User',
150
+ };
151
+ }
152
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/server/state.ts"],"names":[],"mappings":"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"}