@shin1ohno/sage 0.2.4 → 0.5.3

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.
Files changed (96) hide show
  1. package/dist/cli/http-server-with-config.d.ts +38 -0
  2. package/dist/cli/http-server-with-config.d.ts.map +1 -0
  3. package/dist/cli/http-server-with-config.js +458 -0
  4. package/dist/cli/http-server-with-config.js.map +1 -0
  5. package/dist/cli/http-server.d.ts +74 -0
  6. package/dist/cli/http-server.d.ts.map +1 -0
  7. package/dist/cli/http-server.js +407 -0
  8. package/dist/cli/http-server.js.map +1 -0
  9. package/dist/cli/jwt-middleware.d.ts +36 -0
  10. package/dist/cli/jwt-middleware.d.ts.map +1 -0
  11. package/dist/cli/jwt-middleware.js +99 -0
  12. package/dist/cli/jwt-middleware.js.map +1 -0
  13. package/dist/cli/main-entry.d.ts +41 -0
  14. package/dist/cli/main-entry.d.ts.map +1 -0
  15. package/dist/cli/main-entry.js +80 -0
  16. package/dist/cli/main-entry.js.map +1 -0
  17. package/dist/cli/mcp-handler.d.ts +56 -0
  18. package/dist/cli/mcp-handler.d.ts.map +1 -0
  19. package/dist/cli/mcp-handler.js +2189 -0
  20. package/dist/cli/mcp-handler.js.map +1 -0
  21. package/dist/cli/parser.d.ts +43 -0
  22. package/dist/cli/parser.d.ts.map +1 -0
  23. package/dist/cli/parser.js +162 -0
  24. package/dist/cli/parser.js.map +1 -0
  25. package/dist/cli/remote-config-loader.d.ts +85 -0
  26. package/dist/cli/remote-config-loader.d.ts.map +1 -0
  27. package/dist/cli/remote-config-loader.js +129 -0
  28. package/dist/cli/remote-config-loader.js.map +1 -0
  29. package/dist/cli/secret-auth.d.ts +47 -0
  30. package/dist/cli/secret-auth.d.ts.map +1 -0
  31. package/dist/cli/secret-auth.js +165 -0
  32. package/dist/cli/secret-auth.js.map +1 -0
  33. package/dist/cli/sse-stream-handler.d.ts +45 -0
  34. package/dist/cli/sse-stream-handler.d.ts.map +1 -0
  35. package/dist/cli/sse-stream-handler.js +125 -0
  36. package/dist/cli/sse-stream-handler.js.map +1 -0
  37. package/dist/index.js +885 -209
  38. package/dist/index.js.map +1 -1
  39. package/dist/integrations/calendar-event-creator.d.ts +152 -0
  40. package/dist/integrations/calendar-event-creator.d.ts.map +1 -0
  41. package/dist/integrations/calendar-event-creator.js +507 -0
  42. package/dist/integrations/calendar-event-creator.js.map +1 -0
  43. package/dist/integrations/calendar-event-deleter.d.ts +137 -0
  44. package/dist/integrations/calendar-event-deleter.d.ts.map +1 -0
  45. package/dist/integrations/calendar-event-deleter.js +378 -0
  46. package/dist/integrations/calendar-event-deleter.js.map +1 -0
  47. package/dist/integrations/calendar-event-response.d.ts +213 -0
  48. package/dist/integrations/calendar-event-response.d.ts.map +1 -0
  49. package/dist/integrations/calendar-event-response.js +560 -0
  50. package/dist/integrations/calendar-event-response.js.map +1 -0
  51. package/dist/integrations/calendar-service.d.ts +85 -10
  52. package/dist/integrations/calendar-service.d.ts.map +1 -1
  53. package/dist/integrations/calendar-service.js +317 -35
  54. package/dist/integrations/calendar-service.js.map +1 -1
  55. package/dist/oauth/client-store.d.ts +36 -0
  56. package/dist/oauth/client-store.d.ts.map +1 -0
  57. package/dist/oauth/client-store.js +104 -0
  58. package/dist/oauth/client-store.js.map +1 -0
  59. package/dist/oauth/code-store.d.ts +48 -0
  60. package/dist/oauth/code-store.d.ts.map +1 -0
  61. package/dist/oauth/code-store.js +89 -0
  62. package/dist/oauth/code-store.js.map +1 -0
  63. package/dist/oauth/index.d.ts +13 -0
  64. package/dist/oauth/index.d.ts.map +1 -0
  65. package/dist/oauth/index.js +21 -0
  66. package/dist/oauth/index.js.map +1 -0
  67. package/dist/oauth/oauth-handler.d.ts +101 -0
  68. package/dist/oauth/oauth-handler.d.ts.map +1 -0
  69. package/dist/oauth/oauth-handler.js +577 -0
  70. package/dist/oauth/oauth-handler.js.map +1 -0
  71. package/dist/oauth/oauth-server.d.ts +165 -0
  72. package/dist/oauth/oauth-server.d.ts.map +1 -0
  73. package/dist/oauth/oauth-server.js +489 -0
  74. package/dist/oauth/oauth-server.js.map +1 -0
  75. package/dist/oauth/pkce.d.ts +48 -0
  76. package/dist/oauth/pkce.d.ts.map +1 -0
  77. package/dist/oauth/pkce.js +106 -0
  78. package/dist/oauth/pkce.js.map +1 -0
  79. package/dist/oauth/refresh-token-store.d.ts +45 -0
  80. package/dist/oauth/refresh-token-store.d.ts.map +1 -0
  81. package/dist/oauth/refresh-token-store.js +98 -0
  82. package/dist/oauth/refresh-token-store.js.map +1 -0
  83. package/dist/oauth/token-service.d.ts +46 -0
  84. package/dist/oauth/token-service.d.ts.map +1 -0
  85. package/dist/oauth/token-service.js +199 -0
  86. package/dist/oauth/token-service.js.map +1 -0
  87. package/dist/oauth/types.d.ts +264 -0
  88. package/dist/oauth/types.d.ts.map +1 -0
  89. package/dist/oauth/types.js +37 -0
  90. package/dist/oauth/types.js.map +1 -0
  91. package/dist/version.d.ts +9 -0
  92. package/dist/version.d.ts.map +1 -0
  93. package/dist/version.js +11 -0
  94. package/dist/version.js.map +1 -0
  95. package/manifest.json +12 -20
  96. package/package.json +1 -1
