ssh-mcp-pro 1.2.1 → 1.4.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 (214) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/README.md +12 -2
  3. package/dist/agent-bin.js +5 -2
  4. package/dist/agent-bin.js.map +1 -1
  5. package/dist/cli.d.ts +1 -0
  6. package/dist/cli.d.ts.map +1 -1
  7. package/dist/cli.js +38 -47
  8. package/dist/cli.js.map +1 -1
  9. package/dist/config-security-env.d.ts +4 -0
  10. package/dist/config-security-env.d.ts.map +1 -0
  11. package/dist/config-security-env.js +64 -0
  12. package/dist/config-security-env.js.map +1 -0
  13. package/dist/config.d.ts +2 -2
  14. package/dist/config.d.ts.map +1 -1
  15. package/dist/config.js +4 -67
  16. package/dist/config.js.map +1 -1
  17. package/dist/connector-profile.d.ts +17 -3
  18. package/dist/connector-profile.d.ts.map +1 -1
  19. package/dist/connector-profile.js.map +1 -1
  20. package/dist/detect.d.ts.map +1 -1
  21. package/dist/detect.js +226 -192
  22. package/dist/detect.js.map +1 -1
  23. package/dist/ensure-package-service.d.ts +9 -0
  24. package/dist/ensure-package-service.d.ts.map +1 -0
  25. package/dist/ensure-package-service.js +146 -0
  26. package/dist/ensure-package-service.js.map +1 -0
  27. package/dist/ensure-pkg.js +4 -4
  28. package/dist/ensure-pkg.js.map +1 -1
  29. package/dist/ensure.d.ts.map +1 -1
  30. package/dist/ensure.js +15 -144
  31. package/dist/ensure.js.map +1 -1
  32. package/dist/fs-sftp.js +1 -1
  33. package/dist/fs-sftp.js.map +1 -1
  34. package/dist/fs-stat.d.ts +10 -0
  35. package/dist/fs-stat.d.ts.map +1 -0
  36. package/dist/fs-stat.js +62 -0
  37. package/dist/fs-stat.js.map +1 -0
  38. package/dist/fs-tools.d.ts.map +1 -1
  39. package/dist/fs-tools.js +6 -58
  40. package/dist/fs-tools.js.map +1 -1
  41. package/dist/http-security.d.ts.map +1 -1
  42. package/dist/http-security.js +6 -6
  43. package/dist/http-security.js.map +1 -1
  44. package/dist/http-server-runtime.d.ts.map +1 -1
  45. package/dist/http-server-runtime.js +41 -7
  46. package/dist/http-server-runtime.js.map +1 -1
  47. package/dist/index.js +6 -23
  48. package/dist/index.js.map +1 -1
  49. package/dist/mcp-http-web.d.ts +8 -0
  50. package/dist/mcp-http-web.d.ts.map +1 -0
  51. package/dist/mcp-http-web.js +35 -0
  52. package/dist/mcp-http-web.js.map +1 -0
  53. package/dist/mcp.d.ts +6 -2
  54. package/dist/mcp.d.ts.map +1 -1
  55. package/dist/mcp.js +22 -14
  56. package/dist/mcp.js.map +1 -1
  57. package/dist/policy.d.ts +8 -0
  58. package/dist/policy.d.ts.map +1 -1
  59. package/dist/policy.js +147 -105
  60. package/dist/policy.js.map +1 -1
  61. package/dist/process.d.ts.map +1 -1
  62. package/dist/process.js +11 -7
  63. package/dist/process.js.map +1 -1
  64. package/dist/prompts.d.ts +2 -11
  65. package/dist/prompts.d.ts.map +1 -1
  66. package/dist/prompts.js.map +1 -1
  67. package/dist/remote/agent-activity-log.d.ts +26 -0
  68. package/dist/remote/agent-activity-log.d.ts.map +1 -0
  69. package/dist/remote/agent-activity-log.js +211 -0
  70. package/dist/remote/agent-activity-log.js.map +1 -0
  71. package/dist/remote/agent-cli.d.ts.map +1 -1
  72. package/dist/remote/agent-cli.js +92 -25
  73. package/dist/remote/agent-cli.js.map +1 -1
  74. package/dist/remote/agent-executor.d.ts.map +1 -1
  75. package/dist/remote/agent-executor.js +25 -16
  76. package/dist/remote/agent-executor.js.map +1 -1
  77. package/dist/remote/agent-handler.d.ts +2 -0
  78. package/dist/remote/agent-handler.d.ts.map +1 -1
  79. package/dist/remote/agent-handler.js +4 -0
  80. package/dist/remote/agent-handler.js.map +1 -1
  81. package/dist/remote/config.d.ts.map +1 -1
  82. package/dist/remote/config.js +12 -1
  83. package/dist/remote/config.js.map +1 -1
  84. package/dist/remote/control-plane.d.ts +12 -0
  85. package/dist/remote/control-plane.d.ts.map +1 -1
  86. package/dist/remote/control-plane.js +174 -53
  87. package/dist/remote/control-plane.js.map +1 -1
  88. package/dist/remote/crypto.d.ts +9 -4
  89. package/dist/remote/crypto.d.ts.map +1 -1
  90. package/dist/remote/crypto.js +41 -9
  91. package/dist/remote/crypto.js.map +1 -1
  92. package/dist/remote/http-util.d.ts.map +1 -1
  93. package/dist/remote/http-util.js +14 -7
  94. package/dist/remote/http-util.js.map +1 -1
  95. package/dist/remote/mcp-tools.d.ts +7 -0
  96. package/dist/remote/mcp-tools.d.ts.map +1 -1
  97. package/dist/remote/mcp-tools.js +28 -0
  98. package/dist/remote/mcp-tools.js.map +1 -1
  99. package/dist/remote/oauth-handler.d.ts +36 -3
  100. package/dist/remote/oauth-handler.d.ts.map +1 -1
  101. package/dist/remote/oauth-handler.js +287 -13
  102. package/dist/remote/oauth-handler.js.map +1 -1
  103. package/dist/remote/policy.js +2 -2
  104. package/dist/remote/policy.js.map +1 -1
  105. package/dist/remote/safe-file.d.ts +2 -1
  106. package/dist/remote/safe-file.d.ts.map +1 -1
  107. package/dist/remote/safe-file.js +51 -53
  108. package/dist/remote/safe-file.js.map +1 -1
  109. package/dist/remote/schemas.d.ts +9 -9
  110. package/dist/remote/schemas.js +6 -6
  111. package/dist/remote/schemas.js.map +1 -1
  112. package/dist/remote/store.d.ts +38 -1
  113. package/dist/remote/store.d.ts.map +1 -1
  114. package/dist/remote/store.js +149 -11
  115. package/dist/remote/store.js.map +1 -1
  116. package/dist/remote/types.d.ts +14 -0
  117. package/dist/remote/types.d.ts.map +1 -1
  118. package/dist/remote/types.js.map +1 -1
  119. package/dist/remote/web-dashboard-client-config.d.ts +77 -0
  120. package/dist/remote/web-dashboard-client-config.d.ts.map +1 -0
  121. package/dist/remote/web-dashboard-client-config.js +81 -0
  122. package/dist/remote/web-dashboard-client-config.js.map +1 -0
  123. package/dist/remote/web-dashboard-html.d.ts +2 -0
  124. package/dist/remote/web-dashboard-html.d.ts.map +1 -0
  125. package/dist/remote/web-dashboard-html.js +433 -0
  126. package/dist/remote/web-dashboard-html.js.map +1 -0
  127. package/dist/remote/web-dashboard-oauth-users.d.ts +4 -0
  128. package/dist/remote/web-dashboard-oauth-users.d.ts.map +1 -0
  129. package/dist/remote/web-dashboard-oauth-users.js +78 -0
  130. package/dist/remote/web-dashboard-oauth-users.js.map +1 -0
  131. package/dist/remote/web-dashboard-static.d.ts +4 -0
  132. package/dist/remote/web-dashboard-static.d.ts.map +1 -0
  133. package/dist/remote/web-dashboard-static.js +19 -0
  134. package/dist/remote/web-dashboard-static.js.map +1 -0
  135. package/dist/remote/web-dashboard-styles.d.ts +2 -0
  136. package/dist/remote/web-dashboard-styles.d.ts.map +1 -0
  137. package/dist/remote/web-dashboard-styles.js +187 -0
  138. package/dist/remote/web-dashboard-styles.js.map +1 -0
  139. package/dist/remote/web-dashboard.d.ts +62 -0
  140. package/dist/remote/web-dashboard.d.ts.map +1 -0
  141. package/dist/remote/web-dashboard.js +467 -0
  142. package/dist/remote/web-dashboard.js.map +1 -0
  143. package/dist/resources.d.ts +2 -7
  144. package/dist/resources.d.ts.map +1 -1
  145. package/dist/resources.js.map +1 -1
  146. package/dist/retry.d.ts.map +1 -1
  147. package/dist/retry.js +6 -3
  148. package/dist/retry.js.map +1 -1
  149. package/dist/safety.d.ts.map +1 -1
  150. package/dist/safety.js +56 -6
  151. package/dist/safety.js.map +1 -1
  152. package/dist/session-auth.js +7 -7
  153. package/dist/session-auth.js.map +1 -1
  154. package/dist/session.d.ts +5 -0
  155. package/dist/session.d.ts.map +1 -1
  156. package/dist/session.js +81 -54
  157. package/dist/session.js.map +1 -1
  158. package/dist/shell.d.ts.map +1 -1
  159. package/dist/shell.js +5 -4
  160. package/dist/shell.js.map +1 -1
  161. package/dist/ssh-config.d.ts +2 -2
  162. package/dist/ssh-config.d.ts.map +1 -1
  163. package/dist/ssh-config.js +24 -20
  164. package/dist/ssh-config.js.map +1 -1
  165. package/dist/telemetry.d.ts.map +1 -1
  166. package/dist/telemetry.js +9 -2
  167. package/dist/telemetry.js.map +1 -1
  168. package/dist/tools/connector.provider.d.ts +1 -1
  169. package/dist/tools/connector.provider.d.ts.map +1 -1
  170. package/dist/tools/ensure.provider.d.ts +1 -1
  171. package/dist/tools/ensure.provider.d.ts.map +1 -1
  172. package/dist/tools/fs.provider.d.ts +1 -1
  173. package/dist/tools/fs.provider.d.ts.map +1 -1
  174. package/dist/tools/metadata.d.ts +1 -1
  175. package/dist/tools/metadata.d.ts.map +1 -1
  176. package/dist/tools/output-schemas.d.ts +27 -135
  177. package/dist/tools/output-schemas.d.ts.map +1 -1
  178. package/dist/tools/process.provider.d.ts +1 -1
  179. package/dist/tools/process.provider.d.ts.map +1 -1
  180. package/dist/tools/registry.d.ts +1 -1
  181. package/dist/tools/registry.d.ts.map +1 -1
  182. package/dist/tools/registry.js +16 -13
  183. package/dist/tools/registry.js.map +1 -1
  184. package/dist/tools/session.provider.d.ts +1 -1
  185. package/dist/tools/session.provider.d.ts.map +1 -1
  186. package/dist/tools/system.provider.d.ts +1 -1
  187. package/dist/tools/system.provider.d.ts.map +1 -1
  188. package/dist/tools/transfer.provider.d.ts +1 -1
  189. package/dist/tools/transfer.provider.d.ts.map +1 -1
  190. package/dist/tools/tunnel.provider.d.ts +1 -1
  191. package/dist/tools/tunnel.provider.d.ts.map +1 -1
  192. package/dist/tools/types.d.ts +1 -1
  193. package/dist/tools/types.d.ts.map +1 -1
  194. package/dist/transfer.js +2 -2
  195. package/dist/transfer.js.map +1 -1
  196. package/dist/types.js +1 -1
  197. package/dist/types.js.map +1 -1
  198. package/docs/adding-a-device.md +39 -17
  199. package/docs/agent-activity-monitor.md +34 -0
  200. package/docs/coolify.md +29 -0
  201. package/docs/development/coding-standards.md +8 -2
  202. package/docs/development/dependency-management.md +1 -1
  203. package/docs/development/mcp-protocol-2026.md +33 -0
  204. package/docs/development/release-process.md +29 -55
  205. package/docs/doppler-guide.md +34 -0
  206. package/docs/reference/compatibility.md +1 -1
  207. package/docs/remote-mcp-hardening.md +17 -0
  208. package/docs/security/dependency-audit-exceptions.md +3 -7
  209. package/docs/security/hosted-data-inventory.md +81 -0
  210. package/docs/sonarcloud-analysis.md +9 -0
  211. package/mcp.json +1 -1
  212. package/package.json +31 -24
  213. package/registry/ssh-mcp-pro/mcp.json +1 -1
  214. package/server.json +3 -3
