@samanhappy/mcphub 0.9.16 → 0.10.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 (37) hide show
  1. package/README.md +67 -0
  2. package/README.zh.md +65 -0
  3. package/dist/config/index.js +17 -4
  4. package/dist/config/index.js.map +1 -1
  5. package/dist/controllers/authController.js +16 -0
  6. package/dist/controllers/authController.js.map +1 -1
  7. package/dist/controllers/oauthCallbackController.js +276 -0
  8. package/dist/controllers/oauthCallbackController.js.map +1 -0
  9. package/dist/controllers/serverController.js +1 -1
  10. package/dist/controllers/serverController.js.map +1 -1
  11. package/dist/controllers/userController.js +23 -1
  12. package/dist/controllers/userController.js.map +1 -1
  13. package/dist/routes/index.js +3 -0
  14. package/dist/routes/index.js.map +1 -1
  15. package/dist/server.js +10 -0
  16. package/dist/server.js.map +1 -1
  17. package/dist/services/mcpOAuthProvider.js +472 -0
  18. package/dist/services/mcpOAuthProvider.js.map +1 -0
  19. package/dist/services/mcpService.js +321 -191
  20. package/dist/services/mcpService.js.map +1 -1
  21. package/dist/services/oauthClientRegistration.js +444 -0
  22. package/dist/services/oauthClientRegistration.js.map +1 -0
  23. package/dist/services/oauthService.js +216 -0
  24. package/dist/services/oauthService.js.map +1 -0
  25. package/dist/services/oauthSettingsStore.js +106 -0
  26. package/dist/services/oauthSettingsStore.js.map +1 -0
  27. package/dist/utils/passwordValidation.js +38 -0
  28. package/dist/utils/passwordValidation.js.map +1 -0
  29. package/dist/utils/path.js.map +1 -1
  30. package/frontend/dist/assets/index-BP5IZhlg.js +251 -0
  31. package/frontend/dist/assets/index-BP5IZhlg.js.map +1 -0
  32. package/frontend/dist/assets/index-C_58ZhSt.css +1 -0
  33. package/frontend/dist/index.html +2 -2
  34. package/package.json +3 -2
  35. package/frontend/dist/assets/index-DDUK8zl_.js +0 -217
  36. package/frontend/dist/assets/index-DDUK8zl_.js.map +0 -1
  37. package/frontend/dist/assets/index-DcVhHcn9.css +0 -1
package/README.md CHANGED
@@ -19,6 +19,8 @@ MCPHub makes it easy to manage and scale multiple MCP (Model Context Protocol) s
19
19
  - **Hot-Swappable Configuration**: Add, remove, or update MCP servers on the fly — no downtime required.
20
20
  - **Group-Based Access Control**: Organize servers into customizable groups for streamlined permissions management.
21
21
  - **Secure Authentication**: Built-in user management with role-based access powered by JWT and bcrypt.
22
+ - **OAuth 2.0 Support**: Full OAuth support for upstream MCP servers with proxy authorization capabilities.
23
+ - **Environment Variable Expansion**: Use environment variables anywhere in your configuration for secure credential management. See [Environment Variables Guide](docs/environment-variables.md).
22
24
  - **Docker-Ready**: Deploy instantly with our containerized setup.
23
25
 
24
26
  ## 🔧 Quick Start
@@ -57,6 +59,45 @@ Create a `mcp_settings.json` file to customize your server settings:
57
59
  }
58
60
  ```
59
61
 
62
+ #### OAuth Configuration (Optional)
63
+
64
+ MCPHub supports OAuth 2.0 for authenticating with upstream MCP servers. See the [OAuth feature guide](docs/features/oauth.mdx) for a full walkthrough. In practice you will run into two configuration patterns:
65
+
66
+ - **Dynamic registration servers** (e.g., Vercel, Linear) publish all metadata and allow MCPHub to self-register. Simply declare the server URL and MCPHub handles the rest.
67
+ - **Manually provisioned servers** (e.g., GitHub Copilot) require you to create an OAuth App and provide the issued client ID/secret to MCPHub.
68
+
69
+ Dynamic registration example:
70
+
71
+ ```json
72
+ {
73
+ "mcpServers": {
74
+ "vercel": {
75
+ "type": "sse",
76
+ "url": "https://mcp.vercel.com"
77
+ }
78
+ }
79
+ }
80
+ ```
81
+
82
+ Manual registration example:
83
+
84
+ ```json
85
+ {
86
+ "mcpServers": {
87
+ "github": {
88
+ "type": "sse",
89
+ "url": "https://api.githubcopilot.com/mcp/",
90
+ "oauth": {
91
+ "clientId": "${GITHUB_OAUTH_APP_ID}",
92
+ "clientSecret": "${GITHUB_OAUTH_APP_SECRET}"
93
+ }
94
+ }
95
+ }
96
+ }
97
+ ```
98
+
99
+ For manual providers, create the OAuth App in the upstream console, set the redirect URI to `http://localhost:3000/oauth/callback` (or your deployed domain), and then plug the credentials into the dashboard or config file.
100
+
60
101
  ### Docker Deployment
61
102
 
62
103
  **Recommended**: Mount your custom config:
@@ -106,7 +147,11 @@ This endpoint provides a unified streamable HTTP interface for all your MCP serv
106
147
  Smart Routing is MCPHub's intelligent tool discovery system that uses vector semantic search to automatically find the most relevant tools for any given task.
107
148
 
108
149
  ```
150
+ # Search across all servers
109
151
  http://localhost:3000/mcp/$smart
152
+
153
+ # Search within a specific group
154
+ http://localhost:3000/mcp/$smart/{group}
110
155
  ```
