@1mcp/agent 0.10.3 → 0.12.0

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 (147) hide show
  1. package/README.md +41 -17
  2. package/build/auth/authManager.d.ts +109 -0
  3. package/build/auth/authManager.d.ts.map +1 -0
  4. package/build/auth/authManager.js +173 -0
  5. package/build/auth/authManager.js.map +1 -0
  6. package/build/auth/authMiddleware.d.ts +16 -0
  7. package/build/auth/authMiddleware.d.ts.map +1 -0
  8. package/build/auth/authMiddleware.js +45 -0
  9. package/build/auth/authMiddleware.js.map +1 -0
  10. package/build/auth/sessionManager.d.ts +197 -0
  11. package/build/auth/sessionManager.d.ts.map +1 -0
  12. package/build/auth/sessionManager.js +408 -0
  13. package/build/auth/sessionManager.js.map +1 -0
  14. package/build/capabilities/capabilityManager.d.ts +1 -1
  15. package/build/capabilities/capabilityManager.d.ts.map +1 -1
  16. package/build/capabilities/capabilityManager.js +39 -6
  17. package/build/capabilities/capabilityManager.js.map +1 -1
  18. package/build/config/configManager.d.ts +7 -1
  19. package/build/config/configManager.d.ts.map +1 -1
  20. package/build/config/configManager.js +24 -2
  21. package/build/config/configManager.js.map +1 -1
  22. package/build/constants.d.ts +25 -1
  23. package/build/constants.d.ts.map +1 -1
  24. package/build/constants.js +31 -2
  25. package/build/constants.js.map +1 -1
  26. package/build/{client.d.ts → core/client/clientFactory.d.ts} +1 -1
  27. package/build/core/client/clientFactory.d.ts.map +1 -0
  28. package/build/{client.js → core/client/clientFactory.js} +2 -2
  29. package/build/core/client/clientFactory.js.map +1 -0
  30. package/build/{clients → core/client}/clientManager.d.ts +3 -2
  31. package/build/core/client/clientManager.d.ts.map +1 -0
  32. package/build/{clients → core/client}/clientManager.js +10 -6
  33. package/build/core/client/clientManager.js.map +1 -0
  34. package/build/core/server/serverConfig.d.ts +100 -0
  35. package/build/core/server/serverConfig.d.ts.map +1 -0
  36. package/build/core/server/serverConfig.js +117 -0
  37. package/build/core/server/serverConfig.js.map +1 -0
  38. package/build/{serverManager.d.ts → core/server/serverManager.d.ts} +7 -2
  39. package/build/core/server/serverManager.d.ts.map +1 -0
  40. package/build/core/server/serverManager.js +159 -0
  41. package/build/core/server/serverManager.js.map +1 -0
  42. package/build/core/types/client.d.ts +38 -0
  43. package/build/core/types/client.d.ts.map +1 -0
  44. package/build/core/types/client.js +13 -0
  45. package/build/core/types/client.js.map +1 -0
  46. package/build/core/types/index.d.ts +4 -0
  47. package/build/core/types/index.d.ts.map +1 -0
  48. package/build/core/types/index.js +5 -0
  49. package/build/core/types/index.js.map +1 -0
  50. package/build/core/types/server.d.ts +14 -0
  51. package/build/core/types/server.d.ts.map +1 -0
  52. package/build/core/types/server.js +2 -0
  53. package/build/core/types/server.js.map +1 -0
  54. package/build/{types.d.ts → core/types/transport.d.ts} +1 -48
  55. package/build/core/types/transport.d.ts.map +1 -0
  56. package/build/{types.js → core/types/transport.js} +1 -13
  57. package/build/core/types/transport.js.map +1 -0
  58. package/build/handlers/notificationHandlers.d.ts +1 -1
  59. package/build/handlers/notificationHandlers.d.ts.map +1 -1
  60. package/build/handlers/notificationHandlers.js +41 -15
  61. package/build/handlers/notificationHandlers.js.map +1 -1
  62. package/build/handlers/requestHandlers.d.ts +1 -1
  63. package/build/handlers/requestHandlers.d.ts.map +1 -1
  64. package/build/handlers/requestHandlers.js +65 -2
  65. package/build/handlers/requestHandlers.js.map +1 -1
  66. package/build/index.d.ts +1 -1
  67. package/build/index.d.ts.map +1 -1
  68. package/build/index.js +44 -5
  69. package/build/index.js.map +1 -1
  70. package/build/logger/logger.js +1 -1
  71. package/build/logger/logger.js.map +1 -1
  72. package/build/server.d.ts +1 -1
  73. package/build/server.d.ts.map +1 -1
  74. package/build/server.js +6 -3
  75. package/build/server.js.map +1 -1
  76. package/build/services/configReloadService.d.ts +15 -5
  77. package/build/services/configReloadService.d.ts.map +1 -1
  78. package/build/services/configReloadService.js +28 -11
  79. package/build/services/configReloadService.js.map +1 -1
  80. package/build/{config/transportConfig.d.ts → transport/config.d.ts} +2 -2
  81. package/build/transport/config.d.ts.map +1 -0
  82. package/build/{config/transportConfig.js → transport/config.js} +2 -2
  83. package/build/transport/config.js.map +1 -0
  84. package/build/transport/http/errorHandler.d.ts.map +1 -0
  85. package/build/{server → transport/http}/errorHandler.js +1 -1
  86. package/build/transport/http/errorHandler.js.map +1 -0
  87. package/build/transport/http/middleware/loggingMiddleware.d.ts.map +1 -0
  88. package/build/{middleware → transport/http/middleware}/loggingMiddleware.js +11 -7
  89. package/build/transport/http/middleware/loggingMiddleware.js.map +1 -0
  90. package/build/transport/http/routes/oauthRoutes.d.ts +14 -0
  91. package/build/transport/http/routes/oauthRoutes.d.ts.map +1 -0
  92. package/build/transport/http/routes/oauthRoutes.js +132 -0
  93. package/build/transport/http/routes/oauthRoutes.js.map +1 -0
  94. package/build/transport/http/routes/sseRoutes.d.ts +4 -0
  95. package/build/transport/http/routes/sseRoutes.d.ts.map +1 -0
  96. package/build/transport/http/routes/sseRoutes.js +64 -0
  97. package/build/transport/http/routes/sseRoutes.js.map +1 -0
  98. package/build/transport/http/routes/streamableHttpRoutes.d.ts +4 -0
  99. package/build/transport/http/routes/streamableHttpRoutes.d.ts.map +1 -0
  100. package/build/transport/http/routes/streamableHttpRoutes.js +121 -0
  101. package/build/transport/http/routes/streamableHttpRoutes.js.map +1 -0
  102. package/build/transport/http/server.d.ts +69 -0
  103. package/build/transport/http/server.d.ts.map +1 -0
  104. package/build/transport/http/server.js +115 -0
  105. package/build/transport/http/server.js.map +1 -0
  106. package/build/utils/clientFiltering.d.ts +1 -1
  107. package/build/utils/clientFiltering.d.ts.map +1 -1
  108. package/build/utils/errorHandling.d.ts +1 -0
  109. package/build/utils/errorHandling.d.ts.map +1 -1
  110. package/build/utils/errorHandling.js +29 -5
  111. package/build/utils/errorHandling.js.map +1 -1
  112. package/build/utils/errorTypes.d.ts +4 -1
  113. package/build/utils/errorTypes.d.ts.map +1 -1
  114. package/build/utils/errorTypes.js +12 -4
  115. package/build/utils/errorTypes.js.map +1 -1
  116. package/build/utils/pagination.d.ts +1 -1
  117. package/build/utils/pagination.d.ts.map +1 -1
  118. package/build/utils/pagination.js +84 -5
  119. package/build/utils/pagination.js.map +1 -1
  120. package/build/utils/tagsExtractor.d.ts.map +1 -0
  121. package/build/utils/tagsExtractor.js.map +1 -0
  122. package/package.json +14 -5
  123. package/build/client.d.ts.map +0 -1
  124. package/build/client.js.map +0 -1
  125. package/build/clients/clientManager.d.ts.map +0 -1
  126. package/build/clients/clientManager.js.map +0 -1
  127. package/build/config/transportConfig.d.ts.map +0 -1
  128. package/build/config/transportConfig.js.map +0 -1
  129. package/build/middleware/loggingMiddleware.d.ts.map +0 -1
  130. package/build/middleware/loggingMiddleware.js.map +0 -1
  131. package/build/server/errorHandler.d.ts.map +0 -1
  132. package/build/server/errorHandler.js.map +0 -1
  133. package/build/server/expressServer.d.ts +0 -11
  134. package/build/server/expressServer.d.ts.map +0 -1
  135. package/build/server/expressServer.js +0 -177
  136. package/build/server/expressServer.js.map +0 -1
  137. package/build/server/tagsExtractor.d.ts.map +0 -1
  138. package/build/server/tagsExtractor.js.map +0 -1
  139. package/build/serverManager.d.ts.map +0 -1
  140. package/build/serverManager.js +0 -87
  141. package/build/serverManager.js.map +0 -1
  142. package/build/types.d.ts.map +0 -1
  143. package/build/types.js.map +0 -1
  144. /package/build/{server → transport/http}/errorHandler.d.ts +0 -0
  145. /package/build/{middleware → transport/http/middleware}/loggingMiddleware.d.ts +0 -0
  146. /package/build/{server → utils}/tagsExtractor.d.ts +0 -0
  147. /package/build/{server → utils}/tagsExtractor.js +0 -0