@@ -1,6 +1,6 @@
1
1
  import { createPublicKey } from "node:crypto";
2
2
  import { URL } from "node:url";
3
- import { LATEST_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, } from "@modelcontextprotocol/sdk/types.js";
3
+ import { LATEST_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS } from "@modelcontextprotocol/server";
4
4
  import { sha256Base64Url } from "./crypto.js";
5
5
  import { parseScopes } from "./scopes.js";
6
6
  import { REMOTE_SCOPES } from "./types.js";
@@ -20,10 +20,11 @@ export function negotiateMcpProtocolVersion(params) {
20
20
  : LATEST_PROTOCOL_VERSION;
21
21
  }
22
22
  export function quotePosixArg(value) {
23
- return `'${value.replace(/'/gu, `'"'"'`)}'`;
23
+ const escaped = value.replaceAll("'", "'\"'\"'");
24
+ return `'${escaped}'`;
24
25
  }
25
26
  export function quotePowerShellArg(value) {
26
- return `'${value.replace(/'/gu, "''")}'`;
27
+ return `'${value.replaceAll("'", "''")}'`;
27
28
  }
28
29
  export function asStringArray(value) {
29
30
  if (!Array.isArray(value)) {
@@ -99,6 +100,15 @@ export async function readJson(req) {
99
100
  }
100
101
  return parsed;
101
102
  }
103
+ function formFieldString(value) {
104
+ if (value === null || value === undefined) {
105
+ return "";
106
+ }
107
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
108
+ return String(value);
109
+ }
110
+ throw safeError("INVALID_CLIENT", "Expected a scalar JSON form value", 400);
111
+ }
102
112
  export async function readJsonOrForm(req) {
103
113
  const raw = await readBody(req);
104
114
  const contentType = req.headers["content-type"] ?? "";
@@ -107,10 +117,7 @@ export async function readJsonOrForm(req) {
107
117
  if (!isRecord(parsed)) {
108
118
  throw safeError("INTERNAL_ERROR", "Expected JSON object");
109
119
  }
110
- return Object.fromEntries(Object.entries(parsed).map(([key, value]) => [
111
- key,
112
- typeof value === "string" ? value : String(value ?? ""),
113
- ]));
120
+ return Object.fromEntries(Object.entries(parsed).map(([key, value]) => [key, formFieldString(value)]));
114
121
  }
115
122
  try {
116
123
  return formDecode(raw);
@@ -1 +1 @@
1
- {"version":3,"file":"http-util.js","sourceRoot":"","sources":["../../src/remote/http-util.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"http-util.js","sourceRoot":"","sources":["../../src/remote/http-util.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,17 @@
1
1
  import type { RemoteCapability, RemoteToolName } from "./types.js";
2
+ export interface ToolAnnotations {
3
+ readOnlyHint?: boolean;
4
+ destructiveHint?: boolean;
5
+ openWorldHint?: boolean;
6
+ }
2
7
  interface RemoteToolDescriptor {
3
8
  name: RemoteToolName;
4
9
  description: string;
5
10
  capability: RemoteCapability;
6
11
  inputSchema: Record<string, unknown>;
12
+ annotations?: ToolAnnotations;
7
13
  }
14
+ export declare function remoteToolAnnotations(name: RemoteToolName): ToolAnnotations;
8
15
  export declare function listRemoteToolDescriptors(capabilities: readonly RemoteCapability[]): RemoteToolDescriptor[];
9
16
  export {};
10
17
  //# sourceMappingURL=mcp-tools.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-tools.d.ts","sourceRoot":"","sources":["../../src/remote/mcp-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGnE,UAAU,oBAAoB;IAC5B,IAAI,EAAE,cAAc,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,gBAAgB,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAqMD,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,SAAS,gBAAgB,EAAE,GACxC,oBAAoB,EAAE,CAOxB"}
1
+ {"version":3,"file":"mcp-tools.d.ts","sourceRoot":"","sources":["../../src/remote/mcp-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGnE,MAAM,WAAW,eAAe;IAC9B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,UAAU,oBAAoB;IAC5B,IAAI,EAAE,cAAc,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,gBAAgB,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,WAAW,CAAC,EAAE,eAAe,CAAC;CAC/B;AAyND,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,cAAc,GAAG,eAAe,CAQ3E;AAED,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,SAAS,gBAAgB,EAAE,GACxC,oBAAoB,EAAE,CAQxB"}
@@ -190,11 +190,39 @@ const descriptors = {
190
190
  },
191
191
  },
192
192
  };
193
+ const READ_ONLY_REMOTE_TOOLS = new Set([
194
+ "list_hosts",
195
+ "list_agents",
196
+ "get_agent_install_command",
197
+ "get_system_status",
198
+ "tail_logs",
199
+ "docker_ps",
200
+ "docker_logs",
201
+ "file_read",
202
+ "get_audit_events",
203
+ ]);
204
+ const DESTRUCTIVE_REMOTE_TOOLS = new Set([
205
+ "run_shell_as_root",
206
+ "revoke_agent",
207
+ "file_write",
208
+ "restart_service",
209
+ "docker_restart",
210
+ ]);
211
+ export function remoteToolAnnotations(name) {
212
+ const isReadOnly = READ_ONLY_REMOTE_TOOLS.has(name);
213
+ const isDestructive = DESTRUCTIVE_REMOTE_TOOLS.has(name);
214
+ return {
215
+ readOnlyHint: isReadOnly,
216
+ destructiveHint: isDestructive,
217
+ openWorldHint: !isReadOnly,
218
+ };
219
+ }
193
220
  export function listRemoteToolDescriptors(capabilities) {
194
221
  const allowed = new Set(capabilities);
195
222
  return REMOTE_TOOLS.filter((name) => allowed.has(TOOL_CAPABILITY_MAP[name])).map((name) => ({
196
223
  name,
197
224
  capability: TOOL_CAPABILITY_MAP[name],
225
+ annotations: remoteToolAnnotations(name),
198
226
  ...descriptors[name],
199
227
  }));
200
228
  }
@@ -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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"}
@@ -1,7 +1,7 @@
1
1
  import type { IncomingMessage, ServerResponse } from "node:http";
2
2
  import { type JwtKeyPair } from "./crypto.js";
3
3
  import { RemoteStore } from "./store.js";
4
- import type { AuditEvent, RemoteConfig } from "./types.js";
4
+ import type { AuditEvent, GitHubUser, GoogleUser, RemoteConfig } from "./types.js";
5
5
  /** Pending OAuth authorization transaction. */
6
6
  export interface PendingAuthorize {
7
7
  clientId: string;
@@ -11,6 +11,7 @@ export interface PendingAuthorize {
11
11
  scope: string;
12
12
  state: string;
13
13
  expiresAt: number;
14
+ approved?: boolean;
14
15
  }
15
16
  /** Handles OAuth 2.0 authorization code flow with PKCE and GitHub identity. */
16
17
  export declare class OAuthHandler {
@@ -19,6 +20,9 @@ export declare class OAuthHandler {
19
20
  private readonly authorizeTransactions;
20
21
  private readonly getJwtKeyPair;
21
22
  private readonly audit;
23
+ private readonly registrationAttempts;
24
+ private transactionCookie;
25
+ private matchingBrowser;
22
26
  constructor(config: RemoteConfig, store: RemoteStore, authorizeTransactions: Map<string, PendingAuthorize>, getJwtKeyPair: () => JwtKeyPair, audit: (event: Omit<AuditEvent, "id" | "createdAt">) => void);
23
27
  /** GET /.well-known/oauth-protected-resource */
24
28
  protectedResourceMetadata(): Record<string, unknown>;
@@ -28,14 +32,43 @@ export declare class OAuthHandler {
28
32
  handleRegister(req: IncomingMessage, res: ServerResponse): Promise<void>;
29
33
  /** GET /oauth/authorize */
30
34
  handleAuthorize(req: IncomingMessage, res: ServerResponse): Promise<void>;
35
+ /**
36
+ * Avoid chaining browser form submissions through third-party OAuth redirects
37
+ * and then back to the MCP client. Chromium applies form-action to redirects;
38
+ * the final client callback is deliberately not a permitted form destination.
39
+ * A new document starts an ordinary navigation instead.
40
+ */
41
+ private continueToGitHub;
42
+ /** Explicit browser approval binds this client to the current login transaction. */
43
+ handleApprove(req: IncomingMessage, res: ServerResponse): Promise<void>;
31
44
  private validateAuthorizeParams;
32
45
  private restoreChatGptClient;
33
46
  private addChatGptRedirectUri;
47
+ /** Consume one-use OAuth transaction and preserve the associated PKCE request. */
48
+ private consumeOAuthCallback;
49
+ private completeOAuthCallback;
34
50
  /** GET /oauth/callback/github */
35
51
  handleGitHubCallback(req: IncomingMessage, res: ServerResponse): Promise<void>;
52
+ /** GET /oauth/callback/google */
53
+ handleGoogleCallback(req: IncomingMessage, res: ServerResponse): Promise<void>;
54
+ fetchGoogleUser(code: string): Promise<GoogleUser>;
55
+ /** Fixture identities must never bypass provider login on public-facing hosts. */
56
+ private allowFixtureIdentity;
57
+ testGoogleUser(): GoogleUser | undefined;
58
+ upsertGoogleUser(googleUser: GoogleUser): {
59
+ id: string;
60
+ googleId: string;
61
+ email: string;
62
+ displayName: string;
63
+ };
64
+ isGoogleUserAllowed(user: GoogleUser): boolean;
36
65
  private fetchGitHubUser;
37
- private testGitHubUser;
38
- private upsertGitHubUser;
66
+ testGitHubUser(): GitHubUser | undefined;
67
+ upsertGitHubUser(githubUser: GitHubUser): {
68
+ id: string;
69
+ githubId: string;
70
+ githubLogin: string;
71
+ };
39
72
  private isGitHubUserAllowed;
40
73
  private issueAuthorizationCode;
41
74
  /** POST /oauth/token */
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-handler.d.ts","sourceRoot":"","sources":["../../src/remote/oauth-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEjE,OAAO,EAOL,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;AAarB,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,KAAK,EACV,UAAU,EAIV,YAAY,EACb,MAAM,YAAY,CAAC;AAIpB,+CAA+C;AAC/C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,+EAA+E;AAC/E,qBAAa,YAAY;IAErB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,qBAAqB;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAJL,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,WAAW,EAClB,qBAAqB,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,EACpD,aAAa,EAAE,MAAM,UAAU,EAC/B,KAAK,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,WAAW,CAAC,KAAK,IAAI;IAG/E,gDAAgD;IAChD,yBAAyB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAUpD,kDAAkD;IAClD,2BAA2B,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAetD,2BAA2B;IACrB,cAAc,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IA4C9E,2BAA2B;IACrB,eAAe,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IA0D/E,OAAO,CAAC,uBAAuB;IAiC/B,OAAO,CAAC,oBAAoB;IAkC5B,OAAO,CAAC,qBAAqB;IAuB7B,iCAAiC;IAC3B,oBAAoB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;YAoBtE,eAAe;IAuB7B,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,gBAAgB;IAoBxB,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,sBAAsB;IAoB9B,wBAAwB;IAClB,WAAW,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IA6C3E,OAAO,CAAC,UAAU;IAWlB,yDAAyD;IACzD,cAAc,CAAC,GAAG,SAAa,GAAG,IAAI;IAQtC,2BAA2B;IACrB,UAAU,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;CASrD"}
1
+ {"version":3,"file":"oauth-handler.d.ts","sourceRoot":"","sources":["../../src/remote/oauth-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAGjE,OAAO,EAOL,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;AAarB,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,UAAU,EAGV,YAAY,EACb,MAAM,YAAY,CAAC;AAIpB,+CAA+C;AAC/C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,+EAA+E;AAC/E,qBAAa,YAAY;IAerB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,qBAAqB;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,KAAK;IAlBxB,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAA2D;IAEhG,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,eAAe;gBAOJ,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,WAAW,EAClB,qBAAqB,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,EACpD,aAAa,EAAE,MAAM,UAAU,EAC/B,KAAK,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,WAAW,CAAC,KAAK,IAAI;IAG/E,gDAAgD;IAChD,yBAAyB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAUpD,kDAAkD;IAClD,2BAA2B,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAgBtD,2BAA2B;IACrB,cAAc,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAuD9E,2BAA2B;IACrB,eAAe,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAmI/E;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IA2BxB,oFAAoF;IAC9E,aAAa,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAoC7E,OAAO,CAAC,uBAAuB;IAiC/B,OAAO,CAAC,oBAAoB;IAkC5B,OAAO,CAAC,qBAAqB;IAuB7B,kFAAkF;IAClF,OAAO,CAAC,oBAAoB;IAuB5B,OAAO,CAAC,qBAAqB;IAc7B,iCAAiC;IAC3B,oBAAoB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAMpF,iCAAiC;IAC3B,oBAAoB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAM9E,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAsCxD,kFAAkF;IAClF,OAAO,CAAC,oBAAoB;IAa5B,cAAc,IAAI,UAAU,GAAG,SAAS;IAQxC,gBAAgB,CAAC,UAAU,EAAE,UAAU,GAAG;QACxC,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;KACrB;IAqBD,mBAAmB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO;YAQhC,eAAe;IAkC7B,cAAc,IAAI,UAAU,GAAG,SAAS;IAOxC,gBAAgB,CAAC,UAAU,EAAE,UAAU,GAAG;QACxC,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;KACrB;IAgBD,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,sBAAsB;IAoB9B,wBAAwB;IAClB,WAAW,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IA6C3E,OAAO,CAAC,UAAU;IA8BlB,yDAAyD;IACzD,cAAc,CAAC,GAAG,SAAa,GAAG,IAAI;IAWtC,2BAA2B;IACrB,UAAU,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;CASrD"}
@@ -1,3 +1,4 @@
1
+ import { escape as escapeHtml } from "html-escaper";
1
2
  import { URL } from "node:url";
2
3
  import { hashSecret, id, issueAccessToken, nowIso, publicJwkFromPem, randomToken, } from "./crypto.js";
3
4
  import { asString, asStringArray, addNoStore, isSafeRedirectUri, pkceChallenge, readJson, readJsonOrForm, redirect, safeError, scopeList, } from "./http-util.js";
@@ -10,6 +11,16 @@ export class OAuthHandler {
10
11
  authorizeTransactions;
11
12
  getJwtKeyPair;
12
13
  audit;
14
+ registrationAttempts = new Map();
15
+ transactionCookie(value) {
16
+ const secure = this.config.publicBaseUrl.startsWith("https://") ? "; Secure" : "";
17
+ return `ssh_mcp_oauth_tx=${value}; Path=/oauth; HttpOnly; SameSite=Lax; Max-Age=300${secure}`;
18
+ }
19
+ matchingBrowser(req, transactionId) {
20
+ return (req.headers.cookie ?? "")
21
+ .split(";")
22
+ .some((part) => part.trim() === `ssh_mcp_oauth_tx=${transactionId}`);
23
+ }
13
24
  constructor(config, store, authorizeTransactions, getJwtKeyPair, audit) {
14
25
  this.config = config;
15
26
  this.store = store;
@@ -31,6 +42,7 @@ export class OAuthHandler {
31
42
  authorizationServerMetadata() {
32
43
  return {
33
44
  issuer: this.config.publicBaseUrl,
45
+ authorization_response_iss_parameter_supported: true,
34
46
  authorization_endpoint: `${this.config.publicBaseUrl}/oauth/authorize`,
35
47
  token_endpoint: `${this.config.publicBaseUrl}/oauth/token`,
36
48
  registration_endpoint: `${this.config.publicBaseUrl}/oauth/register`,
@@ -49,6 +61,16 @@ export class OAuthHandler {
49
61
  if (redirectUris.length === 0 || redirectUris.some((uri) => !isSafeRedirectUri(uri))) {
50
62
  throw safeError("INVALID_REDIRECT_URI", "redirect_uris must contain HTTPS URLs or localhost HTTP URLs");
51
63
  }
64
+ // Bound unauthenticated DCR registration by the TCP peer, not spoofable proxy headers.
65
+ const peer = req.socket?.remoteAddress ?? "local-test";
66
+ const nowMs = Date.now();
67
+ const previous = this.registrationAttempts.get(peer);
68
+ const window = previous && previous.expiresAt > nowMs ? previous : { count: 0, expiresAt: nowMs + 300_000 };
69
+ if (window.count >= 20) {
70
+ throw safeError("FORBIDDEN", "OAuth client registration rate limit reached", 429);
71
+ }
72
+ window.count++;
73
+ this.registrationAttempts.set(peer, window);
52
74
  if (this.store.countOAuthClients() >= this.config.maxOAuthClients) {
53
75
  throw safeError("FORBIDDEN", "OAuth client registration limit reached", 429);
54
76
  }
@@ -105,23 +127,149 @@ export class OAuthHandler {
105
127
  const code = this.issueAuthorizationCode(pending, user.id);
106
128
  const destination = new URL(redirectUri);
107
129
  destination.searchParams.set("code", code);
130
+ destination.searchParams.set("iss", this.config.publicBaseUrl);
108
131
  if (state) {
109
132
  destination.searchParams.set("state", state);
110
133
  }
111
134
  redirect(res, destination.toString());
112
135
  return;
113
136
  }
114
- if (!this.config.githubClientId || !this.config.githubClientSecret) {
115
- throw safeError("FORBIDDEN", "GitHub OAuth is not configured", 503);
137
+ const testGoogle = this.testGoogleUser();
138
+ if (testGoogle) {
139
+ const user = this.upsertGoogleUser(testGoogle);
140
+ const code = this.issueAuthorizationCode(pending, user.id);
141
+ const destination = new URL(redirectUri);
142
+ destination.searchParams.set("code", code);
143
+ destination.searchParams.set("iss", this.config.publicBaseUrl);
144
+ if (state) {
145
+ destination.searchParams.set("state", state);
146
+ }
147
+ redirect(res, destination.toString());
148
+ return;
149
+ }
150
+ const hasGitHub = Boolean(this.config.githubClientId && this.config.githubClientSecret);
151
+ const hasGoogle = Boolean(this.config.googleClientId && this.config.googleClientSecret);
152
+ if (!hasGitHub && !hasGoogle) {
153
+ throw safeError("FORBIDDEN", "Neither GitHub nor Google OAuth is configured", 503);
116
154
  }
117
155
  const transactionId = id("code");
118
156
  this.authorizeTransactions.set(transactionId, pending);
157
+ const hostname = escapeHtml(new URL(redirectUri).hostname);
158
+ // Chromium also checks form-action on the redirect after POST /oauth/approve.
159
+ // Permit only the configured identity providers, not arbitrary OAuth clients.
160
+ const formActions = [
161
+ "'self'",
162
+ ...(hasGoogle ? ["https://accounts.google.com"] : []),
163
+ ...(hasGitHub ? ["https://github.com"] : []),
164
+ ].join(" ");
165
+ res.writeHead(200, {
166
+ "Content-Type": "text/html; charset=utf-8",
167
+ "Cache-Control": "no-store",
168
+ "Content-Security-Policy": `default-src 'none'; style-src 'unsafe-inline'; form-action ${formActions}; frame-ancestors 'none'; base-uri 'none'`,
169
+ "X-Content-Type-Options": "nosniff",
170
+ "Set-Cookie": this.transactionCookie(transactionId),
171
+ });
172
+ const buttons = [];
173
+ if (hasGoogle) {
174
+ buttons.push(`<button type="submit" name="provider" value="google" style="display:flex;align-items:center;justify-content:center;gap:10px;width:100%;padding:12px;margin-bottom:10px;background:#ffffff;color:#1f2937;border:1px solid #d1d5db;border-radius:8px;font-weight:600;font-size:15px;cursor:pointer;">
175
+ <svg width="18" height="18" viewBox="0 0 24 24"><path fill="#EA4335" d="M12 5c1.7 0 3 .7 3.9 1.5l2.9-2.9C17 2 14.7 1 12 1 7.5 1 3.7 3.6 1.9 7.3l3.7 2.9C6.5 7.4 9 5 12 5z"/><path fill="#4285F4" d="M23.5 12.3c0-.8-.1-1.6-.2-2.3H12v4.5h6.5c-.3 1.5-1.1 2.8-2.4 3.7l3.7 2.9c2.2-2 3.7-5 3.7-8.8z"/><path fill="#FBBC05" d="M5.6 14.8c-.2-.7-.4-1.5-.4-2.3s.2-1.6.4-2.3L1.9 7.3C.7 9.7 0 12.3 0 15.2c0 2.8.7 5.5 1.9 7.8l3.7-2.9z"/><path fill="#34A853" d="M12 23.5c3.2 0 6-1.1 8-3l-3.7-2.9c-1.1.7-2.5 1.2-4.3 1.2-3 0-5.5-2.4-6.4-5.2L1.9 16.5C3.7 20.3 7.5 23.5 12 23.5z"/></svg>
176
+ Continue with Google
177
+ </button>`);
178
+ }
179
+ if (hasGitHub) {
180
+ buttons.push(`<button type="submit" name="provider" value="github" style="display:flex;align-items:center;justify-content:center;gap:10px;width:100%;padding:12px;margin-bottom:10px;background:#24292f;color:#ffffff;border:none;border-radius:8px;font-weight:600;font-size:15px;cursor:pointer;">
181
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" clip-rule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.53 1.032 1.53 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"/></svg>
182
+ Continue with GitHub
183
+ </button>`);
184
+ }
185
+ res.end([
186
+ '<!doctype html><html lang="en"><head><meta charset="utf-8"><title>Authorize SSH MCP Pro</title>',
187
+ '<meta name="viewport" content="width=device-width, initial-scale=1">',
188
+ '<style>body{background:#0d1117;color:#e6edf3;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;display:flex;align-items:center;justify-content:center;min-height:100vh;margin:0;padding:16px;}',
189
+ ".card{background:#161b22;border:1px solid #30363d;border-radius:12px;padding:32px;max-width:440px;width:100%;box-shadow:0 10px 30px rgba(0,0,0,0.5);text-align:center;}",
190
+ "h1{font-size:22px;margin:0 0 12px;color:#f0f6fc;}p{font-size:14px;color:#8b949e;line-height:1.5;margin:0 0 24px;}",
191
+ ".badge{background:#21262d;border:1px solid #30363d;border-radius:6px;padding:4px 8px;font-family:monospace;font-size:12px;color:#58a6ff;}",
192
+ "</style></head><body>",
193
+ '<div class="card">',
194
+ '<div style="margin-bottom:16px;"><span style="font-size:32px;">🔐</span></div>',
195
+ "<h1>Authorize SSH MCP Pro</h1>",
196
+ '<p>Allow client at <strong style="color:#f0f6fc;">',
197
+ hostname,
198
+ "</strong> to request access to:</p>",
199
+ '<p><span class="badge">',
200
+ escapeHtml(scope),
201
+ "</span></p>",
202
+ '<form method="post" action="/oauth/approve"><input type="hidden" name="transaction" value="',
203
+ escapeHtml(transactionId),
204
+ '">',
205
+ buttons.join(""),
206
+ "</form>",
207
+ '<div style="font-size:12px;color:#484f58;margin-top:20px;">Zero-Trust SSH Model Context Protocol Gateway</div>',
208
+ "</div></body></html>",
209
+ ].join(""));
210
+ }
211
+ /**
212
+ * Avoid chaining browser form submissions through third-party OAuth redirects
213
+ * and then back to the MCP client. Chromium applies form-action to redirects;
214
+ * the final client callback is deliberately not a permitted form destination.
215
+ * A new document starts an ordinary navigation instead.
216
+ */
217
+ continueToGitHub(res, githubUrl) {
218
+ const href = escapeHtml(githubUrl.toString());
219
+ res.writeHead(200, {
220
+ "Content-Type": "text/html; charset=utf-8",
221
+ "Cache-Control": "no-store",
222
+ "Referrer-Policy": "no-referrer",
223
+ "X-Content-Type-Options": "nosniff",
224
+ "Content-Security-Policy": "default-src 'none'; style-src 'unsafe-inline'; form-action 'none'; frame-ancestors 'none'; base-uri 'none'",
225
+ });
226
+ res.end([
227
+ '<!doctype html><html lang="en"><head><meta charset="utf-8">',
228
+ '<meta name="viewport" content="width=device-width, initial-scale=1">',
229
+ "<title>Continue with GitHub — SSH MCP Pro</title>",
230
+ '<meta http-equiv="refresh" content="0;url=',
231
+ href,
232
+ '">',
233
+ "</head><body>",
234
+ '<p>Continue to GitHub to sign in.</p><a href="',
235
+ href,
236
+ '">Continue with GitHub</a>',
237
+ "</body></html>",
238
+ ].join(""));
239
+ }
240
+ /** Explicit browser approval binds this client to the current login transaction. */
241
+ async handleApprove(req, res) {
242
+ const form = await readJsonOrForm(req);
243
+ const transactionId = form.transaction ?? "";
244
+ const provider = asString(form.provider) ?? "github";
245
+ const pending = this.authorizeTransactions.get(transactionId);
246
+ if (!pending || pending.expiresAt < Date.now() || !this.matchingBrowser(req, transactionId)) {
247
+ throw safeError("INVALID_TOKEN", "OAuth transaction is missing or expired", 403);
248
+ }
249
+ if (provider === "google") {
250
+ if (!this.config.googleClientId || !this.config.googleClientSecret) {
251
+ throw safeError("FORBIDDEN", "Google OAuth is not configured", 503);
252
+ }
253
+ pending.approved = true;
254
+ const googleUrl = new URL("https://accounts.google.com/o/oauth2/v2/auth");
255
+ googleUrl.searchParams.set("client_id", this.config.googleClientId);
256
+ googleUrl.searchParams.set("redirect_uri", this.config.googleCallbackUrl);
257
+ googleUrl.searchParams.set("response_type", "code");
258
+ googleUrl.searchParams.set("scope", "openid email profile");
259
+ googleUrl.searchParams.set("state", transactionId);
260
+ redirect(res, googleUrl.toString());
261
+ return;
262
+ }
263
+ if (!this.config.githubClientId || !this.config.githubClientSecret) {
264
+ throw safeError("FORBIDDEN", "GitHub OAuth is not configured", 503);
265
+ }
266
+ pending.approved = true;
119
267
  const githubUrl = new URL("https://github.com/login/oauth/authorize");
120
268
  githubUrl.searchParams.set("client_id", this.config.githubClientId);
121
269
  githubUrl.searchParams.set("redirect_uri", this.config.githubCallbackUrl);
122
270
  githubUrl.searchParams.set("scope", "read:user");
123
271
  githubUrl.searchParams.set("state", transactionId);
124
- redirect(res, githubUrl.toString());
272
+ this.continueToGitHub(res, githubUrl);
125
273
  }
126
274
  validateAuthorizeParams(clientId, redirectUri, responseType, codeChallenge, codeChallengeMethod, resource, scope) {
127
275
  let client = this.store.getClient(clientId);
@@ -203,26 +351,126 @@ export class OAuthHandler {
203
351
  });
204
352
  return { ...client, redirectUris: updatedUris };
205
353
  }
206
- /** GET /oauth/callback/github */
207
- async handleGitHubCallback(req, res) {
208
- const url = new URL(req.url ?? "/oauth/callback/github", this.config.publicBaseUrl);
354
+ /** Consume one-use OAuth transaction and preserve the associated PKCE request. */
355
+ consumeOAuthCallback(req, provider) {
356
+ const url = new URL(req.url ?? `/oauth/callback/${provider}`, this.config.publicBaseUrl);
209
357
  const code = url.searchParams.get("code") ?? "";
210
358
  const state = url.searchParams.get("state") ?? "";
211
359
  const pending = this.authorizeTransactions.get(state);
212
360
  this.authorizeTransactions.delete(state);
213
- if (!code || !pending || pending.expiresAt < Date.now()) {
361
+ if (!code ||
362
+ !pending?.approved ||
363
+ pending.expiresAt < Date.now() ||
364
+ !this.matchingBrowser(req, state)) {
214
365
  throw safeError("INVALID_TOKEN", "OAuth transaction is missing or expired");
215
366
  }
216
- const githubUser = await this.fetchGitHubUser(code);
217
- const user = this.upsertGitHubUser(githubUser);
218
- const authCode = this.issueAuthorizationCode(pending, user.id);
367
+ return { code, pending };
368
+ }
369
+ completeOAuthCallback(res, pending, userId) {
370
+ const authCode = this.issueAuthorizationCode(pending, userId);
219
371
  const destination = new URL(pending.redirectUri);
220
372
  destination.searchParams.set("code", authCode);
221
- if (pending.state) {
373
+ destination.searchParams.set("iss", this.config.publicBaseUrl);
374
+ if (pending.state)
222
375
  destination.searchParams.set("state", pending.state);
223
- }
376
+ res.setHeader("Set-Cookie", this.transactionCookie("").replace("Max-Age=300", "Max-Age=0"));
224
377
  redirect(res, destination.toString());
225
378
  }
379
+ /** GET /oauth/callback/github */
380
+ async handleGitHubCallback(req, res) {
381
+ const { code, pending } = this.consumeOAuthCallback(req, "github");
382
+ const user = this.upsertGitHubUser(await this.fetchGitHubUser(code));
383
+ this.completeOAuthCallback(res, pending, user.id);
384
+ }
385
+ /** GET /oauth/callback/google */
386
+ async handleGoogleCallback(req, res) {
387
+ const { code, pending } = this.consumeOAuthCallback(req, "google");
388
+ const user = this.upsertGoogleUser(await this.fetchGoogleUser(code));
389
+ this.completeOAuthCallback(res, pending, user.id);
390
+ }
391
+ async fetchGoogleUser(code) {
392
+ const testUser = this.testGoogleUser();
393
+ if (testUser) {
394
+ 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 };
427
+ }
428
+ /** Fixture identities must never bypass provider login on public-facing hosts. */
429
+ allowFixtureIdentity() {
430
+ if (process.env.NODE_ENV !== "test")
431
+ return false;
432
+ try {
433
+ const baseUrl = new URL(this.config.publicBaseUrl);
434
+ return (baseUrl.protocol === "http:" &&
435
+ ["localhost", "127.0.0.1", "[::1]"].includes(baseUrl.hostname));
436
+ }
437
+ catch {
438
+ return false;
439
+ }
440
+ }
441
+ testGoogleUser() {
442
+ if (!this.allowFixtureIdentity())
443
+ return undefined;
444
+ const idValue = process.env.SSHAUTOMATOR_TEST_GOOGLE_ID;
445
+ const email = process.env.SSHAUTOMATOR_TEST_GOOGLE_EMAIL;
446
+ const name = process.env.SSHAUTOMATOR_TEST_GOOGLE_NAME ?? "Test Google User";
447
+ return idValue && email ? { id: idValue, email, name } : undefined;
448
+ }
449
+ upsertGoogleUser(googleUser) {
450
+ if (!this.isGoogleUserAllowed(googleUser)) {
451
+ throw safeError("FORBIDDEN", "Google user is not allowed");
452
+ }
453
+ const existing = this.store.getUserByGoogleId(googleUser.id);
454
+ const internalId = existing?.id ?? `google:${googleUser.id}`;
455
+ this.store.upsertGoogleUser({ ...googleUser, internalId, now: nowIso() });
456
+ this.audit({
457
+ userId: internalId,
458
+ eventType: "user_login",
459
+ severity: "info",
460
+ metadata: { google_id: googleUser.id, email: googleUser.email, provider: "google" },
461
+ });
462
+ return {
463
+ id: internalId,
464
+ googleId: googleUser.id,
465
+ email: googleUser.email,
466
+ displayName: googleUser.name,
467
+ };
468
+ }
469
+ isGoogleUserAllowed(user) {
470
+ return (this.config.allowAllUsers ||
471
+ this.config.allowedGoogleSubIds.includes(user.id) ||
472
+ this.config.allowedGoogleEmails.includes(user.email));
473
+ }
226
474
  async fetchGitHubUser(code) {
227
475
  const tokenResponse = await fetch("https://github.com/login/oauth/access_token", {
228
476
  method: "POST",
@@ -243,9 +491,20 @@ export class OAuthHandler {
243
491
  headers: { Authorization: `Bearer ${accessToken}`, Accept: "application/vnd.github+json" },
244
492
  });
245
493
  const userPayload = (await userResponse.json());
246
- return { id: String(userPayload.id ?? ""), login: String(userPayload.login ?? "") };
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 };
247
504
  }
248
505
  testGitHubUser() {
506
+ if (!this.allowFixtureIdentity())
507
+ return undefined;
249
508
  const idValue = process.env.SSHAUTOMATOR_TEST_GITHUB_ID;
250
509
  const login = process.env.SSHAUTOMATOR_TEST_GITHUB_LOGIN;
251
510
  return idValue && login ? { id: idValue, login } : undefined;
@@ -338,10 +597,25 @@ export class OAuthHandler {
338
597
  return user;
339
598
  }
340
599
  }
600
+ if (userId.startsWith("google:")) {
601
+ const googleId = userId.slice("google:".length);
602
+ const user = this.store.getUserByGoogleId(googleId);
603
+ if (user) {
604
+ return user;
605
+ }
606
+ }
607
+ const user = this.store.getUserById(userId);
608
+ if (user) {
609
+ return user;
610
+ }
341
611
  throw safeError("UNAUTHORIZED", "User no longer exists", 401);
342
612
  }
343
613
  /** Remove expired pending authorization transactions. */
344
614
  cleanupExpired(now = Date.now()) {
615
+ for (const [peer, entry] of this.registrationAttempts) {
616
+ if (entry.expiresAt <= now)
617
+ this.registrationAttempts.delete(peer);
618
+ }
345
619
  for (const [transactionId, transaction] of this.authorizeTransactions.entries()) {
346
620
  if (transaction.expiresAt <= now) {
347
621
  this.authorizeTransactions.delete(transactionId);