111
156
 
112
157
  **How it Works:**
@@ -115,6 +160,7 @@ http://localhost:3000/mcp/$smart
115
160
  2. **Semantic Search**: User queries are converted to vectors and matched against tool embeddings using cosine similarity
116
161
  3. **Intelligent Filtering**: Dynamic thresholds ensure relevant results without noise
117
162
  4. **Precise Execution**: Found tools can be directly executed with proper parameter validation
163
+ 5. **Group Scoping**: Optionally limit searches to servers within a specific group for focused results
118
164
 
119
165
  **Setup Requirements:**
120
166
 
@@ -126,6 +172,23 @@ To enable Smart Routing, you need:
126
172
  - OpenAI API key (or compatible embedding service)
127
173
  - Enable Smart Routing in MCPHub settings
128
174
 
175
+ **Group-Scoped Smart Routing**:
176
+
177
+ You can combine Smart Routing with group filtering to search only within specific server groups:
178
+
179
+ ```
180
+ # Search only within production servers
181
+ http://localhost:3000/mcp/$smart/production
182
+
183
+ # Search only within development servers
184
+ http://localhost:3000/mcp/$smart/development
185
+ ```
186
+
187
+ This enables:
188
+ - **Focused Discovery**: Find tools only from relevant servers
189
+ - **Environment Isolation**: Separate tool discovery by environment (dev, staging, prod)
190
+ - **Team-Based Access**: Limit tool search to team-specific server groups
191
+
129
192
  **Group-Specific Endpoints (Recommended)**:
130
193
 
131
194
  ![Group Management](assets/group.png)
@@ -164,7 +227,11 @@ http://localhost:3000/sse
164
227
  For smart routing, use:
165
228
 
166
229
  ```
230
+ # Search across all servers
167
231
  http://localhost:3000/sse/$smart
232
+
233
+ # Search within a specific group
234
+ http://localhost:3000/sse/$smart/{group}
168
235
  ```
169
236
 
170
237
  For targeted access to specific server groups, use the group-based SSE endpoint:
package/README.zh.md CHANGED
@@ -57,6 +57,45 @@ MCPHub 通过将多个 MCP(Model Context Protocol)服务器组织为灵活
57
57
  }
58
58
  ```
59
59
 
60
+ #### OAuth 配置(可选)
61
+
62
+ MCPHub 支持通过 OAuth 2.0 访问上游 MCP 服务器。完整说明请参阅[《OAuth 功能指南》](docs/zh/features/oauth.mdx)。实际使用中通常会遇到两类配置:
63
+
64
+ - **支持动态注册的服务器**(如 Vercel、Linear):会公开全部元数据,MCPHub 可自动注册并完成授权,仅需声明服务器地址。
65
+ - **需要手动配置客户端的服务器**(如 GitHub Copilot):需要在提供商后台创建 OAuth 应用,并将获得的 Client ID/Secret 写入 MCPHub。
66
+
67
+ 动态注册示例:
68
+
69
+ ```json
70
+ {
71
+ "mcpServers": {
72
+ "vercel": {
73
+ "type": "sse",
74
+ "url": "https://mcp.vercel.com"
75
+ }
76
+ }
77
+ }
78
+ ```
79
+
80
+ 手动注册示例:
81
+
82
+ ```json
83
+ {
84
+ "mcpServers": {
85
+ "github": {
86
+ "type": "sse",
87
+ "url": "https://api.githubcopilot.com/mcp/",
88
+ "oauth": {
89
+ "clientId": "${GITHUB_OAUTH_APP_ID}",
90
+ "clientSecret": "${GITHUB_OAUTH_APP_SECRET}"
91
+ }
92
+ }
93
+ }
94
+ }
95
+ ```
96
+
97
+ 对于需要手动注册的提供商,请先在上游控制台创建 OAuth 应用,将回调地址设置为 `http://localhost:3000/oauth/callback`(或你的部署域名),然后在控制台或配置文件中填写凭据。
98
+
60
99
  ### Docker 部署
61
100
 
62
101
  **推荐**:挂载自定义配置:
@@ -106,7 +145,11 @@ http://localhost:3000/mcp
106
145
  智能路由是 MCPHub 的智能工具发现系统,使用向量语义搜索自动为任何给定任务找到最相关的工具。
107
146
 
108
147
  ```
148
+ # 在所有服务器中搜索
109
149
  http://localhost:3000/mcp/$smart
150
+
151
+ # 在特定分组中搜索
152
+ http://localhost:3000/mcp/$smart/{group}
110
153
  ```
111
154
 
112
155
  **工作原理:**
@@ -115,6 +158,7 @@ http://localhost:3000/mcp/$smart
115
158
  2. **语义搜索**:用户查询转换为向量并使用余弦相似度与工具嵌入匹配
116
159
  3. **智能筛选**:动态阈值确保相关结果且无噪声
117
160
  4. **精确执行**:找到的工具可以直接执行并进行适当的参数验证
161
+ 5. **分组限定**:可选择将搜索限制在特定分组的服务器内以获得更精确的结果
118
162
 
119
163
  **设置要求:**
120
164
 
@@ -126,6 +170,23 @@ http://localhost:3000/mcp/$smart
126
170
  - OpenAI API 密钥(或兼容的嵌入服务)
127
171
  - 在 MCPHub 设置中启用智能路由
128
172
 