package/README.md CHANGED
@@ -22,19 +22,21 @@ A unified Model Context Protocol server implementation that aggregates multiple
22
22
  To enable Cursor to use existing MCP servers already configured in Claude Desktop, follow these steps:
23
23
 
24
24
  1. Run the 1MCP server with the Claude Desktop config file:
25
+
25
26
  ```bash
26
27
  npx -y @1mcp/agent --config ~/Library/Application\ Support/Claude/claude_desktop_config.json
27
28
  ```
28
29
 
29
30
  2. Add the 1MCP server to your Cursor config file (`~/.cursor/mcp.json`):
31
+
30
32
  ```json
31
33
  {
32
- "mcpServers": {
33
- "1mcp": {
34
- "type": "http",
35
- "url": "http://localhost:3050/sse"
36
- }
34
+ "mcpServers": {
35
+ "1mcp": {
36
+ "type": "http",
37
+ "url": "http://localhost:3050/sse"
37
38
  }
39
+ }
38
40
  }
39
41
  ```
40
42
 
@@ -59,14 +61,20 @@ npx -y @1mcp/agent --help
59
61
  ```
60
62
 
61
63
  Available options:
64
+
62
65
  - `--transport, -t`: Choose transport type ("stdio" or "http", default: "http")
63
66
  - `--config, -c`: Use a specific config file
64
67
  - `--port, -P`: Change HTTP port (default: 3050)
65
68
  - `--host, -H`: Change HTTP host (default: localhost)
66
69
  - `--tags, -g`: Filter servers by tags (see Tags section below)
70
+ - `--pagination, -p`: Enable pagination for client/server lists (boolean, default: false)
71
+ - `--auth`: Enable authentication (OAuth 2.1) (boolean, default: false)
72
+ - `--session-ttl`: Session expiry time in minutes (number, default: 1440)
73
+ - `--session-storage-path`: Custom session storage directory path (string, default: undefined)
67
74
  - `--help, -h`: Show help
68
75
 
69
76
  Example with environment variables:
77
+
70
78
  ```bash
