ssh-mcp-pro 1.4.3 → 1.6.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 (125) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/MIGRATION.md +1 -1
  3. package/README.md +1 -1
  4. package/dist/agent-bin.js +2 -2
  5. package/dist/agent-bin.js.map +1 -1
  6. package/dist/mcp.d.ts +1 -1
  7. package/dist/mcp.js +1 -1
  8. package/dist/remote/action-record-sanitize.d.ts +4 -0
  9. package/dist/remote/action-record-sanitize.d.ts.map +1 -0
  10. package/dist/remote/action-record-sanitize.js +11 -0
  11. package/dist/remote/action-record-sanitize.js.map +1 -0
  12. package/dist/remote/agent-bounded-io.d.ts +30 -0
  13. package/dist/remote/agent-bounded-io.d.ts.map +1 -0
  14. package/dist/remote/agent-bounded-io.js +135 -0
  15. package/dist/remote/agent-bounded-io.js.map +1 -0
  16. package/dist/remote/agent-browser-enrollment.d.ts +16 -0
  17. package/dist/remote/agent-browser-enrollment.d.ts.map +1 -0
  18. package/dist/remote/agent-browser-enrollment.js +190 -0
  19. package/dist/remote/agent-browser-enrollment.js.map +1 -0
  20. package/dist/remote/agent-cli.d.ts +5 -0
  21. package/dist/remote/agent-cli.d.ts.map +1 -1
  22. package/dist/remote/agent-cli.js +91 -14
  23. package/dist/remote/agent-cli.js.map +1 -1
  24. package/dist/remote/agent-content-search.d.ts +20 -0
  25. package/dist/remote/agent-content-search.d.ts.map +1 -0
  26. package/dist/remote/agent-content-search.js +61 -0
  27. package/dist/remote/agent-content-search.js.map +1 -0
  28. package/dist/remote/agent-enrollment.d.ts +12 -0
  29. package/dist/remote/agent-enrollment.d.ts.map +1 -0
  30. package/dist/remote/agent-enrollment.js +87 -0
  31. package/dist/remote/agent-enrollment.js.map +1 -0
  32. package/dist/remote/agent-executor.d.ts +5 -0
  33. package/dist/remote/agent-executor.d.ts.map +1 -1
  34. package/dist/remote/agent-executor.js +96 -107
  35. package/dist/remote/agent-executor.js.map +1 -1
  36. package/dist/remote/agent-file-search.d.ts +22 -0
  37. package/dist/remote/agent-file-search.d.ts.map +1 -0
  38. package/dist/remote/agent-file-search.js +243 -0
  39. package/dist/remote/agent-file-search.js.map +1 -0
  40. package/dist/remote/agent-managed-process.d.ts +43 -0
  41. package/dist/remote/agent-managed-process.d.ts.map +1 -0
  42. package/dist/remote/agent-managed-process.js +291 -0
  43. package/dist/remote/agent-managed-process.js.map +1 -0
  44. package/dist/remote/control-plane.d.ts +3 -2
  45. package/dist/remote/control-plane.d.ts.map +1 -1
  46. package/dist/remote/control-plane.js +24 -80
  47. package/dist/remote/control-plane.js.map +1 -1
  48. package/dist/remote/dashboard-enrollment-commands.d.ts +8 -0
  49. package/dist/remote/dashboard-enrollment-commands.d.ts.map +1 -0
  50. package/dist/remote/dashboard-enrollment-commands.js +23 -0
  51. package/dist/remote/dashboard-enrollment-commands.js.map +1 -0
  52. package/dist/remote/dashboard-enrollment-feedback-script.d.ts +3 -0
  53. package/dist/remote/dashboard-enrollment-feedback-script.d.ts.map +1 -0
  54. package/dist/remote/dashboard-enrollment-feedback-script.js +227 -0
  55. package/dist/remote/dashboard-enrollment-feedback-script.js.map +1 -0
  56. package/dist/remote/mcp-tools.d.ts +1 -0
  57. package/dist/remote/mcp-tools.d.ts.map +1 -1
  58. package/dist/remote/mcp-tools.js +207 -3
  59. package/dist/remote/mcp-tools.js.map +1 -1
  60. package/dist/remote/oauth-handler.d.ts +5 -0
  61. package/dist/remote/oauth-handler.d.ts.map +1 -1
  62. package/dist/remote/oauth-handler.js +110 -65
  63. package/dist/remote/oauth-handler.js.map +1 -1
  64. package/dist/remote/oauth-provider-exchange.d.ts +11 -0
  65. package/dist/remote/oauth-provider-exchange.d.ts.map +1 -0
  66. package/dist/remote/oauth-provider-exchange.js +73 -0
  67. package/dist/remote/oauth-provider-exchange.js.map +1 -0
  68. package/dist/remote/safe-file.d.ts +19 -1
  69. package/dist/remote/safe-file.d.ts.map +1 -1
  70. package/dist/remote/safe-file.js +77 -3
  71. package/dist/remote/safe-file.js.map +1 -1
  72. package/dist/remote/schemas.d.ts +16 -0
  73. package/dist/remote/schemas.d.ts.map +1 -1
  74. package/dist/remote/schemas.js +1 -0
  75. package/dist/remote/schemas.js.map +1 -1
  76. package/dist/remote/store-schema.d.ts +4 -0
  77. package/dist/remote/store-schema.d.ts.map +1 -0
  78. package/dist/remote/store-schema.js +147 -0
  79. package/dist/remote/store-schema.js.map +1 -0
  80. package/dist/remote/store.d.ts +9 -5
  81. package/dist/remote/store.d.ts.map +1 -1
  82. package/dist/remote/store.js +96 -133
  83. package/dist/remote/store.js.map +1 -1
  84. package/dist/remote/types.d.ts +16 -2
  85. package/dist/remote/types.d.ts.map +1 -1
  86. package/dist/remote/types.js +15 -0
  87. package/dist/remote/types.js.map +1 -1
  88. package/dist/remote/web-dashboard-html.d.ts.map +1 -1
  89. package/dist/remote/web-dashboard-html.js +25 -27
  90. package/dist/remote/web-dashboard-html.js.map +1 -1
  91. package/dist/remote/web-dashboard-oauth-users.d.ts.map +1 -1
  92. package/dist/remote/web-dashboard-oauth-users.js +4 -38
  93. package/dist/remote/web-dashboard-oauth-users.js.map +1 -1
  94. package/dist/remote/web-dashboard-styles.d.ts +1 -1
  95. package/dist/remote/web-dashboard-styles.d.ts.map +1 -1
  96. package/dist/remote/web-dashboard-styles.js +2 -0
  97. package/dist/remote/web-dashboard-styles.js.map +1 -1
  98. package/dist/remote/web-dashboard.d.ts +0 -2
  99. package/dist/remote/web-dashboard.d.ts.map +1 -1
  100. package/dist/remote/web-dashboard.js +12 -20
  101. package/dist/remote/web-dashboard.js.map +1 -1
  102. package/dist/session-auth-config.d.ts +8 -0
  103. package/dist/session-auth-config.d.ts.map +1 -0
  104. package/dist/session-auth-config.js +67 -0
  105. package/dist/session-auth-config.js.map +1 -0
  106. package/dist/session.d.ts +0 -12
  107. package/dist/session.d.ts.map +1 -1
  108. package/dist/session.js +3 -64
  109. package/dist/session.js.map +1 -1
  110. package/dist/types.d.ts +1 -1
  111. package/docs/adding-a-device.md +187 -11
  112. package/docs/api-overview.md +67 -0
  113. package/docs/backup-restore-verification.md +45 -0
  114. package/docs/coolify.md +9 -0
  115. package/docs/development/local-setup.md +1 -1
  116. package/docs/reference/compatibility.md +1 -1
  117. package/docs/security/hosted-data-inventory.md +3 -1
  118. package/docs/theme/favicon.svg +12 -0
  119. package/docs/theme/ssh-docs.css +670 -0
  120. package/docs/theme/ssh-docs.js +58 -0
  121. package/docs/tutorials/getting-started.md +1 -1
  122. package/mcp.json +1 -1
  123. package/package.json +12 -12
  124. package/registry/ssh-mcp-pro/mcp.json +1 -1
  125. package/server.json +3 -3