173
+ **分组限定的智能路由**:
174
+
175
+ 您可以将智能路由与分组筛选结合使用,仅在特定服务器分组内搜索:
176
+
177
+ ```
178
+ # 仅在生产服务器中搜索
179
+ http://localhost:3000/mcp/$smart/production
180
+
181
+ # 仅在开发服务器中搜索
182
+ http://localhost:3000/mcp/$smart/development
183
+ ```
184
+
185
+ 这样可以实现:
186
+ - **精准发现**:仅从相关服务器查找工具
187
+ - **环境隔离**:按环境(开发、测试、生产)分离工具发现
188
+ - **基于团队的访问**:将工具搜索限制在特定团队的服务器分组
189
+
129
190
  **基于分组的 HTTP 端点(推荐)**:
130
191
  ![分组](assets/group.zh.png)
131
192
  要针对特定服务器分组进行访问,请使用基于分组的 HTTP 端点:
@@ -164,7 +225,11 @@ http://localhost:3000/sse
164
225
  要启用智能路由,请使用:
165
226
 
166
227
  ```
228
+ # 在所有服务器中搜索
167
229
  http://localhost:3000/sse/$smart
230
+
231
+ # 在特定分组中搜索
232
+ http://localhost:3000/sse/$smart/{group}
168
233
  ```
169
234
 
170
235
  要针对特定服务器分组进行访问,请使用基于分组的 SSE 端点:
@@ -77,22 +77,35 @@ export const getSettingsCacheInfo = () => {
77
77
  };
78
78
  };