71
79
  # Using environment variables
72
80
  ONE_MCP_PORT=3051 ONE_MCP_TAGS=network,filesystem npx -y @1mcp/agent
@@ -96,6 +104,7 @@ docker run -i ghcr.io/1mcp-app/agent --transport stdio
96
104
  ```
97
105
 
98
106
  Available image tags:
107
+
99
108
  - `latest`: Latest stable release
100
109
  - `vX.Y.Z`: Specific version (e.g. `v1.0.0`)
101
110
  - `sha-<commit>`: Specific commit
@@ -103,13 +112,19 @@ Available image tags:
103
112
  ### Environment Variables
104
113
 
105
114
  You can configure 1MCP using environment variables prefixed with `ONE_MCP_`:
115
+
106
116
  - `ONE_MCP_TRANSPORT`: Transport type ("stdio" or "http", default: "http")
107
117
  - `ONE_MCP_PORT`: HTTP port (default: 3050)
108
118
  - `ONE_MCP_HOST`: HTTP host (default: "localhost")
109
119
  - `ONE_MCP_CONFIG`: Path to config file
110
120
  - `ONE_MCP_TAGS`: Comma-separated list of tags to filter servers
121
+ - `ONE_MCP_PAGINATION`: Enable pagination for client/server lists (boolean, default: false)
122
+ - `ONE_MCP_AUTH`: Enable authentication (OAuth 2.1) (boolean, default: false)
123
+ - `ONE_MCP_SESSION_TTL`: Session expiry time in minutes (number, default: 1440)
124
+ - `ONE_MCP_SESSION_STORAGE_PATH`: Custom session storage directory path (string, default: undefined)
111
125
 
112
126
  Example with environment variables:
127
+
113
128
  ```bash
