@agent-native/dispatch 0.8.2 → 0.8.3
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/dist/actions/update-vault-secret.d.ts.map +1 -1
- package/dist/actions/update-vault-secret.js +34 -6
- package/dist/actions/update-vault-secret.js.map +1 -1
- package/dist/routes/index.d.ts.map +1 -1
- package/dist/routes/index.js +1 -0
- package/dist/routes/index.js.map +1 -1
- package/dist/routes/pages/extensions.$id.d.ts +3 -0
- package/dist/routes/pages/extensions.$id.d.ts.map +1 -1
- package/dist/routes/pages/extensions.$id.js +5 -2
- package/dist/routes/pages/extensions.$id.js.map +1 -1
- package/dist/routes/pages/extensions._index.d.ts +3 -0
- package/dist/routes/pages/extensions._index.d.ts.map +1 -1
- package/dist/routes/pages/extensions._index.js +5 -2
- package/dist/routes/pages/extensions._index.js.map +1 -1
- package/dist/routes/pages/tools.$id.d.ts +3 -0
- package/dist/routes/pages/tools.$id.d.ts.map +1 -1
- package/dist/routes/pages/tools.$id.js +3 -0
- package/dist/routes/pages/tools.$id.js.map +1 -1
- package/dist/routes/pages/tools._index.d.ts +3 -0
- package/dist/routes/pages/tools._index.d.ts.map +1 -1
- package/dist/routes/pages/tools._index.js +3 -0
- package/dist/routes/pages/tools._index.js.map +1 -1
- package/dist/routes/pages/vault.d.ts.map +1 -1
- package/dist/routes/pages/vault.js +46 -2
- package/dist/routes/pages/vault.js.map +1 -1
- package/dist/server/lib/vault-store.d.ts +7 -1
- package/dist/server/lib/vault-store.d.ts.map +1 -1
- package/dist/server/lib/vault-store.js +73 -4
- package/dist/server/lib/vault-store.js.map +1 -1
- package/package.json +1 -1
- package/src/actions/update-vault-secret.ts +39 -6
- package/src/routes/index.ts +1 -0
- package/src/routes/pages/extensions.$id.tsx +6 -2
- package/src/routes/pages/extensions._index.tsx +6 -2
- package/src/routes/pages/tools.$id.tsx +4 -0
- package/src/routes/pages/tools._index.tsx +4 -0
- package/src/routes/pages/vault.tsx +172 -1
- package/src/server/lib/vault-store.spec.ts +2 -0
- package/src/server/lib/vault-store.ts +101 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vault-store.d.ts","sourceRoot":"","sources":["../../../src/server/lib/vault-store.ts"],"names":[],"mappings":"AAGA,OAAO,
|
|
1
|
+
{"version":3,"file":"vault-store.d.ts","sourceRoot":"","sources":["../../../src/server/lib/vault-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
2
|
import { and, desc, eq, isNull, or } from "drizzle-orm";
|
|
3
3
|
import { discoverAgents } from "@agent-native/core/server/agent-discovery";
|
|
4
|
-
import { writeAppSecret } from "@agent-native/core/secrets";
|
|
4
|
+
import { deleteAppSecret, writeAppSecret, } from "@agent-native/core/secrets";
|
|
5
5
|
import { getOrgSetting, getUserSetting, putOrgSetting, putUserSetting, } from "@agent-native/core/settings";
|
|
6
6
|
import { getDb, schema } from "../../db/index.js";
|
|
7
7
|
import { currentOwnerEmail, currentOrgId, recordAudit, } from "./dispatch-store.js";
|
|
@@ -201,23 +201,92 @@ export async function createSecret(input, ctx = requireVaultCtx()) {
|
|
|
201
201
|
await syncSecretsToCredentialStore([created], ctx);
|
|
202
202
|
return created;
|
|
203
203
|
}
|
|
204
|
-
export async function updateSecret(secretId,
|
|
204
|
+
export async function updateSecret(secretId, input, ctx = requireVaultCtx()) {
|
|
205
205
|
const db = getDb();
|
|
206
206
|
const existing = await getSecret(secretId, ctx);
|
|
207
207
|
if (!existing)
|
|
208
208
|
throw new Error("Secret not found");
|
|
209
|
+
const patch = typeof input === "string" ? { value: input } : input;
|
|
210
|
+
const credentialKey = patch.credentialKey !== undefined
|
|
211
|
+
? normalizeCredentialKey(patch.credentialKey)
|
|
212
|
+
: existing.credentialKey;
|
|
213
|
+
if (!credentialKey)
|
|
214
|
+
throw new Error("Credential key is required");
|
|
215
|
+
const name = patch.name !== undefined ? patch.name.trim() : existing.name;
|
|
216
|
+
if (!name)
|
|
217
|
+
throw new Error("Secret name is required");
|
|
218
|
+
const value = patch.value !== undefined ? patch.value : existing.value;
|
|
219
|
+
if (!value)
|
|
220
|
+
throw new Error("Secret value is required");
|
|
221
|
+
const provider = patch.provider !== undefined ? patch.provider || null : existing.provider;
|
|
222
|
+
const description = patch.description !== undefined
|
|
223
|
+
? patch.description || null
|
|
224
|
+
: existing.description;
|
|
225
|
+
if (credentialKey !== existing.credentialKey) {
|
|
226
|
+
const conflict = await db
|
|
227
|
+
.select({ id: schema.vaultSecrets.id })
|
|
228
|
+
.from(schema.vaultSecrets)
|
|
229
|
+
.where(and(eq(schema.vaultSecrets.credentialKey, credentialKey), ctxScope(schema.vaultSecrets, ctx)))
|
|
230
|
+
.limit(1);
|
|
231
|
+
if (conflict[0] && conflict[0].id !== secretId) {
|
|
232
|
+
throw new Error(`Credential key "${credentialKey}" is already in use`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
209
235
|
await db
|
|
210
236
|
.update(schema.vaultSecrets)
|
|
211
|
-
.set({
|
|
237
|
+
.set({
|
|
238
|
+
name,
|
|
239
|
+
credentialKey,
|
|
240
|
+
value,
|
|
241
|
+
provider,
|
|
242
|
+
description,
|
|
243
|
+
updatedAt: now(),
|
|
244
|
+
})
|
|
212
245
|
.where(and(eq(schema.vaultSecrets.id, secretId), ctxScope(schema.vaultSecrets, ctx)));
|
|
246
|
+
const auditMetadata = {
|
|
247
|
+
name,
|
|
248
|
+
previousName: name !== existing.name ? existing.name : undefined,
|
|
249
|
+
credentialKey,
|
|
250
|
+
previousCredentialKey: credentialKey !== existing.credentialKey
|
|
251
|
+
? existing.credentialKey
|
|
252
|
+
: undefined,
|
|
253
|
+
provider,
|
|
254
|
+
previousProvider: provider !== existing.provider ? existing.provider : undefined,
|
|
255
|
+
description,
|
|
256
|
+
previousDescription: description !== existing.description ? existing.description : undefined,
|
|
257
|
+
valueChanged: value !== existing.value ? true : undefined,
|
|
258
|
+
};
|
|
213
259
|
await recordVaultAudit({
|
|
214
260
|
action: "secret.updated",
|
|
215
261
|
secretId,
|
|
216
|
-
summary: `Updated
|
|
262
|
+
summary: `Updated secret "${name}" (${credentialKey})`,
|
|
263
|
+
metadata: auditMetadata,
|
|
264
|
+
});
|
|
265
|
+
await recordAudit({
|
|
266
|
+
action: "vault.secret.updated",
|
|
267
|
+
targetType: "vault-secret",
|
|
268
|
+
targetId: secretId,
|
|
269
|
+
summary: `Updated vault secret "${name}" (${credentialKey})`,
|
|
270
|
+
metadata: auditMetadata,
|
|
217
271
|
});
|
|
218
272
|
const updated = await getSecret(secretId, ctx);
|
|
219
273
|
if (updated)
|
|
220
274
|
await syncSecretsToCredentialStore([updated], ctx);
|
|
275
|
+
if (updated && credentialKey !== existing.credentialKey) {
|
|
276
|
+
const stillUsesOldKey = await db
|
|
277
|
+
.select({ id: schema.vaultSecrets.id })
|
|
278
|
+
.from(schema.vaultSecrets)
|
|
279
|
+
.where(and(eq(schema.vaultSecrets.credentialKey, existing.credentialKey), ctxScope(schema.vaultSecrets, ctx)))
|
|
280
|
+
.limit(1);
|
|
281
|
+
if (!stillUsesOldKey[0]) {
|
|
282
|
+
const target = credentialStoreScopeForVaultCtx(ctx);
|
|
283
|
+
await deleteAppSecret({
|
|
284
|
+
key: existing.credentialKey,
|
|
285
|
+
scope: target.scope,
|
|
286
|
+
scopeId: target.scopeId,
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
}
|
|
221
290
|
return updated;
|
|
222
291
|
}
|
|
223
292
|
export async function deleteSecret(secretId, ctx = requireVaultCtx()) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vault-store.js","sourceRoot":"","sources":["../../../src/server/lib/vault-store.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto from \"node:crypto\";\nimport { and, desc, eq, isNull, or } from \"drizzle-orm\";\nimport { discoverAgents } from \"@agent-native/core/server/agent-discovery\";\nimport { writeAppSecret, type SecretScope } from \"@agent-native/core/secrets\";\nimport {\n getOrgSetting,\n getUserSetting,\n putOrgSetting,\n putUserSetting,\n} from \"@agent-native/core/settings\";\nimport { getDb, schema } from \"../../db/index.js\";\nimport {\n currentOwnerEmail,\n currentOrgId,\n recordAudit,\n} from \"./dispatch-store.js\";\n\nconst VAULT_ACCESS_SETTINGS_KEY = \"dispatch-vault-access-settings\";\n\nexport type VaultAccessMode = \"all-apps\" | \"manual\";\n\nexport interface VaultAccessSettings {\n mode: VaultAccessMode;\n scope: \"org\" | \"user\";\n scopeId: string;\n}\n\n/**\n * Caller-supplied access context for vault operations.\n *\n * Every getSecret / updateSecret / deleteSecret / createGrant call must\n * pass the ctx of the *current request* so the row is scoped to that\n * caller's tenant. Looking up a vault secret by id alone is unsafe — UUIDs\n * are not authorization. A row matches the ctx if either the caller owns\n * it or it lives in the caller's active org.\n */\nexport interface VaultCtx {\n ownerEmail: string;\n orgId: string | null;\n}\n\n/**\n * Build a VaultCtx from the current request. Throws if the request is\n * unauthenticated — the previous behavior of falling back to \"local@localhost\"\n * leaked rows across tenants when a misconfigured environment skipped auth.\n */\nexport function requireVaultCtx(): VaultCtx {\n const ownerEmail = currentOwnerEmail();\n if (!ownerEmail) {\n throw new Error(\"Vault operation requires an authenticated user\");\n }\n return { ownerEmail, orgId: currentOrgId() };\n}\n\n/** WHERE clause that limits a vault row to the caller's ownership scope. */\nfunction ctxScope<T extends { ownerEmail: any; orgId: any }>(\n table: T,\n ctx: VaultCtx,\n) {\n if (!ctx.orgId) {\n return and(eq(table.ownerEmail, ctx.ownerEmail), isNull(table.orgId));\n }\n return or(eq(table.ownerEmail, ctx.ownerEmail), eq(table.orgId, ctx.orgId));\n}\n\n/** Build a ctx that scopes to a specific row's owner/org (used when a\n * request approver acts on behalf of the original requester so the\n * created secret lands in the request's org). */\nfunction ctxForRow(row: {\n ownerEmail: string;\n orgId: string | null;\n}): VaultCtx {\n return { ownerEmail: row.ownerEmail, orgId: row.orgId };\n}\n\nfunction id() {\n return crypto.randomUUID();\n}\n\nfunction now() {\n return Date.now();\n}\n\nfunction safeJson(value: unknown) {\n return JSON.stringify(value ?? null);\n}\n\nfunction scopedFilter<T extends { ownerEmail: any; orgId: any }>(table: T) {\n return ctxScope(table, requireVaultCtx());\n}\n\nfunction normalizeCredentialKey(value: string) {\n return value.trim();\n}\n\nfunction vaultAccessScope() {\n const orgId = currentOrgId();\n if (orgId) return { scope: \"org\" as const, scopeId: orgId };\n return { scope: \"user\" as const, scopeId: currentOwnerEmail() };\n}\n\nfunction parseVaultAccessMode(value: unknown): VaultAccessMode {\n return value === \"manual\" ? \"manual\" : \"all-apps\";\n}\n\nexport async function getVaultAccessSettings(): Promise<VaultAccessSettings> {\n const scope = vaultAccessScope();\n const raw =\n scope.scope === \"org\"\n ? await getOrgSetting(scope.scopeId, VAULT_ACCESS_SETTINGS_KEY)\n : await getUserSetting(scope.scopeId, VAULT_ACCESS_SETTINGS_KEY);\n return {\n ...scope,\n mode: parseVaultAccessMode(raw?.mode),\n };\n}\n\nexport async function setVaultAccessSettings(input: {\n mode: VaultAccessMode;\n}): Promise<VaultAccessSettings> {\n const scope = vaultAccessScope();\n const next = { mode: parseVaultAccessMode(input.mode) };\n if (scope.scope === \"org\") {\n await putOrgSetting(scope.scopeId, VAULT_ACCESS_SETTINGS_KEY, next);\n } else {\n await putUserSetting(scope.scopeId, VAULT_ACCESS_SETTINGS_KEY, next);\n }\n await recordAudit({\n action: \"vault.access-settings.updated\",\n targetType: \"vault-settings\",\n targetId: VAULT_ACCESS_SETTINGS_KEY,\n summary:\n next.mode === \"all-apps\"\n ? \"Set vault access to all workspace apps\"\n : \"Set vault access to manual per-app grants\",\n metadata: next,\n });\n return getVaultAccessSettings();\n}\n\n// ─── Vault Audit ──────────────────────────────────────────────────\n\nexport async function recordVaultAudit(input: {\n action: string;\n secretId?: string | null;\n appId?: string | null;\n summary: string;\n metadata?: unknown;\n actor?: string;\n}) {\n const db = getDb();\n await db.insert(schema.vaultAuditLog).values({\n id: id(),\n ownerEmail: currentOwnerEmail(),\n orgId: currentOrgId(),\n secretId: input.secretId || null,\n appId: input.appId || null,\n action: input.action,\n actor: input.actor || currentOwnerEmail(),\n summary: input.summary,\n metadata: input.metadata ? safeJson(input.metadata) : null,\n createdAt: now(),\n });\n}\n\nexport async function listVaultAudit(limit = 50) {\n const db = getDb();\n return db\n .select()\n .from(schema.vaultAuditLog)\n .where(scopedFilter(schema.vaultAuditLog))\n .orderBy(desc(schema.vaultAuditLog.createdAt))\n .limit(limit);\n}\n\n// ─── Secrets ──────────────────────────────────────────────────────\n\nexport async function listSecrets() {\n const db = getDb();\n return db\n .select()\n .from(schema.vaultSecrets)\n .where(scopedFilter(schema.vaultSecrets))\n .orderBy(desc(schema.vaultSecrets.updatedAt));\n}\n\nexport async function getSecret(secretId: string, ctx: VaultCtx) {\n const db = getDb();\n const [row] = await db\n .select()\n .from(schema.vaultSecrets)\n .where(\n and(\n eq(schema.vaultSecrets.id, secretId),\n ctxScope(schema.vaultSecrets, ctx),\n ),\n )\n .limit(1);\n return row ?? null;\n}\n\nexport async function createSecret(\n input: {\n credentialKey: string;\n value: string;\n name: string;\n provider?: string | null;\n description?: string | null;\n },\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const timestamp = now();\n const credentialKey = normalizeCredentialKey(input.credentialKey);\n if (!credentialKey) throw new Error(\"Credential key is required\");\n const existing = await db\n .select()\n .from(schema.vaultSecrets)\n .where(\n and(\n eq(schema.vaultSecrets.credentialKey, credentialKey),\n ctxScope(schema.vaultSecrets, ctx),\n ),\n )\n .orderBy(desc(schema.vaultSecrets.updatedAt))\n .limit(1);\n\n if (existing[0]) {\n await db\n .update(schema.vaultSecrets)\n .set({\n name: input.name,\n credentialKey,\n value: input.value,\n provider: input.provider || null,\n description: input.description || null,\n updatedAt: timestamp,\n })\n .where(\n and(\n eq(schema.vaultSecrets.id, existing[0].id),\n ctxScope(schema.vaultSecrets, ctx),\n ),\n );\n\n await recordVaultAudit({\n action: \"secret.updated\",\n secretId: existing[0].id,\n summary: `Updated secret \"${input.name}\" (${credentialKey})`,\n metadata: { credentialKey, provider: input.provider },\n });\n\n await recordAudit({\n action: \"vault.secret.updated\",\n targetType: \"vault-secret\",\n targetId: existing[0].id,\n summary: `Updated vault secret \"${input.name}\" (${credentialKey})`,\n });\n\n const updated = await getSecret(existing[0].id, ctx);\n if (updated) await syncSecretsToCredentialStore([updated], ctx);\n return updated;\n }\n\n const secretId = id();\n const actor = ctx.ownerEmail;\n\n await db.insert(schema.vaultSecrets).values({\n id: secretId,\n ownerEmail: actor,\n orgId: ctx.orgId,\n name: input.name,\n credentialKey,\n value: input.value,\n provider: input.provider || null,\n description: input.description || null,\n createdBy: actor,\n createdAt: timestamp,\n updatedAt: timestamp,\n });\n\n await recordVaultAudit({\n action: \"secret.created\",\n secretId,\n summary: `Created secret \"${input.name}\" (${credentialKey})`,\n metadata: { credentialKey, provider: input.provider },\n });\n\n await recordAudit({\n action: \"vault.secret.created\",\n targetType: \"vault-secret\",\n targetId: secretId,\n summary: `Created vault secret \"${input.name}\" (${credentialKey})`,\n });\n\n const created = await getSecret(secretId, ctx);\n if (created) await syncSecretsToCredentialStore([created], ctx);\n return created;\n}\n\nexport async function updateSecret(\n secretId: string,\n value: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const existing = await getSecret(secretId, ctx);\n if (!existing) throw new Error(\"Secret not found\");\n\n await db\n .update(schema.vaultSecrets)\n .set({ value, updatedAt: now() })\n .where(\n and(\n eq(schema.vaultSecrets.id, secretId),\n ctxScope(schema.vaultSecrets, ctx),\n ),\n );\n\n await recordVaultAudit({\n action: \"secret.updated\",\n secretId,\n summary: `Updated value for secret \"${existing.name}\" (${existing.credentialKey})`,\n });\n\n const updated = await getSecret(secretId, ctx);\n if (updated) await syncSecretsToCredentialStore([updated], ctx);\n return updated;\n}\n\nexport async function deleteSecret(\n secretId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const existing = await getSecret(secretId, ctx);\n if (!existing) throw new Error(\"Secret not found\");\n\n // Revoke all active grants first\n const grants = await listGrants({ secretId });\n for (const grant of grants) {\n if (grant.status === \"active\") {\n await revokeGrant(grant.id, ctx);\n }\n }\n\n await db\n .delete(schema.vaultSecrets)\n .where(\n and(\n eq(schema.vaultSecrets.id, secretId),\n ctxScope(schema.vaultSecrets, ctx),\n ),\n );\n\n await recordVaultAudit({\n action: \"secret.deleted\",\n secretId,\n summary: `Deleted secret \"${existing.name}\" (${existing.credentialKey})`,\n });\n\n await recordAudit({\n action: \"vault.secret.deleted\",\n targetType: \"vault-secret\",\n targetId: secretId,\n summary: `Deleted vault secret \"${existing.name}\" (${existing.credentialKey})`,\n });\n\n return existing;\n}\n\n// ─── Grants ──────────────────────────────────────────────────────\n\nexport async function listGrants(filter?: {\n secretId?: string;\n appId?: string;\n}) {\n const db = getDb();\n const conditions = [scopedFilter(schema.vaultGrants)];\n if (filter?.secretId) {\n conditions.push(eq(schema.vaultGrants.secretId, filter.secretId) as any);\n }\n if (filter?.appId) {\n conditions.push(eq(schema.vaultGrants.appId, filter.appId) as any);\n }\n return db\n .select()\n .from(schema.vaultGrants)\n .where(and(...conditions))\n .orderBy(desc(schema.vaultGrants.updatedAt));\n}\n\nexport async function getGrant(\n grantId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const [row] = await db\n .select()\n .from(schema.vaultGrants)\n .where(\n and(\n eq(schema.vaultGrants.id, grantId),\n ctxScope(schema.vaultGrants, ctx),\n ),\n )\n .limit(1);\n return row ?? null;\n}\n\nexport async function createGrant(\n secretId: string,\n appId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const secret = await getSecret(secretId, ctx);\n if (!secret) throw new Error(\"Secret not found\");\n\n const timestamp = now();\n const grantId = id();\n const actor = ctx.ownerEmail;\n\n await db.insert(schema.vaultGrants).values({\n id: grantId,\n ownerEmail: actor,\n orgId: ctx.orgId,\n secretId,\n appId,\n grantedBy: actor,\n status: \"active\",\n syncedAt: null,\n createdAt: timestamp,\n updatedAt: timestamp,\n });\n\n await recordVaultAudit({\n action: \"grant.created\",\n secretId,\n appId,\n summary: `Granted \"${secret.name}\" (${secret.credentialKey}) to ${appId}`,\n metadata: { grantId },\n });\n\n await recordAudit({\n action: \"vault.grant.created\",\n targetType: \"vault-grant\",\n targetId: grantId,\n summary: `Granted vault secret \"${secret.name}\" to ${appId}`,\n });\n\n return getGrant(grantId);\n}\n\nexport async function grantSecretsToApp(\n secretIds: string[],\n appId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const access = await getVaultAccessSettings();\n const uniqueSecretIds = Array.from(new Set(secretIds));\n if (access.mode === \"all-apps\") {\n return {\n appId,\n accessMode: access.mode,\n created: [],\n skipped: uniqueSecretIds,\n };\n }\n const existingActive = (await listGrants({ appId })).filter(\n (grant) => grant.status === \"active\",\n );\n const existingSecretIds = new Set(\n existingActive.map((grant) => grant.secretId),\n );\n const created = [];\n const skipped: string[] = [];\n\n for (const secretId of uniqueSecretIds) {\n if (existingSecretIds.has(secretId)) {\n skipped.push(secretId);\n continue;\n }\n const grant = await createGrant(secretId, appId, ctx);\n if (grant) {\n created.push(grant);\n existingSecretIds.add(secretId);\n }\n }\n\n return { appId, accessMode: access.mode, created, skipped };\n}\n\nexport async function revokeGrant(\n grantId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const grant = await getGrant(grantId, ctx);\n if (!grant) throw new Error(\"Grant not found\");\n\n const secret = await getSecret(grant.secretId, ctx);\n\n await db\n .update(schema.vaultGrants)\n .set({ status: \"revoked\", updatedAt: now() })\n .where(\n and(\n eq(schema.vaultGrants.id, grantId),\n ctxScope(schema.vaultGrants, ctx),\n ),\n );\n\n await recordVaultAudit({\n action: \"grant.revoked\",\n secretId: grant.secretId,\n appId: grant.appId,\n summary: `Revoked ${secret?.credentialKey || grant.secretId} from ${grant.appId}`,\n metadata: { grantId },\n });\n\n await recordAudit({\n action: \"vault.grant.revoked\",\n targetType: \"vault-grant\",\n targetId: grantId,\n summary: `Revoked vault secret \"${secret?.name || grant.secretId}\" from ${grant.appId}`,\n });\n\n return getGrant(grantId, ctx);\n}\n\n// ─── Shared Credential Store Sync ─────────────────────────────────\n\ntype VaultSecretRow = typeof schema.vaultSecrets.$inferSelect;\n\nexport function credentialStoreScopeForVaultCtx(ctx: VaultCtx): {\n scope: Extract<SecretScope, \"org\" | \"workspace\">;\n scopeId: string;\n} {\n if (ctx.orgId) return { scope: \"org\", scopeId: ctx.orgId };\n return { scope: \"workspace\", scopeId: `solo:${ctx.ownerEmail}` };\n}\n\nexport async function syncSecretsToCredentialStore(\n secrets: VaultSecretRow[],\n ctx: VaultCtx,\n) {\n const target = credentialStoreScopeForVaultCtx(ctx);\n const syncedKeys: string[] = [];\n\n for (const secret of secrets) {\n if (!secret.credentialKey || !secret.value) continue;\n await writeAppSecret({\n key: secret.credentialKey,\n value: secret.value,\n scope: target.scope,\n scopeId: target.scopeId,\n description: `Synced from Dispatch vault: ${secret.name}`,\n });\n syncedKeys.push(secret.credentialKey);\n }\n\n return { ...target, keys: syncedKeys };\n}\n\n// ─── Sync ──────────────────────────────────────────────────────\n\nexport async function syncGrantsToApp(\n appId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const access = await getVaultAccessSettings();\n const agents = await discoverAgents(\"dispatch\");\n const agent = agents.find((a) => a.id === appId);\n if (!agent) throw new Error(`App \"${appId}\" not found in agent registry`);\n\n const secretsToSync: VaultSecretRow[] = [];\n const activeGrants =\n access.mode === \"manual\"\n ? (await listGrants({ appId })).filter((g) => g.status === \"active\")\n : [];\n\n if (access.mode === \"all-apps\") {\n const secrets = await listSecrets();\n for (const secret of secrets) {\n secretsToSync.push(secret);\n }\n } else {\n for (const grant of activeGrants) {\n const secret = await getSecret(grant.secretId, ctx);\n if (secret) {\n secretsToSync.push(secret);\n }\n }\n }\n\n if (secretsToSync.length === 0) {\n return { appId, accessMode: access.mode, synced: 0, keys: [] };\n }\n\n const credentialStoreSync = await syncSecretsToCredentialStore(\n secretsToSync,\n ctx,\n );\n const vars = secretsToSync.map((secret) => ({\n key: secret.credentialKey,\n value: secret.value,\n }));\n let envVarSync:\n | { status: \"synced\"; keys: string[] }\n | { status: \"skipped\"; reason: string }\n | { status: \"failed\"; reason: string };\n\n // Best-effort push to the app's env-vars endpoint for local/dev apps that\n // still read process.env directly. Production/shared-DB apps intentionally\n // reject env writes; the encrypted app_secrets sync above is the canonical\n // path for request-scoped credentials.\n try {\n const res = await fetch(`${agent.url}/_agent-native/env-vars`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ vars }),\n });\n\n if (res.ok) {\n const result = await res.json();\n envVarSync = { status: \"synced\", keys: result.saved || [] };\n } else {\n const err = await res.text().catch(() => \"Unknown error\");\n envVarSync = { status: \"skipped\", reason: err };\n }\n } catch (err) {\n envVarSync = {\n status: \"failed\",\n reason: err instanceof Error ? err.message : String(err),\n };\n }\n\n const syncedKeys = credentialStoreSync.keys;\n const timestamp = now();\n\n // Update syncedAt on grants that were successfully pushed to the shared\n // credential store. All-apps mode has no explicit grant rows to update.\n for (const grant of activeGrants) {\n const secret = await getSecret(grant.secretId, ctx);\n if (secret && syncedKeys.includes(secret.credentialKey)) {\n await db\n .update(schema.vaultGrants)\n .set({ syncedAt: timestamp, updatedAt: timestamp })\n .where(eq(schema.vaultGrants.id, grant.id));\n }\n }\n\n await recordVaultAudit({\n action: \"secret.synced\",\n appId,\n summary: `Synced ${syncedKeys.length} secret(s) to ${appId}: ${syncedKeys.join(\", \")}`,\n metadata: {\n syncedKeys,\n accessMode: access.mode,\n credentialStore: {\n scope: credentialStoreSync.scope,\n scopeId: credentialStoreSync.scopeId,\n },\n envVars: envVarSync,\n },\n });\n\n return {\n appId,\n accessMode: access.mode,\n synced: syncedKeys.length,\n keys: syncedKeys,\n credentialStore: {\n scope: credentialStoreSync.scope,\n scopeId: credentialStoreSync.scopeId,\n synced: credentialStoreSync.keys.length,\n },\n envVars: envVarSync,\n };\n}\n\n// ─── Requests ──────────────────────────────────────────────────────\n\nexport async function listRequests(filter?: { status?: string }) {\n const db = getDb();\n const conditions = [scopedFilter(schema.vaultRequests)];\n if (filter?.status) {\n conditions.push(eq(schema.vaultRequests.status, filter.status) as any);\n }\n return db\n .select()\n .from(schema.vaultRequests)\n .where(and(...conditions))\n .orderBy(desc(schema.vaultRequests.updatedAt));\n}\n\nexport async function getRequest(\n requestId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const [row] = await db\n .select()\n .from(schema.vaultRequests)\n .where(\n and(\n eq(schema.vaultRequests.id, requestId),\n ctxScope(schema.vaultRequests, ctx),\n ),\n )\n .limit(1);\n return row ?? null;\n}\n\nexport async function createRequest(input: {\n credentialKey: string;\n appId: string;\n reason?: string | null;\n}) {\n const db = getDb();\n const timestamp = now();\n const requestId = id();\n const actor = currentOwnerEmail();\n\n await db.insert(schema.vaultRequests).values({\n id: requestId,\n ownerEmail: actor,\n orgId: currentOrgId(),\n credentialKey: input.credentialKey,\n appId: input.appId,\n reason: input.reason || null,\n requestedBy: actor,\n status: \"pending\",\n reviewedBy: null,\n reviewedAt: null,\n createdAt: timestamp,\n updatedAt: timestamp,\n });\n\n await recordVaultAudit({\n action: \"request.created\",\n appId: input.appId,\n summary: `${actor} requested ${input.credentialKey} for ${input.appId}`,\n metadata: { requestId, reason: input.reason },\n });\n\n await notifyAdminsOfRequest(requestId, input);\n\n return getRequest(requestId);\n}\n\nexport async function approveRequest(\n requestId: string,\n secretValue: string,\n secretName?: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const request = await getRequest(requestId, ctx);\n if (!request) throw new Error(\"Request not found\");\n if (request.status !== \"pending\") {\n throw new Error(\"Only pending requests can be approved\");\n }\n\n const timestamp = now();\n const reviewer = ctx.ownerEmail;\n\n // Update request status — scoped to caller's tenant.\n await db\n .update(schema.vaultRequests)\n .set({\n status: \"approved\",\n reviewedBy: reviewer,\n reviewedAt: timestamp,\n updatedAt: timestamp,\n })\n .where(\n and(\n eq(schema.vaultRequests.id, requestId),\n ctxScope(schema.vaultRequests, ctx),\n ),\n );\n\n // Secret + grant must land in the REQUEST's tenant, not the approver's\n // (the approver may be acting on behalf of another user in the same org).\n const requestCtx = ctxForRow(request);\n\n // Check if secret already exists in the request's tenant for this key.\n const existingSecrets = await db\n .select()\n .from(schema.vaultSecrets)\n .where(\n and(\n eq(schema.vaultSecrets.credentialKey, request.credentialKey),\n ctxScope(schema.vaultSecrets, requestCtx),\n ),\n );\n let secret = existingSecrets[0] ?? null;\n\n if (!secret) {\n secret = await createSecret(\n {\n credentialKey: request.credentialKey,\n value: secretValue,\n name: secretName || request.credentialKey,\n },\n requestCtx,\n );\n }\n\n if (secret) {\n // Create the grant in the request's tenant as well.\n await createGrant(secret.id, request.appId, requestCtx);\n }\n\n await recordVaultAudit({\n action: \"request.approved\",\n appId: request.appId,\n summary: `Approved ${request.credentialKey} for ${request.appId} (requested by ${request.requestedBy})`,\n metadata: { requestId, reviewer },\n });\n\n return getRequest(requestId, ctx);\n}\n\nexport async function denyRequest(\n requestId: string,\n reason?: string | null,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const request = await getRequest(requestId, ctx);\n if (!request) throw new Error(\"Request not found\");\n if (request.status !== \"pending\") {\n throw new Error(\"Only pending requests can be denied\");\n }\n\n const timestamp = now();\n const reviewer = ctx.ownerEmail;\n\n await db\n .update(schema.vaultRequests)\n .set({\n status: \"denied\",\n reviewedBy: reviewer,\n reviewedAt: timestamp,\n updatedAt: timestamp,\n })\n .where(\n and(\n eq(schema.vaultRequests.id, requestId),\n ctxScope(schema.vaultRequests, ctx),\n ),\n );\n\n await recordVaultAudit({\n action: \"request.denied\",\n appId: request.appId,\n summary: `Denied ${request.credentialKey} for ${request.appId} (requested by ${request.requestedBy})`,\n metadata: { requestId, reviewer, reason },\n });\n\n return getRequest(requestId, ctx);\n}\n\n// ─── Integrations Catalog ────────────────────────────────────────\n\nexport interface IntegrationEntry {\n key: string;\n label: string;\n required: boolean;\n configured: boolean;\n vaultGranted: boolean;\n vaultSecretId?: string;\n}\n\nexport interface AppIntegrations {\n appId: string;\n appName: string;\n url: string;\n color: string;\n integrations: IntegrationEntry[];\n vaultAccessMode: VaultAccessMode;\n reachable: boolean;\n}\n\nexport async function listIntegrationsCatalog(): Promise<AppIntegrations[]> {\n const access = await getVaultAccessSettings();\n const agents = await discoverAgents(\"dispatch\");\n const grants = await listGrants();\n const secrets = await listSecrets();\n\n const secretByKey = new Map(secrets.map((s) => [s.credentialKey, s]));\n\n const results: AppIntegrations[] = [];\n\n for (const agent of agents) {\n try {\n const res = await fetch(`${agent.url}/_agent-native/env-status`, {\n signal: AbortSignal.timeout(3000),\n });\n if (!res.ok) {\n results.push({\n appId: agent.id,\n appName: agent.name,\n url: agent.url,\n color: agent.color,\n integrations: [],\n vaultAccessMode: access.mode,\n reachable: false,\n });\n continue;\n }\n\n const envStatus: Array<{\n key: string;\n label: string;\n required: boolean;\n configured: boolean;\n }> = await res.json();\n\n const appGrants = grants.filter(\n (g) => g.appId === agent.id && g.status === \"active\",\n );\n const grantedSecretIds = new Set(appGrants.map((g) => g.secretId));\n\n const integrations: IntegrationEntry[] = envStatus.map((env) => {\n const matchingSecret = secretByKey.get(env.key);\n return {\n key: env.key,\n label: env.label,\n required: env.required,\n configured: env.configured,\n vaultGranted:\n !!matchingSecret &&\n (access.mode === \"all-apps\" ||\n grantedSecretIds.has(matchingSecret.id)),\n vaultSecretId: matchingSecret?.id,\n };\n });\n\n results.push({\n appId: agent.id,\n appName: agent.name,\n url: agent.url,\n color: agent.color,\n integrations,\n vaultAccessMode: access.mode,\n reachable: true,\n });\n } catch {\n results.push({\n appId: agent.id,\n appName: agent.name,\n url: agent.url,\n color: agent.color,\n integrations: [],\n vaultAccessMode: access.mode,\n reachable: false,\n });\n }\n }\n\n return results;\n}\n\n// ─── Vault Overview (for dashboard) ──────────────────────────────\n\nexport async function listVaultOverview() {\n const [secrets, grants, requests, access] = await Promise.all([\n listSecrets(),\n listGrants(),\n listRequests(),\n getVaultAccessSettings(),\n ]);\n const manualGrantCount = grants.filter((g) => g.status === \"active\").length;\n\n return {\n accessMode: access.mode,\n secretCount: secrets.length,\n activeGrantCount:\n access.mode === \"all-apps\" ? secrets.length : manualGrantCount,\n manualGrantCount,\n pendingRequestCount: requests.filter((r) => r.status === \"pending\").length,\n };\n}\n\n// ─── SendGrid Notifications ──────────────────────────────────────\n\nasync function notifyAdminsOfRequest(\n requestId: string,\n input: { credentialKey: string; appId: string; reason?: string | null },\n) {\n const apiKey = process.env.SENDGRID_API_KEY;\n const from = process.env.SENDGRID_FROM_EMAIL;\n const appUrl = process.env.APP_URL;\n if (!apiKey || !from || !appUrl) return;\n\n // Use approval policy approver emails as admin notification targets\n const { getApprovalPolicy } = await import(\"./dispatch-store.js\");\n const policy = await getApprovalPolicy();\n if (policy.approverEmails.length === 0) return;\n\n const body = [\n `Secret request: ${input.credentialKey} for ${input.appId}`,\n input.reason ? `Reason: ${input.reason}` : \"\",\n `Requested by: ${currentOwnerEmail()}`,\n \"\",\n `Review it here: ${appUrl}/vault`,\n ]\n .filter(Boolean)\n .join(\"\\n\");\n\n await fetch(\"https://api.sendgrid.com/v3/mail/send\", {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n personalizations: [\n {\n to: policy.approverEmails.map((email) => ({ email })),\n subject: `Vault request: ${input.credentialKey} for ${input.appId}`,\n },\n ],\n from: { email: from },\n content: [{ type: \"text/plain\", value: body }],\n custom_args: { requestId },\n }),\n }).catch(() => {});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"vault-store.js","sourceRoot":"","sources":["../../../src/server/lib/vault-store.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto from \"node:crypto\";\nimport { and, desc, eq, isNull, or } from \"drizzle-orm\";\nimport { discoverAgents } from \"@agent-native/core/server/agent-discovery\";\nimport {\n deleteAppSecret,\n writeAppSecret,\n type SecretScope,\n} from \"@agent-native/core/secrets\";\nimport {\n getOrgSetting,\n getUserSetting,\n putOrgSetting,\n putUserSetting,\n} from \"@agent-native/core/settings\";\nimport { getDb, schema } from \"../../db/index.js\";\nimport {\n currentOwnerEmail,\n currentOrgId,\n recordAudit,\n} from \"./dispatch-store.js\";\n\nconst VAULT_ACCESS_SETTINGS_KEY = \"dispatch-vault-access-settings\";\n\nexport type VaultAccessMode = \"all-apps\" | \"manual\";\n\nexport interface VaultAccessSettings {\n mode: VaultAccessMode;\n scope: \"org\" | \"user\";\n scopeId: string;\n}\n\n/**\n * Caller-supplied access context for vault operations.\n *\n * Every getSecret / updateSecret / deleteSecret / createGrant call must\n * pass the ctx of the *current request* so the row is scoped to that\n * caller's tenant. Looking up a vault secret by id alone is unsafe — UUIDs\n * are not authorization. A row matches the ctx if either the caller owns\n * it or it lives in the caller's active org.\n */\nexport interface VaultCtx {\n ownerEmail: string;\n orgId: string | null;\n}\n\n/**\n * Build a VaultCtx from the current request. Throws if the request is\n * unauthenticated — the previous behavior of falling back to \"local@localhost\"\n * leaked rows across tenants when a misconfigured environment skipped auth.\n */\nexport function requireVaultCtx(): VaultCtx {\n const ownerEmail = currentOwnerEmail();\n if (!ownerEmail) {\n throw new Error(\"Vault operation requires an authenticated user\");\n }\n return { ownerEmail, orgId: currentOrgId() };\n}\n\n/** WHERE clause that limits a vault row to the caller's ownership scope. */\nfunction ctxScope<T extends { ownerEmail: any; orgId: any }>(\n table: T,\n ctx: VaultCtx,\n) {\n if (!ctx.orgId) {\n return and(eq(table.ownerEmail, ctx.ownerEmail), isNull(table.orgId));\n }\n return or(eq(table.ownerEmail, ctx.ownerEmail), eq(table.orgId, ctx.orgId));\n}\n\n/** Build a ctx that scopes to a specific row's owner/org (used when a\n * request approver acts on behalf of the original requester so the\n * created secret lands in the request's org). */\nfunction ctxForRow(row: {\n ownerEmail: string;\n orgId: string | null;\n}): VaultCtx {\n return { ownerEmail: row.ownerEmail, orgId: row.orgId };\n}\n\nfunction id() {\n return crypto.randomUUID();\n}\n\nfunction now() {\n return Date.now();\n}\n\nfunction safeJson(value: unknown) {\n return JSON.stringify(value ?? null);\n}\n\nfunction scopedFilter<T extends { ownerEmail: any; orgId: any }>(table: T) {\n return ctxScope(table, requireVaultCtx());\n}\n\nfunction normalizeCredentialKey(value: string) {\n return value.trim();\n}\n\nfunction vaultAccessScope() {\n const orgId = currentOrgId();\n if (orgId) return { scope: \"org\" as const, scopeId: orgId };\n return { scope: \"user\" as const, scopeId: currentOwnerEmail() };\n}\n\nfunction parseVaultAccessMode(value: unknown): VaultAccessMode {\n return value === \"manual\" ? \"manual\" : \"all-apps\";\n}\n\nexport async function getVaultAccessSettings(): Promise<VaultAccessSettings> {\n const scope = vaultAccessScope();\n const raw =\n scope.scope === \"org\"\n ? await getOrgSetting(scope.scopeId, VAULT_ACCESS_SETTINGS_KEY)\n : await getUserSetting(scope.scopeId, VAULT_ACCESS_SETTINGS_KEY);\n return {\n ...scope,\n mode: parseVaultAccessMode(raw?.mode),\n };\n}\n\nexport async function setVaultAccessSettings(input: {\n mode: VaultAccessMode;\n}): Promise<VaultAccessSettings> {\n const scope = vaultAccessScope();\n const next = { mode: parseVaultAccessMode(input.mode) };\n if (scope.scope === \"org\") {\n await putOrgSetting(scope.scopeId, VAULT_ACCESS_SETTINGS_KEY, next);\n } else {\n await putUserSetting(scope.scopeId, VAULT_ACCESS_SETTINGS_KEY, next);\n }\n await recordAudit({\n action: \"vault.access-settings.updated\",\n targetType: \"vault-settings\",\n targetId: VAULT_ACCESS_SETTINGS_KEY,\n summary:\n next.mode === \"all-apps\"\n ? \"Set vault access to all workspace apps\"\n : \"Set vault access to manual per-app grants\",\n metadata: next,\n });\n return getVaultAccessSettings();\n}\n\n// ─── Vault Audit ──────────────────────────────────────────────────\n\nexport async function recordVaultAudit(input: {\n action: string;\n secretId?: string | null;\n appId?: string | null;\n summary: string;\n metadata?: unknown;\n actor?: string;\n}) {\n const db = getDb();\n await db.insert(schema.vaultAuditLog).values({\n id: id(),\n ownerEmail: currentOwnerEmail(),\n orgId: currentOrgId(),\n secretId: input.secretId || null,\n appId: input.appId || null,\n action: input.action,\n actor: input.actor || currentOwnerEmail(),\n summary: input.summary,\n metadata: input.metadata ? safeJson(input.metadata) : null,\n createdAt: now(),\n });\n}\n\nexport async function listVaultAudit(limit = 50) {\n const db = getDb();\n return db\n .select()\n .from(schema.vaultAuditLog)\n .where(scopedFilter(schema.vaultAuditLog))\n .orderBy(desc(schema.vaultAuditLog.createdAt))\n .limit(limit);\n}\n\n// ─── Secrets ──────────────────────────────────────────────────────\n\nexport async function listSecrets() {\n const db = getDb();\n return db\n .select()\n .from(schema.vaultSecrets)\n .where(scopedFilter(schema.vaultSecrets))\n .orderBy(desc(schema.vaultSecrets.updatedAt));\n}\n\nexport async function getSecret(secretId: string, ctx: VaultCtx) {\n const db = getDb();\n const [row] = await db\n .select()\n .from(schema.vaultSecrets)\n .where(\n and(\n eq(schema.vaultSecrets.id, secretId),\n ctxScope(schema.vaultSecrets, ctx),\n ),\n )\n .limit(1);\n return row ?? null;\n}\n\nexport async function createSecret(\n input: {\n credentialKey: string;\n value: string;\n name: string;\n provider?: string | null;\n description?: string | null;\n },\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const timestamp = now();\n const credentialKey = normalizeCredentialKey(input.credentialKey);\n if (!credentialKey) throw new Error(\"Credential key is required\");\n const existing = await db\n .select()\n .from(schema.vaultSecrets)\n .where(\n and(\n eq(schema.vaultSecrets.credentialKey, credentialKey),\n ctxScope(schema.vaultSecrets, ctx),\n ),\n )\n .orderBy(desc(schema.vaultSecrets.updatedAt))\n .limit(1);\n\n if (existing[0]) {\n await db\n .update(schema.vaultSecrets)\n .set({\n name: input.name,\n credentialKey,\n value: input.value,\n provider: input.provider || null,\n description: input.description || null,\n updatedAt: timestamp,\n })\n .where(\n and(\n eq(schema.vaultSecrets.id, existing[0].id),\n ctxScope(schema.vaultSecrets, ctx),\n ),\n );\n\n await recordVaultAudit({\n action: \"secret.updated\",\n secretId: existing[0].id,\n summary: `Updated secret \"${input.name}\" (${credentialKey})`,\n metadata: { credentialKey, provider: input.provider },\n });\n\n await recordAudit({\n action: \"vault.secret.updated\",\n targetType: \"vault-secret\",\n targetId: existing[0].id,\n summary: `Updated vault secret \"${input.name}\" (${credentialKey})`,\n });\n\n const updated = await getSecret(existing[0].id, ctx);\n if (updated) await syncSecretsToCredentialStore([updated], ctx);\n return updated;\n }\n\n const secretId = id();\n const actor = ctx.ownerEmail;\n\n await db.insert(schema.vaultSecrets).values({\n id: secretId,\n ownerEmail: actor,\n orgId: ctx.orgId,\n name: input.name,\n credentialKey,\n value: input.value,\n provider: input.provider || null,\n description: input.description || null,\n createdBy: actor,\n createdAt: timestamp,\n updatedAt: timestamp,\n });\n\n await recordVaultAudit({\n action: \"secret.created\",\n secretId,\n summary: `Created secret \"${input.name}\" (${credentialKey})`,\n metadata: { credentialKey, provider: input.provider },\n });\n\n await recordAudit({\n action: \"vault.secret.created\",\n targetType: \"vault-secret\",\n targetId: secretId,\n summary: `Created vault secret \"${input.name}\" (${credentialKey})`,\n });\n\n const created = await getSecret(secretId, ctx);\n if (created) await syncSecretsToCredentialStore([created], ctx);\n return created;\n}\n\nexport async function updateSecret(\n secretId: string,\n input:\n | string\n | {\n credentialKey?: string;\n value?: string;\n name?: string;\n provider?: string | null;\n description?: string | null;\n },\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const existing = await getSecret(secretId, ctx);\n if (!existing) throw new Error(\"Secret not found\");\n const patch = typeof input === \"string\" ? { value: input } : input;\n const credentialKey =\n patch.credentialKey !== undefined\n ? normalizeCredentialKey(patch.credentialKey)\n : existing.credentialKey;\n if (!credentialKey) throw new Error(\"Credential key is required\");\n const name = patch.name !== undefined ? patch.name.trim() : existing.name;\n if (!name) throw new Error(\"Secret name is required\");\n const value = patch.value !== undefined ? patch.value : existing.value;\n if (!value) throw new Error(\"Secret value is required\");\n const provider =\n patch.provider !== undefined ? patch.provider || null : existing.provider;\n const description =\n patch.description !== undefined\n ? patch.description || null\n : existing.description;\n\n if (credentialKey !== existing.credentialKey) {\n const conflict = await db\n .select({ id: schema.vaultSecrets.id })\n .from(schema.vaultSecrets)\n .where(\n and(\n eq(schema.vaultSecrets.credentialKey, credentialKey),\n ctxScope(schema.vaultSecrets, ctx),\n ),\n )\n .limit(1);\n if (conflict[0] && conflict[0].id !== secretId) {\n throw new Error(`Credential key \"${credentialKey}\" is already in use`);\n }\n }\n\n await db\n .update(schema.vaultSecrets)\n .set({\n name,\n credentialKey,\n value,\n provider,\n description,\n updatedAt: now(),\n })\n .where(\n and(\n eq(schema.vaultSecrets.id, secretId),\n ctxScope(schema.vaultSecrets, ctx),\n ),\n );\n\n const auditMetadata = {\n name,\n previousName: name !== existing.name ? existing.name : undefined,\n credentialKey,\n previousCredentialKey:\n credentialKey !== existing.credentialKey\n ? existing.credentialKey\n : undefined,\n provider,\n previousProvider:\n provider !== existing.provider ? existing.provider : undefined,\n description,\n previousDescription:\n description !== existing.description ? existing.description : undefined,\n valueChanged: value !== existing.value ? true : undefined,\n };\n\n await recordVaultAudit({\n action: \"secret.updated\",\n secretId,\n summary: `Updated secret \"${name}\" (${credentialKey})`,\n metadata: auditMetadata,\n });\n\n await recordAudit({\n action: \"vault.secret.updated\",\n targetType: \"vault-secret\",\n targetId: secretId,\n summary: `Updated vault secret \"${name}\" (${credentialKey})`,\n metadata: auditMetadata,\n });\n\n const updated = await getSecret(secretId, ctx);\n if (updated) await syncSecretsToCredentialStore([updated], ctx);\n if (updated && credentialKey !== existing.credentialKey) {\n const stillUsesOldKey = await db\n .select({ id: schema.vaultSecrets.id })\n .from(schema.vaultSecrets)\n .where(\n and(\n eq(schema.vaultSecrets.credentialKey, existing.credentialKey),\n ctxScope(schema.vaultSecrets, ctx),\n ),\n )\n .limit(1);\n if (!stillUsesOldKey[0]) {\n const target = credentialStoreScopeForVaultCtx(ctx);\n await deleteAppSecret({\n key: existing.credentialKey,\n scope: target.scope,\n scopeId: target.scopeId,\n });\n }\n }\n return updated;\n}\n\nexport async function deleteSecret(\n secretId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const existing = await getSecret(secretId, ctx);\n if (!existing) throw new Error(\"Secret not found\");\n\n // Revoke all active grants first\n const grants = await listGrants({ secretId });\n for (const grant of grants) {\n if (grant.status === \"active\") {\n await revokeGrant(grant.id, ctx);\n }\n }\n\n await db\n .delete(schema.vaultSecrets)\n .where(\n and(\n eq(schema.vaultSecrets.id, secretId),\n ctxScope(schema.vaultSecrets, ctx),\n ),\n );\n\n await recordVaultAudit({\n action: \"secret.deleted\",\n secretId,\n summary: `Deleted secret \"${existing.name}\" (${existing.credentialKey})`,\n });\n\n await recordAudit({\n action: \"vault.secret.deleted\",\n targetType: \"vault-secret\",\n targetId: secretId,\n summary: `Deleted vault secret \"${existing.name}\" (${existing.credentialKey})`,\n });\n\n return existing;\n}\n\n// ─── Grants ──────────────────────────────────────────────────────\n\nexport async function listGrants(filter?: {\n secretId?: string;\n appId?: string;\n}) {\n const db = getDb();\n const conditions = [scopedFilter(schema.vaultGrants)];\n if (filter?.secretId) {\n conditions.push(eq(schema.vaultGrants.secretId, filter.secretId) as any);\n }\n if (filter?.appId) {\n conditions.push(eq(schema.vaultGrants.appId, filter.appId) as any);\n }\n return db\n .select()\n .from(schema.vaultGrants)\n .where(and(...conditions))\n .orderBy(desc(schema.vaultGrants.updatedAt));\n}\n\nexport async function getGrant(\n grantId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const [row] = await db\n .select()\n .from(schema.vaultGrants)\n .where(\n and(\n eq(schema.vaultGrants.id, grantId),\n ctxScope(schema.vaultGrants, ctx),\n ),\n )\n .limit(1);\n return row ?? null;\n}\n\nexport async function createGrant(\n secretId: string,\n appId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const secret = await getSecret(secretId, ctx);\n if (!secret) throw new Error(\"Secret not found\");\n\n const timestamp = now();\n const grantId = id();\n const actor = ctx.ownerEmail;\n\n await db.insert(schema.vaultGrants).values({\n id: grantId,\n ownerEmail: actor,\n orgId: ctx.orgId,\n secretId,\n appId,\n grantedBy: actor,\n status: \"active\",\n syncedAt: null,\n createdAt: timestamp,\n updatedAt: timestamp,\n });\n\n await recordVaultAudit({\n action: \"grant.created\",\n secretId,\n appId,\n summary: `Granted \"${secret.name}\" (${secret.credentialKey}) to ${appId}`,\n metadata: { grantId },\n });\n\n await recordAudit({\n action: \"vault.grant.created\",\n targetType: \"vault-grant\",\n targetId: grantId,\n summary: `Granted vault secret \"${secret.name}\" to ${appId}`,\n });\n\n return getGrant(grantId);\n}\n\nexport async function grantSecretsToApp(\n secretIds: string[],\n appId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const access = await getVaultAccessSettings();\n const uniqueSecretIds = Array.from(new Set(secretIds));\n if (access.mode === \"all-apps\") {\n return {\n appId,\n accessMode: access.mode,\n created: [],\n skipped: uniqueSecretIds,\n };\n }\n const existingActive = (await listGrants({ appId })).filter(\n (grant) => grant.status === \"active\",\n );\n const existingSecretIds = new Set(\n existingActive.map((grant) => grant.secretId),\n );\n const created = [];\n const skipped: string[] = [];\n\n for (const secretId of uniqueSecretIds) {\n if (existingSecretIds.has(secretId)) {\n skipped.push(secretId);\n continue;\n }\n const grant = await createGrant(secretId, appId, ctx);\n if (grant) {\n created.push(grant);\n existingSecretIds.add(secretId);\n }\n }\n\n return { appId, accessMode: access.mode, created, skipped };\n}\n\nexport async function revokeGrant(\n grantId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const grant = await getGrant(grantId, ctx);\n if (!grant) throw new Error(\"Grant not found\");\n\n const secret = await getSecret(grant.secretId, ctx);\n\n await db\n .update(schema.vaultGrants)\n .set({ status: \"revoked\", updatedAt: now() })\n .where(\n and(\n eq(schema.vaultGrants.id, grantId),\n ctxScope(schema.vaultGrants, ctx),\n ),\n );\n\n await recordVaultAudit({\n action: \"grant.revoked\",\n secretId: grant.secretId,\n appId: grant.appId,\n summary: `Revoked ${secret?.credentialKey || grant.secretId} from ${grant.appId}`,\n metadata: { grantId },\n });\n\n await recordAudit({\n action: \"vault.grant.revoked\",\n targetType: \"vault-grant\",\n targetId: grantId,\n summary: `Revoked vault secret \"${secret?.name || grant.secretId}\" from ${grant.appId}`,\n });\n\n return getGrant(grantId, ctx);\n}\n\n// ─── Shared Credential Store Sync ─────────────────────────────────\n\ntype VaultSecretRow = typeof schema.vaultSecrets.$inferSelect;\n\nexport function credentialStoreScopeForVaultCtx(ctx: VaultCtx): {\n scope: Extract<SecretScope, \"org\" | \"workspace\">;\n scopeId: string;\n} {\n if (ctx.orgId) return { scope: \"org\", scopeId: ctx.orgId };\n return { scope: \"workspace\", scopeId: `solo:${ctx.ownerEmail}` };\n}\n\nexport async function syncSecretsToCredentialStore(\n secrets: VaultSecretRow[],\n ctx: VaultCtx,\n) {\n const target = credentialStoreScopeForVaultCtx(ctx);\n const syncedKeys: string[] = [];\n\n for (const secret of secrets) {\n if (!secret.credentialKey || !secret.value) continue;\n await writeAppSecret({\n key: secret.credentialKey,\n value: secret.value,\n scope: target.scope,\n scopeId: target.scopeId,\n description: `Synced from Dispatch vault: ${secret.name}`,\n });\n syncedKeys.push(secret.credentialKey);\n }\n\n return { ...target, keys: syncedKeys };\n}\n\n// ─── Sync ──────────────────────────────────────────────────────\n\nexport async function syncGrantsToApp(\n appId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const access = await getVaultAccessSettings();\n const agents = await discoverAgents(\"dispatch\");\n const agent = agents.find((a) => a.id === appId);\n if (!agent) throw new Error(`App \"${appId}\" not found in agent registry`);\n\n const secretsToSync: VaultSecretRow[] = [];\n const activeGrants =\n access.mode === \"manual\"\n ? (await listGrants({ appId })).filter((g) => g.status === \"active\")\n : [];\n\n if (access.mode === \"all-apps\") {\n const secrets = await listSecrets();\n for (const secret of secrets) {\n secretsToSync.push(secret);\n }\n } else {\n for (const grant of activeGrants) {\n const secret = await getSecret(grant.secretId, ctx);\n if (secret) {\n secretsToSync.push(secret);\n }\n }\n }\n\n if (secretsToSync.length === 0) {\n return { appId, accessMode: access.mode, synced: 0, keys: [] };\n }\n\n const credentialStoreSync = await syncSecretsToCredentialStore(\n secretsToSync,\n ctx,\n );\n const vars = secretsToSync.map((secret) => ({\n key: secret.credentialKey,\n value: secret.value,\n }));\n let envVarSync:\n | { status: \"synced\"; keys: string[] }\n | { status: \"skipped\"; reason: string }\n | { status: \"failed\"; reason: string };\n\n // Best-effort push to the app's env-vars endpoint for local/dev apps that\n // still read process.env directly. Production/shared-DB apps intentionally\n // reject env writes; the encrypted app_secrets sync above is the canonical\n // path for request-scoped credentials.\n try {\n const res = await fetch(`${agent.url}/_agent-native/env-vars`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ vars }),\n });\n\n if (res.ok) {\n const result = await res.json();\n envVarSync = { status: \"synced\", keys: result.saved || [] };\n } else {\n const err = await res.text().catch(() => \"Unknown error\");\n envVarSync = { status: \"skipped\", reason: err };\n }\n } catch (err) {\n envVarSync = {\n status: \"failed\",\n reason: err instanceof Error ? err.message : String(err),\n };\n }\n\n const syncedKeys = credentialStoreSync.keys;\n const timestamp = now();\n\n // Update syncedAt on grants that were successfully pushed to the shared\n // credential store. All-apps mode has no explicit grant rows to update.\n for (const grant of activeGrants) {\n const secret = await getSecret(grant.secretId, ctx);\n if (secret && syncedKeys.includes(secret.credentialKey)) {\n await db\n .update(schema.vaultGrants)\n .set({ syncedAt: timestamp, updatedAt: timestamp })\n .where(eq(schema.vaultGrants.id, grant.id));\n }\n }\n\n await recordVaultAudit({\n action: \"secret.synced\",\n appId,\n summary: `Synced ${syncedKeys.length} secret(s) to ${appId}: ${syncedKeys.join(\", \")}`,\n metadata: {\n syncedKeys,\n accessMode: access.mode,\n credentialStore: {\n scope: credentialStoreSync.scope,\n scopeId: credentialStoreSync.scopeId,\n },\n envVars: envVarSync,\n },\n });\n\n return {\n appId,\n accessMode: access.mode,\n synced: syncedKeys.length,\n keys: syncedKeys,\n credentialStore: {\n scope: credentialStoreSync.scope,\n scopeId: credentialStoreSync.scopeId,\n synced: credentialStoreSync.keys.length,\n },\n envVars: envVarSync,\n };\n}\n\n// ─── Requests ──────────────────────────────────────────────────────\n\nexport async function listRequests(filter?: { status?: string }) {\n const db = getDb();\n const conditions = [scopedFilter(schema.vaultRequests)];\n if (filter?.status) {\n conditions.push(eq(schema.vaultRequests.status, filter.status) as any);\n }\n return db\n .select()\n .from(schema.vaultRequests)\n .where(and(...conditions))\n .orderBy(desc(schema.vaultRequests.updatedAt));\n}\n\nexport async function getRequest(\n requestId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const [row] = await db\n .select()\n .from(schema.vaultRequests)\n .where(\n and(\n eq(schema.vaultRequests.id, requestId),\n ctxScope(schema.vaultRequests, ctx),\n ),\n )\n .limit(1);\n return row ?? null;\n}\n\nexport async function createRequest(input: {\n credentialKey: string;\n appId: string;\n reason?: string | null;\n}) {\n const db = getDb();\n const timestamp = now();\n const requestId = id();\n const actor = currentOwnerEmail();\n\n await db.insert(schema.vaultRequests).values({\n id: requestId,\n ownerEmail: actor,\n orgId: currentOrgId(),\n credentialKey: input.credentialKey,\n appId: input.appId,\n reason: input.reason || null,\n requestedBy: actor,\n status: \"pending\",\n reviewedBy: null,\n reviewedAt: null,\n createdAt: timestamp,\n updatedAt: timestamp,\n });\n\n await recordVaultAudit({\n action: \"request.created\",\n appId: input.appId,\n summary: `${actor} requested ${input.credentialKey} for ${input.appId}`,\n metadata: { requestId, reason: input.reason },\n });\n\n await notifyAdminsOfRequest(requestId, input);\n\n return getRequest(requestId);\n}\n\nexport async function approveRequest(\n requestId: string,\n secretValue: string,\n secretName?: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const request = await getRequest(requestId, ctx);\n if (!request) throw new Error(\"Request not found\");\n if (request.status !== \"pending\") {\n throw new Error(\"Only pending requests can be approved\");\n }\n\n const timestamp = now();\n const reviewer = ctx.ownerEmail;\n\n // Update request status — scoped to caller's tenant.\n await db\n .update(schema.vaultRequests)\n .set({\n status: \"approved\",\n reviewedBy: reviewer,\n reviewedAt: timestamp,\n updatedAt: timestamp,\n })\n .where(\n and(\n eq(schema.vaultRequests.id, requestId),\n ctxScope(schema.vaultRequests, ctx),\n ),\n );\n\n // Secret + grant must land in the REQUEST's tenant, not the approver's\n // (the approver may be acting on behalf of another user in the same org).\n const requestCtx = ctxForRow(request);\n\n // Check if secret already exists in the request's tenant for this key.\n const existingSecrets = await db\n .select()\n .from(schema.vaultSecrets)\n .where(\n and(\n eq(schema.vaultSecrets.credentialKey, request.credentialKey),\n ctxScope(schema.vaultSecrets, requestCtx),\n ),\n );\n let secret = existingSecrets[0] ?? null;\n\n if (!secret) {\n secret = await createSecret(\n {\n credentialKey: request.credentialKey,\n value: secretValue,\n name: secretName || request.credentialKey,\n },\n requestCtx,\n );\n }\n\n if (secret) {\n // Create the grant in the request's tenant as well.\n await createGrant(secret.id, request.appId, requestCtx);\n }\n\n await recordVaultAudit({\n action: \"request.approved\",\n appId: request.appId,\n summary: `Approved ${request.credentialKey} for ${request.appId} (requested by ${request.requestedBy})`,\n metadata: { requestId, reviewer },\n });\n\n return getRequest(requestId, ctx);\n}\n\nexport async function denyRequest(\n requestId: string,\n reason?: string | null,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const request = await getRequest(requestId, ctx);\n if (!request) throw new Error(\"Request not found\");\n if (request.status !== \"pending\") {\n throw new Error(\"Only pending requests can be denied\");\n }\n\n const timestamp = now();\n const reviewer = ctx.ownerEmail;\n\n await db\n .update(schema.vaultRequests)\n .set({\n status: \"denied\",\n reviewedBy: reviewer,\n reviewedAt: timestamp,\n updatedAt: timestamp,\n })\n .where(\n and(\n eq(schema.vaultRequests.id, requestId),\n ctxScope(schema.vaultRequests, ctx),\n ),\n );\n\n await recordVaultAudit({\n action: \"request.denied\",\n appId: request.appId,\n summary: `Denied ${request.credentialKey} for ${request.appId} (requested by ${request.requestedBy})`,\n metadata: { requestId, reviewer, reason },\n });\n\n return getRequest(requestId, ctx);\n}\n\n// ─── Integrations Catalog ────────────────────────────────────────\n\nexport interface IntegrationEntry {\n key: string;\n label: string;\n required: boolean;\n configured: boolean;\n vaultGranted: boolean;\n vaultSecretId?: string;\n}\n\nexport interface AppIntegrations {\n appId: string;\n appName: string;\n url: string;\n color: string;\n integrations: IntegrationEntry[];\n vaultAccessMode: VaultAccessMode;\n reachable: boolean;\n}\n\nexport async function listIntegrationsCatalog(): Promise<AppIntegrations[]> {\n const access = await getVaultAccessSettings();\n const agents = await discoverAgents(\"dispatch\");\n const grants = await listGrants();\n const secrets = await listSecrets();\n\n const secretByKey = new Map(secrets.map((s) => [s.credentialKey, s]));\n\n const results: AppIntegrations[] = [];\n\n for (const agent of agents) {\n try {\n const res = await fetch(`${agent.url}/_agent-native/env-status`, {\n signal: AbortSignal.timeout(3000),\n });\n if (!res.ok) {\n results.push({\n appId: agent.id,\n appName: agent.name,\n url: agent.url,\n color: agent.color,\n integrations: [],\n vaultAccessMode: access.mode,\n reachable: false,\n });\n continue;\n }\n\n const envStatus: Array<{\n key: string;\n label: string;\n required: boolean;\n configured: boolean;\n }> = await res.json();\n\n const appGrants = grants.filter(\n (g) => g.appId === agent.id && g.status === \"active\",\n );\n const grantedSecretIds = new Set(appGrants.map((g) => g.secretId));\n\n const integrations: IntegrationEntry[] = envStatus.map((env) => {\n const matchingSecret = secretByKey.get(env.key);\n return {\n key: env.key,\n label: env.label,\n required: env.required,\n configured: env.configured,\n vaultGranted:\n !!matchingSecret &&\n (access.mode === \"all-apps\" ||\n grantedSecretIds.has(matchingSecret.id)),\n vaultSecretId: matchingSecret?.id,\n };\n });\n\n results.push({\n appId: agent.id,\n appName: agent.name,\n url: agent.url,\n color: agent.color,\n integrations,\n vaultAccessMode: access.mode,\n reachable: true,\n });\n } catch {\n results.push({\n appId: agent.id,\n appName: agent.name,\n url: agent.url,\n color: agent.color,\n integrations: [],\n vaultAccessMode: access.mode,\n reachable: false,\n });\n }\n }\n\n return results;\n}\n\n// ─── Vault Overview (for dashboard) ──────────────────────────────\n\nexport async function listVaultOverview() {\n const [secrets, grants, requests, access] = await Promise.all([\n listSecrets(),\n listGrants(),\n listRequests(),\n getVaultAccessSettings(),\n ]);\n const manualGrantCount = grants.filter((g) => g.status === \"active\").length;\n\n return {\n accessMode: access.mode,\n secretCount: secrets.length,\n activeGrantCount:\n access.mode === \"all-apps\" ? secrets.length : manualGrantCount,\n manualGrantCount,\n pendingRequestCount: requests.filter((r) => r.status === \"pending\").length,\n };\n}\n\n// ─── SendGrid Notifications ──────────────────────────────────────\n\nasync function notifyAdminsOfRequest(\n requestId: string,\n input: { credentialKey: string; appId: string; reason?: string | null },\n) {\n const apiKey = process.env.SENDGRID_API_KEY;\n const from = process.env.SENDGRID_FROM_EMAIL;\n const appUrl = process.env.APP_URL;\n if (!apiKey || !from || !appUrl) return;\n\n // Use approval policy approver emails as admin notification targets\n const { getApprovalPolicy } = await import(\"./dispatch-store.js\");\n const policy = await getApprovalPolicy();\n if (policy.approverEmails.length === 0) return;\n\n const body = [\n `Secret request: ${input.credentialKey} for ${input.appId}`,\n input.reason ? `Reason: ${input.reason}` : \"\",\n `Requested by: ${currentOwnerEmail()}`,\n \"\",\n `Review it here: ${appUrl}/vault`,\n ]\n .filter(Boolean)\n .join(\"\\n\");\n\n await fetch(\"https://api.sendgrid.com/v3/mail/send\", {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n personalizations: [\n {\n to: policy.approverEmails.map((email) => ({ email })),\n subject: `Vault request: ${input.credentialKey} for ${input.appId}`,\n },\n ],\n from: { email: from },\n content: [{ type: \"text/plain\", value: body }],\n custom_args: { requestId },\n }),\n }).catch(() => {});\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/dispatch",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Dispatch — workspace control plane for agent-native apps. Vault, integrations, destinations, scheduled jobs, and cross-app delegation, shipped as a single drop-in package.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -3,10 +3,43 @@ import { z } from "zod";
|
|
|
3
3
|
import { updateSecret } from "../server/lib/vault-store.js";
|
|
4
4
|
|
|
5
5
|
export default defineAction({
|
|
6
|
-
description:
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
description:
|
|
7
|
+
"Update an existing vault secret's label, credential key, value, provider, or description. Admin only.",
|
|
8
|
+
schema: z
|
|
9
|
+
.object({
|
|
10
|
+
id: z.string().min(1).describe("Secret ID"),
|
|
11
|
+
credentialKey: z
|
|
12
|
+
.string()
|
|
13
|
+
.trim()
|
|
14
|
+
.min(1)
|
|
15
|
+
.optional()
|
|
16
|
+
.describe("Environment variable name, e.g. GOOGLE_CLIENT_ID"),
|
|
17
|
+
value: z.string().min(1).optional().describe("New secret value"),
|
|
18
|
+
name: z
|
|
19
|
+
.string()
|
|
20
|
+
.trim()
|
|
21
|
+
.min(1)
|
|
22
|
+
.optional()
|
|
23
|
+
.describe("Human-readable label for this secret"),
|
|
24
|
+
provider: z
|
|
25
|
+
.string()
|
|
26
|
+
.nullable()
|
|
27
|
+
.optional()
|
|
28
|
+
.describe("Provider grouping tag, e.g. google, sendgrid, slack"),
|
|
29
|
+
description: z
|
|
30
|
+
.string()
|
|
31
|
+
.nullable()
|
|
32
|
+
.optional()
|
|
33
|
+
.describe("Optional description"),
|
|
34
|
+
})
|
|
35
|
+
.refine(
|
|
36
|
+
({ credentialKey, value, name, provider, description }) =>
|
|
37
|
+
credentialKey !== undefined ||
|
|
38
|
+
value !== undefined ||
|
|
39
|
+
name !== undefined ||
|
|
40
|
+
provider !== undefined ||
|
|
41
|
+
description !== undefined,
|
|
42
|
+
"At least one secret field must be updated",
|
|
43
|
+
),
|
|
44
|
+
run: async (args) => updateSecret(args.id, args),
|
|
12
45
|
});
|
package/src/routes/index.ts
CHANGED
|
@@ -51,6 +51,7 @@ export const dispatchRoutes: RouteConfig = [
|
|
|
51
51
|
route("team", "./pages/team.js"),
|
|
52
52
|
route("extensions", "./pages/extensions._index.js"),
|
|
53
53
|
route("extensions/:id", "./pages/extensions.$id.js"),
|
|
54
|
+
route("extensions/:id/:slug", "./pages/extensions.$id.js"),
|
|
54
55
|
// Catch-all for /:appId — bounces /dispatch/<appId> to /<appId> when the
|
|
55
56
|
// segment names a workspace app sibling (e.g. Builder.io routing a "go to
|
|
56
57
|
// /todo" call through Dispatch's mount). Declared last so React Router 7's
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ExtensionViewerPage } from "@agent-native/core/client/extensions";
|
|
2
|
+
|
|
3
|
+
export function meta() {
|
|
4
|
+
return [{ title: "Extension \u2014 Dispatch" }];
|
|
5
|
+
}
|
|
2
6
|
|
|
3
7
|
export default function ExtensionViewerRoute() {
|
|
4
|
-
return <
|
|
8
|
+
return <ExtensionViewerPage />;
|
|
5
9
|
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ExtensionsListPage } from "@agent-native/core/client/extensions";
|
|
2
|
+
|
|
3
|
+
export function meta() {
|
|
4
|
+
return [{ title: "Extensions \u2014 Dispatch" }];
|
|
5
|
+
}
|
|
2
6
|
|
|
3
7
|
export default function ExtensionsRoute() {
|
|
4
|
-
return <
|
|
8
|
+
return <ExtensionsListPage />;
|
|
5
9
|
}
|