@opengeni/api-router 3.0.1 → 4.0.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 (96) hide show
  1. package/dist/admission-trace.d.ts +8 -0
  2. package/dist/app.js +1 -1
  3. package/dist/auth/managed-auth-attempt-context.d.ts +2 -0
  4. package/dist/auth/managed-auth-session-adapter.d.ts +2 -0
  5. package/dist/auth/managed-auth.d.ts +1 -0
  6. package/dist/auth/managed-sign-in-notifications.d.ts +4 -0
  7. package/dist/{chunk-AJ62T5QN.js → chunk-E7TZFJ65.js} +22300 -21113
  8. package/dist/{chunk-AJ62T5QN.js.map → chunk-E7TZFJ65.js.map} +1 -1
  9. package/dist/connection-ownership.d.ts +1 -2
  10. package/dist/fatal-process-boundary.d.ts +1 -1
  11. package/dist/index.js +24 -6
  12. package/dist/index.js.map +1 -1
  13. package/dist/integrations/atlassian.d.ts +8 -3
  14. package/dist/integrations/fiken.d.ts +3 -1
  15. package/dist/integrations/github-lens-connect.d.ts +5 -65
  16. package/dist/integrations/google-drive.d.ts +2 -0
  17. package/dist/integrations/integration-commit-authority.d.ts +13 -0
  18. package/dist/integrations/oauth-client.d.ts +119 -11
  19. package/dist/integrations/oauth-profiles.d.ts +8 -13
  20. package/dist/integrations/slack-interactions.d.ts +1 -1
  21. package/dist/mcp/capability-account-readiness.d.ts +7 -0
  22. package/dist/mcp/first-party-tool-permissions.d.ts +4 -0
  23. package/dist/mcp-oauth.d.ts +22 -1
  24. package/dist/routes/api-integrations.d.ts +1 -0
  25. package/dist/routes/codex.d.ts +28 -0
  26. package/dist/routes/managed-sign-in-methods.d.ts +6 -0
  27. package/dist/routes/organization-integration-policy.d.ts +3 -0
  28. package/dist/routes/sessions.d.ts +24 -2
  29. package/dist/scheduled-task-deletion.d.ts +3 -4
  30. package/dist/workspace-tool-gateway.d.ts +3 -1
  31. package/package.json +15 -15
  32. package/src/admission-trace.ts +14 -0
  33. package/src/app.ts +141 -94
  34. package/src/auth/managed-auth-attempt-context.ts +9 -0
  35. package/src/auth/managed-auth-session-adapter.ts +11 -0
  36. package/src/auth/managed-auth.ts +39 -2
  37. package/src/auth/managed-sign-in-notifications.ts +81 -0
  38. package/src/connection-ownership.ts +2 -9
  39. package/src/editable-artifact-production.ts +6 -0
  40. package/src/fatal-process-boundary.ts +17 -2
  41. package/src/index.ts +3 -4
  42. package/src/integrations/atlassian.ts +184 -76
  43. package/src/integrations/fiken.ts +57 -35
  44. package/src/integrations/github-app-connect.ts +51 -15
  45. package/src/integrations/github-lens-connect.ts +7 -28
  46. package/src/integrations/google-drive.ts +296 -125
  47. package/src/integrations/integration-commit-authority.ts +69 -0
  48. package/src/integrations/oauth-client.ts +231 -132
  49. package/src/integrations/oauth-profiles.ts +10 -45
  50. package/src/integrations/personal-github.ts +55 -31
  51. package/src/integrations/provider-oauth.ts +57 -82
  52. package/src/integrations/social-oauth.ts +83 -56
  53. package/src/mcp/capability-account-readiness.ts +17 -0
  54. package/src/mcp/editable-artifacts.ts +7 -2
  55. package/src/mcp/first-party-tool-permissions.ts +1 -0
  56. package/src/mcp/knowledge-entries.ts +25 -8
  57. package/src/mcp/server.ts +135 -43
  58. package/src/mcp-oauth.ts +336 -34
  59. package/src/routes/api-integrations.ts +116 -4
  60. package/src/routes/automations.ts +5 -13
  61. package/src/routes/billing.ts +52 -0
  62. package/src/routes/canonical-human-identities.ts +61 -0
  63. package/src/routes/capabilities.ts +51 -1
  64. package/src/routes/codex.ts +4 -2
  65. package/src/routes/connect.ts +90 -31
  66. package/src/routes/connections.ts +487 -307
  67. package/src/routes/files.ts +21 -12
  68. package/src/routes/github.ts +48 -19
  69. package/src/routes/insights.ts +17 -7
  70. package/src/routes/integration-facets.ts +66 -25
  71. package/src/routes/knowledge.ts +48 -1
  72. package/src/routes/managed-sign-in-methods.ts +433 -0
  73. package/src/routes/organization-integration-policy.ts +113 -0
  74. package/src/routes/organization-memberships.ts +22 -2
  75. package/src/routes/plugins.ts +42 -4
  76. package/src/routes/pr-review-github.ts +67 -57
  77. package/src/routes/pr-review.ts +74 -71
  78. package/src/routes/rigs.ts +32 -13
  79. package/src/routes/scheduled-tasks.ts +6 -6
  80. package/src/routes/sessions.ts +233 -11
  81. package/src/routes/skill-content.ts +19 -3
  82. package/src/routes/social.ts +24 -13
  83. package/src/sandbox/channel-a.ts +7 -1
  84. package/src/sandbox/rematerialize.ts +2 -1
  85. package/src/scheduled-task-deletion.ts +13 -3
  86. package/src/workspace-tool-gateway.ts +31 -31
  87. package/dist/connection-authority-owner.d.ts +0 -59
  88. package/dist/routes/connection-authorities.d.ts +0 -3
  89. package/dist/routes/host-mcp-bindings.d.ts +0 -5
  90. package/dist/routes/host-mcp-resolvers.d.ts +0 -3
  91. package/dist/routes/packs.d.ts +0 -3
  92. package/src/connection-authority-owner.ts +0 -61
  93. package/src/routes/connection-authorities.ts +0 -139
  94. package/src/routes/host-mcp-bindings.ts +0 -122
  95. package/src/routes/host-mcp-resolvers.ts +0 -41
  96. package/src/routes/packs.ts +0 -784
