ssh-mcp-pro 1.2.3 → 1.4.2

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 (212) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/MIGRATION.md +2 -2
  3. package/README.md +34 -13
  4. package/SECURITY_DECISIONS.md +19 -0
  5. package/dist/agent-bin.js +5 -2
  6. package/dist/agent-bin.js.map +1 -1
  7. package/dist/cli.d.ts +1 -0
  8. package/dist/cli.d.ts.map +1 -1
  9. package/dist/cli.js +38 -47
  10. package/dist/cli.js.map +1 -1
  11. package/dist/config-security-env.d.ts +4 -0
  12. package/dist/config-security-env.d.ts.map +1 -0
  13. package/dist/config-security-env.js +64 -0
  14. package/dist/config-security-env.js.map +1 -0
  15. package/dist/config-types.d.ts +82 -0
  16. package/dist/config-types.d.ts.map +1 -0
  17. package/dist/config-types.js +2 -0
  18. package/dist/config-types.js.map +1 -0
  19. package/dist/config.d.ts +3 -82
  20. package/dist/config.d.ts.map +1 -1
  21. package/dist/config.js +4 -67
  22. package/dist/config.js.map +1 -1
  23. package/dist/connector-profile.d.ts +1 -1
  24. package/dist/connector-profile.d.ts.map +1 -1
  25. package/dist/detect.d.ts.map +1 -1
  26. package/dist/detect.js +226 -192
  27. package/dist/detect.js.map +1 -1
  28. package/dist/ensure-package-service.d.ts +9 -0
  29. package/dist/ensure-package-service.d.ts.map +1 -0
  30. package/dist/ensure-package-service.js +146 -0
  31. package/dist/ensure-package-service.js.map +1 -0
  32. package/dist/ensure-pkg.js +4 -4
  33. package/dist/ensure-pkg.js.map +1 -1
  34. package/dist/ensure.d.ts.map +1 -1
  35. package/dist/ensure.js +15 -144
  36. package/dist/ensure.js.map +1 -1
  37. package/dist/fs-sftp.js +1 -1
  38. package/dist/fs-sftp.js.map +1 -1
  39. package/dist/fs-stat.d.ts +10 -0
  40. package/dist/fs-stat.d.ts.map +1 -0
  41. package/dist/fs-stat.js +62 -0
  42. package/dist/fs-stat.js.map +1 -0
  43. package/dist/fs-tools.d.ts.map +1 -1
  44. package/dist/fs-tools.js +6 -58
  45. package/dist/fs-tools.js.map +1 -1
  46. package/dist/http-security.d.ts.map +1 -1
  47. package/dist/http-security.js +6 -6
  48. package/dist/http-security.js.map +1 -1
  49. package/dist/http-server-runtime.d.ts.map +1 -1
  50. package/dist/http-server-runtime.js +41 -7
  51. package/dist/http-server-runtime.js.map +1 -1
  52. package/dist/index.js +7 -24
  53. package/dist/index.js.map +1 -1
  54. package/dist/mcp-http-web.d.ts +8 -0
  55. package/dist/mcp-http-web.d.ts.map +1 -0
  56. package/dist/mcp-http-web.js +35 -0
  57. package/dist/mcp-http-web.js.map +1 -0
  58. package/dist/mcp.d.ts +6 -2
  59. package/dist/mcp.d.ts.map +1 -1
  60. package/dist/mcp.js +22 -14
  61. package/dist/mcp.js.map +1 -1
  62. package/dist/policy.d.ts +8 -0
  63. package/dist/policy.d.ts.map +1 -1
  64. package/dist/policy.js +147 -105
  65. package/dist/policy.js.map +1 -1
  66. package/dist/process.d.ts.map +1 -1
  67. package/dist/process.js +11 -7
  68. package/dist/process.js.map +1 -1
  69. package/dist/remote/agent-activity-log.d.ts +26 -0
  70. package/dist/remote/agent-activity-log.d.ts.map +1 -0
  71. package/dist/remote/agent-activity-log.js +211 -0
  72. package/dist/remote/agent-activity-log.js.map +1 -0
  73. package/dist/remote/agent-cli.d.ts.map +1 -1
  74. package/dist/remote/agent-cli.js +153 -33
  75. package/dist/remote/agent-cli.js.map +1 -1
  76. package/dist/remote/agent-executor.d.ts.map +1 -1
  77. package/dist/remote/agent-executor.js +22 -10
  78. package/dist/remote/agent-executor.js.map +1 -1
  79. package/dist/remote/agent-handler.d.ts +2 -0
  80. package/dist/remote/agent-handler.d.ts.map +1 -1
  81. package/dist/remote/agent-handler.js +4 -0
  82. package/dist/remote/agent-handler.js.map +1 -1
  83. package/dist/remote/config.d.ts.map +1 -1
  84. package/dist/remote/config.js +12 -1
  85. package/dist/remote/config.js.map +1 -1
  86. package/dist/remote/control-plane.d.ts +12 -0
  87. package/dist/remote/control-plane.d.ts.map +1 -1
  88. package/dist/remote/control-plane.js +164 -56
  89. package/dist/remote/control-plane.js.map +1 -1
  90. package/dist/remote/crypto.d.ts +9 -4
  91. package/dist/remote/crypto.d.ts.map +1 -1
  92. package/dist/remote/crypto.js +41 -9
  93. package/dist/remote/crypto.js.map +1 -1
  94. package/dist/remote/http-util.d.ts.map +1 -1
  95. package/dist/remote/http-util.js +14 -7
  96. package/dist/remote/http-util.js.map +1 -1
  97. package/dist/remote/mcp-tools.d.ts +7 -0
  98. package/dist/remote/mcp-tools.d.ts.map +1 -1
  99. package/dist/remote/mcp-tools.js +28 -0
  100. package/dist/remote/mcp-tools.js.map +1 -1
  101. package/dist/remote/oauth-handler.d.ts +30 -3
  102. package/dist/remote/oauth-handler.d.ts.map +1 -1
  103. package/dist/remote/oauth-handler.js +232 -18
  104. package/dist/remote/oauth-handler.js.map +1 -1
  105. package/dist/remote/policy.js +2 -2
  106. package/dist/remote/policy.js.map +1 -1
  107. package/dist/remote/schemas.d.ts +9 -9
  108. package/dist/remote/schemas.js +6 -6
  109. package/dist/remote/schemas.js.map +1 -1
  110. package/dist/remote/store.d.ts +38 -1
  111. package/dist/remote/store.d.ts.map +1 -1
  112. package/dist/remote/store.js +149 -11
  113. package/dist/remote/store.js.map +1 -1
  114. package/dist/remote/types.d.ts +14 -0
  115. package/dist/remote/types.d.ts.map +1 -1
  116. package/dist/remote/types.js.map +1 -1
  117. package/dist/remote/web-dashboard-client-config.d.ts +77 -0
  118. package/dist/remote/web-dashboard-client-config.d.ts.map +1 -0
  119. package/dist/remote/web-dashboard-client-config.js +81 -0
  120. package/dist/remote/web-dashboard-client-config.js.map +1 -0
  121. package/dist/remote/web-dashboard-html.d.ts +2 -0
  122. package/dist/remote/web-dashboard-html.d.ts.map +1 -0
  123. package/dist/remote/web-dashboard-html.js +451 -0
  124. package/dist/remote/web-dashboard-html.js.map +1 -0
  125. package/dist/remote/web-dashboard-oauth-users.d.ts +4 -0
  126. package/dist/remote/web-dashboard-oauth-users.d.ts.map +1 -0
  127. package/dist/remote/web-dashboard-oauth-users.js +78 -0
  128. package/dist/remote/web-dashboard-oauth-users.js.map +1 -0
  129. package/dist/remote/web-dashboard-static.d.ts +4 -0
  130. package/dist/remote/web-dashboard-static.d.ts.map +1 -0
  131. package/dist/remote/web-dashboard-static.js +19 -0
  132. package/dist/remote/web-dashboard-static.js.map +1 -0
  133. package/dist/remote/web-dashboard-styles.d.ts +2 -0
  134. package/dist/remote/web-dashboard-styles.d.ts.map +1 -0
  135. package/dist/remote/web-dashboard-styles.js +206 -0
  136. package/dist/remote/web-dashboard-styles.js.map +1 -0
  137. package/dist/remote/web-dashboard.d.ts +62 -0
  138. package/dist/remote/web-dashboard.d.ts.map +1 -0
  139. package/dist/remote/web-dashboard.js +467 -0
  140. package/dist/remote/web-dashboard.js.map +1 -0
  141. package/dist/retry.d.ts.map +1 -1
  142. package/dist/retry.js +6 -3
  143. package/dist/retry.js.map +1 -1
  144. package/dist/safety.d.ts.map +1 -1
  145. package/dist/safety.js +56 -6
  146. package/dist/safety.js.map +1 -1
  147. package/dist/session-auth.js +7 -7
  148. package/dist/session-auth.js.map +1 -1
  149. package/dist/session.d.ts +1 -0
  150. package/dist/session.d.ts.map +1 -1
  151. package/dist/session.js +44 -40
  152. package/dist/session.js.map +1 -1
  153. package/dist/shell.d.ts.map +1 -1
  154. package/dist/shell.js +5 -4
  155. package/dist/shell.js.map +1 -1
  156. package/dist/ssh-config.d.ts +2 -2
  157. package/dist/ssh-config.d.ts.map +1 -1
  158. package/dist/ssh-config.js +24 -20
  159. package/dist/ssh-config.js.map +1 -1
  160. package/dist/telemetry.d.ts.map +1 -1
  161. package/dist/telemetry.js +9 -2
  162. package/dist/telemetry.js.map +1 -1
  163. package/dist/tools/connector.provider.d.ts +1 -1
  164. package/dist/tools/connector.provider.d.ts.map +1 -1
  165. package/dist/tools/ensure.provider.d.ts +1 -1
  166. package/dist/tools/ensure.provider.d.ts.map +1 -1
  167. package/dist/tools/fs.provider.d.ts +1 -1
  168. package/dist/tools/fs.provider.d.ts.map +1 -1
  169. package/dist/tools/metadata.d.ts +1 -1
  170. package/dist/tools/metadata.d.ts.map +1 -1
  171. package/dist/tools/output-schemas.d.ts +27 -135
  172. package/dist/tools/output-schemas.d.ts.map +1 -1
  173. package/dist/tools/process.provider.d.ts +1 -1
  174. package/dist/tools/process.provider.d.ts.map +1 -1
  175. package/dist/tools/registry.d.ts +1 -1
  176. package/dist/tools/registry.d.ts.map +1 -1
  177. package/dist/tools/registry.js +16 -13
  178. package/dist/tools/registry.js.map +1 -1
  179. package/dist/tools/session.provider.d.ts +1 -1
  180. package/dist/tools/session.provider.d.ts.map +1 -1
  181. package/dist/tools/system.provider.d.ts +1 -1
  182. package/dist/tools/system.provider.d.ts.map +1 -1
  183. package/dist/tools/transfer.provider.d.ts +1 -1
  184. package/dist/tools/transfer.provider.d.ts.map +1 -1
  185. package/dist/tools/tunnel.provider.d.ts +1 -1
  186. package/dist/tools/tunnel.provider.d.ts.map +1 -1
  187. package/dist/tools/types.d.ts +1 -1
  188. package/dist/tools/types.d.ts.map +1 -1
  189. package/dist/transfer.js +2 -2
  190. package/dist/transfer.js.map +1 -1
  191. package/dist/types.js +1 -1
  192. package/dist/types.js.map +1 -1
  193. package/docs/adding-a-device.md +39 -17
  194. package/docs/agent-activity-monitor.md +34 -0
  195. package/docs/coolify.md +29 -0
  196. package/docs/development/dependency-management.md +1 -1
  197. package/docs/development/local-setup.md +1 -1
  198. package/docs/development/mcp-protocol-2026.md +33 -0
  199. package/docs/docker.md +4 -4
  200. package/docs/doppler-guide.md +34 -0
  201. package/docs/openssf-evidence.md +11 -7
  202. package/docs/openssf-gap-analysis.md +7 -8
  203. package/docs/reference/cli.md +17 -6
  204. package/docs/reference/compatibility.md +1 -1
  205. package/docs/security/dependency-audit-exceptions.md +3 -7
  206. package/docs/security/hosted-data-inventory.md +81 -0
  207. package/docs/sonarcloud-analysis.md +9 -0
  208. package/docs/tutorials/getting-started.md +1 -1
  209. package/mcp.json +1 -1
  210. package/package.json +26 -21
  211. package/registry/ssh-mcp-pro/mcp.json +1 -1
  212. 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;
