@arbium/enterprise-agent-connect 0.0.0-stage → 0.1.2-dev.d2aa5ca
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/LICENSE +202 -0
- package/README.md +264 -2
- package/dist/connectors/dell-techdirect/connector.json +39 -0
- package/dist/connectors/dell-techdirect/index.d.ts +8 -0
- package/dist/connectors/dell-techdirect/index.js +7 -0
- package/dist/connectors/dell-techdirect/index.js.map +1 -0
- package/dist/connectors/dell-techdirect/tools.d.ts +2 -0
- package/dist/connectors/dell-techdirect/tools.js +49 -0
- package/dist/connectors/dell-techdirect/tools.js.map +1 -0
- package/dist/connectors/dell-techdirect/vendor.d.ts +6 -0
- package/dist/connectors/dell-techdirect/vendor.js +57 -0
- package/dist/connectors/dell-techdirect/vendor.js.map +1 -0
- package/dist/connectors/dynamics-365/connector.json +213 -0
- package/dist/connectors/dynamics-365/index.d.ts +11 -0
- package/dist/connectors/dynamics-365/index.js +10 -0
- package/dist/connectors/dynamics-365/index.js.map +1 -0
- package/dist/connectors/dynamics-365/tools.d.ts +35 -0
- package/dist/connectors/dynamics-365/tools.js +806 -0
- package/dist/connectors/dynamics-365/tools.js.map +1 -0
- package/dist/connectors/dynamics-365/vendor.d.ts +9 -0
- package/dist/connectors/dynamics-365/vendor.js +110 -0
- package/dist/connectors/dynamics-365/vendor.js.map +1 -0
- package/dist/connectors/entra/connector.json +85 -0
- package/dist/connectors/entra/index.d.ts +2 -0
- package/dist/connectors/entra/index.js +4 -0
- package/dist/connectors/entra/index.js.map +1 -0
- package/dist/connectors/entra/tools.d.ts +14 -0
- package/dist/connectors/entra/tools.js +262 -0
- package/dist/connectors/entra/tools.js.map +1 -0
- package/dist/connectors/fedex/connector.json +118 -0
- package/dist/connectors/fedex/index.d.ts +8 -0
- package/dist/connectors/fedex/index.js +7 -0
- package/dist/connectors/fedex/index.js.map +1 -0
- package/dist/connectors/fedex/tools.d.ts +3 -0
- package/dist/connectors/fedex/tools.js +152 -0
- package/dist/connectors/fedex/tools.js.map +1 -0
- package/dist/connectors/fedex/vendor.d.ts +7 -0
- package/dist/connectors/fedex/vendor.js +98 -0
- package/dist/connectors/fedex/vendor.js.map +1 -0
- package/dist/connectors/gong/connector.json +127 -0
- package/dist/connectors/gong/index.d.ts +8 -0
- package/dist/connectors/gong/index.js +7 -0
- package/dist/connectors/gong/index.js.map +1 -0
- package/dist/connectors/gong/tools.d.ts +8 -0
- package/dist/connectors/gong/tools.js +424 -0
- package/dist/connectors/gong/tools.js.map +1 -0
- package/dist/connectors/gong/vendor.d.ts +4 -0
- package/dist/connectors/gong/vendor.js +97 -0
- package/dist/connectors/gong/vendor.js.map +1 -0
- package/dist/connectors/http/index.d.ts +38 -0
- package/dist/connectors/http/index.js +322 -0
- package/dist/connectors/http/index.js.map +1 -0
- package/dist/connectors/intune/connector.json +106 -0
- package/dist/connectors/intune/index.d.ts +2 -0
- package/dist/connectors/intune/index.js +4 -0
- package/dist/connectors/intune/index.js.map +1 -0
- package/dist/connectors/intune/tools.d.ts +12 -0
- package/dist/connectors/intune/tools.js +416 -0
- package/dist/connectors/intune/tools.js.map +1 -0
- package/dist/connectors/jamf/connector.json +182 -0
- package/dist/connectors/jamf/index.d.ts +8 -0
- package/dist/connectors/jamf/index.js +7 -0
- package/dist/connectors/jamf/index.js.map +1 -0
- package/dist/connectors/jamf/tools.d.ts +7 -0
- package/dist/connectors/jamf/tools.js +659 -0
- package/dist/connectors/jamf/tools.js.map +1 -0
- package/dist/connectors/jamf/vendor.d.ts +5 -0
- package/dist/connectors/jamf/vendor.js +66 -0
- package/dist/connectors/jamf/vendor.js.map +1 -0
- package/dist/connectors/jira/connector.json +272 -0
- package/dist/connectors/jira/index.d.ts +8 -0
- package/dist/connectors/jira/index.js +7 -0
- package/dist/connectors/jira/index.js.map +1 -0
- package/dist/connectors/jira/jql.d.ts +4 -0
- package/dist/connectors/jira/jql.js +67 -0
- package/dist/connectors/jira/jql.js.map +1 -0
- package/dist/connectors/jira/tools.d.ts +3 -0
- package/dist/connectors/jira/tools.js +464 -0
- package/dist/connectors/jira/tools.js.map +1 -0
- package/dist/connectors/jira/vendor.d.ts +3 -0
- package/dist/connectors/jira/vendor.js +94 -0
- package/dist/connectors/jira/vendor.js.map +1 -0
- package/dist/connectors/microsoft/client.d.ts +58 -0
- package/dist/connectors/microsoft/client.js +434 -0
- package/dist/connectors/microsoft/client.js.map +1 -0
- package/dist/connectors/microsoft/provider.json +118 -0
- package/dist/connectors/netsuite/connector.json +315 -0
- package/dist/connectors/netsuite/index.d.ts +8 -0
- package/dist/connectors/netsuite/index.js +7 -0
- package/dist/connectors/netsuite/index.js.map +1 -0
- package/dist/connectors/netsuite/tools.d.ts +24 -0
- package/dist/connectors/netsuite/tools.js +447 -0
- package/dist/connectors/netsuite/tools.js.map +1 -0
- package/dist/connectors/netsuite/vendor.d.ts +26 -0
- package/dist/connectors/netsuite/vendor.js +248 -0
- package/dist/connectors/netsuite/vendor.js.map +1 -0
- package/dist/connectors/odata/index.d.ts +36 -0
- package/dist/connectors/odata/index.js +460 -0
- package/dist/connectors/odata/index.js.map +1 -0
- package/dist/connectors/okta/connector.json +193 -0
- package/dist/connectors/okta/index.d.ts +8 -0
- package/dist/connectors/okta/index.js +7 -0
- package/dist/connectors/okta/index.js.map +1 -0
- package/dist/connectors/okta/tools.d.ts +6 -0
- package/dist/connectors/okta/tools.js +429 -0
- package/dist/connectors/okta/tools.js.map +1 -0
- package/dist/connectors/okta/vendor.d.ts +14 -0
- package/dist/connectors/okta/vendor.js +203 -0
- package/dist/connectors/okta/vendor.js.map +1 -0
- package/dist/connectors/outlook-calendar/connector.json +136 -0
- package/dist/connectors/outlook-calendar/index.d.ts +2 -0
- package/dist/connectors/outlook-calendar/index.js +4 -0
- package/dist/connectors/outlook-calendar/index.js.map +1 -0
- package/dist/connectors/outlook-calendar/tools.d.ts +65 -0
- package/dist/connectors/outlook-calendar/tools.js +398 -0
- package/dist/connectors/outlook-calendar/tools.js.map +1 -0
- package/dist/connectors/outlook-mail/connector.json +154 -0
- package/dist/connectors/outlook-mail/index.d.ts +2 -0
- package/dist/connectors/outlook-mail/index.js +4 -0
- package/dist/connectors/outlook-mail/index.js.map +1 -0
- package/dist/connectors/outlook-mail/tools.d.ts +8 -0
- package/dist/connectors/outlook-mail/tools.js +236 -0
- package/dist/connectors/outlook-mail/tools.js.map +1 -0
- package/dist/connectors/salesforce/connector.json +122 -0
- package/dist/connectors/salesforce/index.d.ts +8 -0
- package/dist/connectors/salesforce/index.js +7 -0
- package/dist/connectors/salesforce/index.js.map +1 -0
- package/dist/connectors/salesforce/soql.d.ts +3 -0
- package/dist/connectors/salesforce/soql.js +60 -0
- package/dist/connectors/salesforce/soql.js.map +1 -0
- package/dist/connectors/salesforce/tools.d.ts +9 -0
- package/dist/connectors/salesforce/tools.js +234 -0
- package/dist/connectors/salesforce/tools.js.map +1 -0
- package/dist/connectors/salesforce/vendor.d.ts +3 -0
- package/dist/connectors/salesforce/vendor.js +107 -0
- package/dist/connectors/salesforce/vendor.js.map +1 -0
- package/dist/connectors/sap-s4hana/connector.json +263 -0
- package/dist/connectors/sap-s4hana/index.d.ts +8 -0
- package/dist/connectors/sap-s4hana/index.js +7 -0
- package/dist/connectors/sap-s4hana/index.js.map +1 -0
- package/dist/connectors/sap-s4hana/tools.d.ts +4 -0
- package/dist/connectors/sap-s4hana/tools.js +761 -0
- package/dist/connectors/sap-s4hana/tools.js.map +1 -0
- package/dist/connectors/sap-s4hana/vendor.d.ts +5 -0
- package/dist/connectors/sap-s4hana/vendor.js +176 -0
- package/dist/connectors/sap-s4hana/vendor.js.map +1 -0
- package/dist/connectors/servicenow/connector.json +228 -0
- package/dist/connectors/servicenow/index.d.ts +8 -0
- package/dist/connectors/servicenow/index.js +7 -0
- package/dist/connectors/servicenow/index.js.map +1 -0
- package/dist/connectors/servicenow/tools.d.ts +4 -0
- package/dist/connectors/servicenow/tools.js +884 -0
- package/dist/connectors/servicenow/tools.js.map +1 -0
- package/dist/connectors/servicenow/vendor.d.ts +4 -0
- package/dist/connectors/servicenow/vendor.js +109 -0
- package/dist/connectors/servicenow/vendor.js.map +1 -0
- package/dist/connectors/sharepoint-files/connector.json +194 -0
- package/dist/connectors/sharepoint-files/excel.d.ts +16 -0
- package/dist/connectors/sharepoint-files/excel.js +300 -0
- package/dist/connectors/sharepoint-files/excel.js.map +1 -0
- package/dist/connectors/sharepoint-files/index.d.ts +11 -0
- package/dist/connectors/sharepoint-files/index.js +12 -0
- package/dist/connectors/sharepoint-files/index.js.map +1 -0
- package/dist/connectors/sharepoint-files/tools.d.ts +52 -0
- package/dist/connectors/sharepoint-files/tools.js +365 -0
- package/dist/connectors/sharepoint-files/tools.js.map +1 -0
- package/dist/connectors/sharepoint-files/vendor.d.ts +11 -0
- package/dist/connectors/sharepoint-files/vendor.js +167 -0
- package/dist/connectors/sharepoint-files/vendor.js.map +1 -0
- package/dist/connectors/slack/connector.json +148 -0
- package/dist/connectors/slack/index.d.ts +8 -0
- package/dist/connectors/slack/index.js +7 -0
- package/dist/connectors/slack/index.js.map +1 -0
- package/dist/connectors/slack/tools.d.ts +3 -0
- package/dist/connectors/slack/tools.js +355 -0
- package/dist/connectors/slack/tools.js.map +1 -0
- package/dist/connectors/slack/vendor.d.ts +17 -0
- package/dist/connectors/slack/vendor.js +195 -0
- package/dist/connectors/slack/vendor.js.map +1 -0
- package/dist/connectors/soap/index.d.ts +19 -0
- package/dist/connectors/soap/index.js +248 -0
- package/dist/connectors/soap/index.js.map +1 -0
- package/dist/connectors/soap/xml.d.ts +12 -0
- package/dist/connectors/soap/xml.js +126 -0
- package/dist/connectors/soap/xml.js.map +1 -0
- package/dist/connectors/sql/engines.d.ts +58 -0
- package/dist/connectors/sql/engines.js +292 -0
- package/dist/connectors/sql/engines.js.map +1 -0
- package/dist/connectors/sql/index.d.ts +19 -0
- package/dist/connectors/sql/index.js +212 -0
- package/dist/connectors/sql/index.js.map +1 -0
- package/dist/connectors/teams/connector.json +298 -0
- package/dist/connectors/teams/index.d.ts +2 -0
- package/dist/connectors/teams/index.js +5 -0
- package/dist/connectors/teams/index.js.map +1 -0
- package/dist/connectors/teams/tools.d.ts +2 -0
- package/dist/connectors/teams/tools.js +391 -0
- package/dist/connectors/teams/tools.js.map +1 -0
- package/dist/connectors/workday/connector.json +186 -0
- package/dist/connectors/workday/index.d.ts +8 -0
- package/dist/connectors/workday/index.js +7 -0
- package/dist/connectors/workday/index.js.map +1 -0
- package/dist/connectors/workday/tools.d.ts +33 -0
- package/dist/connectors/workday/tools.js +410 -0
- package/dist/connectors/workday/tools.js.map +1 -0
- package/dist/connectors/workday/vendor.d.ts +18 -0
- package/dist/connectors/workday/vendor.js +195 -0
- package/dist/connectors/workday/vendor.js.map +1 -0
- package/dist/packages/connector-kit/src/branding.d.ts +57 -0
- package/dist/packages/connector-kit/src/branding.js +102 -0
- package/dist/packages/connector-kit/src/branding.js.map +1 -0
- package/dist/packages/connector-kit/src/certificate.d.ts +19 -0
- package/dist/packages/connector-kit/src/certificate.js +84 -0
- package/dist/packages/connector-kit/src/certificate.js.map +1 -0
- package/dist/packages/connector-kit/src/common.d.ts +40 -0
- package/dist/packages/connector-kit/src/common.js +107 -0
- package/dist/packages/connector-kit/src/common.js.map +1 -0
- package/dist/packages/connector-kit/src/connector.d.ts +1346 -0
- package/dist/packages/connector-kit/src/connector.js +1034 -0
- package/dist/packages/connector-kit/src/connector.js.map +1 -0
- package/dist/packages/connector-kit/src/index.d.ts +5 -0
- package/dist/packages/connector-kit/src/index.js +5 -0
- package/dist/packages/connector-kit/src/index.js.map +1 -0
- package/dist/packages/connector-kit/src/oauth.d.ts +15 -0
- package/dist/packages/connector-kit/src/oauth.js +96 -0
- package/dist/packages/connector-kit/src/oauth.js.map +1 -0
- package/dist/packages/connector-kit/src/types.d.ts +85 -0
- package/dist/packages/connector-kit/src/types.js +20 -0
- package/dist/packages/connector-kit/src/types.js.map +1 -0
- package/dist/packages/server/migrations/0001_tables.sql +268 -0
- package/dist/packages/server/migrations/0002_organizations.sql +72 -0
- package/dist/packages/server/migrations/0003_drop_unused.sql +3 -0
- package/dist/packages/server/migrations/0004_trigger_runners.sql +15 -0
- package/dist/packages/server/migrations/0005_run_runner.sql +3 -0
- package/dist/packages/server/migrations/0006_approvals.sql +36 -0
- package/dist/packages/server/migrations/0007_app_events.sql +110 -0
- package/dist/packages/server/migrations/rollback/to-legacy.sql +90 -0
- package/dist/packages/server/src/api.d.ts +3714 -0
- package/dist/packages/server/src/api.js +818 -0
- package/dist/packages/server/src/api.js.map +1 -0
- package/dist/packages/server/src/app.d.ts +23 -0
- package/dist/packages/server/src/app.js +467 -0
- package/dist/packages/server/src/app.js.map +1 -0
- package/dist/packages/server/src/builtin.d.ts +4 -0
- package/dist/packages/server/src/builtin.js +42 -0
- package/dist/packages/server/src/builtin.js.map +1 -0
- package/dist/packages/server/src/consent.d.ts +27 -0
- package/dist/packages/server/src/consent.js +36 -0
- package/dist/packages/server/src/consent.js.map +1 -0
- package/dist/packages/server/src/events/admin.d.ts +156 -0
- package/dist/packages/server/src/events/admin.js +255 -0
- package/dist/packages/server/src/events/admin.js.map +1 -0
- package/dist/packages/server/src/events/deliver.d.ts +43 -0
- package/dist/packages/server/src/events/deliver.js +129 -0
- package/dist/packages/server/src/events/deliver.js.map +1 -0
- package/dist/packages/server/src/events/runtime.d.ts +28 -0
- package/dist/packages/server/src/events/runtime.js +397 -0
- package/dist/packages/server/src/events/runtime.js.map +1 -0
- package/dist/packages/server/src/events/store.d.ts +172 -0
- package/dist/packages/server/src/events/store.js +275 -0
- package/dist/packages/server/src/events/store.js.map +1 -0
- package/dist/packages/server/src/index.d.ts +40 -0
- package/dist/packages/server/src/index.js +185 -0
- package/dist/packages/server/src/index.js.map +1 -0
- package/dist/packages/server/src/migrate.d.ts +11 -0
- package/dist/packages/server/src/migrate.js +134 -0
- package/dist/packages/server/src/migrate.js.map +1 -0
- package/dist/packages/server/src/openapi.d.ts +4 -0
- package/dist/packages/server/src/openapi.js +101 -0
- package/dist/packages/server/src/openapi.js.map +1 -0
- package/dist/packages/server/src/queue.d.ts +10 -0
- package/dist/packages/server/src/queue.js +45 -0
- package/dist/packages/server/src/queue.js.map +1 -0
- package/dist/packages/server/src/secrets.d.ts +19 -0
- package/dist/packages/server/src/secrets.js +76 -0
- package/dist/packages/server/src/secrets.js.map +1 -0
- package/dist/packages/server/src/server.d.ts +1 -0
- package/dist/packages/server/src/server.js +82 -0
- package/dist/packages/server/src/server.js.map +1 -0
- package/dist/packages/server/src/service.d.ts +760 -0
- package/dist/packages/server/src/service.js +918 -0
- package/dist/packages/server/src/service.js.map +1 -0
- package/dist/packages/server/src/store.d.ts +158 -0
- package/dist/packages/server/src/store.js +415 -0
- package/dist/packages/server/src/store.js.map +1 -0
- package/dist/packages/server/src/teams/activity.d.ts +123 -0
- package/dist/packages/server/src/teams/activity.js +188 -0
- package/dist/packages/server/src/teams/activity.js.map +1 -0
- package/dist/packages/server/src/teams/admin.d.ts +335 -0
- package/dist/packages/server/src/teams/admin.js +699 -0
- package/dist/packages/server/src/teams/admin.js.map +1 -0
- package/dist/packages/server/src/teams/approval.d.ts +57 -0
- package/dist/packages/server/src/teams/approval.js +118 -0
- package/dist/packages/server/src/teams/approval.js.map +1 -0
- package/dist/packages/server/src/teams/bot.d.ts +25 -0
- package/dist/packages/server/src/teams/bot.js +124 -0
- package/dist/packages/server/src/teams/bot.js.map +1 -0
- package/dist/packages/server/src/teams/claude.d.ts +46 -0
- package/dist/packages/server/src/teams/claude.js +165 -0
- package/dist/packages/server/src/teams/claude.js.map +1 -0
- package/dist/packages/server/src/teams/jwt.d.ts +17 -0
- package/dist/packages/server/src/teams/jwt.js +121 -0
- package/dist/packages/server/src/teams/jwt.js.map +1 -0
- package/dist/packages/server/src/teams/package.d.ts +79 -0
- package/dist/packages/server/src/teams/package.js +319 -0
- package/dist/packages/server/src/teams/package.js.map +1 -0
- package/dist/packages/server/src/teams/provision.d.ts +84 -0
- package/dist/packages/server/src/teams/provision.js +505 -0
- package/dist/packages/server/src/teams/provision.js.map +1 -0
- package/dist/packages/server/src/teams/runner.d.ts +80 -0
- package/dist/packages/server/src/teams/runner.js +187 -0
- package/dist/packages/server/src/teams/runner.js.map +1 -0
- package/dist/packages/server/src/teams/runtime.d.ts +91 -0
- package/dist/packages/server/src/teams/runtime.js +679 -0
- package/dist/packages/server/src/teams/runtime.js.map +1 -0
- package/dist/packages/server/src/teams/store.d.ts +233 -0
- package/dist/packages/server/src/teams/store.js +507 -0
- package/dist/packages/server/src/teams/store.js.map +1 -0
- package/package.json +68 -4
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { pathToFileURL } from "node:url";
|
|
2
|
+
import { createApp } from "./app.js";
|
|
3
|
+
import { parseBranding, setBranding, } from "../../connector-kit/src/branding.js";
|
|
4
|
+
import { builtinConnectors } from "./builtin.js";
|
|
5
|
+
import httpConnector from "../../../connectors/http/index.js";
|
|
6
|
+
import odataConnector from "../../../connectors/odata/index.js";
|
|
7
|
+
import soapConnector from "../../../connectors/soap/index.js";
|
|
8
|
+
import sqlConnector from "../../../connectors/sql/index.js";
|
|
9
|
+
import { loadConnectors, loadProviders, parseConnector, } from "../../connector-kit/src/connector.js";
|
|
10
|
+
import { migrate as runMigrations } from "./migrate.js";
|
|
11
|
+
import { CredentialKey } from "./secrets.js";
|
|
12
|
+
import { assertToolsImplemented, createService } from "./service.js";
|
|
13
|
+
import { assertSchemaName, connectDatabase, createStore } from "./store.js";
|
|
14
|
+
import { createEventsAdmin, resealEventSecrets } from "./events/admin.js";
|
|
15
|
+
import { createEventsRuntime } from "./events/runtime.js";
|
|
16
|
+
import { createEventsStore } from "./events/store.js";
|
|
17
|
+
import { createTeamsAdmin, resealTeamsCredentials } from "./teams/admin.js";
|
|
18
|
+
import { botClient } from "./teams/bot.js";
|
|
19
|
+
import { claudeClient } from "./teams/claude.js";
|
|
20
|
+
import { botFrameworkAuth } from "./teams/jwt.js";
|
|
21
|
+
import { LIVE_CHECKS } from "./teams/provision.js";
|
|
22
|
+
import { claudeManagedAgents, signedWebhook } from "./teams/runner.js";
|
|
23
|
+
import { createTeamsRuntime } from "./teams/runtime.js";
|
|
24
|
+
import { createTeamsStore } from "./teams/store.js";
|
|
25
|
+
import { microsoftClient } from "../../../connectors/microsoft/client.js";
|
|
26
|
+
export { builtinConnectors } from "./builtin.js";
|
|
27
|
+
export { claudeManagedAgents, signature, signedWebhook } from "./teams/runner.js";
|
|
28
|
+
/** The whole service, checked and wired: fetch serves /agent-connect/*, start runs the Teams
|
|
29
|
+
* and app events queue workers, watchers and polls. Throws on anything misconfigured. */
|
|
30
|
+
export async function createAgentConnect(options) {
|
|
31
|
+
const log = options.log ?? console;
|
|
32
|
+
setBranding(parseBranding(options.branding));
|
|
33
|
+
const schema = options.schema ?? "agent_connect";
|
|
34
|
+
assertSchemaName(schema);
|
|
35
|
+
const microsoft = microsoftClient({ sharedApp: options.microsoftSharedApp ?? null });
|
|
36
|
+
const modules = new Map();
|
|
37
|
+
const inline = [];
|
|
38
|
+
for (const entry of options.connectors ?? builtinConnectors) {
|
|
39
|
+
if (!("create" in entry)) {
|
|
40
|
+
inline.push(parseConnector(entry, `Connector ${entry.id}`));
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (modules.has(entry.id))
|
|
44
|
+
throw new Error(`Two connector modules have the id ${entry.id}`);
|
|
45
|
+
modules.set(entry.id, entry);
|
|
46
|
+
if (!entry.connector)
|
|
47
|
+
continue;
|
|
48
|
+
const connector = parseConnector(entry.connector, `Connector ${entry.id}`);
|
|
49
|
+
if (connector.id !== entry.id)
|
|
50
|
+
throw new Error(`Connector module ${entry.id} carries the definition of ${connector.id}`);
|
|
51
|
+
inline.push(connector);
|
|
52
|
+
}
|
|
53
|
+
const builtin = loadConnectors();
|
|
54
|
+
const connectors = [
|
|
55
|
+
...builtin.filter((c) => modules.has(c.id)),
|
|
56
|
+
...inline,
|
|
57
|
+
...(options.extraConnectorDirs ?? []).flatMap((dir) => {
|
|
58
|
+
const found = loadConnectors(pathToFileURL(`${dir.replace(/\/+$/, "")}/`));
|
|
59
|
+
if (!found.length)
|
|
60
|
+
throw new Error(`No connector.json in a subfolder of ${dir}`);
|
|
61
|
+
return found;
|
|
62
|
+
}),
|
|
63
|
+
];
|
|
64
|
+
for (const id of modules.keys())
|
|
65
|
+
if (!connectors.some((c) => c.id === id))
|
|
66
|
+
throw new Error(`Connector module ${id} has no definition: give it as its connector, or its folder in extraConnectorDirs`);
|
|
67
|
+
const apps = connectors.map((connector) => {
|
|
68
|
+
if (connectors.filter((c) => c.id === connector.id).length > 1)
|
|
69
|
+
throw new Error(`Two connectors have the id ${connector.id}`);
|
|
70
|
+
// An app described entirely in its connector.json runs on a generic module.
|
|
71
|
+
const module = modules.get(connector.id) ??
|
|
72
|
+
(connector.http
|
|
73
|
+
? httpConnector
|
|
74
|
+
: connector.soap
|
|
75
|
+
? soapConnector
|
|
76
|
+
: connector.odata
|
|
77
|
+
? odataConnector
|
|
78
|
+
: connector.sql
|
|
79
|
+
? sqlConnector
|
|
80
|
+
: undefined);
|
|
81
|
+
if (!module)
|
|
82
|
+
throw new Error(`Connector ${connector.id} has no code (ConnectorModule)`);
|
|
83
|
+
return { connector, ...module.create({ microsoft, connector }) };
|
|
84
|
+
});
|
|
85
|
+
if (!apps.length)
|
|
86
|
+
throw new Error("No connectors: pass at least one app in connectors");
|
|
87
|
+
assertToolsImplemented(apps);
|
|
88
|
+
// Every `live` step check a connector names is one the Teams admin runs.
|
|
89
|
+
for (const { connector } of apps)
|
|
90
|
+
for (const step of [...connector.setup, ...connector.afterConnect])
|
|
91
|
+
if (step.live && !LIVE_CHECKS.includes(step.live))
|
|
92
|
+
throw new Error(`Connector ${connector.id}: no live check ${step.live}`);
|
|
93
|
+
const providerClients = { microsoft: microsoft.provider };
|
|
94
|
+
// A built-in app left out drops out of its provider's add-agent steps.
|
|
95
|
+
const left = new Set(builtin.map((c) => c.id).filter((id) => !apps.some((a) => a.connector.id === id)));
|
|
96
|
+
const providers = loadProviders().map((provider) => {
|
|
97
|
+
const client = providerClients[provider.id];
|
|
98
|
+
if (!client)
|
|
99
|
+
throw new Error(`connectors/${provider.id}/provider.json has no client`);
|
|
100
|
+
const addAgent = provider.addAgent
|
|
101
|
+
.map((step) => ({ ...step, apps: step.apps.filter((id) => !left.has(id)) }))
|
|
102
|
+
.filter((step) => step.apps.length);
|
|
103
|
+
return { provider: { ...provider, addAgent }, client };
|
|
104
|
+
});
|
|
105
|
+
const teamsConnector = apps.find((a) => a.connector.id === "teams")?.connector ?? null;
|
|
106
|
+
const ownsSql = !("unsafe" in options.database);
|
|
107
|
+
const sql = "unsafe" in options.database ? options.database : connectDatabase(options.database.url);
|
|
108
|
+
if (options.migrate ?? true)
|
|
109
|
+
await runMigrations(sql, schema);
|
|
110
|
+
const store = createStore(sql, schema);
|
|
111
|
+
const key = new CredentialKey(options.encryptionKey, options.previousEncryptionKey);
|
|
112
|
+
const teamsStore = createTeamsStore(sql, schema);
|
|
113
|
+
const bots = botClient();
|
|
114
|
+
const base = options.publicBaseUrl?.trim().replace(/\/+$/, "");
|
|
115
|
+
const publicUrl = base ? `${base}/agent-connect` : null;
|
|
116
|
+
const runners = new Map((options.runners ?? [claudeManagedAgents(), signedWebhook()])
|
|
117
|
+
.map((make) => make({ teams: teamsStore, key, publicUrl }))
|
|
118
|
+
.map((r) => [r.id, r]));
|
|
119
|
+
const runtime = createTeamsRuntime({
|
|
120
|
+
store,
|
|
121
|
+
teams: teamsStore,
|
|
122
|
+
key,
|
|
123
|
+
auth: botFrameworkAuth(),
|
|
124
|
+
bots,
|
|
125
|
+
runners,
|
|
126
|
+
connector: teamsConnector,
|
|
127
|
+
publicUrl,
|
|
128
|
+
});
|
|
129
|
+
const service = createService({
|
|
130
|
+
apps,
|
|
131
|
+
providers,
|
|
132
|
+
store,
|
|
133
|
+
key,
|
|
134
|
+
bots: { botForAgent: teamsStore.botForAgent, access: runtime.access },
|
|
135
|
+
});
|
|
136
|
+
const eventsStore = createEventsStore(sql, schema);
|
|
137
|
+
const eventApps = new Map(apps.filter((a) => a.connector.events).map((a) => [a.connector.id, a.connector]));
|
|
138
|
+
const eventDeps = {
|
|
139
|
+
store,
|
|
140
|
+
events: eventsStore,
|
|
141
|
+
key,
|
|
142
|
+
connectors: eventApps,
|
|
143
|
+
appCall: service.appCall,
|
|
144
|
+
runners,
|
|
145
|
+
};
|
|
146
|
+
const events = createEventsRuntime(eventDeps);
|
|
147
|
+
const app = createApp({
|
|
148
|
+
service,
|
|
149
|
+
store,
|
|
150
|
+
adminToken: options.adminToken,
|
|
151
|
+
events: { runtime: events, admin: createEventsAdmin({ ...eventDeps, publicUrl }) },
|
|
152
|
+
teams: {
|
|
153
|
+
runtime,
|
|
154
|
+
admin: createTeamsAdmin({
|
|
155
|
+
store,
|
|
156
|
+
teams: teamsStore,
|
|
157
|
+
key,
|
|
158
|
+
bots,
|
|
159
|
+
claude: claudeClient,
|
|
160
|
+
runners,
|
|
161
|
+
publicUrl,
|
|
162
|
+
microsoft,
|
|
163
|
+
}),
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
return {
|
|
167
|
+
fetch: (req) => app.fetch(req),
|
|
168
|
+
connectors: apps.map((a) => a.connector.id),
|
|
169
|
+
start() {
|
|
170
|
+
runtime.start();
|
|
171
|
+
events.start();
|
|
172
|
+
// While rotating the key, move what Teams sealed onto the new one.
|
|
173
|
+
if (options.previousEncryptionKey)
|
|
174
|
+
resealTeamsCredentials(teamsStore, key).then((n) => log.log(`[agent-connect] re-sealed ${n.bots} bot credentials, ${n.claudeKeys} Claude keys and ${n.triggerSecrets} trigger secrets`), (error) => log.error("[agent-connect] re-sealing Teams credentials failed", error));
|
|
175
|
+
if (options.previousEncryptionKey)
|
|
176
|
+
resealEventSecrets(eventsStore, key).then((n) => log.log(`[agent-connect] re-sealed ${n} app event secrets`), (error) => log.error("[agent-connect] re-sealing app event secrets failed", error));
|
|
177
|
+
},
|
|
178
|
+
async stop() {
|
|
179
|
+
await Promise.all([runtime.stop(), events.stop()]);
|
|
180
|
+
if (ownsSql)
|
|
181
|
+
await sql.end();
|
|
182
|
+
},
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/server/src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type Sql } from "./store.js";
|
|
2
|
+
export type Migration = {
|
|
3
|
+
id: string;
|
|
4
|
+
version: number;
|
|
5
|
+
name: string;
|
|
6
|
+
sql: string;
|
|
7
|
+
checksum: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function migrationFiles(): Migration[];
|
|
10
|
+
/** Applies pending migrations in one transaction; returns what it did, in order. */
|
|
11
|
+
export declare function migrate(sql: Sql, schema: string, log?: (line: string) => void): Promise<string[]>;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { readdirSync, readFileSync } from "node:fs";
|
|
3
|
+
import { assertSchemaName } from "./store.js";
|
|
4
|
+
// The service's own schema migrations: plain numbered SQL in migrations/, written with
|
|
5
|
+
// unqualified names and run with search_path set to the configured schema, recorded in that
|
|
6
|
+
// schema's schema_migrations.
|
|
7
|
+
const DIR = new URL("../migrations/", import.meta.url);
|
|
8
|
+
// What the earlier layout had in public, made by the host's migration before the service had a schema.
|
|
9
|
+
// 0001 makes the same tables, so an install that has them adopts them as 0001.
|
|
10
|
+
const PREFIX = "agent_connect_";
|
|
11
|
+
const LEGACY = [
|
|
12
|
+
"agents",
|
|
13
|
+
"providers",
|
|
14
|
+
"connections",
|
|
15
|
+
"grants",
|
|
16
|
+
"audit",
|
|
17
|
+
"confirmed",
|
|
18
|
+
"teams_bots",
|
|
19
|
+
"teams_conversations",
|
|
20
|
+
"teams_events",
|
|
21
|
+
"teams_triggers",
|
|
22
|
+
"teams_runs",
|
|
23
|
+
"teams_spend",
|
|
24
|
+
].map((name) => `${PREFIX}${name}`);
|
|
25
|
+
export function migrationFiles() {
|
|
26
|
+
return readdirSync(DIR)
|
|
27
|
+
.filter((file) => /^\d{4}_[a-z0-9_]+\.sql$/.test(file))
|
|
28
|
+
.sort()
|
|
29
|
+
.map((file) => {
|
|
30
|
+
const sql = readFileSync(new URL(file, DIR), "utf8");
|
|
31
|
+
return {
|
|
32
|
+
id: file.slice(0, -4),
|
|
33
|
+
version: Number(file.slice(0, 4)),
|
|
34
|
+
name: file.slice(5, -4),
|
|
35
|
+
sql,
|
|
36
|
+
checksum: createHash("sha256").update(sql).digest("hex"),
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/** Applies pending migrations in one transaction; returns what it did, in order. */
|
|
41
|
+
export async function migrate(sql, schema, log = console.log) {
|
|
42
|
+
assertSchemaName(schema);
|
|
43
|
+
const files = migrationFiles();
|
|
44
|
+
return sql.begin(async (tx) => {
|
|
45
|
+
// One run at a time, e.g. two pods starting together; released with the transaction.
|
|
46
|
+
await tx `select pg_advisory_xact_lock(hashtext(${`${schema}.migrate`}))`;
|
|
47
|
+
// "Already exists, skipping" on every start is noise.
|
|
48
|
+
await tx `set local client_min_messages = warning`;
|
|
49
|
+
await tx.unsafe(`create schema if not exists ${schema}`);
|
|
50
|
+
await tx.unsafe(`revoke all on schema ${schema} from public`);
|
|
51
|
+
await tx.unsafe(`create table if not exists ${schema}.schema_migrations (
|
|
52
|
+
version int primary key,
|
|
53
|
+
name text not null,
|
|
54
|
+
checksum text not null,
|
|
55
|
+
adopted boolean not null default false,
|
|
56
|
+
applied_at timestamptz not null default now())`);
|
|
57
|
+
const applied = await tx.unsafe(`select version, checksum from ${schema}.schema_migrations order by version`);
|
|
58
|
+
for (const row of applied) {
|
|
59
|
+
const file = files.find((f) => f.version === row.version);
|
|
60
|
+
if (!file)
|
|
61
|
+
throw new Error(`Migration ${row.version} is applied in ${schema} but not known to this version`);
|
|
62
|
+
if (file.checksum !== row.checksum)
|
|
63
|
+
throw new Error(`Migration ${file.id} changed after it was applied`);
|
|
64
|
+
}
|
|
65
|
+
const ran = [];
|
|
66
|
+
const legacy = await legacyTables(tx);
|
|
67
|
+
const adopting = legacy.length > 0 && !applied.length;
|
|
68
|
+
if (adopting) {
|
|
69
|
+
// Moved, not copied: the rows, ids and sequences stay as they are.
|
|
70
|
+
for (const table of LEGACY)
|
|
71
|
+
await tx.unsafe(`alter table public.${table} set schema ${schema}`);
|
|
72
|
+
const first = files[0];
|
|
73
|
+
await tx.unsafe(`insert into ${schema}.schema_migrations (version, name, checksum, adopted)
|
|
74
|
+
values ($1, $2, $3, true)`, [first.version, first.name, first.checksum]);
|
|
75
|
+
applied.push({ version: first.version, checksum: first.checksum });
|
|
76
|
+
ran.push(`adopted public.agent_connect_* as ${first.id}`);
|
|
77
|
+
}
|
|
78
|
+
else if (legacy.length) {
|
|
79
|
+
// The host's migration made them after this schema existed: a fresh install where the
|
|
80
|
+
// service started before the host's migrations ran. Empty, they are dropped; rows are not.
|
|
81
|
+
const filled = [];
|
|
82
|
+
for (const table of legacy) {
|
|
83
|
+
// FORCE RLS with no policies hides every row from an owner without bypassrls, and
|
|
84
|
+
// this check is all that stands before the drop. Rolled back with the transaction.
|
|
85
|
+
await tx.unsafe(`alter table public.${table} no force row level security`);
|
|
86
|
+
const [{ any }] = await tx.unsafe(`select exists (select from public.${table}) as any`);
|
|
87
|
+
if (any)
|
|
88
|
+
filled.push(table);
|
|
89
|
+
}
|
|
90
|
+
if (filled.length)
|
|
91
|
+
throw new Error(`public.${filled.join(", public.")} hold rows, but ${schema} already has the service's tables`);
|
|
92
|
+
await tx.unsafe(`drop table ${legacy.map((t) => `public.${t}`).join(", ")}`);
|
|
93
|
+
ran.push(`dropped empty public.${legacy.join(", public.")}`);
|
|
94
|
+
}
|
|
95
|
+
await tx.unsafe(`set local search_path to ${schema}`);
|
|
96
|
+
const done = new Set(applied.map((row) => row.version));
|
|
97
|
+
for (const file of files.filter((f) => !done.has(f.version))) {
|
|
98
|
+
await tx.unsafe(file.sql).simple();
|
|
99
|
+
await tx.unsafe(`insert into ${schema}.schema_migrations (version, name, checksum) values ($1, $2, $3)`, [file.version, file.name, file.checksum]);
|
|
100
|
+
ran.push(`applied ${file.id}`);
|
|
101
|
+
}
|
|
102
|
+
if (adopting) {
|
|
103
|
+
// So that a rolled-back 0.7.x image, which reads public.agent_connect_*, keeps serving
|
|
104
|
+
// until to-legacy.sql runs. Simple views, so its inserts, upserts and row locks go
|
|
105
|
+
// through. TODO(next release): drop them in a migration before any column changes.
|
|
106
|
+
for (const table of LEGACY)
|
|
107
|
+
await tx.unsafe(`create view public.${table} as select * from ${schema}.${table.slice(PREFIX.length)}`);
|
|
108
|
+
// Default privileges on public can grant them to API roles; they bypass RLS, so only
|
|
109
|
+
// their owner keeps them.
|
|
110
|
+
const grants = await tx.unsafe(`select distinct c.relname as view, a.grantee::regrole::text as role
|
|
111
|
+
from pg_class c join pg_namespace n on n.oid = c.relnamespace,
|
|
112
|
+
aclexplode(c.relacl) a
|
|
113
|
+
where n.nspname = 'public' and c.relname = any($1::text[])
|
|
114
|
+
and a.grantee not in (0, c.relowner)`, [LEGACY]);
|
|
115
|
+
for (const { view, role } of grants)
|
|
116
|
+
await tx.unsafe(`revoke all on public.${view} from ${role}`);
|
|
117
|
+
for (const table of LEGACY)
|
|
118
|
+
await tx.unsafe(`revoke all on public.${table} from public`);
|
|
119
|
+
ran.push(`made views public.${PREFIX}* for the previous release`);
|
|
120
|
+
}
|
|
121
|
+
for (const line of ran)
|
|
122
|
+
log(`[agent-connect] migrations: ${line} (schema ${schema})`);
|
|
123
|
+
return ran;
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
async function legacyTables(tx) {
|
|
127
|
+
// Tables only: the views made on adoption have the same names. In LEGACY's order, not the
|
|
128
|
+
// catalog's, which moves as other tables are made.
|
|
129
|
+
const rows = await tx.unsafe(`select c.relname as name from pg_class c join pg_namespace n on n.oid = c.relnamespace
|
|
130
|
+
where n.nspname = 'public' and c.relkind in ('r', 'p') and c.relname = any($1::text[])
|
|
131
|
+
order by array_position($1::text[], c.relname::text)`, [LEGACY]);
|
|
132
|
+
return rows.map((row) => row.name);
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=migrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../../../packages/server/src/migrate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { isDeepStrictEqual } from "node:util";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { PARAMS, routes, schemas } from "./api.js";
|
|
4
|
+
export const ADMIN_V1 = "/agent-connect/admin/v1";
|
|
5
|
+
function convert(schema, io, components) {
|
|
6
|
+
const { $schema: _, $defs, ...json } = z.toJSONSchema(schema, {
|
|
7
|
+
io,
|
|
8
|
+
target: "draft-2020-12",
|
|
9
|
+
});
|
|
10
|
+
const ref = (value) => Array.isArray(value)
|
|
11
|
+
? value.map(ref)
|
|
12
|
+
: value && typeof value === "object"
|
|
13
|
+
? Object.fromEntries(Object.entries(value).map(([k, v]) => [
|
|
14
|
+
k,
|
|
15
|
+
k === "$ref" && typeof v === "string"
|
|
16
|
+
? v.replace("#/$defs/", "#/components/schemas/")
|
|
17
|
+
: ref(v),
|
|
18
|
+
]))
|
|
19
|
+
: value;
|
|
20
|
+
for (const [id, def] of Object.entries($defs ?? {})) {
|
|
21
|
+
const next = ref(def);
|
|
22
|
+
// One id, one shape: a body and an answer naming the same schema must agree.
|
|
23
|
+
if (id in components && !isDeepStrictEqual(components[id], next))
|
|
24
|
+
throw new Error(`Schema ${id} differs between its uses`);
|
|
25
|
+
components[id] = next;
|
|
26
|
+
}
|
|
27
|
+
return ref(json);
|
|
28
|
+
}
|
|
29
|
+
function answer(status, a, components) {
|
|
30
|
+
const description = status < 300 ? "OK" : "Refused";
|
|
31
|
+
if (a === null)
|
|
32
|
+
return { description };
|
|
33
|
+
if ("file" in a)
|
|
34
|
+
return { description, content: { [a.file]: { schema: { type: "string", format: "binary" } } } };
|
|
35
|
+
return {
|
|
36
|
+
description,
|
|
37
|
+
content: { "application/json": { schema: convert(a, "output", components) } },
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export function openapi() {
|
|
41
|
+
const components = {};
|
|
42
|
+
const error = () => answer(400, schemas.Error, components);
|
|
43
|
+
const paths = {};
|
|
44
|
+
for (const [operationId, spec] of Object.entries(routes)) {
|
|
45
|
+
const parameters = [
|
|
46
|
+
...[...spec.path.matchAll(/\{(\w+)\}/g)].map(([, p]) => ({
|
|
47
|
+
name: p,
|
|
48
|
+
in: "path",
|
|
49
|
+
required: true,
|
|
50
|
+
schema: { type: "string", pattern: `^${PARAMS[p]}$` },
|
|
51
|
+
})),
|
|
52
|
+
...Object.entries(spec.query ?? {}).map(([q, description]) => ({
|
|
53
|
+
name: q,
|
|
54
|
+
in: "query",
|
|
55
|
+
required: false,
|
|
56
|
+
description,
|
|
57
|
+
schema: { type: "string" },
|
|
58
|
+
})),
|
|
59
|
+
];
|
|
60
|
+
const responses = {};
|
|
61
|
+
for (const [status, a] of Object.entries(spec.responses))
|
|
62
|
+
responses[status] = answer(Number(status), a, components);
|
|
63
|
+
// Every route: bad input, a wrong token, an unknown organization or route, a refusal by
|
|
64
|
+
// the app being connected.
|
|
65
|
+
for (const status of ["400", "401", "404", "422"])
|
|
66
|
+
responses[status] ??= error();
|
|
67
|
+
(paths[spec.path] ??= {})[spec.method.toLowerCase()] = {
|
|
68
|
+
operationId,
|
|
69
|
+
summary: spec.summary,
|
|
70
|
+
...(spec.teams ? { tags: ["teams"] } : spec.events ? { tags: ["events"] } : {}),
|
|
71
|
+
...(parameters.length ? { parameters } : {}),
|
|
72
|
+
...(spec.body
|
|
73
|
+
? {
|
|
74
|
+
requestBody: {
|
|
75
|
+
required: !spec.body.safeParse(undefined).success,
|
|
76
|
+
content: { "application/json": { schema: convert(spec.body, "input", components) } },
|
|
77
|
+
},
|
|
78
|
+
}
|
|
79
|
+
: {}),
|
|
80
|
+
responses,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
openapi: "3.1.0",
|
|
85
|
+
info: {
|
|
86
|
+
title: "Agent Connect admin API",
|
|
87
|
+
version: "1",
|
|
88
|
+
description: "Server to server only: a bearer token (AGENT_CONNECT_ADMIN_TOKEN), and requests " +
|
|
89
|
+
"carrying X-Forwarded-For are refused. Routes tagged teams are served only where " +
|
|
90
|
+
"Teams is set up, routes tagged events only where app events are.",
|
|
91
|
+
},
|
|
92
|
+
servers: [{ url: ADMIN_V1 }],
|
|
93
|
+
security: [{ bearer: [] }],
|
|
94
|
+
paths,
|
|
95
|
+
components: {
|
|
96
|
+
schemas: Object.fromEntries(Object.entries(components).sort(([a], [b]) => a.localeCompare(b))),
|
|
97
|
+
securitySchemes: { bearer: { type: "http", scheme: "bearer" } },
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=openapi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openapi.js","sourceRoot":"","sources":["../../../../packages/server/src/openapi.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** A queue worker for one process: `next` handles one item and says whether there was one.
|
|
2
|
+
* One drain at a time; a kick during one makes it look again before stopping. */
|
|
3
|
+
export declare function drainer(name: string, next: () => Promise<boolean>): {
|
|
4
|
+
kick: () => void;
|
|
5
|
+
start(): void;
|
|
6
|
+
/** Stops claiming and waits for the item in hand, so a rollout neither strands it nor
|
|
7
|
+
* handles it twice. */
|
|
8
|
+
stop(): Promise<void>;
|
|
9
|
+
idle(): Promise<void>;
|
|
10
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/** A queue worker for one process: `next` handles one item and says whether there was one.
|
|
2
|
+
* One drain at a time; a kick during one makes it look again before stopping. */
|
|
3
|
+
export function drainer(name, next) {
|
|
4
|
+
let draining = null;
|
|
5
|
+
let again = false;
|
|
6
|
+
let stopped = false;
|
|
7
|
+
async function drain() {
|
|
8
|
+
while (again) {
|
|
9
|
+
again = false;
|
|
10
|
+
while (!stopped && (await next()))
|
|
11
|
+
;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function kick() {
|
|
15
|
+
if (stopped)
|
|
16
|
+
return;
|
|
17
|
+
again = true;
|
|
18
|
+
draining ??= drain()
|
|
19
|
+
.catch((error) => console.error(`[${name}] worker`, error))
|
|
20
|
+
.finally(() => {
|
|
21
|
+
draining = null;
|
|
22
|
+
if (again)
|
|
23
|
+
kick();
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
kick,
|
|
28
|
+
start() {
|
|
29
|
+
stopped = false;
|
|
30
|
+
},
|
|
31
|
+
/** Stops claiming and waits for the item in hand, so a rollout neither strands it nor
|
|
32
|
+
* handles it twice. */
|
|
33
|
+
async stop() {
|
|
34
|
+
stopped = true;
|
|
35
|
+
again = false;
|
|
36
|
+
while (draining)
|
|
37
|
+
await draining;
|
|
38
|
+
},
|
|
39
|
+
async idle() {
|
|
40
|
+
while (draining)
|
|
41
|
+
await draining;
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.js","sourceRoot":"","sources":["../../../../packages/server/src/queue.ts"],"names":[],"mappings":"AAAA;kFACkF;AAClF,MAAM,UAAU,OAAO,CAAC,IAAY,EAAE,IAA4B;IAChE,IAAI,QAAQ,GAAyB,IAAI,CAAC;IAC1C,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,KAAK,UAAU,KAAK;QAClB,OAAO,KAAK,EAAE,CAAC;YACb,KAAK,GAAG,KAAK,CAAC;YACd,OAAO,CAAC,OAAO,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;gBAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,SAAS,IAAI;QACX,IAAI,OAAO;YAAE,OAAO;QACpB,KAAK,GAAG,IAAI,CAAC;QACb,QAAQ,KAAK,KAAK,EAAE;aACjB,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,UAAU,EAAE,KAAK,CAAC,CAAC;aAC1D,OAAO,CAAC,GAAG,EAAE;YACZ,QAAQ,GAAG,IAAI,CAAC;YAChB,IAAI,KAAK;gBAAE,IAAI,EAAE,CAAC;QACpB,CAAC,CAAC,CAAC;IACP,CAAC;IAED,OAAO;QACL,IAAI;QACJ,KAAK;YACH,OAAO,GAAG,KAAK,CAAC;QAClB,CAAC;QACD;gCACwB;QACxB,KAAK,CAAC,IAAI;YACR,OAAO,GAAG,IAAI,CAAC;YACf,KAAK,GAAG,KAAK,CAAC;YACd,OAAO,QAAQ;gBAAE,MAAM,QAAQ,CAAC;QAClC,CAAC;QACD,KAAK,CAAC,IAAI;YACR,OAAO,QAAQ;gBAAE,MAAM,QAAQ,CAAC;QAClC,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type Sealed = {
|
|
2
|
+
ciphertext: Buffer;
|
|
3
|
+
keyId: string;
|
|
4
|
+
};
|
|
5
|
+
export declare class CredentialKey {
|
|
6
|
+
#private;
|
|
7
|
+
readonly id: string;
|
|
8
|
+
constructor(base64: string, previousBase64?: string);
|
|
9
|
+
/** Ids of the previous key(s) still loaded while rotating. */
|
|
10
|
+
get previousIds(): string[];
|
|
11
|
+
derive(purpose: string): Buffer;
|
|
12
|
+
seal(secret: Record<string, string>, aad: string): Sealed;
|
|
13
|
+
open(sealed: Sealed, aad: string): Record<string, string>;
|
|
14
|
+
}
|
|
15
|
+
export declare const credentialAad: (organizationId: string, connectorId: string) => string;
|
|
16
|
+
export declare function newAgentKey(): string;
|
|
17
|
+
export declare function hashAgentKey(key: string): string;
|
|
18
|
+
export declare function looksLikeAgentKey(key: string): boolean;
|
|
19
|
+
export declare function tokensEqual(a: string, b: string): boolean;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { createCipheriv, createDecipheriv, createHash, hkdfSync, randomBytes, timingSafeEqual, } from "node:crypto";
|
|
2
|
+
const keyId = (key) => createHash("sha256").update(key).digest("hex").slice(0, 16);
|
|
3
|
+
function parseKey(base64, name) {
|
|
4
|
+
const key = Buffer.from(base64, "base64");
|
|
5
|
+
if (key.length !== 32)
|
|
6
|
+
throw new Error(`${name} must be 32 bytes, base64`);
|
|
7
|
+
return key;
|
|
8
|
+
}
|
|
9
|
+
// Rotation: set the new key as CONNECT_ENCRYPTION_KEY and the old one as `previous`. Rows
|
|
10
|
+
// sealed with the old key still open, and are re-sealed with the new one when next checked.
|
|
11
|
+
export class CredentialKey {
|
|
12
|
+
id;
|
|
13
|
+
#key;
|
|
14
|
+
#previous;
|
|
15
|
+
constructor(base64, previousBase64) {
|
|
16
|
+
this.#key = parseKey(base64, "CONNECT_ENCRYPTION_KEY");
|
|
17
|
+
this.id = keyId(this.#key);
|
|
18
|
+
const previous = previousBase64
|
|
19
|
+
? parseKey(previousBase64, "CONNECT_ENCRYPTION_KEY_PREVIOUS")
|
|
20
|
+
: null;
|
|
21
|
+
this.#previous = new Map(previous ? [[keyId(previous), previous]] : []);
|
|
22
|
+
}
|
|
23
|
+
/** Ids of the previous key(s) still loaded while rotating. */
|
|
24
|
+
get previousIds() {
|
|
25
|
+
return [...this.#previous.keys()];
|
|
26
|
+
}
|
|
27
|
+
// A separate key for another purpose (e.g. signing consent state), never the sealing key.
|
|
28
|
+
derive(purpose) {
|
|
29
|
+
return Buffer.from(hkdfSync("sha256", this.#key, "", `agent-connect:${purpose}`, 32));
|
|
30
|
+
}
|
|
31
|
+
seal(secret, aad) {
|
|
32
|
+
const iv = randomBytes(12);
|
|
33
|
+
const cipher = createCipheriv("aes-256-gcm", this.#key, iv);
|
|
34
|
+
cipher.setAAD(Buffer.from(aad));
|
|
35
|
+
const body = Buffer.concat([cipher.update(JSON.stringify(secret), "utf8"), cipher.final()]);
|
|
36
|
+
return { ciphertext: Buffer.concat([iv, cipher.getAuthTag(), body]), keyId: this.id };
|
|
37
|
+
}
|
|
38
|
+
open(sealed, aad) {
|
|
39
|
+
const key = sealed.keyId === this.id ? this.#key : this.#previous.get(sealed.keyId);
|
|
40
|
+
if (!key)
|
|
41
|
+
throw new Error(`Credential was sealed with key ${sealed.keyId}, which is not loaded`);
|
|
42
|
+
const iv = sealed.ciphertext.subarray(0, 12);
|
|
43
|
+
const tag = sealed.ciphertext.subarray(12, 28);
|
|
44
|
+
const decipher = createDecipheriv("aes-256-gcm", key, iv);
|
|
45
|
+
decipher.setAAD(Buffer.from(aad));
|
|
46
|
+
decipher.setAuthTag(tag);
|
|
47
|
+
const plain = Buffer.concat([
|
|
48
|
+
decipher.update(sealed.ciphertext.subarray(28)),
|
|
49
|
+
decipher.final(),
|
|
50
|
+
]);
|
|
51
|
+
return JSON.parse(plain.toString("utf8"));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
export const credentialAad = (organizationId, connectorId) => `agent-connect:${organizationId}:${connectorId}`;
|
|
55
|
+
// Both shapes are accepted, forever (the shape check is not the authentication; the hash
|
|
56
|
+
// lookup is). New keys keep arb_agent_ for this release, because a rollback to the previous one,
|
|
57
|
+
// which accepts only that, must still take keys made meanwhile. Switch to eac_agent_ in the
|
|
58
|
+
// next release.
|
|
59
|
+
const AGENT_KEY_PREFIX = "arb_agent_";
|
|
60
|
+
export function newAgentKey() {
|
|
61
|
+
return AGENT_KEY_PREFIX + randomBytes(32).toString("base64url");
|
|
62
|
+
}
|
|
63
|
+
// Agent keys carry 256 bits of randomness, so an unsalted SHA-256 is enough to make a
|
|
64
|
+
// database read useless for calling the service.
|
|
65
|
+
export function hashAgentKey(key) {
|
|
66
|
+
return createHash("sha256").update(key).digest("hex");
|
|
67
|
+
}
|
|
68
|
+
export function looksLikeAgentKey(key) {
|
|
69
|
+
return /^(eac|arb)_agent_[A-Za-z0-9_-]{43}$/.test(key);
|
|
70
|
+
}
|
|
71
|
+
export function tokensEqual(a, b) {
|
|
72
|
+
const ha = createHash("sha256").update(a).digest();
|
|
73
|
+
const hb = createHash("sha256").update(b).digest();
|
|
74
|
+
return timingSafeEqual(ha, hb);
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=secrets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../../../packages/server/src/secrets.ts"],"names":[],"mappings":"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"}
|