@@ -4,7 +4,6 @@ import { HTTPException } from "hono/http-exception";
4
4
  import type { ConnectAdvance, ConnectAttempt } from "@opengeni/contracts/connect";
5
5
  import {
6
6
  bindAuthorizedGitHubInstallationRepositories,
7
- claimConnectOperation,
8
7
  finishConnectOperation,
9
8
  getConnectAttempt,
10
9
  type ConnectActorScope,
@@ -23,7 +22,7 @@ import {
23
22
  import { commitGitHubLensConnect, requireGitHubLensConnect } from "./github-lens-connect";
24
23
  import type { ApiRouteDeps, PreparedConnectOperation } from "@opengeni/core";
25
24
  import { requireConnectOwnerAuthority } from "./connect-authority";
26
- import { integrationBaseUrl } from "./oauth-client";
25
+ import { claimOAuthAcquisition, finishOAuthAcquisition, integrationBaseUrl } from "./oauth-client";
27
26
  import {
28
27
  isConsistentGitHubBindingCandidates,
29
28
  isConsistentGitHubBindingProof,
@@ -177,27 +176,52 @@ export async function completeGitHubAppConnect(
177
176
  const stored = await getConnectAttempt(deps.db, state, state.connectAttemptId);
178
177
  if (stored.attempt.providerId !== state.providerId || stored.attempt.ownership !== "workspace")
179
178
  throw new Error("GitHub attempt mismatch");
180
- destination = stored.returnUrl;
181
179
  // Reject obsolete browser stages before committing an operation claim.
182
180
  // Otherwise a valid older callback could strand the current stage in-flight.
183
181
  // Completed callbacks still navigate home without repeating provider work.
184
- if (
185
- stored.attempt.nextAction.type !== "authorize" ||
186
- new URL(stored.attempt.nextAction.url).searchParams.get("state") !== input.state
187
- )
188
- throw new Error("Stale GitHub setup stage");
189
- if (state.providerId === "github-lens") await requireGitHubLensConnect(deps, state.workspaceId);
190
- const authorize = callbackAuthority(state);
182
+ const authorize: ConnectOperationAuthorization = async (tx, attempt, origin) => {
183
+ await callbackAuthority(state)(tx, attempt, origin);
184
+ destination = stored.returnUrl;
185
+ };
186
+ const acquiring =
187
+ !input.error && (state.phase === "install" ? input.setupAction !== "request" : !!input.code);
191
188
  const operation = {
192
189
  attemptId: state.connectAttemptId,
193
190
  operationId: `github:${state.nonce}`,
194
191
  inputDigest: createHash("sha256").update(input.state!).digest("hex"),
195
192
  authorize,
196
193
  };
197
- const claim = await claimConnectOperation(deps.db, state, {
198
- ...operation,
199
- expectedRevision: stored.attempt.revision,
200
- });
194
+ const claim = await claimOAuthAcquisition(
195
+ deps.db,
196
+ state,
197
+ {
198
+ ...operation,
199
+ expectedRevision: stored.attempt.revision,
200
+ authorizeAcquisition: async (tx, current) => {
201
+ if (
202
+ current.nextAction.type !== "authorize" ||
203
+ new URL(current.nextAction.url).searchParams.get("state") !== input.state
204
+ )
205
+ throw new Error("Stale GitHub setup stage");
206
+ if (acquiring && state.providerId === "github-lens")
207
+ await requireGitHubLensConnect({ ...deps, db: tx });
208
+ },
209
+ },
210
+ state.providerId,
211
+ acquiring,
212
+ );
213
+ // Recover a repeated install callback only while its next stage is still
214
+ // current. A completed/superseded attempt returns home without reopening OAuth.
215
+ if (
216
+ claim.status === "replayed" &&
217
+ state.phase === "install" &&
218
+ claim.attempt.revision === stored.attempt.revision &&
219
+ claim.attempt.nextAction.type === "authorize"
220
+ )
221
+ return new Response(null, {
222
+ status: 302,
223
+ headers: { Location: claim.attempt.nextAction.url },
224
+ });
201
225
  if (claim.status !== "replayed") {
202
226
  const provider =
203
227
  state.providerId === "github-lens" ? deps.prReviewGithubAppApi : deps.githubAppApi;
@@ -378,7 +402,19 @@ export async function completeGitHubAppConnect(
378
402
  },
379
403
  };
380
404
  }
381
- await finishConnectOperation(deps.db, state, { ...operation, commit: prepared.commit });
405
+ const completed = acquiring
406
+ ? await finishOAuthAcquisition(
407
+ deps.db,
408
+ state,
409
+ { ...operation, commit: prepared.commit },
410
+ state.providerId,
411
+ )
412
+ : await finishConnectOperation(deps.db, state, { ...operation, commit: prepared.commit });
413
+ // Installation is only the first half of consent. Keep this browser on
414
+ // the exact authorization stage committed above; polling still waits for
415
+ // the final owner proof before reporting connection completion.
416
+ if (state.phase === "install" && completed.nextAction.type === "authorize")
417
+ return new Response(null, { status: 302, headers: { Location: completed.nextAction.url } });
382
418
  }
383
419
  } catch {
384
420
  // Preserve unknown outcomes; never replay provider authorization to recover.
@@ -1,35 +1,20 @@
1
1
  import { environmentsEncryptionKeyBytes } from "@opengeni/config";
2
- import {
3
- OPENGENI_PR_REVIEW_PACK_ID,
4
- type GitHubInstallationBindingProof,
5
- } from "@opengeni/contracts";
6
- import {
7
- getCapabilityPack,
8
- PR_REVIEW_AUTOMATION_TEMPLATE_ID,
9
- prReviewPackConnectorId,
10
- type ApiRouteDeps,
11
- } from "@opengeni/core";
2
+ import { type GitHubInstallationBindingProof } from "@opengeni/contracts";
3
+ import { PR_REVIEW_AUTOMATION_SETUP, type ApiRouteDeps } from "@opengeni/core";
12
4
  import {
13
5
  encryptVariableSetValue,
14
- getPackInstallation,
15
6
  recordAuditEvent,
16
7
  syncManagedGitHubPrReviewInstallation,
17
8
  type Database,
18
9
  } from "@opengeni/db";
19
10
  import { HTTPException } from "hono/http-exception";
20
11
 
21
- export async function requireGitHubLensConnect(deps: ApiRouteDeps, workspaceId: string) {
12
+ export async function requireGitHubLensConnect(deps: ApiRouteDeps) {
22
13
  if (deps.settings.sandboxBackend === "selfhosted")
23
14
  throw new HTTPException(409, { message: "OpenGeni Lens requires managed compute" });
24
- const installation = await getPackInstallation(deps.db, workspaceId, OPENGENI_PR_REVIEW_PACK_ID);
25
- if (installation?.status !== "active")
26
- throw new HTTPException(409, { message: "Install and enable the Review Bot Pack first" });
27
- const template = getCapabilityPack(OPENGENI_PR_REVIEW_PACK_ID)?.automationTemplates?.find(
28
- (value) => value.id === PR_REVIEW_AUTOMATION_TEMPLATE_ID,
29
- );
30
- if (!template || !environmentsEncryptionKeyBytes(deps.settings))
31
- throw new HTTPException(503, { message: "Lens template or secret encryption is unavailable" });
32
- return { installation, template };
15
+ if (!environmentsEncryptionKeyBytes(deps.settings))
16
+ throw new HTTPException(503, { message: "Lens secret encryption is unavailable" });
17
+ return { template: PR_REVIEW_AUTOMATION_SETUP };
33
18
  }
34
19
 
35
20
  /** Separate Lens registration/source/automation domain, not a repository-access
@@ -48,10 +33,7 @@ export async function commitGitHubLensConnect(
48
33
  nonce: string;
49
34
  },
50
35
  ) {
51
- const { installation, template } = await requireGitHubLensConnect(
52
- { ...deps, db: tx },
53
- input.workspaceId,
54
- );
36
+ const { template } = await requireGitHubLensConnect({ ...deps, db: tx });
55
37
  const synchronized = await syncManagedGitHubPrReviewInstallation(tx, {
56
38
  accountId: input.accountId,
57
39
  workspaceId: input.workspaceId,
@@ -70,9 +52,6 @@ export async function commitGitHubLensConnect(
70
52
  ),
71
53
  repositories: input.proof.repositories,
72
54
  createdBySubjectId: input.subjectId,
73
- packInstallationId: installation.id,
74
- packConnectorId: prReviewPackConnectorId("github"),
75
- packTemplateId: template.id,
76
55
  adapterId: template.adapterId,
77
56
  eventTypes: template.eventTypes,
78
57
  configuration: template.configuration,