114
129
  docker run -p 3051:3051 \
115
130
  -e ONE_MCP_PORT=3051 \
@@ -124,6 +139,7 @@ Tags help you control which MCP servers are available to different clients. Thin
124
139
  #### How to Use Tags
125
140
 
126
141
  1. **In your server config**: Add tags to each server to describe its capabilities
142
+
127
143
  ```json
128
144
  {
129
145
  "mcpServers": {
@@ -144,6 +160,7 @@ Tags help you control which MCP servers are available to different clients. Thin
144
160
  ```
145
161
 
146
162
  2. **When starting 1MCP in stdio mode**: You can filter servers by tags
163
+
147
164
  ```bash
148
165
  # Only start servers with the "network" tag
149
166
  npx -y @1mcp/agent --transport stdio --tags "network"
@@ -153,18 +170,20 @@ npx -y @1mcp/agent --transport stdio --tags "network,filesystem"
153
170
  ```
154
171
 
155
172
  3. **When using SSE transport**: Clients can request servers with specific tags
173
+
156
174
  ```json
157
175
  {
158
- "mcpServers": {
159
- "1mcp": {
160
- "type": "http",
161
- "url": "http://localhost:3050/sse?tags=network" // Only connect to network-capable servers
162
- }
176
+ "mcpServers": {
177
+ "1mcp": {
178
+ "type": "http",
179
+ "url": "http://localhost:3050/sse?tags=network" // Only connect to network-capable servers
163
180
  }
181
+ }
164
182
  }
165
183
  ```
166
184
 
167
185
  Example tags:
186
+
168
187
  - `network`: For servers that make web requests
169
188
  - `filesystem`: For servers that handle file operations
170
189
  - `memory`: For servers that provide memory/storage
@@ -187,17 +206,12 @@ The server automatically manages configuration in a global location:
187
206
  "mcpServers": {
188
207
  "mcp-server-fetch": {
189
208
  "command": "uvx",
190
- "args": [
191
- "mcp-server-fetch"
192
- ],
209
+ "args": ["mcp-server-fetch"],
193
210
  "disabled": false
194
211
  },
195
212
  "server-memory": {
196
213
  "command": "npx",
197
- "args": [
198
- "-y",
199
- "@modelcontextprotocol/server-memory"
200
- ],
214
+ "args": ["-y", "@modelcontextprotocol/server-memory"],
201
215
  "disabled": false
202
216
  }
203
217
  }
@@ -263,21 +277,25 @@ sequenceDiagram
263
277
  ## Development
264
278
 
265
279
  Install dependencies:
280
+
266
281
  ```bash
267
282
  pnpm install
268
283
  ```
269
284
 
270
285
  Build the server:
286
+
271
287
  ```bash
272
288
  pnpm build
273
289
  ```
274
290
 
275
291
  For development with auto-rebuild:
292
+
276
293
  ```bash
277
294
  pnpm watch
278
295
  ```
279
296
 
280
297
  Run the server:
298
+
281
299
  ```bash
282
300
  pnpm dev
283
301
  ```