@@ -9,6 +9,61 @@ const limitSchema = {
9
9
  maximum: 200,
10
10
  default: 50,
11
11
  };
12
+ // Every hosted MCP tool returns structuredContent. Exposing the actual
13
+ // top-level result shape helps clients validate responses and plan follow-up
14
+ // calls without assuming an arbitrary JSON blob.
15
+ const ACTION_OUTPUT_SCHEMA = {
16
+ type: "object",
17
+ properties: { action: { type: "object" } },
18
+ required: ["action"],
19
+ };
20
+ const REMOTE_OUTPUT_SCHEMAS = {
21
+ list_hosts: {
22
+ type: "object",
23
+ properties: { hosts: { type: "array", items: { type: "object" } } },
24
+ required: ["hosts"],
25
+ },
26
+ list_agents: {
27
+ type: "object",
28
+ properties: { agents: { type: "array", items: { type: "object" } } },
29
+ required: ["agents"],
30
+ },
31
+ create_enrollment_token: {
32
+ type: "object",
33
+ properties: {
34
+ agent_id: { type: "string" },
35
+ alias: { type: "string" },
36
+ commands: { type: "object" },
37
+ enrollment_token: { type: "string" },
38
+ },
39
+ required: ["agent_id", "alias", "commands", "enrollment_token"],
40
+ },
41
+ get_agent_install_command: {
42
+ type: "object",
43
+ properties: {
44
+ agent_id: { type: "string" },
45
+ alias: { type: "string" },
46
+ commands: { type: "object" },
47
+ token_recoverable: { type: "boolean" },
48
+ },
49
+ required: ["agent_id", "alias", "commands", "token_recoverable"],
50
+ },
51
+ update_agent_policy: {
52
+ type: "object",
53
+ properties: { agent: { type: "object" } },
54
+ required: ["agent"],
55
+ },
56
+ revoke_agent: {
57
+ type: "object",
58
+ properties: { agent: { type: "object" } },
59
+ required: ["agent"],
60
+ },
61
+ get_audit_events: {
62
+ type: "object",
63
+ properties: { events: { type: "array", items: { type: "object" } } },
64
+ required: ["events"],
65
+ },
66
+ };
12
67
  const descriptors = {
13
68
  list_hosts: {
14
69
  description: "List enrolled host aliases available through outbound agents.",
@@ -106,12 +161,76 @@ const descriptors = {
106
161
  additionalProperties: false,
107
162
  },
108
163
  },
164
+ file_search: {
165
+ description: "Find file names in locally allowed folders without reading file contents. Optional root_path narrows the search; results and scan depth are bounded.",
166
+ inputSchema: {
167
+ type: "object",
168
+ required: ["agent_id_or_alias", "name_pattern"],
169
+ properties: {
170
+ agent_id_or_alias: agentSelector,
171
+ name_pattern: {
172
+ type: "string",
173
+ minLength: 1,
174
+ maxLength: 100,
175
+ description: "Case-insensitive name fragment or * / ? wildcard pattern; cannot contain directory separators.",
176
+ },
177
+ root_path: {
178
+ type: "string",
179
+ minLength: 1,
180
+ description: "Optional allowed folder. Omit to search all policy-allowed roots.",
181
+ },
182
+ max_depth: { type: "integer", minimum: 0, maximum: 5, default: 3 },
183
+ max_results: { type: "integer", minimum: 1, maximum: 50, default: 20 },
184
+ include_hidden: { type: "boolean", default: false },
185
+ },
186
+ additionalProperties: false,
187
+ },
188
+ },
189
+ file_content_search: {
190
+ description: "Find which allowed text files contain a literal phrase, with the first matching line and short snippet. " +
191
+ "Defaults to all names; optional name_pattern narrows files. Case-insensitive by default. " +
192
+ "Only scans up to 128 text files (128 KiB each); returns truncated when scan/output limits apply.",
193
+ inputSchema: {
194
+ type: "object",
195
+ required: ["agent_id_or_alias", "query"],
196
+ properties: {
197
+ agent_id_or_alias: agentSelector,
198
+ query: {
199
+ type: "string",
200
+ minLength: 1,
201
+ maxLength: 200,
202
+ description: "Single-line literal text to find (not a regex).",
203
+ },
204
+ name_pattern: {
205
+ type: "string",
206
+ minLength: 1,
207
+ maxLength: 100,
208
+ description: "Optional filename fragment or * / ? wildcard; defaults to *.",
209
+ },
210
+ root_path: {
211
+ type: "string",
212
+ minLength: 1,
213
+ description: "Optional allowed folder. Omit to search all locally approved roots.",
214
+ },
215
+ max_depth: { type: "integer", minimum: 0, maximum: 5, default: 3 },
216
+ max_results: { type: "integer", minimum: 1, maximum: 50, default: 20 },
217
+ include_hidden: { type: "boolean", default: false },
218
+ case_sensitive: { type: "boolean", default: false },
219
+ },
220
+ additionalProperties: false,
221
+ },
222
+ },
109
223
  file_read: {
110
- description: "Read a bounded text file from an allowed path.",
224
+ description: "Read an allowed text file; optional byte offsets and limits page large files.",
111
225
  inputSchema: {
112
226
  type: "object",
113
227
  required: ["agent_id_or_alias", "path"],
114
- properties: { agent_id_or_alias: agentSelector, path: { type: "string", minLength: 1 } },
228
+ properties: {
229
+ agent_id_or_alias: agentSelector,
230
+ path: { type: "string", minLength: 1 },
231
+ offset_bytes: { type: "integer", minimum: 0, maximum: 2147483647 },
232
+ max_bytes: { type: "integer", minimum: 4, maximum: 1048576 },
233
+ },
115
234
  additionalProperties: false,
116
235
  },
117
236
  },
@@ -129,6 +248,22 @@ const descriptors = {
129
248
  additionalProperties: false,
130
249
  },
131
250
  },
