@desplega.ai/agent-swarm 1.129.0 → 1.131.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.
- package/README.md +2 -2
- package/dist/{actions-kfv2dawe.js → actions-w53mbns9.js} +11 -11
- package/dist/{anthropic-messages-3xgme8my.js → anthropic-messages-rjmd2e7n.js} +5 -5
- package/dist/{app-q8vjk6e8.js → app-m9gwqsqv.js} +8 -8
- package/dist/{artifact-hg4t1nx7.js → artifact-jysj3wrg.js} +2 -2
- package/dist/{assistant-g037r345.js → assistant-bp65m6f3.js} +13 -13
- package/dist/{azure-openai-responses-xa4sh9f6.js → azure-openai-responses-c0yjmbfd.js} +8 -5
- package/dist/{boot-reembed-18pzsrxa.js → boot-reembed-62p0at2k.js} +6 -6
- package/dist/{boot-reembed-wpks2cj8.js → boot-reembed-xmfp6wdh.js} +7 -7
- package/dist/{boot-scrub-logs-n7szd57r.js → boot-scrub-logs-rr8q2dms.js} +5 -5
- package/dist/{claude-adapter-qz4r0ajt.js → claude-adapter-2y47mrkd.js} +9 -9
- package/dist/{cli-mhjnbgb6.js → cli-0rcyq6d9.js} +450 -186
- package/dist/{cli-ttkmehy0.js → cli-2q72qz2s.js} +274 -25
- package/dist/{cli-gztgc3hz.js → cli-2wadx7p2.js} +2 -2
- package/dist/cli-3fj60etf.js +153 -0
- package/dist/{cli-7ecgm5v0.js → cli-3kf51j15.js} +1 -1
- package/dist/{cli-vgexpfsr.js → cli-57khth04.js} +6 -3
- package/dist/{cli-2mbe7vk0.js → cli-5dsbcjjw.js} +1 -1
- package/dist/{cli-etr62zy6.js → cli-5kx36evn.js} +2 -2
- package/dist/{cli-v2tr6amf.js → cli-5n6e5yfn.js} +30 -8
- package/dist/{cli-hx02s9zq.js → cli-5v4rw6yd.js} +2 -2
- package/dist/{cli-v37yr6mf.js → cli-5ze9rv97.js} +4 -4
- package/dist/{cli-ch7t5v7n.js → cli-6map995v.js} +9 -4
- package/dist/{cli-h0457a67.js → cli-70xqj0z3.js} +3 -3
- package/dist/{cli-kk4f9r17.js → cli-72q8m8gk.js} +8 -6
- package/dist/{cli-7padk69a.js → cli-78xwvkhj.js} +2 -2
- package/dist/{cli-dxtxacy7.js → cli-9dr5qzc0.js} +45 -8
- package/dist/{cli-17zxdgsq.js → cli-a40rnf71.js} +6 -6
- package/dist/{cli-t53vnnxz.js → cli-a4jzdpa3.js} +2514 -1055
- package/dist/{cli-w10fkrf1.js → cli-akdvwc9v.js} +354 -115
- package/dist/{cli-1qkk5er0.js → cli-bmze986d.js} +1 -1
- package/dist/{cli-ga12dc1d.js → cli-bqw0mt1n.js} +3 -3
- package/dist/{cli-0sf92efp.js → cli-cdeg08wx.js} +1 -1
- package/dist/{cli-a8ynhkyj.js → cli-cvgjwnh1.js} +17 -15
- package/dist/{cli-9fxg3v5m.js → cli-d2tfkcga.js} +4 -4
- package/dist/{cli-nhcd7x43.js → cli-d3x3x1c9.js} +2 -2
- package/dist/{cli-6nh2qxvh.js → cli-darcwax3.js} +1 -1
- package/dist/{cli-yjbgmysx.js → cli-e7ckcg4v.js} +12 -12
- package/dist/{cli-4n2gcjpd.js → cli-efxfnq6q.js} +4 -3
- package/dist/{cli-z9xqqhfk.js → cli-er3a4bb0.js} +1 -1
- package/dist/{cli-xg2eezyv.js → cli-f1am9szv.js} +1 -1
- package/dist/{cli-xy4cwsm9.js → cli-fywms69x.js} +1 -1
- package/dist/{cli-33jj76y8.js → cli-g6b8x1h8.js} +1 -1
- package/dist/{cli-epsvdckx.js → cli-gm9cbhbq.js} +20 -10
- package/dist/{cli-rkndnn90.js → cli-k9qkf1hw.js} +6 -4
- package/dist/{cli-zejvt395.js → cli-kh3ba2zf.js} +1 -1
- package/dist/{cli-gb25p1h2.js → cli-nm5gtp1x.js} +2 -2
- package/dist/{cli-akxnpx17.js → cli-pm6xbh84.js} +1829 -1629
- package/dist/{cli-2k0ztbfp.js → cli-psh3c4va.js} +1 -1
- package/dist/{cli-39vgrsep.js → cli-qv61hp37.js} +2 -2
- package/dist/{cli-hv2fndhm.js → cli-r6kqqbj0.js} +6 -4
- package/dist/{cli-1y1cm570.js → cli-rzbpmxdr.js} +1 -1
- package/dist/{cli-mmrk00vp.js → cli-t1xze5qh.js} +1 -1
- package/dist/{cli-g252a9ky.js → cli-t55yw3a1.js} +2 -2
- package/dist/{cli-7bz8dzqa.js → cli-t76vw5db.js} +1184 -1522
- package/dist/{cli-4n4mdv21.js → cli-xpxde7rm.js} +7 -3
- package/dist/{cli-fpaa5k2q.js → cli-yw8vghx2.js} +54 -18
- package/dist/cli-zsspvvm2.js +490 -0
- package/dist/cli.js +27 -25
- package/dist/{codex-adapter-7v6t7ff6.js → codex-adapter-d24q75wk.js} +7 -7
- package/dist/{codex-hook-amndawyb.js → codex-hook-hq54t9ft.js} +2 -2
- package/dist/{codex-session-runner-e7j4khe2.js → codex-session-runner-g50vcsex.js} +7 -7
- package/dist/{commands-ex0k5tbf.js → commands-c3nrc5hg.js} +5 -5
- package/dist/{db-df7jatfc.js → db-nt7fg3tw.js} +5 -5
- package/dist/{google-generative-ai-y42hnw9p.js → google-generative-ai-hysrd8qx.js} +7 -5
- package/dist/{google-vertex-4sg66gb6.js → google-vertex-p5arrga0.js} +7 -5
- package/dist/{handlers-1j2cfqt2.js → handlers-fkr6swat.js} +13 -13
- package/dist/{hook-nx9a0mj3.js → hook-77wpvnjc.js} +7 -7
- package/dist/{hook-w6yaf6sy.js → hook-g019yehy.js} +8 -8
- package/dist/{http-4tz5h8wg.js → http-jewj0syk.js} +2993 -716
- package/dist/{index-0bpkzb09.js → index-070v4eyb.js} +3 -3
- package/dist/{index-0s67qv7h.js → index-6gm5he8h.js} +11 -11
- package/dist/{index-35gtv6gj.js → index-7n2xpbd4.js} +310 -40
- package/dist/{index-ker3gccb.js → index-9znhar3x.js} +4 -4
- package/dist/{index-5n2c8yay.js → index-hase6zbe.js} +2 -2
- package/dist/{index-kcf3tm9h.js → index-hfvggd0z.js} +12 -12
- package/dist/{index-7c0jqna0.js → index-hp1kdbjj.js} +13 -13
- package/dist/{keepalive-3j4a9168.js → keepalive-j0fjvqfd.js} +7 -7
- package/dist/{lead-6kpevymb.js → lead-1n8x30xe.js} +33 -33
- package/dist/{maintenance-m1k82ean.js → maintenance-gvev11sa.js} +7 -7
- package/dist/{mistral-conversations-bjkdfb6z.js → mistral-conversations-81fwav0j.js} +6 -6
- package/dist/{oauth-refresh-sweep-881k8e4q.js → oauth-refresh-sweep-s9ecsvh0.js} +6 -6
- package/dist/{onboard-c0ykffjn.js → onboard-pvm5b38w.js} +2 -2
- package/dist/{openai-codex-responses-xetseqvt.js → openai-codex-responses-5g27pd6f.js} +43 -23
- package/dist/{openai-completions-5r2g5axa.js → openai-completions-3vkmfz2a.js} +55 -11
- package/dist/{openai-responses-ce67hd23.js → openai-responses-dg4t7j7a.js} +8 -5
- package/dist/{openrouter-images-pzfp22jb.js → openrouter-images-g3gm8931.js} +1 -1
- package/dist/{otel-impl-sqagjerv.js → otel-impl-p6jvgd9c.js} +6 -4
- package/dist/{otel-3mp81ppd.js → otel-nqa12wf3.js} +2 -2
- package/dist/{pi-mono-adapter-k584k16g.js → pi-mono-adapter-t091s27g.js} +17117 -7517
- package/dist/{pricing-refresh-y82whbf9.js → pricing-refresh-k49rcyed.js} +7 -7
- package/dist/{rbac-roles-nvkqmzyd.js → rbac-roles-30pspvy7.js} +7 -7
- package/dist/{rbac-roles-4ht8gegc.js → rbac-roles-cr80g96t.js} +6 -6
- package/dist/{render-v2-wvqdgvvp.js → render-v2-xm457ng1.js} +8 -8
- package/dist/{seed-pricing-fy3rxhde.js → seed-pricing-yhpv35fr.js} +6 -6
- package/dist/{setup-ak5cnc6f.js → setup-nytnmwwr.js} +2 -2
- package/dist/{worker-d8769q8a.js → worker-msytr2cw.js} +33 -33
- package/openapi.json +34039 -11036
- package/package.json +8 -6
- package/src/apps/definition.ts +368 -26
- package/src/apps/row-store.ts +66 -10
- package/src/apps/schema-migrate.ts +95 -1
- package/src/apps/store.ts +13 -4
- package/src/apps/sync-run-as.ts +18 -0
- package/src/apps/sync.ts +934 -0
- package/src/apps/version.ts +16 -2
- package/src/assets/key.ts +8 -1
- package/src/be/asset-key-audit.ts +3 -1
- package/src/be/db-queries/mcp-oauth.ts +297 -24
- package/src/be/db.ts +42 -1
- package/src/be/migrations/129_asset_keys_apps_scripts.sql +161 -0
- package/src/be/scripts/db.ts +5 -2
- package/src/be/scripts/typecheck.ts +1 -0
- package/src/be/seed-scripts/catalog/app-sync-run.ts +32 -0
- package/src/be/seed-scripts/catalog/github-issues-pull.ts +102 -0
- package/src/be/seed-scripts/index.ts +18 -0
- package/src/be/seed-skills/index.ts +7 -0
- package/src/http/active-sessions.ts +26 -18
- package/src/http/agents.ts +94 -27
- package/src/http/api-keys.ts +91 -17
- package/src/http/approval-requests.ts +87 -10
- package/src/http/apps.ts +361 -53
- package/src/http/assets.ts +165 -31
- package/src/http/budgets.ts +7 -5
- package/src/http/codex-oauth-keep-warm.ts +21 -3
- package/src/http/config.ts +46 -16
- package/src/http/context.ts +33 -6
- package/src/http/ecosystem.ts +20 -6
- package/src/http/events.ts +24 -9
- package/src/http/favorites.ts +20 -6
- package/src/http/fs.ts +60 -17
- package/src/http/heartbeat.ts +18 -4
- package/src/http/inbox-state.ts +12 -6
- package/src/http/integrations.ts +25 -5
- package/src/http/kv.ts +36 -15
- package/src/http/mcp-bridge.ts +5 -1
- package/src/http/mcp-oauth.ts +332 -17
- package/src/http/mcp-servers.ts +56 -18
- package/src/http/memory.ts +282 -29
- package/src/http/metrics.ts +80 -17
- package/src/http/oauth-callback.ts +10 -4
- package/src/http/oauth-generic.ts +5 -1
- package/src/http/oauth-locks.ts +6 -3
- package/src/http/openapi.ts +57 -9
- package/src/http/page-proxy.ts +25 -5
- package/src/http/pages-public.ts +37 -20
- package/src/http/pages.ts +93 -28
- package/src/http/poll.ts +89 -5
- package/src/http/pricing.ts +9 -6
- package/src/http/prompt-templates.ts +85 -21
- package/src/http/route-def.ts +67 -4
- package/src/http/schedules.ts +63 -14
- package/src/http/script-connection-proxy.ts +30 -4
- package/src/http/script-connections.ts +393 -43
- package/src/http/script-runs.ts +73 -19
- package/src/http/scripts.ts +257 -39
- package/src/http/session-data.ts +87 -14
- package/src/http/sessions.ts +80 -5
- package/src/http/skills.ts +115 -35
- package/src/http/stats.ts +94 -13
- package/src/http/task-templates.ts +6 -4
- package/src/http/tasks.ts +230 -61
- package/src/http/trackers/jira.ts +90 -30
- package/src/http/trackers/linear.ts +46 -12
- package/src/http/users.ts +162 -25
- package/src/http/utils.ts +12 -2
- package/src/http/webhooks.ts +30 -16
- package/src/http/workflow-events.ts +18 -5
- package/src/http/workflows.ts +128 -39
- package/src/http/x.ts +37 -6
- package/src/oauth/ensure-mcp-token.ts +16 -1
- package/src/oauth/mcp-wrapper.ts +281 -26
- package/src/providers/pi-mono-adapter.ts +1 -1
- package/src/scripts-runtime/credential-broker/README.md +1 -1
- package/src/scripts-runtime/credential-broker/fetch-patch.ts +12 -2
- package/src/scripts-runtime/sdk-allowlist.ts +1 -0
- package/src/scripts-runtime/stdlib/fetch.ts +6 -0
- package/src/scripts-runtime/types/stdlib.d.ts +1 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +1 -0
- package/src/server.ts +2 -0
- package/src/tests/apps-rbac.test.ts +110 -0
- package/src/tests/apps-spike2.test.ts +4 -1
- package/src/tests/apps-sync-engine.test.ts +2540 -0
- package/src/tests/apps-sync.test.ts +1627 -0
- package/src/tests/asset-key-api.test.ts +48 -2
- package/src/tests/asset-key-invariants.test.ts +92 -0
- package/src/tests/asset-key-migration.test.ts +174 -8
- package/src/tests/asset-key-normalization.test.ts +2 -0
- package/src/tests/credential-broker.test.ts +27 -2
- package/src/tests/mcp-oauth-dcr-reuse.test.ts +743 -0
- package/src/tests/mcp-oauth-ensure-token.test.ts +45 -0
- package/src/tests/mcp-oauth-manual-client.test.ts +135 -2
- package/src/tests/mcp-oauth-queries.test.ts +153 -0
- package/src/tests/mcp-oauth-wrapper.test.ts +432 -0
- package/src/tests/memory-http-recall-gating.test.ts +2 -0
- package/src/tests/openapi-response-contract.test.ts +138 -0
- package/src/tests/rbac-admission-e2e.test.ts +68 -0
- package/src/tests/script-connections.test.ts +3 -0
- package/src/tests/scripts-runtime-fetch.test.ts +121 -0
- package/src/tests/scripts-runtime-secret-egress.test.ts +4 -2
- package/src/tests/seed-scripts.test.ts +2 -2
- package/src/tests/swarm-tool-result-gate.test.ts +32 -0
- package/src/tests/task-working-dir.test.ts +8 -4
- package/src/tests/whoami-route.test.ts +127 -0
- package/src/tests/workflow-engine-v2.test.ts +80 -7
- package/src/tests/workflow-swarm-script.test.ts +104 -0
- package/src/tools/app-get.ts +10 -2
- package/src/tools/app-rollback.ts +1 -0
- package/src/tools/app-sync.ts +112 -0
- package/src/tools/script-common.ts +20 -0
- package/src/tools/tool-config.ts +2 -1
- package/src/tools/utils.ts +11 -0
- package/src/tools/workflows/create-workflow.ts +4 -1
- package/src/types.ts +1394 -1206
- package/src/utils/template.ts +8 -1
- package/src/utils/zod-openapi.ts +11 -0
- package/src/workflows/engine.ts +27 -4
- package/src/workflows/executors/swarm-script.ts +28 -0
- package/src/workflows/retry-poller.ts +19 -2
- package/templates/skills/apps/content.md +94 -5
- package/templates/skills/asset-namespaces/content.md +2 -2
- package/templates/skills/scheduled-task-resilience/SKILL.md +102 -0
- package/templates/skills/scheduled-task-resilience/config.json +14 -0
- package/templates/skills/scheduled-task-resilience/content.md +97 -0
- package/dist/cli-7wmybrt5.js +0 -115
- package/dist/cli-d91pvmq1.js +0 -14
|
@@ -59,7 +59,7 @@ import { resolveScopedResourceId, scopedResourceScopeIdSchema } from "@/utils/sc
|
|
|
59
59
|
import { registerVolatileSecret, scrubSecrets } from "@/utils/secret-scrubber";
|
|
60
60
|
import { staticOAuthCallbackUri } from "./oauth-callback";
|
|
61
61
|
import { route } from "./route-def";
|
|
62
|
-
import {
|
|
62
|
+
import { jsonError } from "./utils";
|
|
63
63
|
|
|
64
64
|
const providerSchema = z
|
|
65
65
|
.string()
|
|
@@ -163,6 +163,257 @@ const discoverOAuthAppBodySchema = z.object({
|
|
|
163
163
|
url: z.string().url(),
|
|
164
164
|
});
|
|
165
165
|
|
|
166
|
+
// ─── Response schemas ────────────────────────────────────────────────────────
|
|
167
|
+
// Local zod mirrors of the response shapes built by this handler. Nothing in
|
|
168
|
+
// src/types.ts models script connections / OAuth apps / credential bindings,
|
|
169
|
+
// so these are defined here rather than reusing a shared entity schema.
|
|
170
|
+
|
|
171
|
+
const oauthBindingTokenStatusSchema = z.enum([
|
|
172
|
+
"ok",
|
|
173
|
+
"expiring",
|
|
174
|
+
"refresh-failed",
|
|
175
|
+
"revoked",
|
|
176
|
+
"missing",
|
|
177
|
+
]);
|
|
178
|
+
|
|
179
|
+
const oauthAuthorizationStatusSchema = z.enum(["active", "refresh-failed", "expired", "revoked"]);
|
|
180
|
+
|
|
181
|
+
const credentialAuthKindSchema = z.enum(["config", "oauth"]);
|
|
182
|
+
|
|
183
|
+
const connectionAuthTypeResponseSchema = z.enum(["none", "bearer", "header", "query", "oauth"]);
|
|
184
|
+
|
|
185
|
+
// DB CHECK constraint on script_connections.kind also allows the legacy 'raw'
|
|
186
|
+
// value (never written via this handler's upsert path, but readable via the
|
|
187
|
+
// list/get routes for rows written elsewhere) — wider than the HTTP-body-only
|
|
188
|
+
// `connectionKindSchema` above.
|
|
189
|
+
const connectionRecordKindSchema = z.enum(["raw", "openapi", "mcp", "graphql"]);
|
|
190
|
+
|
|
191
|
+
const bindingSummarySchema = z.object({
|
|
192
|
+
id: z.string(),
|
|
193
|
+
configKey: z.string(),
|
|
194
|
+
authKind: credentialAuthKindSchema,
|
|
195
|
+
oauthAuthorizationId: z.string().optional(),
|
|
196
|
+
tokenStatus: oauthBindingTokenStatusSchema.optional(),
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
const connectionAuthSummaryResponseSchema = z.object({
|
|
200
|
+
type: connectionAuthTypeResponseSchema,
|
|
201
|
+
configKey: z.string().optional(),
|
|
202
|
+
authorizationId: z.string().optional(),
|
|
203
|
+
paramName: z.string().optional(),
|
|
204
|
+
status: oauthBindingTokenStatusSchema.optional(),
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
const decoratedConnectionSchema = z.object({
|
|
208
|
+
id: z.string(),
|
|
209
|
+
slug: z.string(),
|
|
210
|
+
displayName: z.string().nullable(),
|
|
211
|
+
kind: connectionRecordKindSchema,
|
|
212
|
+
scope: scopeSchema,
|
|
213
|
+
scopeId: z.string().nullable(),
|
|
214
|
+
baseUrl: z.string().nullable(),
|
|
215
|
+
baseUrlSource: z.enum(["user", "spec"]),
|
|
216
|
+
baseUrlMismatch: z.object({ specUrl: z.string(), effectiveUrl: z.string() }).optional(),
|
|
217
|
+
allowedHosts: z.array(z.string()),
|
|
218
|
+
credentialBindingId: z.string().nullable(),
|
|
219
|
+
authType: connectionAuthTypeResponseSchema,
|
|
220
|
+
authConfigKey: z.string().nullable(),
|
|
221
|
+
authAuthorizationId: z.string().nullable(),
|
|
222
|
+
authParamName: z.string().nullable(),
|
|
223
|
+
authTemplateOverride: z.string().nullable(),
|
|
224
|
+
authHostsOverride: z.array(z.string()).nullable(),
|
|
225
|
+
openapiSpecSourceKind: z.enum(["url", "inline", "agent_fs", "vendored"]).nullable(),
|
|
226
|
+
openapiSpecSource: z.string().nullable(),
|
|
227
|
+
openapiSpecEtag: z.string().nullable(),
|
|
228
|
+
openapiSpecFetchedAt: z.string().nullable(),
|
|
229
|
+
mcpServerId: z.string().nullable(),
|
|
230
|
+
generatedAt: z.string().nullable(),
|
|
231
|
+
generationError: z.string().nullable(),
|
|
232
|
+
enabled: z.boolean(),
|
|
233
|
+
version: z.number(),
|
|
234
|
+
createdAt: z.string(),
|
|
235
|
+
updatedAt: z.string(),
|
|
236
|
+
createdBy: z.string().nullable(),
|
|
237
|
+
updatedBy: z.string().nullable(),
|
|
238
|
+
operationCount: z.number(),
|
|
239
|
+
toolCount: z.number(),
|
|
240
|
+
credentialBinding: bindingSummarySchema.nullable(),
|
|
241
|
+
auth: connectionAuthSummaryResponseSchema,
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
const connectionDetailSchema = decoratedConnectionSchema.extend({
|
|
245
|
+
operations: z.array(
|
|
246
|
+
z.object({
|
|
247
|
+
name: z.string(),
|
|
248
|
+
method: z.string(),
|
|
249
|
+
path: z.string(),
|
|
250
|
+
parameters: z
|
|
251
|
+
.array(
|
|
252
|
+
z.object({
|
|
253
|
+
name: z.string(),
|
|
254
|
+
in: z.string(),
|
|
255
|
+
required: z.boolean(),
|
|
256
|
+
schema: z.unknown().optional(),
|
|
257
|
+
}),
|
|
258
|
+
)
|
|
259
|
+
.optional(),
|
|
260
|
+
hasBody: z.boolean().optional(),
|
|
261
|
+
successStatus: z.string().optional(),
|
|
262
|
+
requestBodySchema: z.unknown().optional(),
|
|
263
|
+
responseSchema: z.unknown().optional(),
|
|
264
|
+
}),
|
|
265
|
+
),
|
|
266
|
+
tools: z.array(
|
|
267
|
+
z.object({
|
|
268
|
+
name: z.string(),
|
|
269
|
+
description: z.string().optional(),
|
|
270
|
+
inputSchema: z.unknown().optional(),
|
|
271
|
+
}),
|
|
272
|
+
),
|
|
273
|
+
graphql: z.boolean(),
|
|
274
|
+
generatedTypes: z.string(),
|
|
275
|
+
specSummary: z
|
|
276
|
+
.object({
|
|
277
|
+
title: z.string().optional(),
|
|
278
|
+
version: z.string().optional(),
|
|
279
|
+
pathCount: z.number(),
|
|
280
|
+
})
|
|
281
|
+
.optional(),
|
|
282
|
+
specPreview: z.object({ json: z.string(), truncated: z.boolean() }).optional(),
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
const scriptCredentialBindingRecordSchema = z.object({
|
|
286
|
+
id: z.string(),
|
|
287
|
+
configKey: z.string(),
|
|
288
|
+
allowedHosts: z.array(z.string()),
|
|
289
|
+
headerTemplate: z.string().optional(),
|
|
290
|
+
queryTemplate: z.string().optional(),
|
|
291
|
+
scope: scopeSchema,
|
|
292
|
+
// ScriptCredentialBindingRecord inherits this from the zod-inferred
|
|
293
|
+
// CredentialBinding type (`.nullable().optional()`); bindingFromRow always
|
|
294
|
+
// sets a concrete `string | null` at runtime, but the declared TS type
|
|
295
|
+
// still allows `undefined`.
|
|
296
|
+
scopeId: z.string().nullable().optional(),
|
|
297
|
+
active: z.boolean(),
|
|
298
|
+
authKind: credentialAuthKindSchema,
|
|
299
|
+
oauthAuthorizationId: z.string().optional(),
|
|
300
|
+
source: z.enum(["default", "user", "migration", "connection"]),
|
|
301
|
+
managedByConnectionId: z.string().nullable(),
|
|
302
|
+
createdAt: z.string(),
|
|
303
|
+
updatedAt: z.string(),
|
|
304
|
+
createdBy: z.string().nullable(),
|
|
305
|
+
updatedBy: z.string().nullable(),
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
const decoratedBindingSchema = scriptCredentialBindingRecordSchema.extend({
|
|
309
|
+
tokenStatus: oauthBindingTokenStatusSchema.optional(),
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
const oauthPresetSchema = z.object({
|
|
313
|
+
id: z.string(),
|
|
314
|
+
displayName: z.string(),
|
|
315
|
+
provider: z.string(),
|
|
316
|
+
authorizeUrl: z.string(),
|
|
317
|
+
tokenUrl: z.string(),
|
|
318
|
+
revocationUrl: z.string().optional(),
|
|
319
|
+
userinfoUrl: z.string().optional(),
|
|
320
|
+
scopes: z.array(z.string()),
|
|
321
|
+
scopeSeparator: z.string().optional(),
|
|
322
|
+
tokenAuthStyle: z.enum(["body", "basic"]).optional(),
|
|
323
|
+
tokenBodyFormat: z.enum(["form", "json"]).optional(),
|
|
324
|
+
requiresRefreshTokenRotation: z.boolean().optional(),
|
|
325
|
+
extraParams: z.record(z.string(), z.string()).optional(),
|
|
326
|
+
setupHints: z.array(z.string()),
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
const sanitizedAuthorizationSchema = z.object({
|
|
330
|
+
id: z.string(),
|
|
331
|
+
label: z.string(),
|
|
332
|
+
accountEmail: z.string().nullable(),
|
|
333
|
+
status: oauthAuthorizationStatusSchema,
|
|
334
|
+
expiresAt: z.string().nullable(),
|
|
335
|
+
scope: z.string().nullable(),
|
|
336
|
+
hasRefreshToken: z.boolean(),
|
|
337
|
+
lastErrorMessage: z.string().nullable(),
|
|
338
|
+
lastRefreshedAt: z.string().nullable(),
|
|
339
|
+
createdAt: z.string(),
|
|
340
|
+
updatedAt: z.string(),
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
const sanitizedOAuthAppSchema = z.object({
|
|
344
|
+
id: z.string(),
|
|
345
|
+
provider: z.string(),
|
|
346
|
+
clientId: z.string(),
|
|
347
|
+
authorizeUrl: z.string(),
|
|
348
|
+
tokenUrl: z.string(),
|
|
349
|
+
redirectUri: z.string(),
|
|
350
|
+
scopes: z.array(z.string()),
|
|
351
|
+
extraParams: z.record(z.string(), z.string()).optional(),
|
|
352
|
+
tokenAuthStyle: z.enum(["body", "basic"]),
|
|
353
|
+
tokenBodyFormat: z.enum(["form", "json"]),
|
|
354
|
+
source: z.string(),
|
|
355
|
+
tokenStatus: oauthBindingTokenStatusSchema,
|
|
356
|
+
expiresAt: z.string().nullable(),
|
|
357
|
+
lastRefreshedAt: z.string().nullable(),
|
|
358
|
+
authorizations: z.array(sanitizedAuthorizationSchema),
|
|
359
|
+
createdAt: z.string(),
|
|
360
|
+
updatedAt: z.string(),
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
const integrationsCatalogEntrySchema = z.object({
|
|
364
|
+
id: z.string(),
|
|
365
|
+
kind: z.string(),
|
|
366
|
+
slug: z.string(),
|
|
367
|
+
name: z.string(),
|
|
368
|
+
description: z.string(),
|
|
369
|
+
url: z.string(),
|
|
370
|
+
icon: z.string().nullable(),
|
|
371
|
+
domain: z.string(),
|
|
372
|
+
categories: z.array(z.string()),
|
|
373
|
+
feeds: z.array(z.string()),
|
|
374
|
+
vendoredSlug: z.string().optional(),
|
|
375
|
+
presetId: z.string().optional(),
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
const integrationsCatalogListSchema = z.object({
|
|
379
|
+
entries: z.array(integrationsCatalogEntrySchema),
|
|
380
|
+
cachedAt: z.string(),
|
|
381
|
+
partial: z.boolean(),
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
const integrationsSurfaceMechanicsSchema = z.object({
|
|
385
|
+
in: z.string(),
|
|
386
|
+
headerName: z.string().nullable(),
|
|
387
|
+
scheme: z.string().nullable(),
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
const integrationsSurfaceEntrySchema = z.object({
|
|
391
|
+
type: z.string(),
|
|
392
|
+
name: z.string(),
|
|
393
|
+
url: z.string().nullable(),
|
|
394
|
+
docs: z.string().nullable(),
|
|
395
|
+
spec: z.string().nullable(),
|
|
396
|
+
auth: z.object({
|
|
397
|
+
required: z.boolean(),
|
|
398
|
+
credentialIds: z.array(z.string()),
|
|
399
|
+
mechanics: integrationsSurfaceMechanicsSchema.nullable(),
|
|
400
|
+
}),
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
const integrationsSurfaceCredentialSchema = z.object({
|
|
404
|
+
type: z.string(),
|
|
405
|
+
label: z.string(),
|
|
406
|
+
generateUrl: z.string().nullable(),
|
|
407
|
+
setup: z.string().nullable(),
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
const integrationsSurfacePayloadSchema = z.object({
|
|
411
|
+
domain: z.string(),
|
|
412
|
+
summary: z.string(),
|
|
413
|
+
surfaces: z.array(integrationsSurfaceEntrySchema),
|
|
414
|
+
credentials: z.record(z.string(), integrationsSurfaceCredentialSchema),
|
|
415
|
+
});
|
|
416
|
+
|
|
166
417
|
const listConnectionsRoute = route({
|
|
167
418
|
method: "get",
|
|
168
419
|
path: "/api/script-connections",
|
|
@@ -174,7 +425,10 @@ const listConnectionsRoute = route({
|
|
|
174
425
|
tags: ["Script Connections"],
|
|
175
426
|
query: listConnectionsQuerySchema,
|
|
176
427
|
responses: {
|
|
177
|
-
200: {
|
|
428
|
+
200: {
|
|
429
|
+
description: "Script connections",
|
|
430
|
+
schema: z.object({ connections: z.array(decoratedConnectionSchema) }),
|
|
431
|
+
},
|
|
178
432
|
400: { description: "Validation error" },
|
|
179
433
|
},
|
|
180
434
|
});
|
|
@@ -188,7 +442,10 @@ const getConnectionRoute = route({
|
|
|
188
442
|
tags: ["Script Connections"],
|
|
189
443
|
params: idParamsSchema,
|
|
190
444
|
responses: {
|
|
191
|
-
200: {
|
|
445
|
+
200: {
|
|
446
|
+
description: "Script connection detail",
|
|
447
|
+
schema: z.object({ connection: connectionDetailSchema }),
|
|
448
|
+
},
|
|
192
449
|
404: { description: "Script connection not found" },
|
|
193
450
|
},
|
|
194
451
|
});
|
|
@@ -202,7 +459,10 @@ const upsertConnectionRoute = route({
|
|
|
202
459
|
tags: ["Script Connections"],
|
|
203
460
|
body: upsertConnectionBodySchema,
|
|
204
461
|
responses: {
|
|
205
|
-
200: {
|
|
462
|
+
200: {
|
|
463
|
+
description: "Saved script connection",
|
|
464
|
+
schema: z.object({ connection: decoratedConnectionSchema }),
|
|
465
|
+
},
|
|
206
466
|
400: { description: "Validation or generation error" },
|
|
207
467
|
403: { description: "Only the lead agent can manage script connections" },
|
|
208
468
|
},
|
|
@@ -218,7 +478,10 @@ const refreshConnectionRoute = route({
|
|
|
218
478
|
tags: ["Script Connections"],
|
|
219
479
|
params: idParamsSchema,
|
|
220
480
|
responses: {
|
|
221
|
-
200: {
|
|
481
|
+
200: {
|
|
482
|
+
description: "Refreshed script connection",
|
|
483
|
+
schema: z.object({ connection: decoratedConnectionSchema }),
|
|
484
|
+
},
|
|
222
485
|
400: { description: "Connection cannot be refreshed" },
|
|
223
486
|
403: { description: "Only the lead agent can manage script connections" },
|
|
224
487
|
404: { description: "Script connection not found" },
|
|
@@ -236,7 +499,10 @@ const setConnectionEnabledRoute = route({
|
|
|
236
499
|
params: idParamsSchema,
|
|
237
500
|
body: disableConnectionBodySchema,
|
|
238
501
|
responses: {
|
|
239
|
-
200: {
|
|
502
|
+
200: {
|
|
503
|
+
description: "Updated script connection",
|
|
504
|
+
schema: z.object({ connection: decoratedConnectionSchema }),
|
|
505
|
+
},
|
|
240
506
|
403: { description: "Only the lead agent can manage script connections" },
|
|
241
507
|
404: { description: "Script connection not found" },
|
|
242
508
|
},
|
|
@@ -254,7 +520,10 @@ const listCredentialBindingsRoute = route({
|
|
|
254
520
|
tags: ["Script Connections"],
|
|
255
521
|
query: z.object({ includeManaged: z.enum(["true", "false"]).optional() }),
|
|
256
522
|
responses: {
|
|
257
|
-
200: {
|
|
523
|
+
200: {
|
|
524
|
+
description: "Credential bindings",
|
|
525
|
+
schema: z.object({ bindings: z.array(decoratedBindingSchema) }),
|
|
526
|
+
},
|
|
258
527
|
},
|
|
259
528
|
});
|
|
260
529
|
|
|
@@ -267,7 +536,10 @@ const upsertCredentialBindingRoute = route({
|
|
|
267
536
|
tags: ["Script Connections"],
|
|
268
537
|
body: credentialBindingBodySchema,
|
|
269
538
|
responses: {
|
|
270
|
-
200: {
|
|
539
|
+
200: {
|
|
540
|
+
description: "Saved credential binding",
|
|
541
|
+
schema: z.object({ binding: decoratedBindingSchema }),
|
|
542
|
+
},
|
|
271
543
|
400: { description: "Validation error" },
|
|
272
544
|
403: { description: "Only the lead agent can manage script connections" },
|
|
273
545
|
},
|
|
@@ -282,7 +554,10 @@ const listOAuthAppsRoute = route({
|
|
|
282
554
|
summary: "List OAuth apps for script credential bindings",
|
|
283
555
|
tags: ["Script Connections"],
|
|
284
556
|
responses: {
|
|
285
|
-
200: {
|
|
557
|
+
200: {
|
|
558
|
+
description: "OAuth apps without client secrets",
|
|
559
|
+
schema: z.object({ oauthApps: z.array(sanitizedOAuthAppSchema) }),
|
|
560
|
+
},
|
|
286
561
|
},
|
|
287
562
|
});
|
|
288
563
|
|
|
@@ -296,7 +571,10 @@ const listOAuthPresetsRoute = route({
|
|
|
296
571
|
"Static curated OAuth presets (endpoints, scopes, quirks, and setup hints). Contains no secrets; client credentials are always customer-supplied.",
|
|
297
572
|
tags: ["Script Connections"],
|
|
298
573
|
responses: {
|
|
299
|
-
200: {
|
|
574
|
+
200: {
|
|
575
|
+
description: "Curated OAuth presets",
|
|
576
|
+
schema: z.object({ presets: z.array(oauthPresetSchema) }),
|
|
577
|
+
},
|
|
300
578
|
},
|
|
301
579
|
});
|
|
302
580
|
|
|
@@ -309,7 +587,16 @@ const upsertOAuthAppRoute = route({
|
|
|
309
587
|
tags: ["Script Connections"],
|
|
310
588
|
body: oauthAppBodySchema,
|
|
311
589
|
responses: {
|
|
312
|
-
200: {
|
|
590
|
+
200: {
|
|
591
|
+
description: "Saved OAuth app without client secret",
|
|
592
|
+
schema: z.object({
|
|
593
|
+
// `.find()` after create/update — always resolves in practice, but the
|
|
594
|
+
// lookup is not provably total, so this stays honestly optional.
|
|
595
|
+
oauthApp: sanitizedOAuthAppSchema.optional(),
|
|
596
|
+
redirectUri: z.string(),
|
|
597
|
+
setupHints: z.array(z.string()).optional(),
|
|
598
|
+
}),
|
|
599
|
+
},
|
|
313
600
|
400: { description: "Validation error" },
|
|
314
601
|
403: { description: "Only the lead agent can manage script connections" },
|
|
315
602
|
},
|
|
@@ -325,7 +612,15 @@ const discoverOAuthAppRoute = route({
|
|
|
325
612
|
tags: ["Script Connections"],
|
|
326
613
|
body: discoverOAuthAppBodySchema,
|
|
327
614
|
responses: {
|
|
328
|
-
200: {
|
|
615
|
+
200: {
|
|
616
|
+
description: "Discovered OAuth metadata",
|
|
617
|
+
schema: z.object({
|
|
618
|
+
authorizeUrl: z.string(),
|
|
619
|
+
tokenUrl: z.string(),
|
|
620
|
+
scopes: z.array(z.string()),
|
|
621
|
+
sourceUrl: z.string(),
|
|
622
|
+
}),
|
|
623
|
+
},
|
|
329
624
|
400: { description: "Discovery failed" },
|
|
330
625
|
403: { description: "Only the lead agent can manage script connections" },
|
|
331
626
|
},
|
|
@@ -341,7 +636,10 @@ const deleteOAuthAppRoute = route({
|
|
|
341
636
|
tags: ["Script Connections"],
|
|
342
637
|
params: providerParamsSchema,
|
|
343
638
|
responses: {
|
|
344
|
-
200: {
|
|
639
|
+
200: {
|
|
640
|
+
description: "OAuth app deleted",
|
|
641
|
+
schema: z.object({ success: z.literal(true), warnings: z.array(z.string()).optional() }),
|
|
642
|
+
},
|
|
345
643
|
403: { description: "Only the lead agent can manage script connections" },
|
|
346
644
|
404: { description: "OAuth app not found" },
|
|
347
645
|
},
|
|
@@ -373,7 +671,15 @@ const authorizeUrlRoute = route({
|
|
|
373
671
|
params: oauthResourceIdParamsSchema,
|
|
374
672
|
body: authorizeUrlBodySchema,
|
|
375
673
|
responses: {
|
|
376
|
-
200: {
|
|
674
|
+
200: {
|
|
675
|
+
description: "OAuth authorization URL + state",
|
|
676
|
+
schema: z.object({
|
|
677
|
+
authorizeUrl: z.string(),
|
|
678
|
+
state: z.string(),
|
|
679
|
+
label: z.string(),
|
|
680
|
+
redirectUri: z.string(),
|
|
681
|
+
}),
|
|
682
|
+
},
|
|
377
683
|
403: { description: "Only the lead agent can manage OAuth authorizations" },
|
|
378
684
|
404: { description: "OAuth app not found" },
|
|
379
685
|
},
|
|
@@ -389,7 +695,10 @@ const listAuthorizationsRoute = route({
|
|
|
389
695
|
tags: ["Script Connections"],
|
|
390
696
|
params: oauthResourceIdParamsSchema,
|
|
391
697
|
responses: {
|
|
392
|
-
200: {
|
|
698
|
+
200: {
|
|
699
|
+
description: "Authorizations without token material",
|
|
700
|
+
schema: z.object({ authorizations: z.array(sanitizedAuthorizationSchema) }),
|
|
701
|
+
},
|
|
393
702
|
404: { description: "OAuth app not found" },
|
|
394
703
|
},
|
|
395
704
|
});
|
|
@@ -403,7 +712,10 @@ const deleteAuthorizationRoute = route({
|
|
|
403
712
|
tags: ["Script Connections"],
|
|
404
713
|
params: oauthResourceIdParamsSchema,
|
|
405
714
|
responses: {
|
|
406
|
-
200: {
|
|
715
|
+
200: {
|
|
716
|
+
description: "Authorization revoked + deleted",
|
|
717
|
+
schema: z.object({ deleted: z.literal(true), revocationAttempted: z.boolean() }),
|
|
718
|
+
},
|
|
407
719
|
403: { description: "Only the lead agent can manage OAuth authorizations" },
|
|
408
720
|
404: { description: "Authorization not found" },
|
|
409
721
|
},
|
|
@@ -419,7 +731,14 @@ const refreshAuthorizationRoute = route({
|
|
|
419
731
|
tags: ["Script Connections"],
|
|
420
732
|
params: oauthResourceIdParamsSchema,
|
|
421
733
|
responses: {
|
|
422
|
-
200: {
|
|
734
|
+
200: {
|
|
735
|
+
description: "Refresh result with token status and new expiry",
|
|
736
|
+
schema: z.object({
|
|
737
|
+
ok: z.literal(true),
|
|
738
|
+
status: oauthAuthorizationStatusSchema,
|
|
739
|
+
expiresAt: z.string().nullable(),
|
|
740
|
+
}),
|
|
741
|
+
},
|
|
423
742
|
400: { description: "No refresh token stored" },
|
|
424
743
|
403: { description: "Only the lead agent can manage OAuth authorizations" },
|
|
425
744
|
404: { description: "Authorization not found" },
|
|
@@ -436,7 +755,7 @@ const integrationsCatalogRoute = route({
|
|
|
436
755
|
summary: "Proxy integrations.sh catalog entries",
|
|
437
756
|
tags: ["Script Connections"],
|
|
438
757
|
responses: {
|
|
439
|
-
200: { description: "Integrations catalog entries" },
|
|
758
|
+
200: { description: "Integrations catalog entries", schema: integrationsCatalogListSchema },
|
|
440
759
|
502: { description: "Catalog upstream unavailable" },
|
|
441
760
|
},
|
|
442
761
|
});
|
|
@@ -456,7 +775,10 @@ const integrationsSurfaceRoute = route({
|
|
|
456
775
|
tags: ["Script Connections"],
|
|
457
776
|
params: z.object({ domain: surfaceDomainSchema }),
|
|
458
777
|
responses: {
|
|
459
|
-
200: {
|
|
778
|
+
200: {
|
|
779
|
+
description: "Trimmed integration surface details for a domain",
|
|
780
|
+
schema: integrationsSurfacePayloadSchema,
|
|
781
|
+
},
|
|
460
782
|
404: { description: "No surface data for this domain" },
|
|
461
783
|
502: { description: "Surface upstream unavailable" },
|
|
462
784
|
},
|
|
@@ -472,7 +794,13 @@ const disconnectOAuthAppRoute = route({
|
|
|
472
794
|
tags: ["Script Connections"],
|
|
473
795
|
params: providerParamsSchema,
|
|
474
796
|
responses: {
|
|
475
|
-
200: {
|
|
797
|
+
200: {
|
|
798
|
+
description: "Disconnect result",
|
|
799
|
+
schema: z.union([
|
|
800
|
+
z.object({ disconnected: z.literal(false), message: z.string() }),
|
|
801
|
+
z.object({ disconnected: z.literal(true), revocationAttempted: z.boolean() }),
|
|
802
|
+
]),
|
|
803
|
+
},
|
|
476
804
|
403: { description: "Only the lead agent can manage script connections" },
|
|
477
805
|
404: { description: "OAuth app not found" },
|
|
478
806
|
},
|
|
@@ -488,7 +816,14 @@ const refreshOAuthAppTokensRoute = route({
|
|
|
488
816
|
tags: ["Script Connections"],
|
|
489
817
|
params: providerParamsSchema,
|
|
490
818
|
responses: {
|
|
491
|
-
200: {
|
|
819
|
+
200: {
|
|
820
|
+
description: "Refresh result with token status and new expiry",
|
|
821
|
+
schema: z.object({
|
|
822
|
+
refreshed: z.literal(true),
|
|
823
|
+
tokenStatus: oauthBindingTokenStatusSchema,
|
|
824
|
+
expiresAt: z.string().nullable(),
|
|
825
|
+
}),
|
|
826
|
+
},
|
|
492
827
|
400: { description: "No stored tokens or provider does not support refresh" },
|
|
493
828
|
403: { description: "Only the lead agent can manage script connections" },
|
|
494
829
|
404: { description: "OAuth app not found" },
|
|
@@ -1515,7 +1850,7 @@ export async function handleScriptConnections(
|
|
|
1515
1850
|
if (listConnectionsRoute.match(req.method, pathSegments)) {
|
|
1516
1851
|
const parsed = await listConnectionsRoute.parse(req, res, pathSegments, queryParams);
|
|
1517
1852
|
if (!parsed) return true;
|
|
1518
|
-
|
|
1853
|
+
listConnectionsRoute.respond(res, 200, { connections: listConnections(parsed.query) });
|
|
1519
1854
|
return true;
|
|
1520
1855
|
}
|
|
1521
1856
|
|
|
@@ -1530,7 +1865,7 @@ export async function handleScriptConnections(
|
|
|
1530
1865
|
jsonError(res, "Script connection not found.", 404);
|
|
1531
1866
|
return true;
|
|
1532
1867
|
}
|
|
1533
|
-
|
|
1868
|
+
getConnectionRoute.respond(res, 200, { connection: connectionDetail(connection) });
|
|
1534
1869
|
return true;
|
|
1535
1870
|
}
|
|
1536
1871
|
|
|
@@ -1646,7 +1981,9 @@ export async function handleScriptConnections(
|
|
|
1646
1981
|
userId,
|
|
1647
1982
|
});
|
|
1648
1983
|
|
|
1649
|
-
|
|
1984
|
+
upsertConnectionRoute.respond(res, 200, {
|
|
1985
|
+
connection: decorateConnections([connection])[0]!,
|
|
1986
|
+
});
|
|
1650
1987
|
} catch (err) {
|
|
1651
1988
|
jsonError(res, err instanceof Error ? err.message : String(err), 400);
|
|
1652
1989
|
}
|
|
@@ -1667,7 +2004,9 @@ export async function handleScriptConnections(
|
|
|
1667
2004
|
jsonError(res, "Script connection not found.", 404);
|
|
1668
2005
|
return true;
|
|
1669
2006
|
}
|
|
1670
|
-
|
|
2007
|
+
refreshConnectionRoute.respond(res, 200, {
|
|
2008
|
+
connection: decorateConnections([refreshed])[0]!,
|
|
2009
|
+
});
|
|
1671
2010
|
} catch (err) {
|
|
1672
2011
|
jsonError(res, err instanceof Error ? err.message : String(err), 400);
|
|
1673
2012
|
}
|
|
@@ -1687,13 +2026,13 @@ export async function handleScriptConnections(
|
|
|
1687
2026
|
jsonError(res, "Script connection not found.", 404);
|
|
1688
2027
|
return true;
|
|
1689
2028
|
}
|
|
1690
|
-
|
|
2029
|
+
setConnectionEnabledRoute.respond(res, 200, { connection: decorateConnections([updated])[0]! });
|
|
1691
2030
|
return true;
|
|
1692
2031
|
}
|
|
1693
2032
|
|
|
1694
2033
|
if (listCredentialBindingsRoute.match(req.method, pathSegments)) {
|
|
1695
2034
|
const includeManaged = queryParams.get("includeManaged") === "true";
|
|
1696
|
-
|
|
2035
|
+
listCredentialBindingsRoute.respond(res, 200, {
|
|
1697
2036
|
bindings: listRelationalCredentialBindings({
|
|
1698
2037
|
includeInactive: true,
|
|
1699
2038
|
excludeManaged: !includeManaged,
|
|
@@ -1748,7 +2087,7 @@ export async function handleScriptConnections(
|
|
|
1748
2087
|
oauthAuthorizationId: nextBinding.oauthAuthorizationId ?? null,
|
|
1749
2088
|
userId: resolveHttpAuditUserId(req, agentId),
|
|
1750
2089
|
});
|
|
1751
|
-
|
|
2090
|
+
upsertCredentialBindingRoute.respond(res, 200, { binding: decorateBinding(binding) });
|
|
1752
2091
|
} catch (err) {
|
|
1753
2092
|
jsonError(res, err instanceof Error ? err.message : String(err), 400);
|
|
1754
2093
|
}
|
|
@@ -1756,12 +2095,12 @@ export async function handleScriptConnections(
|
|
|
1756
2095
|
}
|
|
1757
2096
|
|
|
1758
2097
|
if (listOAuthPresetsRoute.match(req.method, pathSegments)) {
|
|
1759
|
-
|
|
2098
|
+
listOAuthPresetsRoute.respond(res, 200, { presets: listOAuthPresets() });
|
|
1760
2099
|
return true;
|
|
1761
2100
|
}
|
|
1762
2101
|
|
|
1763
2102
|
if (listOAuthAppsRoute.match(req.method, pathSegments)) {
|
|
1764
|
-
|
|
2103
|
+
listOAuthAppsRoute.respond(res, 200, { oauthApps: listOAuthApps() });
|
|
1765
2104
|
return true;
|
|
1766
2105
|
}
|
|
1767
2106
|
|
|
@@ -1869,7 +2208,7 @@ export async function handleScriptConnections(
|
|
|
1869
2208
|
savedId = createOAuthApp(provider, appData);
|
|
1870
2209
|
}
|
|
1871
2210
|
const app = listOAuthApps().find((row) => row.id === savedId);
|
|
1872
|
-
|
|
2211
|
+
upsertOAuthAppRoute.respond(res, 200, {
|
|
1873
2212
|
oauthApp: app,
|
|
1874
2213
|
redirectUri,
|
|
1875
2214
|
...(hydrated ? { setupHints: hydrated.setupHints } : {}),
|
|
@@ -1886,7 +2225,7 @@ export async function handleScriptConnections(
|
|
|
1886
2225
|
if (!ensureOAuthAppAdmin(req, res, agentId)) return true;
|
|
1887
2226
|
try {
|
|
1888
2227
|
const discovered = await discoverOAuthApp(parsed.body.url);
|
|
1889
|
-
|
|
2228
|
+
discoverOAuthAppRoute.respond(res, 200, discovered);
|
|
1890
2229
|
} catch (err) {
|
|
1891
2230
|
jsonError(res, err instanceof Error ? err.message : String(err), 400);
|
|
1892
2231
|
}
|
|
@@ -1902,7 +2241,7 @@ export async function handleScriptConnections(
|
|
|
1902
2241
|
jsonError(res, `OAuth app ${parsed.params.provider} not found.`, 404);
|
|
1903
2242
|
return true;
|
|
1904
2243
|
}
|
|
1905
|
-
|
|
2244
|
+
deleteOAuthAppRoute.respond(res, 200, {
|
|
1906
2245
|
success: true,
|
|
1907
2246
|
...(deletion.warnings.length > 0 ? { warnings: deletion.warnings } : {}),
|
|
1908
2247
|
});
|
|
@@ -1917,7 +2256,7 @@ export async function handleScriptConnections(
|
|
|
1917
2256
|
jsonError(res, `OAuth app ${parsed.params.id} not found.`, 404);
|
|
1918
2257
|
return true;
|
|
1919
2258
|
}
|
|
1920
|
-
|
|
2259
|
+
listAuthorizationsRoute.respond(res, 200, {
|
|
1921
2260
|
authorizations: listAuthorizationsForApp(app.id).map(sanitizeAuthorization),
|
|
1922
2261
|
});
|
|
1923
2262
|
return true;
|
|
@@ -1944,7 +2283,7 @@ export async function handleScriptConnections(
|
|
|
1944
2283
|
...(parsed.body?.finalRedirect ? { finalRedirect: parsed.body.finalRedirect } : {}),
|
|
1945
2284
|
userId: resolveHttpAuditUserId(req, agentId),
|
|
1946
2285
|
});
|
|
1947
|
-
|
|
2286
|
+
authorizeUrlRoute.respond(res, 200, {
|
|
1948
2287
|
authorizeUrl: result.url,
|
|
1949
2288
|
state: result.state,
|
|
1950
2289
|
label,
|
|
@@ -1972,7 +2311,7 @@ export async function handleScriptConnections(
|
|
|
1972
2311
|
revocationAttempted = await attemptRemoteRevocation(app, authorization.accessToken);
|
|
1973
2312
|
}
|
|
1974
2313
|
deleteAuthorizationById(authorization.id);
|
|
1975
|
-
|
|
2314
|
+
deleteAuthorizationRoute.respond(res, 200, { deleted: true, revocationAttempted });
|
|
1976
2315
|
return true;
|
|
1977
2316
|
}
|
|
1978
2317
|
|
|
@@ -2024,21 +2363,25 @@ export async function handleScriptConnections(
|
|
|
2024
2363
|
jsonError(res, `Authorization ${parsed.params.id} not found.`, 404);
|
|
2025
2364
|
return true;
|
|
2026
2365
|
}
|
|
2027
|
-
|
|
2366
|
+
refreshAuthorizationRoute.respond(res, 200, {
|
|
2367
|
+
ok: true,
|
|
2368
|
+
status: refreshed.status,
|
|
2369
|
+
expiresAt: refreshed.expiresAt,
|
|
2370
|
+
});
|
|
2028
2371
|
return true;
|
|
2029
2372
|
}
|
|
2030
2373
|
|
|
2031
2374
|
if (integrationsCatalogRoute.match(req.method, pathSegments)) {
|
|
2032
2375
|
try {
|
|
2033
2376
|
const catalog = await fetchIntegrationsCatalog();
|
|
2034
|
-
|
|
2377
|
+
integrationsCatalogRoute.respond(res, 200, {
|
|
2035
2378
|
...catalog,
|
|
2036
2379
|
entries: mergeBlessedCatalogEntries(catalog.entries),
|
|
2037
2380
|
partial: false,
|
|
2038
2381
|
});
|
|
2039
2382
|
} catch (err) {
|
|
2040
2383
|
if (BLESSED_CATALOG_ENTRIES.length > 0) {
|
|
2041
|
-
|
|
2384
|
+
integrationsCatalogRoute.respond(res, 200, {
|
|
2042
2385
|
entries: BLESSED_CATALOG_ENTRIES,
|
|
2043
2386
|
cachedAt: new Date().toISOString(),
|
|
2044
2387
|
partial: true,
|
|
@@ -2058,7 +2401,11 @@ export async function handleScriptConnections(
|
|
|
2058
2401
|
const parsed = await integrationsSurfaceRoute.parse(req, res, pathSegments, queryParams);
|
|
2059
2402
|
if (!parsed) return true;
|
|
2060
2403
|
try {
|
|
2061
|
-
|
|
2404
|
+
integrationsSurfaceRoute.respond(
|
|
2405
|
+
res,
|
|
2406
|
+
200,
|
|
2407
|
+
await fetchIntegrationsSurface(parsed.params.domain),
|
|
2408
|
+
);
|
|
2062
2409
|
} catch (err) {
|
|
2063
2410
|
if (err instanceof SurfaceNotFoundError) {
|
|
2064
2411
|
jsonError(res, err.message, 404);
|
|
@@ -2085,12 +2432,15 @@ export async function handleScriptConnections(
|
|
|
2085
2432
|
}
|
|
2086
2433
|
const tokens = getOAuthTokens(parsed.params.provider);
|
|
2087
2434
|
if (!tokens) {
|
|
2088
|
-
|
|
2435
|
+
disconnectOAuthAppRoute.respond(res, 200, {
|
|
2436
|
+
disconnected: false,
|
|
2437
|
+
message: "no stored tokens",
|
|
2438
|
+
});
|
|
2089
2439
|
return true;
|
|
2090
2440
|
}
|
|
2091
2441
|
const revocationAttempted = await attemptRemoteRevocation(app, tokens.accessToken);
|
|
2092
2442
|
deleteOAuthTokens(parsed.params.provider);
|
|
2093
|
-
|
|
2443
|
+
disconnectOAuthAppRoute.respond(res, 200, { disconnected: true, revocationAttempted });
|
|
2094
2444
|
return true;
|
|
2095
2445
|
}
|
|
2096
2446
|
|
|
@@ -2126,7 +2476,7 @@ export async function handleScriptConnections(
|
|
|
2126
2476
|
return true;
|
|
2127
2477
|
}
|
|
2128
2478
|
|
|
2129
|
-
|
|
2479
|
+
refreshOAuthAppTokensRoute.respond(res, 200, {
|
|
2130
2480
|
refreshed: true,
|
|
2131
2481
|
tokenStatus: getOAuthBindingTokenStatus(tokens.id),
|
|
2132
2482
|
expiresAt: getOAuthTokens(provider)?.expiresAt ?? null,
|