@@ -32,16 +32,43 @@ export declare class OAuthHandler {
32
32
  handleRegister(req: IncomingMessage, res: ServerResponse): Promise<void>;
33
33
  /** GET /oauth/authorize */
34
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;
35
42
  /** Explicit browser approval binds this client to the current login transaction. */
36
43
  handleApprove(req: IncomingMessage, res: ServerResponse): Promise<void>;
37
44
  private validateAuthorizeParams;
38
45
  private restoreChatGptClient;
39
46
  private addChatGptRedirectUri;
47
+ /** Consume one-use OAuth transaction and preserve the associated PKCE request. */
48
+ private consumeOAuthCallback;
49
+ private completeOAuthCallback;
40
50
  /** GET /oauth/callback/github */
41
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;
42
65
  private fetchGitHubUser;
43
- private testGitHubUser;
44
- private upsertGitHubUser;
66
+ testGitHubUser(): GitHubUser | undefined;
67
+ upsertGitHubUser(githubUser: GitHubUser): {
68
+ id: string;
69
+ githubId: string;
70
+ githubLogin: string;
71
+ };
45
72
  private isGitHubUserAllowed;
46
73
  private issueAuthorizationCode;
47
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;AAGjE,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;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;IAetD,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;IAyE/E,oFAAoF;IAC9E,aAAa,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB7E,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;YA0BtE,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;IAWtC,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":"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"}
@@ -42,6 +42,7 @@ export class OAuthHandler {
42
42
  authorizationServerMetadata() {
43
43
  return {
44
44
  issuer: this.config.publicBaseUrl,
45
+ authorization_response_iss_parameter_supported: true,
45
46
  authorization_endpoint: `${this.config.publicBaseUrl}/oauth/authorize`,
46
47
  token_endpoint: `${this.config.publicBaseUrl}/oauth/token`,
47
48
  registration_endpoint: `${this.config.publicBaseUrl}/oauth/register`,
@@ -126,44 +127,139 @@ export class OAuthHandler {
126
127
  const code = this.issueAuthorizationCode(pending, user.id);
127
128
  const destination = new URL(redirectUri);
128
129
  destination.searchParams.set("code", code);
130
+ destination.searchParams.set("iss", this.config.publicBaseUrl);
129
131
  if (state) {
130
132
  destination.searchParams.set("state", state);
131
133
  }
132
134
  redirect(res, destination.toString());
133
135
  return;
134
136
  }
135
- if (!this.config.githubClientId || !this.config.githubClientSecret) {
136
- 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);
137
154
  }
138
155
  const transactionId = id("code");
139
156
  this.authorizeTransactions.set(transactionId, pending);
140
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(" ");
141
165
  res.writeHead(200, {
142
166
  "Content-Type": "text/html; charset=utf-8",
143
167
  "Cache-Control": "no-store",
144
- "Content-Security-Policy": "default-src 'none'; form-action 'self'; frame-ancestors 'none'; base-uri 'none'",
168
+ "Content-Security-Policy": `default-src 'none'; style-src 'unsafe-inline'; form-action ${formActions}; frame-ancestors 'none'; base-uri 'none'`,
145
169
  "X-Content-Type-Options": "nosniff",
146
170
  "Set-Cookie": this.transactionCookie(transactionId),
147
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
+ }
148
185
  res.end([
149
- '<!doctype html><html lang="en"><head><meta charset="utf-8"><title>Authorize SSH MCP</title></head>',
150
- "<body><h1>Authorize SSH MCP</h1><p>Allow the client at ",
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;">',
151
197
  hostname,
152
- " to request: ",
198
+ "</strong> to request access to:</p>",
199
+ '<p><span class="badge">',
153
200
  escapeHtml(scope),
154
- '?</p><form method="post" action="/oauth/approve"><input type="hidden" name="transaction" value="',
201
+ "</span></p>",
202
+ '<form method="post" action="/oauth/approve"><input type="hidden" name="transaction" value="',
155
203
  escapeHtml(transactionId),
156
- '"><button type="submit">Continue with GitHub</button></form></body></html>',
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>",
157
238
  ].join(""));
158
239
  }
159
240
  /** Explicit browser approval binds this client to the current login transaction. */
160
241
  async handleApprove(req, res) {
161
242
  const form = await readJsonOrForm(req);
162
243
  const transactionId = form.transaction ?? "";
244
+ const provider = asString(form.provider) ?? "github";
163
245
  const pending = this.authorizeTransactions.get(transactionId);
164
246
  if (!pending || pending.expiresAt < Date.now() || !this.matchingBrowser(req, transactionId)) {
165
247
  throw safeError("INVALID_TOKEN", "OAuth transaction is missing or expired", 403);
166
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
+ }
167
263
  if (!this.config.githubClientId || !this.config.githubClientSecret) {
168
264
  throw safeError("FORBIDDEN", "GitHub OAuth is not configured", 503);
169
265
  }
@@ -173,7 +269,7 @@ export class OAuthHandler {
173
269
  githubUrl.searchParams.set("redirect_uri", this.config.githubCallbackUrl);
174
270
  githubUrl.searchParams.set("scope", "read:user");
175
271
  githubUrl.searchParams.set("state", transactionId);
176
- redirect(res, githubUrl.toString());
272
+ this.continueToGitHub(res, githubUrl);
177
273
  }
178
274
  validateAuthorizeParams(clientId, redirectUri, responseType, codeChallenge, codeChallengeMethod, resource, scope) {
179
275
  let client = this.store.getClient(clientId);
@@ -255,9 +351,9 @@ export class OAuthHandler {
255
351
  });
256
352
  return { ...client, redirectUris: updatedUris };
257
353
  }
258
- /** GET /oauth/callback/github */
259
- async handleGitHubCallback(req, res) {
260
- 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);
261
357
  const code = url.searchParams.get("code") ?? "";
262
358
  const state = url.searchParams.get("state") ?? "";
263
359
  const pending = this.authorizeTransactions.get(state);
@@ -268,17 +364,113 @@ export class OAuthHandler {
268
364
  !this.matchingBrowser(req, state)) {
269
365
  throw safeError("INVALID_TOKEN", "OAuth transaction is missing or expired");
270
366
  }
271
- const githubUser = await this.fetchGitHubUser(code);
272
- const user = this.upsertGitHubUser(githubUser);
273
- const authCode = this.issueAuthorizationCode(pending, user.id);
367
+ return { code, pending };
368
+ }
369
+ completeOAuthCallback(res, pending, userId) {
370
+ const authCode = this.issueAuthorizationCode(pending, userId);
274
371
  const destination = new URL(pending.redirectUri);
275
372
  destination.searchParams.set("code", authCode);
276
- if (pending.state) {
373
+ destination.searchParams.set("iss", this.config.publicBaseUrl);
374
+ if (pending.state)
277
375
  destination.searchParams.set("state", pending.state);
278
- }
279
376
  res.setHeader("Set-Cookie", this.transactionCookie("").replace("Max-Age=300", "Max-Age=0"));
280
377
  redirect(res, destination.toString());
281
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
+ }
282
474
  async fetchGitHubUser(code) {
283
475
  const tokenResponse = await fetch("https://github.com/login/oauth/access_token", {
284
476
  method: "POST",
@@ -299,9 +491,20 @@ export class OAuthHandler {
299
491
  headers: { Authorization: `Bearer ${accessToken}`, Accept: "application/vnd.github+json" },
300
492
  });
301
493
  const userPayload = (await userResponse.json());
302
- 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 };
303
504
  }
304
505
  testGitHubUser() {
506
+ if (!this.allowFixtureIdentity())
507
+ return undefined;
305
508
  const idValue = process.env.SSHAUTOMATOR_TEST_GITHUB_ID;
306
509
  const login = process.env.SSHAUTOMATOR_TEST_GITHUB_LOGIN;
307
510
  return idValue && login ? { id: idValue, login } : undefined;
@@ -394,6 +597,17 @@ export class OAuthHandler {
394
597
  return user;
395
598
  }
396
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
+ }
397
611
  throw safeError("UNAUTHORIZED", "User no longer exists", 401);
398
612
  }
399
613
  /** Remove expired pending authorization transactions. */