251
+ file_replace: {
252
+ description: "Preview or apply one exact text replacement in an allowed existing file. Preview first (default); apply requires expected_sha256 from preview. Both files.read and files.write must be granted.",
253
+ inputSchema: {
254
+ type: "object",
255
+ required: ["agent_id_or_alias", "path", "old_text", "new_text"],
256
+ properties: {
257
+ agent_id_or_alias: agentSelector,
258
+ path: { type: "string", minLength: 1 },
259
+ old_text: { type: "string", minLength: 1, maxLength: 20000 },
260
+ new_text: { type: "string", maxLength: 20000 },
261
+ dry_run: { type: "boolean", default: true },
262
+ expected_sha256: { type: "string", pattern: "^[a-f0-9]{64}$" },
263
+ },
264
+ additionalProperties: false,
265
+ },
266
+ },
132
267
  run_shell: {
133
268
  description: "Run a bounded shell command. Disabled unless shell.exec is explicitly granted.",
134
269
  inputSchema: {
@@ -143,6 +278,60 @@ const descriptors = {
143
278
  additionalProperties: false,
144
279
  },
145
280
  },
281
+ process_start: {
282
+ description: "Start a bounded interactive shell process on an enrolled agent. Use process_read to view output and process_stop to cancel. Requires shell.exec.",
283
+ inputSchema: {
284
+ type: "object",
285
+ required: ["agent_id_or_alias", "command"],
286
+ properties: {
287
+ agent_id_or_alias: agentSelector,
288
+ command: { type: "string", minLength: 1, maxLength: 4096 },
289
+ cwd: { type: "string", minLength: 1 },
290
+ max_runtime_seconds: { type: "integer", minimum: 1, maximum: 600, default: 300 },
291
+ },
292
+ additionalProperties: false,
293
+ },
294
+ },
295
+ process_read: {
296
+ description: "Read cursor-paged output and status for a managed shell process owned by the current user.",
297
+ inputSchema: {
298
+ type: "object",
299
+ required: ["agent_id_or_alias", "process_id"],
300
+ properties: {
301
+ agent_id_or_alias: agentSelector,
302
+ process_id: { type: "string", minLength: 1 },
303
+ cursor: { type: "integer", minimum: 0, default: 0 },
304
+ max_bytes: { type: "integer", minimum: 1024, maximum: 32768, default: 8192 },
305
+ },
306
+ additionalProperties: false,
307
+ },
308
+ },
309
+ process_input: {
310
+ description: "Send limited text to stdin of a running shell process owned by the current user.",
311
+ inputSchema: {
312
+ type: "object",
313
+ required: ["agent_id_or_alias", "process_id", "input"],
314
+ properties: {
315
+ agent_id_or_alias: agentSelector,
316
+ process_id: { type: "string", minLength: 1 },
317
+ input: { type: "string", maxLength: 4096 },
318
+ close_stdin: { type: "boolean", default: false },
319
+ },
320
+ additionalProperties: false,
321
+ },
322
+ },
323
+ process_stop: {
324
+ description: "Terminate a managed shell process owned by the current user.",
325
+ inputSchema: {
326
+ type: "object",
327
+ required: ["agent_id_or_alias", "process_id"],
328
+ properties: {
329
+ agent_id_or_alias: agentSelector,
330
+ process_id: { type: "string", minLength: 1 },
331
+ },
332
+ additionalProperties: false,
333
+ },
334
+ },
146
335
  run_shell_as_root: {
147
336
  description: "Run a bounded privileged command. Disabled unless sudo.exec is explicitly granted.",
148
337
  inputSchema: {
@@ -198,13 +387,26 @@ const READ_ONLY_REMOTE_TOOLS = new Set([
198
387
  "tail_logs",
199
388
  "docker_ps",
200
389
  "docker_logs",
390
+ "file_search",
391
+ "file_content_search",
201
392
  "file_read",
393
+ "process_read",
202
394
  "get_audit_events",
203
395
  ]);
396
+ // These hints communicate potential impact to AI clients, not the permission
397
+ // decision. Arbitrary shell commands and administrative enrollment/policy
398
+ // changes can mutate state even when an individual invocation does not.
204
399
  const DESTRUCTIVE_REMOTE_TOOLS = new Set([
400
+ "create_enrollment_token",
401
+ "run_shell",
402
+ "process_start",
403
+ "process_input",
404
+ "process_stop",
205
405
  "run_shell_as_root",
406
+ "update_agent_policy",
206
407
  "revoke_agent",
207
408
  "file_write",
409
+ "file_replace",
208
410
  "restart_service",
209
411
  "docker_restart",
210
412
  ]);
@@ -219,9 +421,11 @@ export function remoteToolAnnotations(name) {
219
421
  }
220
422
  export function listRemoteToolDescriptors(capabilities) {
221
423
  const allowed = new Set(capabilities);
222
- return REMOTE_TOOLS.filter((name) => allowed.has(TOOL_CAPABILITY_MAP[name])).map((name) => ({
424
+ return REMOTE_TOOLS.filter((name) => allowed.has(TOOL_CAPABILITY_MAP[name]) &&
425
+ (name !== "file_replace" || allowed.has("files.read"))).map((name) => ({
223
426
  name,
224
427
  capability: TOOL_CAPABILITY_MAP[name],
428
+ outputSchema: REMOTE_OUTPUT_SCHEMAS[name] ?? ACTION_OUTPUT_SCHEMA,
225
429
  annotations: remoteToolAnnotations(name),
226
430
  ...descriptors[name],
227
431
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-tools.js","sourceRoot":"","sources":["../../src/remote/mcp-tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mcp-tools.js","sourceRoot":"","sources":["../../src/remote/mcp-tools.ts"],"names":[],"mappings":"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"}
@@ -21,6 +21,7 @@ export declare class OAuthHandler {
21
21
  private readonly getJwtKeyPair;
22
22
  private readonly audit;
23
23
  private readonly registrationAttempts;
24
+ private readonly refreshTokenResponseField;
24
25
  private transactionCookie;
25
26
  private matchingBrowser;
26
27
  constructor(config: RemoteConfig, store: RemoteStore, authorizeTransactions: Map<string, PendingAuthorize>, getJwtKeyPair: () => JwtKeyPair, audit: (event: Omit<AuditEvent, "id" | "createdAt">) => void);
@@ -71,8 +72,12 @@ export declare class OAuthHandler {
71
72
  };
72
73
  private isGitHubUserAllowed;
73
74
  private issueAuthorizationCode;
75
+ /** Explicit OAuth revocation; RFC 7009 never reveals token validity. */
76
+ handleRevoke(req: IncomingMessage, res: ServerResponse): Promise<void>;
74
77
  /** POST /oauth/token */
75
78
  handleToken(req: IncomingMessage, res: ServerResponse): Promise<void>;
79
+ /** Rotate a bearer refresh token exactly once; all descendants die on replay. */
80
+ private refreshAccessToken;
76
81
  private userFromId;
77
82
  /** Remove expired pending authorization transactions. */
78
83
  cleanupExpired(now?: number): void;
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-handler.d.ts","sourceRoot":"","sources":["../../src/remote/oauth-handler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"oauth-handler.d.ts","sourceRoot":"","sources":["../../src/remote/oauth-handler.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ import { escape as escapeHtml } from "html-escaper";
2
2
  import { URL } from "node:url";
3
3
  import { hashSecret, id, issueAccessToken, nowIso, publicJwkFromPem, randomToken, } from "./crypto.js";
4
4
  import { asString, asStringArray, addNoStore, isSafeRedirectUri, pkceChallenge, readJson, readJsonOrForm, redirect, safeError, scopeList, } from "./http-util.js";
5
+ import { exchangeGitHubIdentity, exchangeGoogleIdentity } from "./oauth-provider-exchange.js";
5
6
  import { REMOTE_SCOPES } from "./types.js";
6
7
  import { jsonResponse } from "./util.js";
7
8
  /** Handles OAuth 2.0 authorization code flow with PKCE and GitHub identity. */
@@ -12,6 +13,7 @@ export class OAuthHandler {
12
13
  getJwtKeyPair;
13
14
  audit;
14
15
  registrationAttempts = new Map();
16
+ refreshTokenResponseField = "refresh_token";
15
17
  transactionCookie(value) {
16
18
  const secure = this.config.publicBaseUrl.startsWith("https://") ? "; Secure" : "";
17
19
  return `ssh_mcp_oauth_tx=${value}; Path=/oauth; HttpOnly; SameSite=Lax; Max-Age=300${secure}`;
@@ -45,10 +47,11 @@ export class OAuthHandler {
45
47
  authorization_response_iss_parameter_supported: true,
46
48
  authorization_endpoint: `${this.config.publicBaseUrl}/oauth/authorize`,
47
49
  token_endpoint: `${this.config.publicBaseUrl}/oauth/token`,
50
+ revocation_endpoint: `${this.config.publicBaseUrl}/oauth/revoke`,
48
51
  registration_endpoint: `${this.config.publicBaseUrl}/oauth/register`,
49
52
  jwks_uri: `${this.config.publicBaseUrl}/oauth/jwks.json`,
50
53
  response_types_supported: ["code"],
51
- grant_types_supported: ["authorization_code"],
54
+ grant_types_supported: ["authorization_code", "refresh_token"],
52
55
  code_challenge_methods_supported: ["S256"],
53
56
  token_endpoint_auth_methods_supported: ["none"],
54
57
  scopes_supported: REMOTE_SCOPES,
@@ -74,13 +77,22 @@ export class OAuthHandler {
74
77
  if (this.store.countOAuthClients() >= this.config.maxOAuthClients) {
75
78
  throw safeError("FORBIDDEN", "OAuth client registration limit reached", 429);
76
79
  }
80
+ const grantTypes = body.grant_types === undefined
81
+ ? ["authorization_code", "refresh_token"]
82
+ : asStringArray(body.grant_types);
83
+ if ((!Array.isArray(body.grant_types) && body.grant_types !== undefined) ||
84
+ !grantTypes.includes("authorization_code") ||
85
+ grantTypes.some((grant) => !["authorization_code", "refresh_token"].includes(grant)) ||
86
+ new Set(grantTypes).size !== grantTypes.length) {
87
+ throw safeError("INVALID_CLIENT", "Unsupported OAuth grant_types");
88
+ }
77
89
  const now = nowIso();
78
90
  const client = {
79
91
  id: id("clirow"),
80
92
  clientId: id("cli"),
81
93
  clientName: asString(body.client_name) ?? "ChatGPT Connector",
82
94
  redirectUris,
83
- grantTypes: ["authorization_code"],
95
+ grantTypes,
84
96
  responseTypes: ["code"],
85
97
  tokenEndpointAuthMethod: "none",
86
98
  createdAt: now,
@@ -315,7 +327,7 @@ export class OAuthHandler {
315
327
  clientId,
316
328
  clientName: "Restored ChatGPT Connector",
317
329
  redirectUris: [redirectUri],
318
- grantTypes: ["authorization_code"],
330
+ grantTypes: ["authorization_code", "refresh_token"],
319
331
  responseTypes: ["code"],
320
332
  tokenEndpointAuthMethod: "none",
321
333
  createdAt: nowIso(),
@@ -390,40 +402,9 @@ export class OAuthHandler {
390
402
  }
391
403
  async fetchGoogleUser(code) {
392
404
  const testUser = this.testGoogleUser();
393
- if (testUser) {
405
+ if (testUser)
394
406
  return testUser;
395
- }
396
- if (!this.config.googleClientId || !this.config.googleClientSecret) {
397
- throw safeError("FORBIDDEN", "Google OAuth is not configured", 503);
398
- }
399
- const tokenResponse = await fetch("https://oauth2.googleapis.com/token", {
400
- method: "POST",
401
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
402
- body: new URLSearchParams({
403
- code,
404
- client_id: this.config.googleClientId,
405
- client_secret: this.config.googleClientSecret,
406
- redirect_uri: this.config.googleCallbackUrl,
407
- grant_type: "authorization_code",
408
- }).toString(),
409
- });
410
- const tokenPayload = (await tokenResponse.json());
411
- const accessToken = asString(tokenPayload.access_token);
412
- if (!accessToken) {
413
- throw safeError("INVALID_TOKEN", "Google OAuth token exchange failed", 502);
414
- }
415
- const userResponse = await fetch("https://openidconnect.googleapis.com/v1/userinfo", {
416
- headers: { Authorization: `Bearer ${accessToken}` },
417
- });
418
- const userPayload = (await userResponse.json());
419
- const googleSub = asString(userPayload.sub);
420
- const email = asString(userPayload.email);
421
- const name = asString(userPayload.name) ?? email ?? "Google User";
422
- const picture = asString(userPayload.picture);
423
- if (!googleSub || !email) {
424
- throw safeError("INVALID_TOKEN", "Google OAuth user response missing valid identity", 502);
425
- }
426
- return { id: googleSub, email, name, picture };
407
+ return exchangeGoogleIdentity(this.config, code);
427
408
  }
428
409
  /** Fixture identities must never bypass provider login on public-facing hosts. */
429
410
  allowFixtureIdentity() {
@@ -472,35 +453,7 @@ export class OAuthHandler {
472
453
  this.config.allowedGoogleEmails.includes(user.email));
473
454
  }
474
455
  async fetchGitHubUser(code) {
475
- const tokenResponse = await fetch("https://github.com/login/oauth/access_token", {
476
- method: "POST",
477
- headers: { Accept: "application/json", "Content-Type": "application/json" },
478
- body: JSON.stringify({
479
- client_id: this.config.githubClientId,
480
- client_secret: this.config.githubClientSecret,
481
- code,
482
- redirect_uri: this.config.githubCallbackUrl,
483
- }),
484
- });
485
- const tokenPayload = (await tokenResponse.json());
486
- const accessToken = asString(tokenPayload.access_token);
487
- if (!accessToken) {
488
- throw safeError("INVALID_TOKEN", "GitHub OAuth token exchange failed", 502);
489
- }
490
- const userResponse = await fetch("https://api.github.com/user", {
491
- headers: { Authorization: `Bearer ${accessToken}`, Accept: "application/vnd.github+json" },
492
- });
493
- const userPayload = (await userResponse.json());
494
- const githubId = userPayload.id;
495
- const githubLogin = userPayload.login;
496
- if (typeof githubId !== "number" ||
497
- !Number.isSafeInteger(githubId) ||
498
- githubId <= 0 ||
499
- typeof githubLogin !== "string" ||
500
- !githubLogin) {
501
- throw safeError("INVALID_TOKEN", "GitHub OAuth user response missing valid identity", 502);
502
- }
503
- return { id: String(githubId), login: githubLogin };
456
+ return exchangeGitHubIdentity(this.config, code);
504
457
  }
505
458
  testGitHubUser() {
506
459
  if (!this.allowFixtureIdentity())
@@ -548,9 +501,24 @@ export class OAuthHandler {
548
501
  this.store.insertAuthorizationCode(record);
549
502
  return code;
550
503
  }
504
+ /** Explicit OAuth revocation; RFC 7009 never reveals token validity. */
505
+ async handleRevoke(req, res) {
506
+ const body = await readJsonOrForm(req);
507
+ const token = body.token ?? "";
508
+ const clientId = body.client_id ?? "";
509
+ if (/^[a-zA-Z0-9_-]{32,128}$/u.test(token) && clientId) {
510
+ this.store.revokeRefreshFamily(hashSecret(token), clientId, nowIso());
511
+ }
512
+ res.writeHead(200, { "Cache-Control": "no-store", Pragma: "no-cache" });
513
+ res.end();
514
+ }
551
515
  /** POST /oauth/token */
552
516
  async handleToken(req, res) {
553
517
  const body = await readJsonOrForm(req);
518
+ if (body.grant_type === "refresh_token") {
519
+ await this.refreshAccessToken(res, body);
520
+ return;
521
+ }
554
522
  if (body.grant_type !== "authorization_code") {
555
523
  throw safeError("INVALID_CLIENT", "grant_type must be authorization_code");
556
524
  }
@@ -582,8 +550,85 @@ export class OAuthHandler {
582
550
  throw safeError("INVALID_TOKEN", "Authorization code is expired or already used");
583
551
  }
584
552
  const token = await issueAccessToken(this.config, jwtKeyPair, user, scopes);
553
+ const refreshToken = client.grantTypes.includes("refresh_token") ? randomToken(32) : undefined;
554
+ if (refreshToken) {
555
+ this.store.createRefreshToken({
556
+ tokenHash: hashSecret(refreshToken),
557
+ familyId: id("refreshfam"),
558
+ clientId,
559
+ userId: codeRecord.userId,
560
+ resource: codeRecord.resource,
561
+ scope: scopes.join(" "),
562
+ expiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(),
563
+ createdAt: nowIso(),
564
+ });
565
+ }
566
+ jsonResponse(res, 200, {
567
+ access_token: token.token,
568
+ ...(refreshToken ? { refresh_token: refreshToken } : {}),
569
+ token_type: "Bearer",
570
+ expires_in: this.config.accessTokenTtlSeconds,
571
+ scope: scopes.join(" "),
572
+ }, addNoStore());
573
+ }
574
+ /** Rotate a bearer refresh token exactly once; all descendants die on replay. */
575
+ async refreshAccessToken(res, body) {
576
+ const clientId = body.client_id ?? "";
577
+ const raw = body.refresh_token ?? "";
578
+ const client = this.store.getClient(clientId);
579
+ const invalidGrant = () => jsonResponse(res, 400, { error: "invalid_grant" }, addNoStore());
580
+ if (!client ||
581
+ !client.grantTypes.includes("refresh_token") ||
582
+ !/^[a-zA-Z0-9_-]{32,128}$/u.test(raw)) {
583
+ invalidGrant();
584
+ return;
585
+ }
586
+ const old = this.store.getRefreshTokenByHash(hashSecret(raw));
587
+ if (!old) {
588
+ invalidGrant();
589
+ return;
590
+ }
591
+ if (old.clientId !== clientId || old.resource !== this.config.mcpResourceUrl) {
592
+ invalidGrant();
593
+ return;
594
+ }
595
+ const now = nowIso();
596
+ if (old.expiresAt <= now || old.revokedAt) {
597
+ invalidGrant();
598
+ return;
599
+ }
600
+ const user = this.userFromId(old.userId);
601
+ if ((user.githubId &&
602
+ !this.isGitHubUserAllowed({ id: user.githubId, login: user.githubLogin ?? "" })) ||
603
+ (user.googleId &&
604
+ !this.isGoogleUserAllowed({
605
+ id: user.googleId,
606
+ email: user.email ?? "",
607
+ name: user.displayName ?? "",
608
+ }))) {
609
+ invalidGrant();
610
+ return;
611
+ }
612
+ const scopes = scopeList(old.scope);
613
+ const token = await issueAccessToken(this.config, this.getJwtKeyPair(), user, scopes);
614
+ const newRaw = randomToken(32);
615
+ const successor = {
616
+ tokenHash: hashSecret(newRaw),
617
+ familyId: old.familyId,
618
+ clientId: old.clientId,
619
+ userId: old.userId,
620
+ resource: old.resource,
621
+ scope: old.scope,
622
+ expiresAt: old.expiresAt,
623
+ createdAt: now,
624
+ };
625
+ if (!this.store.rotateRefreshToken(old.tokenHash, clientId, successor, now)) {
626
+ invalidGrant();
627
+ return;
628
+ }
585
629
  jsonResponse(res, 200, {
586
630
  access_token: token.token,
631
+ [this.refreshTokenResponseField]: newRaw,
587
632
  token_type: "Bearer",
588
633
  expires_in: this.config.accessTokenTtlSeconds,
589
634
  scope: scopes.join(" "),