79
79
  export function replaceEnvVars(input) {
80
- // Handle object input
80
+ // Handle object input - recursively expand all nested values
81
81
  if (input && typeof input === 'object' && !Array.isArray(input)) {
82
82
  const res = {};
83
83
  for (const [key, value] of Object.entries(input)) {
84
84
  if (typeof value === 'string') {
85
85
  res[key] = expandEnvVars(value);
86
86
  }
87
+ else if (typeof value === 'object' && value !== null) {
88
+ // Recursively handle nested objects and arrays
89
+ res[key] = replaceEnvVars(value);
90
+ }
87
91
  else {
88
- res[key] = String(value);
92
+ // Preserve non-string, non-object values (numbers, booleans, etc.)
93
+ res[key] = value;
89
94
  }
90
95
  }
91
96
  return res;
92
97
  }
93
- // Handle array input
98
+ // Handle array input - recursively expand all elements
94
99
  if (Array.isArray(input)) {
95
- return input.map((item) => expandEnvVars(item));
100
+ return input.map((item) => {
101
+ if (typeof item === 'string') {
102
+ return expandEnvVars(item);
103
+ }
104
+ else if (typeof item === 'object' && item !== null) {
105
+ return replaceEnvVars(item);
106
+ }
107
+ return item;
108
+ });
96
109
  }
97
110
  // Handle string input
98
111
  if (typeof input === 'string') {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAA;AAC3B,OAAO,EAAE,MAAM,IAAI,CAAA;AAEnB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAGxD,MAAM,CAAC,MAAM,EAAE,CAAA;AAEf,MAAM,aAAa,GAAG;IACpB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI;IAC9B,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,MAAM;IAC/C,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE;IACrC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,KAAK;IAClD,UAAU,EAAE,QAAQ;IACpB,aAAa,EAAE,iBAAiB,EAAE;CACnC,CAAA;AAED,MAAM,WAAW,GAAgB,cAAc,EAAE,CAAA;AAEjD,iBAAiB;AACjB,IAAI,aAAa,GAAuB,IAAI,CAAA;AAE5C,MAAM,CAAC,MAAM,eAAe,GAAG,GAAW,EAAE;IAC1C,OAAO,iBAAiB,CAAC,mBAAmB,EAAE,UAAU,CAAC,CAAA;AAC3D,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAgB,EAAE;IACpD,+CAA+C;IAC/C,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,aAAa,CAAA;IACtB,CAAC;IAED,MAAM,YAAY,GAAG,eAAe,EAAE,CAAA;IACtC,uBAAuB;IACvB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,IAAI,CAAC,8BAA8B,YAAY,2BAA2B,CAAC,CAAA;QACnF,MAAM,eAAe,GAAG,EAAE,UAAU,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAA;QACrD,yBAAyB;QACzB,aAAa,GAAG,eAAe,CAAA;QAC/B,OAAO,eAAe,CAAA;IACxB,CAAC;IAED,IAAI,CAAC;QACH,+BAA+B;QAC/B,MAAM,YAAY,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAA;QAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;QAEzC,eAAe;QACf,aAAa,GAAG,QAAQ,CAAA;QAExB,OAAO,CAAC,GAAG,CAAC,wBAAwB,YAAY,EAAE,CAAC,CAAA;QACnD,OAAO,QAAQ,CAAA;IACjB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,gCAAgC,YAAY,KAAK,KAAK,EAAE,CAAC,CAAA;IAC3E,CAAC;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAAY,EAAe,EAAE;IACxD,OAAO,WAAW,CAAC,cAAe,CAAC,oBAAoB,EAAE,EAAE,IAAI,CAAC,CAAA;AAClE,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,QAAqB,EAAE,IAAY,EAAW,EAAE;IAC3E,MAAM,YAAY,GAAG,eAAe,EAAE,CAAA;IACtC,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,WAAW,CAAC,aAAc,CAAC,oBAAoB,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAA;QACzF,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;QAE/E,qCAAqC;QACrC,aAAa,GAAG,cAAc,CAAA;QAE9B,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,YAAY,GAAG,EAAE,KAAK,CAAC,CAAA;QACnE,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAS,EAAE;IAC3C,aAAa,GAAG,IAAI,CAAA;AACtB,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAA0B,EAAE;IAC9D,OAAO;QACL,QAAQ,EAAE,aAAa,KAAK,IAAI;KACjC,CAAA;AACH,CAAC,CAAA;AAKD,MAAM,UAAU,cAAc,CAC5B,KAA0D;IAE1D,sBAAsB;IACtB,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAChE,MAAM,GAAG,GAA2B,EAAE,CAAA;QACtC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACjD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC9B,GAAG,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,CAAA;YACjC,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;YAC1B,CAAC;QACH,CAAC;QACD,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,qBAAqB;IACrB,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAA;IACjD,CAAC;IAED,sBAAsB;IACtB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,aAAa,CAAC,KAAK,CAAC,CAAA;IAC7B,CAAC;IAED,oCAAoC;IACpC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAC1C,OAAO,EAAE,CAAA;IACX,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAa,EAAU,EAAE;IACrD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,MAAM,CAAC,KAAK,CAAC,CAAA;IACtB,CAAC;IACD,wBAAwB;IACxB,IAAI,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAA;IAChF,yDAAyD;IACzD,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAA;IACpF,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAED,eAAe,aAAa,CAAA;AAE5B,MAAM,UAAU,gBAAgB;IAC9B,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAA;IAC/B,OAAO,QAAQ,CAAC,YAAY,EAAE,aAAa,IAAI,GAAG,CAAA;AACpD,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAGzD,MAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,MAAM,aAAa,GAAG;IACpB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI;IAC9B,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,MAAM;IAC/C,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE;IACrC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,KAAK;IAClD,UAAU,EAAE,QAAQ;IACpB,aAAa,EAAE,iBAAiB,EAAE;CACnC,CAAC;AAEF,MAAM,WAAW,GAAgB,cAAc,EAAE,CAAC;AAElD,iBAAiB;AACjB,IAAI,aAAa,GAAuB,IAAI,CAAC;AAE7C,MAAM,CAAC,MAAM,eAAe,GAAG,GAAW,EAAE;IAC1C,OAAO,iBAAiB,CAAC,mBAAmB,EAAE,UAAU,CAAC,CAAC;AAC5D,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAgB,EAAE;IACpD,+CAA+C;IAC/C,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;IACvC,uBAAuB;IACvB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,IAAI,CAAC,8BAA8B,YAAY,2BAA2B,CAAC,CAAC;QACpF,MAAM,eAAe,GAAG,EAAE,UAAU,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QACtD,yBAAyB;QACzB,aAAa,GAAG,eAAe,CAAC;QAChC,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,IAAI,CAAC;QACH,+BAA+B;QAC/B,MAAM,YAAY,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAE1C,eAAe;QACf,aAAa,GAAG,QAAQ,CAAC;QAEzB,OAAO,CAAC,GAAG,CAAC,wBAAwB,YAAY,EAAE,CAAC,CAAC;QACpD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,gCAAgC,YAAY,KAAK,KAAK,EAAE,CAAC,CAAC;IAC5E,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAAY,EAAe,EAAE;IACxD,OAAO,WAAW,CAAC,cAAe,CAAC,oBAAoB,EAAE,EAAE,IAAI,CAAC,CAAC;AACnE,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,QAAqB,EAAE,IAAY,EAAW,EAAE;IAC3E,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;IACvC,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,WAAW,CAAC,aAAc,CAAC,oBAAoB,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC1F,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QAEhF,qCAAqC;QACrC,aAAa,GAAG,cAAc,CAAC;QAE/B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,YAAY,GAAG,EAAE,KAAK,CAAC,CAAC;QACpE,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAS,EAAE;IAC3C,aAAa,GAAG,IAAI,CAAC;AACvB,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAA0B,EAAE;IAC9D,OAAO;QACL,QAAQ,EAAE,aAAa,KAAK,IAAI;KACjC,CAAC;AACJ,CAAC,CAAC;AAKF,MAAM,UAAU,cAAc,CAC5B,KAA0D;IAE1D,6DAA6D;IAC7D,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAChE,MAAM,GAAG,GAAwB,EAAE,CAAC;QACpC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACjD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC9B,GAAG,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;YAClC,CAAC;iBAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACvD,+CAA+C;gBAC/C,GAAG,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC,KAAY,CAAC,CAAC;YAC1C,CAAC;iBAAM,CAAC;gBACN,mEAAmE;gBACnE,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YACnB,CAAC;QACH,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,uDAAuD;IACvD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACxB,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC7B,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC;YAC7B,CAAC;iBAAM,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBACrD,OAAO,cAAc,CAAC,IAAW,CAAC,CAAC;YACrC,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC;IAED,sBAAsB;IACtB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED,oCAAoC;IACpC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAC1C,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAa,EAAU,EAAE;IACrD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IACD,wBAAwB;IACxB,IAAI,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IACjF,yDAAyD;IACzD,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IACrF,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,eAAe,aAAa,CAAC;AAE7B,MAAM,UAAU,gBAAgB;IAC9B,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;IAChC,OAAO,QAAQ,CAAC,YAAY,EAAE,aAAa,IAAI,GAAG,CAAC;AACrD,CAAC"}
@@ -3,6 +3,8 @@ import { validationResult } from 'express-validator';
3
3
  import { findUserByUsername, verifyPassword, createUser, updateUserPassword, } from '../models/User.js';
4
4
  import { getDataService } from '../services/services.js';
5
5
  import { JWT_SECRET } from '../config/jwt.js';
6
+ import { validatePasswordStrength, isDefaultPassword } from '../utils/passwordValidation.js';
7
+ import { getPackageVersion } from '../utils/version.js';
6
8
  const dataService = getDataService();
7
9
  const TOKEN_EXPIRY = '24h';
8
10
  // Login user
@@ -46,6 +48,9 @@ export const login = async (req, res) => {
46
48
  isAdmin: user.isAdmin || false,
47
49
  },
48
50
  };
51
+ // Check if user is admin with default password
52
+ const version = getPackageVersion();
53
+ const isUsingDefaultPassword = user.username === 'admin' && user.isAdmin && isDefaultPassword(password) && version !== 'dev';
49
54
  jwt.sign(payload, JWT_SECRET, { expiresIn: TOKEN_EXPIRY }, (err, token) => {
50
55
  if (err)
51
56
  throw err;
@@ -58,6 +63,7 @@ export const login = async (req, res) => {
58
63
  isAdmin: user.isAdmin,
59
64
  permissions: dataService.getPermissions(user),
60
65
  },
66
+ isUsingDefaultPassword,
61
67
  });
62
68
  });