@@ -0,0 +1,165 @@
1
+ /**
2
+ * OAuth 2.1 Server
3
+ * Requirements: 21-31 (OAuth 2.1 Authentication)
4
+ *
5
+ * Main OAuth server that coordinates all OAuth components and handles requests.
6
+ */
7
+ import { AuthorizationServerMetadata, ProtectedResourceMetadata, AuthorizationRequest, TokenResponse, OAuthError, OAuthClient, ClientRegistrationRequest, VerifyTokenResult, OAuthUser, UserSession } from './types.js';
8
+ import { ClientRegistrationResult } from './client-store.js';
9
+ /**
10
+ * OAuth Server Configuration
11
+ */
12
+ export interface OAuthServerConfig {
13
+ issuer: string;
14
+ accessTokenExpiry?: string;
15
+ refreshTokenExpiry?: string;
16
+ authorizationCodeExpiry?: string;
17
+ allowedRedirectUris?: string[];
18
+ users?: OAuthUser[];
19
+ privateKey?: string;
20
+ publicKey?: string;
21
+ }
22
+ /**
23
+ * Authorization Pending Request (stored during consent flow)
24
+ */
25
+ interface PendingAuthRequest {
26
+ request: AuthorizationRequest;
27
+ client: OAuthClient;
28
+ createdAt: number;
29
+ }
30
+ /**
31
+ * OAuth Server Class
32
+ */
33
+ export declare class OAuthServer {
34
+ private config;
35
+ private tokenService;
36
+ private codeStore;
37
+ private refreshTokenStore;
38
+ private clientStore;
39
+ private sessionStore;
40
+ private users;
41
+ private pendingAuthRequests;
42
+ private loginAttempts;
43
+ private privateKey;
44
+ private publicKey;
45
+ constructor(config: OAuthServerConfig, keys?: {
46
+ privateKey: string;
47
+ publicKey: string;
48
+ });
49
+ /**
50
+ * Initialize the server with generated keys if not provided
51
+ */
52
+ initialize(): Promise<void>;
53
+ private parseExpiryToSeconds;
54
+ /**
55
+ * Get Protected Resource Metadata (RFC 9728)
56
+ * Requirement 22.1-22.3
57
+ */
58
+ getProtectedResourceMetadata(): ProtectedResourceMetadata;
59
+ /**
60
+ * Get Authorization Server Metadata (RFC 8414)
61
+ * Requirement 23.1-23.9
62
+ */
63
+ getAuthorizationServerMetadata(): AuthorizationServerMetadata;
64
+ /**
65
+ * Get WWW-Authenticate header for 401 responses
66
+ * Requirement 22.4, 22.5
67
+ */
68
+ getWWWAuthenticateHeader(): string;
69
+ /**
70
+ * Register a new client (Dynamic Client Registration)
71
+ * Requirement 24.1-24.7
72
+ */
73
+ registerClient(request: ClientRegistrationRequest): Promise<ClientRegistrationResult>;
74
+ /**
75
+ * Get a registered client
76
+ */
77
+ getClient(clientId: string): Promise<OAuthClient | null>;
78
+ /**
79
+ * Delete a client (Requirement 24.8)
80
+ */
81
+ deleteClient(clientId: string): Promise<boolean>;
82
+ /**
83
+ * Validate an authorization request
84
+ * Requirement 25.1-25.8
85
+ */
86
+ validateAuthorizationRequest(request: AuthorizationRequest): Promise<{
87
+ valid: boolean;
88
+ error?: OAuthError;
89
+ client?: OAuthClient;
90
+ }>;
91
+ /**
92
+ * Store a pending authorization request (for consent flow)
93
+ */
94
+ storePendingAuthRequest(requestId: string, request: AuthorizationRequest, client: OAuthClient): void;
95
+ /**
96
+ * Get a pending authorization request
97
+ */
98
+ getPendingAuthRequest(requestId: string): PendingAuthRequest | null;
99
+ /**
100
+ * Complete authorization and generate code
101
+ * Requirement 25.9, 25.10
102
+ */
103
+ completeAuthorization(request: AuthorizationRequest, userId: string): Promise<string>;
104
+ /**
105
+ * Exchange authorization code for tokens
106
+ * Requirement 26.1-26.7
107
+ */
108
+ exchangeAuthorizationCode(code: string, clientId: string, redirectUri: string, codeVerifier: string, resource?: string): Promise<{
109
+ success: boolean;
110
+ tokens?: TokenResponse;
111
+ error?: OAuthError;
112
+ }>;
113
+ /**
114
+ * Exchange refresh token for new tokens
115
+ * Requirement 26.3, 26.8
116
+ */
117
+ exchangeRefreshToken(refreshToken: string, clientId: string, scope?: string): Promise<{
118
+ success: boolean;
119
+ tokens?: TokenResponse;
120
+ error?: OAuthError;
121
+ }>;
122
+ /**
123
+ * Verify an access token
124
+ * Requirement 27.1-27.5
125
+ */
126
+ verifyAccessToken(token: string, expectedAudience?: string): Promise<VerifyTokenResult>;
127
+ /**
128
+ * Extract token from Authorization header
129
+ * Requirement 27.1
130
+ */
131
+ extractTokenFromHeader(header: string | undefined): string | null;
132
+ /**
133
+ * Authenticate a user (Requirement 29.1-29.5)
134
+ */
135
+ authenticateUser(username: string, password: string): Promise<{
136
+ success: boolean;
137
+ session?: UserSession;
138
+ error?: string;
139
+ }>;
140
+ /**
141
+ * Validate a session
142
+ */
143
+ validateSession(sessionId: string): UserSession | null;
144
+ /**
145
+ * Logout user
146
+ */
147
+ logout(sessionId: string): void;
148
+ /**
149
+ * Check if a scope includes another scope
150
+ */
151
+ hasScope(tokenScope: string, requiredScope: string): boolean;
152
+ /**
153
+ * Get scope descriptions for consent UI
154
+ */
155
+ getScopeDescriptions(scopes: string): Array<{
156
+ scope: string;
157
+ description: string;
158
+ }>;
159
+ }
160
+ /**
161
+ * Create an OAuth Server instance
162
+ */
163
+ export declare function createOAuthServer(config: OAuthServerConfig): Promise<OAuthServer>;
164
+ export {};
165
+ //# sourceMappingURL=oauth-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-server.d.ts","sourceRoot":"","sources":["../../src/oauth/oauth-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,489 @@
1
+ /**
2
+ * OAuth 2.1 Server
3
+ * Requirements: 21-31 (OAuth 2.1 Authentication)
4
+ *
5
+ * Main OAuth server that coordinates all OAuth components and handles requests.
6
+ */
7
+ import { randomBytes, createHash } from 'crypto';
8
+ import { SCOPE_DEFINITIONS, DEFAULT_TOKEN_EXPIRY, CLAUDE_CALLBACK_URLS, } from './types.js';
9
+ import { createTokenService, generateKeyPair } from './token-service.js';
10
+ import { createAuthorizationCodeStore } from './code-store.js';
11
+ import { createRefreshTokenStore } from './refresh-token-store.js';
12
+ import { createClientStore } from './client-store.js';
13
+ import { verifyCodeChallenge } from './pkce.js';
14
+ /**
15
+ * In-memory Session Store
16
+ */
17
+ class InMemorySessionStore {
18
+ sessions = new Map();
19
+ sessionExpiryMs = 24 * 60 * 60 * 1000; // 24 hours
20
+ createSession(userId) {
21
+ const sessionId = randomBytes(32).toString('hex');
22
+ const now = Date.now();
23
+ const session = {
24
+ sessionId,
25
+ userId,
26
+ createdAt: now,
27
+ expiresAt: now + this.sessionExpiryMs,
28
+ };
29
+ this.sessions.set(sessionId, session);
30
+ return session;
31
+ }
32
+ getSession(sessionId) {
33
+ const session = this.sessions.get(sessionId);
34
+ if (!session)
35
+ return null;
36
+ if (Date.now() > session.expiresAt) {
37
+ this.sessions.delete(sessionId);
38
+ return null;
39
+ }
40
+ return session;
41
+ }
42
+ deleteSession(sessionId) {
43
+ this.sessions.delete(sessionId);
44
+ }
45
+ }
46
+ /**
47
+ * OAuth Server Class
48
+ */
49
+ export class OAuthServer {
50
+ config;
51
+ tokenService;
52
+ codeStore;
53
+ refreshTokenStore;
54
+ clientStore;
55
+ sessionStore;
56
+ users;
57
+ pendingAuthRequests = new Map();
58
+ loginAttempts = new Map();
59
+ privateKey;
60
+ publicKey;
61
+ constructor(config, keys) {
62
+ this.config = config;
63
+ this.privateKey = keys?.privateKey || '';
64
+ this.publicKey = keys?.publicKey || '';
65
+ // Parse expiry durations to seconds
66
+ const refreshTokenExpirySec = this.parseExpiryToSeconds(config.refreshTokenExpiry || DEFAULT_TOKEN_EXPIRY.refreshToken);
67
+ const authCodeExpirySec = this.parseExpiryToSeconds(config.authorizationCodeExpiry || DEFAULT_TOKEN_EXPIRY.authorizationCode);
68
+ // Initialize stores
69
+ this.codeStore = createAuthorizationCodeStore({ expirySeconds: authCodeExpirySec });
70
+ this.refreshTokenStore = createRefreshTokenStore({ expirySeconds: refreshTokenExpirySec });
71
+ this.clientStore = createClientStore({
72
+ allowedRedirectUris: [...(config.allowedRedirectUris || []), ...CLAUDE_CALLBACK_URLS],
73
+ });
74
+ this.sessionStore = new InMemorySessionStore();
75
+ // Initialize token service (will be updated when keys are available)
76
+ this.tokenService = createTokenService({
77
+ issuer: config.issuer,
78
+ privateKey: this.privateKey,
79
+ publicKey: this.publicKey,
80
+ accessTokenExpiry: config.accessTokenExpiry || DEFAULT_TOKEN_EXPIRY.accessToken,
81
+ });
82
+ // Store users
83
+ this.users = new Map();
84
+ for (const user of config.users || []) {
85
+ this.users.set(user.username, user);
86
+ }
87
+ }
88
+ /**
89
+ * Initialize the server with generated keys if not provided
90
+ */
91
+ async initialize() {
92
+ if (!this.privateKey || !this.publicKey) {
93
+ const keys = await generateKeyPair();
94
+ this.privateKey = keys.privateKey;
95
+ this.publicKey = keys.publicKey;
96
+ // Recreate token service with new keys
97
+ this.tokenService = createTokenService({
98
+ issuer: this.config.issuer,
99
+ privateKey: this.privateKey,
100
+ publicKey: this.publicKey,
101
+ accessTokenExpiry: this.config.accessTokenExpiry || DEFAULT_TOKEN_EXPIRY.accessToken,
102
+ });
103
+ }
104
+ }
105
+ parseExpiryToSeconds(expiry) {
106
+ const match = expiry.match(/^(\d+)([smhdw])$/);
107
+ if (!match)
108
+ return 3600;
109
+ const value = parseInt(match[1], 10);
110
+ const unit = match[2];
111
+ switch (unit) {
112
+ case 's': return value;
113
+ case 'm': return value * 60;
114
+ case 'h': return value * 3600;
115
+ case 'd': return value * 86400;
116
+ case 'w': return value * 604800;
117
+ default: return 3600;
118
+ }
119
+ }
120
+ /**
121
+ * Get Protected Resource Metadata (RFC 9728)
122
+ * Requirement 22.1-22.3
123
+ */
124
+ getProtectedResourceMetadata() {
125
+ return {
126
+ resource: this.config.issuer,
127
+ authorization_servers: [this.config.issuer],
128
+ scopes_supported: Object.keys(SCOPE_DEFINITIONS),
129
+ bearer_methods_supported: ['header'],
130
+ };
131
+ }
132
+ /**
133
+ * Get Authorization Server Metadata (RFC 8414)
134
+ * Requirement 23.1-23.9
135
+ */
136
+ getAuthorizationServerMetadata() {
137
+ return {
138
+ issuer: this.config.issuer,
139
+ authorization_endpoint: `${this.config.issuer}/oauth/authorize`,
140
+ token_endpoint: `${this.config.issuer}/oauth/token`,
141
+ registration_endpoint: `${this.config.issuer}/oauth/register`,
142
+ scopes_supported: Object.keys(SCOPE_DEFINITIONS),
143
+ response_types_supported: ['code'],
144
+ response_modes_supported: ['query'],
145
+ grant_types_supported: ['authorization_code', 'refresh_token'],
146
+ token_endpoint_auth_methods_supported: ['none', 'client_secret_post'],
147
+ code_challenge_methods_supported: ['S256'],
148
+ service_documentation: 'https://github.com/shin1ohno/sage',
149
+ };
150
+ }
151
+ /**
152
+ * Get WWW-Authenticate header for 401 responses
153
+ * Requirement 22.4, 22.5
154
+ */
155
+ getWWWAuthenticateHeader() {
156
+ return `Bearer realm="sage", resource_metadata="${this.config.issuer}/.well-known/oauth-protected-resource"`;
157
+ }
158
+ /**
159
+ * Register a new client (Dynamic Client Registration)
160
+ * Requirement 24.1-24.7
161
+ */
162
+ async registerClient(request) {
163
+ return this.clientStore.registerClient(request);
164
+ }
165
+ /**
166
+ * Get a registered client
167
+ */
168
+ async getClient(clientId) {
169
+ return this.clientStore.getClient(clientId);
170
+ }
171
+ /**
172
+ * Delete a client (Requirement 24.8)
173
+ */
174
+ async deleteClient(clientId) {
175
+ // Also revoke all refresh tokens for this client
176
+ await this.refreshTokenStore.revokeAllForClient(clientId);
177
+ return this.clientStore.deleteClient(clientId);
178
+ }
179
+ /**
180
+ * Validate an authorization request
181
+ * Requirement 25.1-25.8
182
+ */
183
+ async validateAuthorizationRequest(request) {
184
+ // Requirement 25.2: Only support response_type=code
185
+ if (request.response_type !== 'code') {
186
+ return {
187
+ valid: false,
188
+ error: {
189
+ error: 'unsupported_response_type',
190
+ error_description: 'Only response_type=code is supported',
191
+ state: request.state,
192
+ },
193
+ };
194
+ }
195
+ // Requirement 25.3: client_id is required
196
+ const client = await this.clientStore.getClient(request.client_id);
197
+ if (!client) {
198
+ return {
199
+ valid: false,
200
+ error: {
201
+ error: 'invalid_client',
202
+ error_description: 'Unknown client_id',
203
+ state: request.state,
204
+ },
205
+ };
206
+ }
207
+ // Requirement 25.4: Validate redirect_uri
208
+ if (!await this.clientStore.isValidRedirectUri(request.client_id, request.redirect_uri)) {
209
+ return {
210
+ valid: false,
211
+ error: {
212
+ error: 'invalid_request',
213
+ error_description: 'Invalid redirect_uri',
214
+ state: request.state,
215
+ },
216
+ };
217
+ }
218
+ // Requirement 25.5, 25.6: PKCE is required, only S256
219
+ if (!request.code_challenge) {
220
+ return {
221
+ valid: false,
222
+ error: {
223
+ error: 'invalid_request',
224
+ error_description: 'code_challenge is required',
225
+ state: request.state,
226
+ },
227
+ };
228
+ }
229
+ if (request.code_challenge_method !== 'S256') {
230
+ return {
231
+ valid: false,
232
+ error: {
233
+ error: 'invalid_request',
234
+ error_description: 'Only code_challenge_method=S256 is supported',
235
+ state: request.state,
236
+ },
237
+ };
238
+ }
239
+ // Requirement 25.7: state is required
240
+ if (!request.state) {
241
+ return {
242
+ valid: false,
243
+ error: {
244
+ error: 'invalid_request',
245
+ error_description: 'state is required',
246
+ },
247
+ };
248
+ }
249
+ return { valid: true, client };
250
+ }
251
+ /**
252
+ * Store a pending authorization request (for consent flow)
253
+ */
254
+ storePendingAuthRequest(requestId, request, client) {
255
+ this.pendingAuthRequests.set(requestId, {
256
+ request,
257
+ client,
258
+ createdAt: Date.now(),
259
+ });
260
+ // Cleanup old requests (older than 10 minutes)
261
+ const cutoff = Date.now() - 10 * 60 * 1000;
262
+ for (const [id, pending] of this.pendingAuthRequests.entries()) {
263
+ if (pending.createdAt < cutoff) {
264
+ this.pendingAuthRequests.delete(id);
265
+ }
266
+ }
267
+ }
268
+ /**
269
+ * Get a pending authorization request
270
+ */
271
+ getPendingAuthRequest(requestId) {
272
+ return this.pendingAuthRequests.get(requestId) || null;
273
+ }
274
+ /**
275
+ * Complete authorization and generate code
276
+ * Requirement 25.9, 25.10
277
+ */
278
+ async completeAuthorization(request, userId) {
279
+ const code = await this.codeStore.generateCode({
280
+ clientId: request.client_id,
281
+ redirectUri: request.redirect_uri,
282
+ scope: request.scope || '',
283
+ codeChallenge: request.code_challenge,
284
+ codeChallengeMethod: request.code_challenge_method,
285
+ userId,
286
+ resource: request.resource,
287
+ });
288
+ return code;
289
+ }
290
+ /**
291
+ * Exchange authorization code for tokens
292
+ * Requirement 26.1-26.7
293
+ */
294
+ async exchangeAuthorizationCode(code, clientId, redirectUri, codeVerifier, resource) {
295
+ // Consume code (marks it as used)
296
+ const codeResult = await this.codeStore.consumeCode(code, clientId);
297
+ if (!codeResult.valid || !codeResult.codeData) {
298
+ return {
299
+ success: false,
300
+ error: {
301
+ error: 'invalid_grant',
302
+ error_description: 'Invalid or expired authorization code',
303
+ },
304
+ };
305
+ }
306
+ // Verify redirect_uri matches
307
+ if (codeResult.codeData.redirect_uri !== redirectUri) {
308
+ return {
309
+ success: false,
310
+ error: {
311
+ error: 'invalid_grant',
312
+ error_description: 'redirect_uri does not match',
313
+ },
314
+ };
315
+ }
316
+ // Verify PKCE code_verifier (Requirement 26.4)
317
+ if (!verifyCodeChallenge(codeVerifier, codeResult.codeData.code_challenge, 'S256')) {
318
+ return {
319
+ success: false,
320
+ error: {
321
+ error: 'invalid_grant',
322
+ error_description: 'Invalid code_verifier',
323
+ },
324
+ };
325
+ }
326
+ // Verify resource if specified (Requirement 26.5)
327
+ if (resource && codeResult.codeData.resource && resource !== codeResult.codeData.resource) {
328
+ return {
329
+ success: false,
330
+ error: {
331
+ error: 'invalid_grant',
332
+ error_description: 'resource does not match',
333
+ },
334
+ };
335
+ }
336
+ // Generate access token
337
+ const accessTokenResponse = await this.tokenService.generateAccessToken({
338
+ clientId,
339
+ userId: codeResult.codeData.user_id,
340
+ scope: codeResult.codeData.scope,
341
+ audience: resource || this.config.issuer,
342
+ });
343
+ // Generate refresh token (Requirement 21.6)
344
+ const refreshToken = await this.refreshTokenStore.generateToken({
345
+ clientId,
346
+ userId: codeResult.codeData.user_id,
347
+ scope: codeResult.codeData.scope,
348
+ });
349
+ return {
350
+ success: true,
351
+ tokens: {
352
+ ...accessTokenResponse,
353
+ refresh_token: refreshToken,
354
+ },
355
+ };
356
+ }
357
+ /**
358
+ * Exchange refresh token for new tokens
359
+ * Requirement 26.3, 26.8
360
+ */
361
+ async exchangeRefreshToken(refreshToken, clientId, scope) {
362
+ // Rotate refresh token (Requirement 26.8)
363
+ const newRefreshToken = await this.refreshTokenStore.rotateToken(refreshToken, clientId);
364
+ if (!newRefreshToken) {
365
+ return {
366
+ success: false,
367
+ error: {
368
+ error: 'invalid_grant',
369
+ error_description: 'Invalid or expired refresh token',
370
+ },
371
+ };
372
+ }
373
+ // Get the original token data before it was rotated
374
+ const tokenResult = await this.refreshTokenStore.validateToken(newRefreshToken, clientId);
375
+ if (!tokenResult.valid || !tokenResult.tokenData) {
376
+ return {
377
+ success: false,
378
+ error: {
379
+ error: 'invalid_grant',
380
+ error_description: 'Invalid refresh token',
381
+ },
382
+ };
383
+ }
384
+ // Use requested scope or original scope
385
+ const effectiveScope = scope || tokenResult.tokenData.scope;
386
+ // Generate new access token
387
+ const accessTokenResponse = await this.tokenService.generateAccessToken({
388
+ clientId,
389
+ userId: tokenResult.tokenData.user_id,
390
+ scope: effectiveScope,
391
+ audience: this.config.issuer,
392
+ });
393
+ return {
394
+ success: true,
395
+ tokens: {
396
+ ...accessTokenResponse,
397
+ refresh_token: newRefreshToken,
398
+ },
399
+ };
400
+ }
401
+ /**
402
+ * Verify an access token
403
+ * Requirement 27.1-27.5
404
+ */
405
+ async verifyAccessToken(token, expectedAudience) {
406
+ return this.tokenService.verifyAccessToken(token, expectedAudience);
407
+ }
408
+ /**
409
+ * Extract token from Authorization header
410
+ * Requirement 27.1
411
+ */
412
+ extractTokenFromHeader(header) {
413
+ return this.tokenService.extractTokenFromHeader(header);
414
+ }
415
+ /**
416
+ * Authenticate a user (Requirement 29.1-29.5)
417
+ */
418
+ async authenticateUser(username, password) {
419
+ // Rate limiting (Requirement 29.5)
420
+ const key = username;
421
+ const attempts = this.loginAttempts.get(key) || { count: 0, lastAttempt: 0 };
422
+ // Reset attempts after 15 minutes
423
+ if (Date.now() - attempts.lastAttempt > 15 * 60 * 1000) {
424
+ attempts.count = 0;
425
+ }
426
+ if (attempts.count >= 5) {
427
+ return { success: false, error: 'Too many login attempts. Please try again later.' };
428
+ }
429
+ const user = this.users.get(username);
430
+ if (!user) {
431
+ attempts.count++;
432
+ attempts.lastAttempt = Date.now();
433
+ this.loginAttempts.set(key, attempts);
434
+ return { success: false, error: 'Invalid username or password' };
435
+ }
436
+ // Verify password (Requirement 29.4: passwords should be hashed)
437
+ // For simplicity, we'll compare against the stored hash
438
+ // In production, use bcrypt or similar
439
+ const passwordHash = createHash('sha256').update(password).digest('hex');
440
+ if (passwordHash !== user.passwordHash) {
441
+ attempts.count++;
442
+ attempts.lastAttempt = Date.now();
443
+ this.loginAttempts.set(key, attempts);
444
+ return { success: false, error: 'Invalid username or password' };
445
+ }
446
+ // Reset login attempts on success
447
+ this.loginAttempts.delete(key);
448
+ // Create session
449
+ const session = this.sessionStore.createSession(user.id);
450
+ return { success: true, session };
451
+ }
452
+ /**
453
+ * Validate a session
454
+ */
455
+ validateSession(sessionId) {
456
+ return this.sessionStore.getSession(sessionId);
457
+ }
458
+ /**
459
+ * Logout user
460
+ */
461
+ logout(sessionId) {
462
+ this.sessionStore.deleteSession(sessionId);
463
+ }
464
+ /**
465
+ * Check if a scope includes another scope
466
+ */
467
+ hasScope(tokenScope, requiredScope) {
468
+ const tokenScopes = tokenScope.split(' ');
469
+ return tokenScopes.includes(requiredScope);
470
+ }
471
+ /**
472
+ * Get scope descriptions for consent UI
473
+ */
474
+ getScopeDescriptions(scopes) {
475
+ return scopes.split(' ').filter(s => s in SCOPE_DEFINITIONS).map(scope => ({
476
+ scope,
477
+ description: SCOPE_DEFINITIONS[scope],
478
+ }));
479
+ }
480
+ }
481
+ /**
482
+ * Create an OAuth Server instance
483
+ */
484
+ export async function createOAuthServer(config) {
485
+ const server = new OAuthServer(config);
486
+ await server.initialize();
487
+ return server;
488
+ }
489
+ //# sourceMappingURL=oauth-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-server.js","sourceRoot":"","sources":["../../src/oauth/oauth-server.ts"],"names":[],"mappings":"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"}