@@ -291,3 +309,9 @@ pnpm inspector
291
309
  ```
292
310
 
293
311
  The Inspector will provide a URL to access debugging tools in your browser.
312
+
313
+ ## Debugging & Source Maps
314
+
315
+ This project uses [source-map-support](https://www.npmjs.com/package/source-map-support) to enhance stack traces. When you run the server, stack traces will reference the original TypeScript source files instead of the compiled JavaScript. This makes debugging much easier, as error locations and line numbers will match your source code.
316
+
317
+ No extra setup is required—this is enabled by default. If you see a stack trace, it will point to `.ts` files and the correct line numbers. 🗺️
@@ -0,0 +1,109 @@
1
+ import { SessionData } from './sessionManager.js';
2
+ /**
3
+ * AuthManager handles OAuth 2.1 authentication flow and token validation.
4
+ *
5
+ * This class orchestrates the OAuth 2.1 authorization code grant flow,
6
+ * manages access token validation, and provides session information.
7
+ * It integrates with SessionManager for persistent storage and
8
+ * ServerConfigManager for configuration settings.
9
+ *
10
+ * Features:
11
+ * - OAuth 2.1 authorization code grant flow
12
+ * - Access token validation with prefix support
13
+ * - Session information retrieval
14
+ * - Configurable authentication settings
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * const authManager = new AuthManager('/custom/sessions');
19
+ * const token = authManager.exchangeCodeForToken('code-123', 'client-456');
20
+ * const session = authManager.validateAccessToken('tk-sess-789');
21
+ * ```
22
+ */
23
+ export declare class AuthManager {
24
+ private sessionManager;
25
+ private configManager;
26
+ /**
27
+ * Creates a new AuthManager instance.
28
+ *
29
+ * Initializes the session manager with optional custom storage path
30
+ * and retrieves the server configuration manager instance.
31
+ *
32
+ * @param sessionStoragePath - Optional custom path for session storage
33
+ */
34
+ constructor(sessionStoragePath?: string);
35
+ /**
36
+ * Checks if authentication is currently enabled.
37
+ *
38
+ * @returns True if OAuth 2.1 authentication is enabled, false otherwise
39
+ */
40
+ isAuthEnabled(): boolean;
41
+ /**
42
+ * Validates an access token and returns session data.
43
+ *
44
+ * If authentication is disabled, returns null (always valid).
45
+ * For enabled authentication, strips the token prefix if present
46
+ * and validates the underlying session.
47
+ *
48
+ * @param token - The access token to validate (with or without prefix)
49
+ * @returns Session data if token is valid, null otherwise
50
+ */
51
+ validateAccessToken(token: string): SessionData | null;
52
+ /**
53
+ * Creates an authorization code for OAuth 2.1 flow.
54
+ *
55
+ * Delegates to the session manager to create a prefixed authorization
56
+ * code with the configured time-to-live.
57
+ *
58
+ * @param clientId - The client identifier
59
+ * @param redirectUri - The redirect URI for this code
60
+ * @param resource - The resource this code grants access to
61
+ * @returns The generated authorization code with prefix
62
+ */
63
+ createAuthCode(clientId: string, redirectUri: string, resource: string): string;
64
+ /**
65
+ * Exchanges an authorization code for an access token.
66
+ *
67
+ * Validates the authorization code, checks client ID and redirect URI
68
+ * matches, then creates a new access token with the configured TTL.
69
+ * The authorization code is deleted after successful exchange.
70
+ *
71
+ * @param code - The authorization code to exchange
72
+ * @param clientId - The client identifier
73
+ * @param redirectUri - Optional redirect URI for validation
74
+ * @param resource - Optional resource for validation
75
+ * @returns Access token with prefix if exchange successful, null otherwise
76
+ */
77
+ exchangeCodeForToken(code: string, clientId: string, redirectUri?: string, resource?: string): string | null;
78
+ /**
79
+ * Gets information about an access token.
80
+ *
81
+ * Retrieves session data for the token and returns formatted
82
+ * information including client ID, resource, and time until expiration.
83
+ *
84
+ * @param token - The access token to get information for
85
+ * @returns Token information if valid, null otherwise
86
+ */
87
+ getTokenInfo(token: string): {
88
+ clientId: string;
89
+ resource: string;
90
+ expiresIn: number;
91
+ } | null;
92
+ /**
93
+ * Revokes an access token.
94
+ *
95
+ * Removes the session associated with the token from storage.
96
+ *
97
+ * @param token - The access token to revoke
98
+ * @returns True if token was revoked, false if it didn't exist
99
+ */
100
+ revokeToken(token: string): boolean;
101
+ /**
102
+ * Performs graceful shutdown of the AuthManager.
103
+ *
104
+ * Delegates shutdown to the session manager to ensure proper
105
+ * cleanup of resources and timers.
106
+ */
107
+ shutdown(): void;
108
+ }
109
+ //# sourceMappingURL=authManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authManager.d.ts","sourceRoot":"","sources":["../../src/auth/authManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAKlE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,aAAa,CAAsB;IAE3C;;;;;;;OAOG;gBACS,kBAAkB,CAAC,EAAE,MAAM;IAKvC;;;;OAIG;IACI,aAAa,IAAI,OAAO;IAI/B;;;;;;;;;OASG;IACI,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAmB7D;;;;;;;;;;OAUG;IACI,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAKtF;;;;;;;;;;;;OAYG;IACI,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAoCnH;;;;;;;;OAQG;IACI,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAapG;;;;;;;OAOG;IACI,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAI1C;;;;;OAKG;IACI,QAAQ,IAAI,IAAI;CAGxB"}
@@ -0,0 +1,173 @@
1
+ import logger from '../logger/logger.js';
2
+ import { SessionManager } from './sessionManager.js';
3
+ import { ServerConfigManager } from '../core/server/serverConfig.js';
4
+ import { AUTH_CONFIG } from '../constants.js';
5
+ import { v4 as uuidv4 } from 'uuid';
6
+ /**
7
+ * AuthManager handles OAuth 2.1 authentication flow and token validation.
8
+ *
9
+ * This class orchestrates the OAuth 2.1 authorization code grant flow,
10
+ * manages access token validation, and provides session information.
11
+ * It integrates with SessionManager for persistent storage and
12
+ * ServerConfigManager for configuration settings.
13
+ *
14
+ * Features:
15
+ * - OAuth 2.1 authorization code grant flow
16
+ * - Access token validation with prefix support
17
+ * - Session information retrieval
18
+ * - Configurable authentication settings
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * const authManager = new AuthManager('/custom/sessions');
23
+ * const token = authManager.exchangeCodeForToken('code-123', 'client-456');
24
+ * const session = authManager.validateAccessToken('tk-sess-789');
25
+ * ```
26
+ */
27
+ export class AuthManager {
28
+ sessionManager;
29
+ configManager;
30
+ /**
31
+ * Creates a new AuthManager instance.
32
+ *
33
+ * Initializes the session manager with optional custom storage path
34
+ * and retrieves the server configuration manager instance.
35
+ *
36
+ * @param sessionStoragePath - Optional custom path for session storage
37
+ */
38
+ constructor(sessionStoragePath) {
39
+ this.sessionManager = new SessionManager(sessionStoragePath);
40
+ this.configManager = ServerConfigManager.getInstance();
41
+ }
42
+ /**
43
+ * Checks if authentication is currently enabled.
44
+ *
45
+ * @returns True if OAuth 2.1 authentication is enabled, false otherwise
46
+ */
47
+ isAuthEnabled() {
48
+ return this.configManager.isAuthEnabled();
49
+ }
50
+ /**
51
+ * Validates an access token and returns session data.
52
+ *
53
+ * If authentication is disabled, returns null (always valid).
54
+ * For enabled authentication, strips the token prefix if present
55
+ * and validates the underlying session.
56
+ *
57
+ * @param token - The access token to validate (with or without prefix)
58
+ * @returns Session data if token is valid, null otherwise
59
+ */
60
+ validateAccessToken(token) {
61
+ if (!this.isAuthEnabled()) {
62
+ return null; // Auth disabled, always valid
63
+ }
64
+ if (!token) {
65
+ return null;
66
+ }
67
+ // Strip token prefix if present
68
+ const tokenId = token.startsWith(AUTH_CONFIG.PREFIXES.ACCESS_TOKEN)
69
+ ? token.slice(AUTH_CONFIG.PREFIXES.ACCESS_TOKEN.length)
70
+ : token;
71
+ // Session is stored with 'sess-' + tokenId
72
+ const sessionId = AUTH_CONFIG.PREFIXES.SESSION_ID + tokenId;
73
+ return this.sessionManager.getSession(sessionId);
74
+ }
75
+ /**
76
+ * Creates an authorization code for OAuth 2.1 flow.
77
+ *
78
+ * Delegates to the session manager to create a prefixed authorization
79
+ * code with the configured time-to-live.
80
+ *
81
+ * @param clientId - The client identifier
82
+ * @param redirectUri - The redirect URI for this code
83
+ * @param resource - The resource this code grants access to
84
+ * @returns The generated authorization code with prefix
85
+ */
86
+ createAuthCode(clientId, redirectUri, resource) {
87
+ const ttlMs = this.configManager.getOAuthCodeTtlMs();
88
+ return this.sessionManager.createAuthCode(clientId, redirectUri, resource, ttlMs);
89
+ }
90
+ /**
91
+ * Exchanges an authorization code for an access token.
92
+ *
93
+ * Validates the authorization code, checks client ID and redirect URI
94
+ * matches, then creates a new access token with the configured TTL.
95
+ * The authorization code is deleted after successful exchange.
96
+ *
97
+ * @param code - The authorization code to exchange
98
+ * @param clientId - The client identifier
99
+ * @param redirectUri - Optional redirect URI for validation
100
+ * @param resource - Optional resource for validation
101
+ * @returns Access token with prefix if exchange successful, null otherwise
102
+ */
103
+ exchangeCodeForToken(code, clientId, redirectUri, resource) {
104
+ const codeData = this.sessionManager.getAuthCode(code);
105
+ if (!codeData) {
106
+ logger.warn(`Invalid or expired auth code: ${code}`);
107
+ return null;
108
+ }
109
+ if (codeData.clientId !== clientId) {
110
+ logger.warn(`Client ID mismatch for code ${code}: expected ${codeData.clientId}, got ${clientId}`);
111
+ return null;
112
+ }
113
+ if (redirectUri && codeData.redirectUri !== redirectUri) {
114
+ logger.warn(`Redirect URI mismatch for code ${code}: expected ${codeData.redirectUri}, got ${redirectUri}`);
115
+ return null;
116
+ }
117
+ if (resource && codeData.resource && codeData.resource !== resource) {
118
+ logger.warn(`Resource mismatch for code ${code}: expected ${codeData.resource}, got ${resource}`);
119
+ return null;
120
+ }
121
+ // Delete the auth code after successful exchange
122
+ this.sessionManager.deleteAuthCode(code);
123
+ // Create access token with prefix and a new UUID
124
+ const rawTokenId = uuidv4();
125
+ const accessToken = AUTH_CONFIG.PREFIXES.ACCESS_TOKEN + rawTokenId;
126
+ const ttlMs = this.configManager.getOAuthTokenTtlMs();
127
+ // Store the session using the rawTokenId (not prefixed)
128
+ this.sessionManager.createSessionWithId(rawTokenId, clientId, codeData.resource, ttlMs);
129
+ logger.info(`Exchanged code ${code} for token ${accessToken} for client ${clientId}`);
130
+ return accessToken;
131
+ }
132
+ /**
133
+ * Gets information about an access token.
134
+ *
135
+ * Retrieves session data for the token and returns formatted
136
+ * information including client ID, resource, and time until expiration.
137
+ *
138
+ * @param token - The access token to get information for
139
+ * @returns Token information if valid, null otherwise
140
+ */
141
+ getTokenInfo(token) {
142
+ const session = this.sessionManager.getSession(token);
143
+ if (!session) {
144
+ return null;
145
+ }
146
+ return {
147
+ clientId: session.clientId,
148
+ resource: session.resource,
149
+ expiresIn: Math.max(0, Math.floor((session.expires - Date.now()) / 1000)),
150
+ };
151
+ }
152
+ /**
153
+ * Revokes an access token.
154
+ *
155
+ * Removes the session associated with the token from storage.
156
+ *
157
+ * @param token - The access token to revoke
158
+ * @returns True if token was revoked, false if it didn't exist
159
+ */
160
+ revokeToken(token) {
161
+ return this.sessionManager.deleteSession(token);
162
+ }
163
+ /**
164
+ * Performs graceful shutdown of the AuthManager.
165
+ *
166
+ * Delegates shutdown to the session manager to ensure proper
167
+ * cleanup of resources and timers.
168
+ */
169
+ shutdown() {
170
+ this.sessionManager.shutdown();
171
+ }
172
+ }
173
+ //# sourceMappingURL=authManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authManager.js","sourceRoot":"","sources":["../../src/auth/authManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import express from 'express';
2
+ import { AuthManager } from './authManager.js';
3
+ export declare function createAuthMiddleware(authManager: AuthManager): (req: express.Request, res: express.Response, next: express.NextFunction) => void;
4
+ declare global {
5
+ namespace Express {
6
+ interface Request {
7
+ sessionData?: {
8
+ clientId: string;
9
+ resource: string;
10
+ expires: number;
11
+ createdAt: number;
12
+ };
13
+ }
14
+ }
15
+ }
16
+ //# sourceMappingURL=authMiddleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authMiddleware.d.ts","sourceRoot":"","sources":["../../src/auth/authMiddleware.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,WAAW,IACnD,KAAK,OAAO,CAAC,OAAO,EAAE,KAAK,OAAO,CAAC,QAAQ,EAAE,MAAM,OAAO,CAAC,YAAY,UA8ChF;AAGD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,WAAW,CAAC,EAAE;gBACZ,QAAQ,EAAE,MAAM,CAAC;gBACjB,QAAQ,EAAE,MAAM,CAAC;gBACjB,OAAO,EAAE,MAAM,CAAC;gBAChB,SAAS,EAAE,MAAM,CAAC;aACnB,CAAC;SACH;KACF;CACF"}
@@ -0,0 +1,45 @@
1
+ import logger from '../logger/logger.js';
2
+ export function createAuthMiddleware(authManager) {
3
+ return (req, res, next) => {
4
+ // Skip auth if disabled
5
+ if (!authManager.isAuthEnabled()) {
6
+ return next();
7
+ }
8
+ const auth = req.headers['authorization'];
9
+ if (!auth || !auth.startsWith('Bearer ')) {
10
+ logger.warn('Missing Bearer token in request', {
11
+ url: req.url,
12
+ method: req.method,
13
+ headers: req.headers,
14
+ });
15
+ res.status(401).json({
16
+ error: 'invalid_token',
17
+ error_description: 'Missing Bearer token',
18
+ });
19
+ return;
20
+ }
21
+ const token = auth.slice('Bearer '.length);
22
+ const sessionData = authManager.validateAccessToken(token);
23
+ if (!sessionData) {
24
+ logger.warn('Invalid or expired token', {
25
+ url: req.url,
26
+ method: req.method,
27
+ token: token.substring(0, 8) + '...',
28
+ });
29
+ res.status(401).json({
30
+ error: 'invalid_token',
31
+ error_description: 'Invalid or expired token',
32
+ });
33
+ return;
34
+ }
35
+ // Add session data to request for downstream use
36
+ req.sessionData = sessionData;
37
+ logger.debug('Valid token for request', {
38
+ url: req.url,
39
+ method: req.method,
40
+ clientId: sessionData.clientId,
41
+ });
42
+ next();
43
+ };
44
+ }
45
+ //# sourceMappingURL=authMiddleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authMiddleware.js","sourceRoot":"","sources":["../../src/auth/authMiddleware.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,qBAAqB,CAAC;AAGzC,MAAM,UAAU,oBAAoB,CAAC,WAAwB;IAC3D,OAAO,CAAC,GAAoB,EAAE,GAAqB,EAAE,IAA0B,EAAE,EAAE;QACjF,wBAAwB;QACxB,IAAI,CAAC,WAAW,CAAC,aAAa,EAAE,EAAE,CAAC;YACjC,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QAED,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAC1C,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACzC,MAAM,CAAC,IAAI,CAAC,iCAAiC,EAAE;gBAC7C,GAAG,EAAE,GAAG,CAAC,GAAG;gBACZ,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,OAAO,EAAE,GAAG,CAAC,OAAO;aACrB,CAAC,CAAC;YACH,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,eAAe;gBACtB,iBAAiB,EAAE,sBAAsB;aAC1C,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC3C,MAAM,WAAW,GAAG,WAAW,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAE3D,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,CAAC,IAAI,CAAC,0BAA0B,EAAE;gBACtC,GAAG,EAAE,GAAG,CAAC,GAAG;gBACZ,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK;aACrC,CAAC,CAAC;YACH,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,eAAe;gBACtB,iBAAiB,EAAE,0BAA0B;aAC9C,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,iDAAiD;QACjD,GAAG,CAAC,WAAW,GAAG,WAAW,CAAC;QAC9B,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE;YACtC,GAAG,EAAE,GAAG,CAAC,GAAG;YACZ,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,QAAQ,EAAE,WAAW,CAAC,QAAQ;SAC/B,CAAC,CAAC;QAEH,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;AACJ,CAAC"}