63
69
  }
@@ -147,6 +153,16 @@ export const changePassword = async (req, res) => {
147
153
  const { currentPassword, newPassword } = req.body;
148
154
  const username = req.user.username;
149
155
  try {
156
+ // Validate new password strength
157
+ const validationResult = validatePasswordStrength(newPassword);
158
+ if (!validationResult.isValid) {
159
+ res.status(400).json({
160
+ success: false,
161
+ message: 'Password does not meet security requirements',
162
+ errors: validationResult.errors,
163
+ });
164
+ return;
165
+ }
150
166
  // Find user by username
151
167
  const user = findUserByUsername(username);
152
168
  if (!user) {
@@ -1 +1 @@
1
- {"version":3,"file":"authController.js","sourceRoot":"","sources":["../../src/controllers/authController.ts"],"names":[],"mappings":"AACA,OAAO,GAAG,MAAM,cAAc,CAAC;AAC/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,UAAU,EACV,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,MAAM,WAAW,GAAgB,cAAc,EAAE,CAAC;AAElD,MAAM,YAAY,GAAG,KAAK,CAAC;AAE3B,aAAa;AACb,MAAM,CAAC,MAAM,KAAK,GAAG,KAAK,EAAE,GAAY,EAAE,GAAa,EAAiB,EAAE;IACxE,wCAAwC;IACxC,MAAM,CAAC,GAAI,GAAW,CAAC,CAAC,CAAC;IAEzB,mBAAmB;IACnB,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACrC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;QACtB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,CAAC,CAAC,8BAA8B,CAAC;YAC1C,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE;SACvB,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;IAExC,IAAI,CAAC;QACH,wBAAwB;QACxB,MAAM,IAAI,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAE1C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,CAAC,CAAC,gCAAgC,CAAC;aAC7C,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,kBAAkB;QAClB,MAAM,eAAe,GAAG,MAAM,cAAc,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEtE,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,CAAC,CAAC,gCAAgC,CAAC;aAC7C,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,qBAAqB;QACrB,MAAM,OAAO,GAAG;YACd,IAAI,EAAE;gBACJ,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,KAAK;aAC/B;SACF,CAAC;QAEF,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;YACxE,IAAI,GAAG;gBAAE,MAAM,GAAG,CAAC;YACnB,GAAG,CAAC,IAAI,CAAC;gBACP,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,CAAC,CAAC,8BAA8B,CAAC;gBAC1C,KAAK;gBACL,IAAI,EAAE;oBACJ,QAAQ,EAAE,IAAI,CAAC,QAAQ;oBACvB,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,WAAW,EAAE,WAAW,CAAC,cAAc,CAAC,IAAI,CAAC;iBAC9C;aACF,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;QACrC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,CAAC,CAAC,yBAAyB,CAAC;SACtC,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC;AAEF,oBAAoB;AACpB,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,EAAE,GAAY,EAAE,GAAa,EAAiB,EAAE;IAC3E,wCAAwC;IACxC,MAAM,CAAC,GAAI,GAAW,CAAC,CAAC,CAAC;IAEzB,mBAAmB;IACnB,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACrC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;QACtB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,CAAC,CAAC,8BAA8B,CAAC;YAC1C,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE;SACvB,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;IAEjD,IAAI,CAAC;QACH,kBAAkB;QAClB,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QAElE,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,qBAAqB,EAAE,CAAC,CAAC;YACzE,OAAO;QACT,CAAC;QAED,qBAAqB;QACrB,MAAM,OAAO,GAAG;YACd,IAAI,EAAE;gBACJ,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,KAAK;aAClC;SACF,CAAC;QAEF,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;YACxE,IAAI,GAAG;gBAAE,MAAM,GAAG,CAAC;YACnB,GAAG,CAAC,IAAI,CAAC;gBACP,OAAO,EAAE,IAAI;gBACb,KAAK;gBACL,IAAI,EAAE;oBACJ,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,OAAO,EAAE,OAAO,CAAC,OAAO;oBACxB,WAAW,EAAE,WAAW,CAAC,cAAc,CAAC,OAAO,CAAC;iBACjD;aACF,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;QAC5C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;IACpE,CAAC;AACH,CAAC,CAAC;AAEF,mBAAmB;AACnB,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,GAAY,EAAE,GAAa,EAAQ,EAAE;IAClE,IAAI,CAAC;QACH,yDAAyD;QACzD,MAAM,IAAI,GAAI,GAAW,CAAC,IAAI,CAAC;QAE/B,GAAG,CAAC,IAAI,CAAC;YACP,OAAO,EAAE,IAAI;YACb,IAAI,EAAE;gBACJ,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,WAAW,EAAE,WAAW,CAAC,cAAc,CAAC,IAAI,CAAC;aAC9C;SACF,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;QAChD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;IACpE,CAAC;AACH,CAAC,CAAC;AAEF,kBAAkB;AAClB,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EAAE,GAAY,EAAE,GAAa,EAAiB,EAAE;IACjF,mBAAmB;IACnB,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACrC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;QACtB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACjE,OAAO;IACT,CAAC;IAED,MAAM,EAAE,eAAe,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;IAClD,MAAM,QAAQ,GAAI,GAAW,CAAC,IAAI,CAAC,QAAQ,CAAC;IAE5C,IAAI,CAAC;QACH,wBAAwB;QACxB,MAAM,IAAI,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAE1C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC,CAAC;YACpE,OAAO;QACT,CAAC;QAED,0BAA0B;QAC1B,MAAM,eAAe,GAAG,MAAM,cAAc,CAAC,eAAe,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAE7E,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,+BAA+B,EAAE,CAAC,CAAC;YACnF,OAAO;QACT,CAAC;QAED,sBAAsB;QACtB,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QAEhE,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,2BAA2B,EAAE,CAAC,CAAC;YAC/E,OAAO;QACT,CAAC;QAED,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,+BAA+B,EAAE,CAAC,CAAC;IACxE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;QAC/C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;IACpE,CAAC;AACH,CAAC,CAAC"}
1
+ {"version":3,"file":"authController.js","sourceRoot":"","sources":["../../src/controllers/authController.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,276 @@
1
+ /**
2
+ * OAuth Callback Controller
3
+ *
4
+ * Handles OAuth 2.0 authorization callbacks for upstream MCP servers.
5
+ *
6
+ * This controller implements a simplified callback flow that relies on the MCP SDK
7
+ * to handle the complete OAuth token exchange:
8
+ *
9
+ * 1. Extract authorization code from callback URL
10
+ * 2. Find the corresponding server using the state parameter
11
+ * 3. Store the authorization code temporarily
12
+ * 4. Reconnect the server - SDK's auth() function will:
13
+ * - Automatically discover OAuth endpoints
14
+ * - Exchange the code for tokens using PKCE
15
+ * - Save tokens via our OAuthClientProvider.saveTokens()
16
+ */
17
+ import { getServerByName, getServerByOAuthState, createTransportFromConfig, } from '../services/mcpService.js';
18
+ import { getNameSeparator, loadSettings } from '../config/index.js';
19
+ /**
20
+ * Generate HTML response page with i18n support
21
+ */
22
+ const generateHtmlResponse = (type, title, message, details, autoClose = false) => {
23
+ const backgroundColor = type === 'error' ? '#fee' : '#efe';
24
+ const borderColor = type === 'error' ? '#fcc' : '#cfc';
25
+ const titleColor = type === 'error' ? '#c33' : '#3c3';
26
+ const buttonColor = type === 'error' ? '#c33' : '#3c3';
27
+ return `
28
+ <!DOCTYPE html>
29
+ <html>
30
+ <head>
31
+ <title>${title}</title>
32
+ <style>
33
+ body { font-family: Arial, sans-serif; max-width: 600px; margin: 50px auto; padding: 20px; }
34
+ .container { background-color: ${backgroundColor}; border: 1px solid ${borderColor}; padding: 20px; border-radius: 8px; }
35
+ h1 { color: ${titleColor}; margin-top: 0; }
36
+ .detail { margin-top: 10px; padding: 10px; background: #f9f9f9; border-radius: 4px; ${type === 'error' ? 'font-family: monospace; font-size: 12px; white-space: pre-wrap;' : ''} }
37
+ .close-btn { margin-top: 20px; padding: 10px 20px; background: ${buttonColor}; color: white; border: none; border-radius: 4px; cursor: pointer; }
38
+ </style>
39
+ ${autoClose ? '<script>setTimeout(() => { window.close(); }, 3000);</script>' : ''}
40
+ </head>
41
+ <body>
42
+ <div class="container">
43
+ <h1>${type === 'success' ? '✓ ' : ''}${title}</h1>
44
+ ${details ? details.map((d) => `<div class="detail"><strong>${d.label}:</strong> ${d.value}</div>`).join('') : ''}
45
+ <p>${message}</p>
46
+ ${autoClose ? '<p>This window will close automatically in 3 seconds...</p>' : ''}
47
+ <button class="close-btn" onclick="window.close()">${autoClose ? 'Close Now' : 'Close Window'}</button>
48
+ </div>
49
+ </body>
50
+ </html>
51
+ `;
52
+ };
53
+ const normalizeQueryParam = (value) => {
54
+ if (typeof value === 'string') {
55
+ return value;
56
+ }
57
+ if (Array.isArray(value) && value.length > 0) {
58
+ const [first] = value;
59
+ return typeof first === 'string' ? first : undefined;
60
+ }
61
+ return undefined;
62
+ };
63
+ const extractServerNameFromState = (stateValue) => {
64
+ try {
65
+ const normalized = stateValue.replace(/-/g, '+').replace(/_/g, '/');
66
+ const padding = (4 - (normalized.length % 4)) % 4;
67
+ const base64 = normalized + '='.repeat(padding);
68
+ const decoded = Buffer.from(base64, 'base64').toString('utf8');
69
+ const payload = JSON.parse(decoded);
70
+ if (payload && typeof payload.server === 'string') {
71
+ return payload.server;
72
+ }
73
+ }
74
+ catch (error) {
75
+ // Ignore decoding errors and fall back to delimiter-based parsing
76
+ }
77
+ const separatorIndex = stateValue.indexOf(':');
78
+ if (separatorIndex > 0) {
79
+ return stateValue.slice(0, separatorIndex);
80
+ }
81
+ return undefined;
82
+ };
83
+ /**
84
+ * Handle OAuth callback after user authorization
85
+ *
86
+ * This endpoint receives the authorization code from the OAuth provider
87
+ * and initiates the server reconnection process.
88
+ *
89
+ * Expected query parameters:
90
+ * - code: Authorization code from OAuth provider
91
+ * - state: Encoded server identifier used for OAuth session validation
92
+ * - error: Optional error code if authorization failed
93
+ * - error_description: Optional error description
94
+ */
95
+ export const handleOAuthCallback = async (req, res) => {
96
+ try {
97
+ const { code, state, error, error_description } = req.query;
98
+ const codeParam = normalizeQueryParam(code);
99
+ const stateParam = normalizeQueryParam(state);
100
+ // Get translation function from request (set by i18n middleware)
101
+ const t = req.t || ((key) => key);
102
+ // Check for authorization errors
103
+ if (error) {
104
+ console.error(`OAuth authorization failed: ${error} - ${error_description || ''}`);
105
+ return res.status(400).send(generateHtmlResponse('error', t('oauthCallback.authorizationFailed'), '', [
106
+ { label: t('oauthCallback.authorizationFailedError'), value: String(error) },
107
+ ...(error_description
108
+ ? [
109
+ {
110
+ label: t('oauthCallback.authorizationFailedDetails'),
111
+ value: String(error_description),
112
+ },
113
+ ]
114
+ : []),
115
+ ]));
116
+ }
117
+ // Validate required parameters
118
+ if (!stateParam) {
119
+ console.error('OAuth callback missing state parameter');
120
+ return res
121
+ .status(400)
122
+ .send(generateHtmlResponse('error', t('oauthCallback.invalidRequest'), t('oauthCallback.missingStateParameter')));
123
+ }
124
+ if (!codeParam) {
125
+ console.error('OAuth callback missing authorization code');
126
+ return res
127
+ .status(400)
128
+ .send(generateHtmlResponse('error', t('oauthCallback.invalidRequest'), t('oauthCallback.missingCodeParameter')));
129
+ }
130
+ console.log(`OAuth callback received - code: present, state: ${stateParam}`);
131
+ // Find server by state parameter
132
+ let serverInfo;
133
+ serverInfo = getServerByOAuthState(stateParam);
134
+ let decodedServerName;
135
+ if (!serverInfo) {
136
+ decodedServerName = extractServerNameFromState(stateParam);
137
+ if (decodedServerName) {
138
+ console.log(`State lookup failed; decoding server name from state: ${decodedServerName}`);
139
+ serverInfo = getServerByName(decodedServerName);
140
+ }
141
+ }
142
+ if (!serverInfo) {
143
+ console.error(`No server found for OAuth callback. State: ${stateParam}${decodedServerName ? `, decoded server: ${decodedServerName}` : ''}`);
144
+ return res
145
+ .status(400)
146
+ .send(generateHtmlResponse('error', t('oauthCallback.serverNotFound'), `${t('oauthCallback.serverNotFoundMessage')}\n${t('oauthCallback.sessionExpiredMessage')}`));
147
+ }
148
+ // Optional: Validate state parameter for additional security
149
+ if (serverInfo.oauth?.state && serverInfo.oauth.state !== stateParam) {
150
+ console.warn(`State mismatch for server ${serverInfo.name}. Expected: ${serverInfo.oauth.state}, Got: ${stateParam}`);
151
+ // Note: We log a warning but don't fail the request since we have server name as primary identifier
152
+ }
153
+ console.log(`Processing OAuth callback for server: ${serverInfo.name}`);
154
+ // For StreamableHTTPClientTransport, we need to call finishAuth() on the transport
155
+ // This will exchange the authorization code for tokens automatically
156
+ if (serverInfo.transport && 'finishAuth' in serverInfo.transport) {
157
+ try {
158
+ console.log(`Calling transport.finishAuth() for server: ${serverInfo.name}`);
159
+ const currentTransport = serverInfo.transport;
160
+ await currentTransport.finishAuth(codeParam);
161
+ console.log(`Successfully exchanged authorization code for tokens: ${serverInfo.name}`);
162
+ // Refresh server configuration from disk to ensure we pick up newly saved tokens
163
+ const settings = loadSettings();
164
+ const storedConfig = settings.mcpServers?.[serverInfo.name];
165
+ const effectiveConfig = storedConfig || serverInfo.config;
166
+ if (!effectiveConfig) {
167
+ throw new Error(`Missing server configuration for ${serverInfo.name} after OAuth callback`);
168
+ }
169
+ // Keep latest configuration cached on serverInfo
170
+ serverInfo.config = effectiveConfig;
171
+ // Ensure we have up-to-date request options for the reconnect attempt
172
+ if (!serverInfo.options) {
173
+ const requestConfig = effectiveConfig.options || {};
174
+ serverInfo.options = {
175
+ timeout: requestConfig.timeout || 60000,
176
+ resetTimeoutOnProgress: requestConfig.resetTimeoutOnProgress || false,
177
+ maxTotalTimeout: requestConfig.maxTotalTimeout,
178
+ };
179
+ }
180
+ // Replace the existing transport instance to avoid reusing a closed/aborted transport
181
+ try {
182
+ if (serverInfo.transport && 'close' in serverInfo.transport) {
183
+ await serverInfo.transport.close();
184
+ }
185
+ }
186
+ catch (closeError) {
187
+ console.warn(`Failed to close existing transport for ${serverInfo.name}:`, closeError);
188
+ }
189
+ console.log(`Rebuilding transport with refreshed credentials for server: ${serverInfo.name}`);
190
+ const refreshedTransport = await createTransportFromConfig(serverInfo.name, effectiveConfig);
191
+ serverInfo.transport = refreshedTransport;
192
+ // Update server status to indicate OAuth is complete
193
+ serverInfo.status = 'connected';
194
+ if (serverInfo.oauth) {
195
+ serverInfo.oauth.authorizationUrl = undefined;
196
+ serverInfo.oauth.state = undefined;
197
+ serverInfo.oauth.codeVerifier = undefined;
198
+ }
199
+ // Check if client needs to be connected
200
+ const isClientConnected = serverInfo.client && serverInfo.client.getServerCapabilities();
201
+ if (!isClientConnected) {
202
+ // Client is not connected yet, connect it
203
+ if (serverInfo.client && serverInfo.transport) {
204
+ console.log(`Connecting client with refreshed transport for: ${serverInfo.name}`);
205
+ try {
206
+ await serverInfo.client.connect(serverInfo.transport, serverInfo.options);
207
+ console.log(`Client connected successfully for: ${serverInfo.name}`);
208
+ // List tools after successful connection
209
+ const capabilities = serverInfo.client.getServerCapabilities();
210
+ console.log(`Server capabilities for ${serverInfo.name}:`, JSON.stringify(capabilities));
211
+ if (capabilities?.tools) {
212
+ console.log(`Listing tools for server: ${serverInfo.name}`);
213
+ const toolsResult = await serverInfo.client.listTools({}, serverInfo.options);
214
+ const separator = getNameSeparator();
215
+ serverInfo.tools = toolsResult.tools.map((tool) => ({
216
+ name: `${serverInfo.name}${separator}${tool.name}`,
217
+ description: tool.description || '',
218
+ inputSchema: tool.inputSchema || {},
219
+ }));
220
+ console.log(`Listed ${serverInfo.tools.length} tools for server: ${serverInfo.name}`);
221
+ }
222
+ else {
223
+ console.log(`Server ${serverInfo.name} does not support tools capability`);
224
+ }
225
+ }
226
+ catch (connectError) {
227
+ console.error(`Error connecting client for ${serverInfo.name}:`, connectError);
228
+ if (connectError instanceof Error) {
229
+ console.error(`Connect error details for ${serverInfo.name}: ${connectError.message}`, connectError.stack);
230
+ }
231
+ // Even if connection fails, mark OAuth as complete
232
+ // The user can try reconnecting from the dashboard
233
+ }
234
+ }
235
+ else {
236
+ console.log(`Cannot connect client for ${serverInfo.name}: client or transport missing`);
237
+ }
238
+ }
239
+ else {
240
+ console.log(`Client already connected for server: ${serverInfo.name}`);
241
+ }
242
+ console.log(`Successfully completed OAuth flow for server: ${serverInfo.name}`);
243
+ // Return success page
244
+ return res.status(200).send(generateHtmlResponse('success', t('oauthCallback.authorizationSuccessful'), `${t('oauthCallback.successMessage')}\n${t('oauthCallback.autoCloseMessage')}`, [
245
+ { label: t('oauthCallback.server'), value: serverInfo.name },
246
+ { label: t('oauthCallback.status'), value: t('oauthCallback.connected') },
247
+ ], true));
248
+ }
249
+ catch (error) {
250
+ console.error(`Failed to complete OAuth flow for server ${serverInfo.name}:`, error);
251
+ console.error(`Error type: ${typeof error}, Error name: ${error?.constructor?.name}`);
252
+ console.error(`Error message: ${error instanceof Error ? error.message : String(error)}`);
253
+ console.error(`Error stack:`, error instanceof Error ? error.stack : 'No stack trace');
254
+ return res
255
+ .status(500)
256
+ .send(generateHtmlResponse('error', t('oauthCallback.connectionError'), `${t('oauthCallback.connectionErrorMessage')}\n${t('oauthCallback.reconnectMessage')}`, [{ label: '', value: error instanceof Error ? error.message : String(error) }]));
257
+ }
258
+ }
259
+ else {
260
+ // No transport available or transport doesn't support finishAuth
261
+ console.error(`Transport for server ${serverInfo.name} does not support finishAuth()`);
262
+ return res
263
+ .status(500)
264
+ .send(generateHtmlResponse('error', t('oauthCallback.configurationError'), t('oauthCallback.configurationErrorMessage')));
265
+ }
266
+ }
267
+ catch (error) {
268
+ console.error('Unexpected error handling OAuth callback:', error);
269
+ // Get translation function from request (set by i18n middleware)
270
+ const t = req.t || ((key) => key);
271
+ return res
272
+ .status(500)
273
+ .send(generateHtmlResponse('error', t('oauthCallback.internalError'), t('oauthCallback.internalErrorMessage')));
274
+ }
275
+ };
276
+ //# sourceMappingURL=oauthCallbackController.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauthCallbackController.js","sourceRoot":"","sources":["../../src/controllers/oauthCallbackController.ts"],"names":[],"mappings":"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"}