@apart-tech/intelligence-core 1.11.4 → 1.11.5
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/auth/ability.d.ts +148 -0
- package/dist/auth/ability.d.ts.map +1 -0
- package/dist/auth/ability.js +285 -0
- package/dist/auth/ability.js.map +1 -0
- package/dist/auth/ability.test.d.ts +2 -0
- package/dist/auth/ability.test.d.ts.map +1 -0
- package/dist/auth/ability.test.js +680 -0
- package/dist/auth/ability.test.js.map +1 -0
- package/dist/auth/delegation-jwt.d.ts +167 -0
- package/dist/auth/delegation-jwt.d.ts.map +1 -0
- package/dist/auth/delegation-jwt.js +237 -0
- package/dist/auth/delegation-jwt.js.map +1 -0
- package/dist/auth/delegation-jwt.test.d.ts +2 -0
- package/dist/auth/delegation-jwt.test.d.ts.map +1 -0
- package/dist/auth/delegation-jwt.test.js +283 -0
- package/dist/auth/delegation-jwt.test.js.map +1 -0
- package/dist/auth/principal.d.ts +94 -0
- package/dist/auth/principal.d.ts.map +1 -0
- package/dist/auth/principal.js +33 -0
- package/dist/auth/principal.js.map +1 -0
- package/dist/config/config.test.d.ts +2 -0
- package/dist/config/config.test.d.ts.map +1 -0
- package/dist/config/config.test.js +57 -0
- package/dist/config/config.test.js.map +1 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +17 -0
- package/dist/config/index.js.map +1 -1
- package/dist/index.d.ts +13 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/__tests__/jwt.test.d.ts +2 -0
- package/dist/lib/__tests__/jwt.test.d.ts.map +1 -0
- package/dist/lib/__tests__/jwt.test.js +97 -0
- package/dist/lib/__tests__/jwt.test.js.map +1 -0
- package/dist/lib/jwt.d.ts +20 -0
- package/dist/lib/jwt.d.ts.map +1 -1
- package/dist/lib/jwt.js +56 -3
- package/dist/lib/jwt.js.map +1 -1
- package/dist/services/__tests__/delegation-cleanup-service.test.d.ts +2 -0
- package/dist/services/__tests__/delegation-cleanup-service.test.d.ts.map +1 -0
- package/dist/services/__tests__/delegation-cleanup-service.test.js +211 -0
- package/dist/services/__tests__/delegation-cleanup-service.test.js.map +1 -0
- package/dist/services/agent-run-service.d.ts +44 -7
- package/dist/services/agent-run-service.d.ts.map +1 -1
- package/dist/services/agent-run-service.js +14 -0
- package/dist/services/agent-run-service.js.map +1 -1
- package/dist/services/agent-schedule-service.d.ts +21 -0
- package/dist/services/agent-schedule-service.d.ts.map +1 -1
- package/dist/services/agent-schedule-service.js +12 -0
- package/dist/services/agent-schedule-service.js.map +1 -1
- package/dist/services/audit-event-service.d.ts +76 -0
- package/dist/services/audit-event-service.d.ts.map +1 -0
- package/dist/services/audit-event-service.js +48 -0
- package/dist/services/audit-event-service.js.map +1 -0
- package/dist/services/delegation-cleanup-service.d.ts +133 -0
- package/dist/services/delegation-cleanup-service.d.ts.map +1 -0
- package/dist/services/delegation-cleanup-service.js +111 -0
- package/dist/services/delegation-cleanup-service.js.map +1 -0
- package/dist/services/edge-service.d.ts.map +1 -1
- package/dist/services/edge-service.js +3 -0
- package/dist/services/edge-service.js.map +1 -1
- package/dist/services/org-agent-type-service.d.ts +15 -0
- package/dist/services/org-agent-type-service.d.ts.map +1 -1
- package/dist/services/org-agent-type-service.js +2 -0
- package/dist/services/org-agent-type-service.js.map +1 -1
- package/dist/services/usage-service.d.ts +48 -0
- package/dist/services/usage-service.d.ts.map +1 -0
- package/dist/services/usage-service.js +116 -0
- package/dist/services/usage-service.js.map +1 -0
- package/dist/services/user-service.d.ts.map +1 -1
- package/dist/services/user-service.js +24 -6
- package/dist/services/user-service.js.map +1 -1
- package/dist/services/user-service.test.d.ts +2 -0
- package/dist/services/user-service.test.d.ts.map +1 -0
- package/dist/services/user-service.test.js +86 -0
- package/dist/services/user-service.test.js.map +1 -0
- package/dist/types/index.d.ts +13 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +3 -2
- package/prisma/schema.prisma +158 -82
- package/dist/db/schema.d.ts +0 -507
- package/dist/db/schema.d.ts.map +0 -1
- package/dist/db/schema.js +0 -77
- package/dist/db/schema.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -7,6 +7,9 @@ export { encryptAesGcm, decryptAesGcm, deriveKey, deriveKeyV2 } from "./lib/cryp
|
|
|
7
7
|
export { getAgentKeySecret, getPiiKeySecret, getEmbeddingKeySecret } from "./lib/encryption-keys.js";
|
|
8
8
|
// JWT
|
|
9
9
|
export { verifyAuth0Jwt } from "./lib/jwt.js";
|
|
10
|
+
export { isUserPrincipal, isOrgAgentPrincipal, isDelegatedAgentPrincipal, } from "./auth/principal.js";
|
|
11
|
+
export { buildAbility, intersect, UnsupportedIntersectionError, } from "./auth/ability.js";
|
|
12
|
+
export { DELEGATION_ALGORITHM, DELEGATION_ISSUER, DELEGATION_KEY_MIN_BYTES, DELEGATION_TTL_SECONDS, DelegationKeyLoadError, DelegationTokenError, loadDelegationKeyFromEnv, mintDelegationToken, peekIssuer, verifyDelegationToken, } from "./auth/delegation-jwt.js";
|
|
10
13
|
// Types
|
|
11
14
|
export * from "./types/index.js";
|
|
12
15
|
// Config
|
|
@@ -27,11 +30,14 @@ export { OrgAgentConfigService } from "./services/org-agent-config-service.js";
|
|
|
27
30
|
export { OrgAgentTypeService } from "./services/org-agent-type-service.js";
|
|
28
31
|
export { OrgMcpServerService } from "./services/org-mcp-server-service.js";
|
|
29
32
|
export { AgentRunService } from "./services/agent-run-service.js";
|
|
33
|
+
export { AuditEventService } from "./services/audit-event-service.js";
|
|
34
|
+
export { cancelOrphanedAgentRuns } from "./services/delegation-cleanup-service.js";
|
|
30
35
|
export { AgentScheduleService } from "./services/agent-schedule-service.js";
|
|
31
36
|
export { CLI_REFERENCE } from "./services/agent-cli-reference.js";
|
|
32
37
|
export { UserService } from "./services/user-service.js";
|
|
33
38
|
export { MembershipService } from "./services/membership-service.js";
|
|
34
39
|
export { InviteService } from "./services/invite-service.js";
|
|
40
|
+
export { UsageService } from "./services/usage-service.js";
|
|
35
41
|
// Providers
|
|
36
42
|
export { createEmbeddingProvider, validateEmbeddingKey, OpenAIEmbeddingProvider, VoyageEmbeddingProvider, OllamaEmbeddingProvider } from "./providers/index.js";
|
|
37
43
|
export { BatchingEmbeddingProvider } from "./providers/batching.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,WAAW;AACX,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAEjE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAGvF,SAAS;AACT,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACvF,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAErG,MAAM;AACN,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt.test.d.ts","sourceRoot":"","sources":["../../../src/lib/__tests__/jwt.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
2
|
+
import { JWKS_CACHE_MAX_AGE_MS, JWKS_COOLDOWN_MS, createAuth0JwksResolver, resetJwksCache, verifyAuth0Jwt, } from "../jwt.js";
|
|
3
|
+
// A minimal JWKS response body. jose parses this on reload() but won't
|
|
4
|
+
// fail just because the keys are not usable for real verification —
|
|
5
|
+
// failure only happens when a JWT is actually verified against a key.
|
|
6
|
+
const FAKE_JWKS_BODY = JSON.stringify({
|
|
7
|
+
keys: [
|
|
8
|
+
{
|
|
9
|
+
kty: "RSA",
|
|
10
|
+
kid: "test-key-1",
|
|
11
|
+
use: "sig",
|
|
12
|
+
alg: "RS256",
|
|
13
|
+
n: "xGP_acGn7xCn3OQ0qoBXwOyw5nSGY3SnlbSXr3QxBOQPfOSmM0wQ4TgKGhY0t5T3pNS6EHF3OwBf3jL5p8O5_yQ",
|
|
14
|
+
e: "AQAB",
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
});
|
|
18
|
+
function fakeJwksFetch(counter) {
|
|
19
|
+
return async (_url, _init) => {
|
|
20
|
+
counter.calls += 1;
|
|
21
|
+
return new Response(FAKE_JWKS_BODY, {
|
|
22
|
+
status: 200,
|
|
23
|
+
headers: { "content-type": "application/json" },
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
describe("JWKS bounded cache (finding M6)", () => {
|
|
28
|
+
afterEach(() => {
|
|
29
|
+
resetJwksCache();
|
|
30
|
+
});
|
|
31
|
+
it("publishes explicit cache bounds as source-visible constants", () => {
|
|
32
|
+
// The finding is that the JWKS cache has no visible invalidation.
|
|
33
|
+
// Closing it means the bounds live in our source, not in a library
|
|
34
|
+
// default that a future version bump could silently change.
|
|
35
|
+
expect(JWKS_CACHE_MAX_AGE_MS).toBe(5 * 60 * 1000);
|
|
36
|
+
expect(JWKS_COOLDOWN_MS).toBe(30 * 1000);
|
|
37
|
+
});
|
|
38
|
+
it("reload() on a fresh resolver triggers exactly one fetch", async () => {
|
|
39
|
+
const counter = { calls: 0 };
|
|
40
|
+
const resolver = createAuth0JwksResolver("example.auth0.com", {
|
|
41
|
+
cacheMaxAgeMs: 50,
|
|
42
|
+
cooldownMs: 0,
|
|
43
|
+
fetchImpl: fakeJwksFetch(counter),
|
|
44
|
+
});
|
|
45
|
+
await resolver.reload();
|
|
46
|
+
expect(counter.calls).toBe(1);
|
|
47
|
+
expect(resolver.fresh).toBe(true);
|
|
48
|
+
});
|
|
49
|
+
it("fresh becomes false after cacheMaxAge elapses", async () => {
|
|
50
|
+
const counter = { calls: 0 };
|
|
51
|
+
const resolver = createAuth0JwksResolver("example.auth0.com", {
|
|
52
|
+
cacheMaxAgeMs: 30,
|
|
53
|
+
cooldownMs: 0,
|
|
54
|
+
fetchImpl: fakeJwksFetch(counter),
|
|
55
|
+
});
|
|
56
|
+
await resolver.reload();
|
|
57
|
+
expect(resolver.fresh).toBe(true);
|
|
58
|
+
// Wait past cacheMaxAge. After this, jose's bounded-age check
|
|
59
|
+
// returns false, which is the signal that triggers automatic
|
|
60
|
+
// refetch on the next verification attempt.
|
|
61
|
+
await new Promise((r) => setTimeout(r, 60));
|
|
62
|
+
expect(resolver.fresh).toBe(false);
|
|
63
|
+
});
|
|
64
|
+
it("a second reload after cache expiry triggers a second fetch", async () => {
|
|
65
|
+
// The core M6 guarantee: a rotated/compromised signing key at
|
|
66
|
+
// Auth0 cannot stay trusted indefinitely. After cacheMaxAge
|
|
67
|
+
// elapses, jose re-fetches the JWKS — observable here via the
|
|
68
|
+
// mock fetch's call counter.
|
|
69
|
+
const counter = { calls: 0 };
|
|
70
|
+
const resolver = createAuth0JwksResolver("example.auth0.com", {
|
|
71
|
+
cacheMaxAgeMs: 20,
|
|
72
|
+
cooldownMs: 0,
|
|
73
|
+
fetchImpl: fakeJwksFetch(counter),
|
|
74
|
+
});
|
|
75
|
+
await resolver.reload();
|
|
76
|
+
expect(counter.calls).toBe(1);
|
|
77
|
+
await new Promise((r) => setTimeout(r, 40));
|
|
78
|
+
await resolver.reload();
|
|
79
|
+
expect(counter.calls).toBe(2);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
describe("verifyAuth0Jwt", () => {
|
|
83
|
+
afterEach(() => {
|
|
84
|
+
resetJwksCache();
|
|
85
|
+
});
|
|
86
|
+
it("rejects a malformed token without touching the network", async () => {
|
|
87
|
+
// Sanity regression: verifyAuth0Jwt should fail fast on obviously
|
|
88
|
+
// invalid input. jose throws a parse error before any JWKS
|
|
89
|
+
// retrieval is attempted, so this is safe to run without
|
|
90
|
+
// mocking the network.
|
|
91
|
+
await expect(verifyAuth0Jwt("not-a-real-jwt", {
|
|
92
|
+
domain: "example.auth0.com",
|
|
93
|
+
audience: "https://api.example.com",
|
|
94
|
+
})).rejects.toThrow();
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
//# sourceMappingURL=jwt.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/jwt.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,uBAAuB,EACvB,cAAc,EACd,cAAc,GACf,MAAM,WAAW,CAAC;AAEnB,uEAAuE;AACvE,oEAAoE;AACpE,sEAAsE;AACtE,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC;IACpC,IAAI,EAAE;QACJ;YACE,GAAG,EAAE,KAAK;YACV,GAAG,EAAE,YAAY;YACjB,GAAG,EAAE,KAAK;YACV,GAAG,EAAE,OAAO;YACZ,CAAC,EAAE,yFAAyF;YAC5F,CAAC,EAAE,MAAM;SACV;KACF;CACF,CAAC,CAAC;AAEH,SAAS,aAAa,CAAC,OAA0B;IAC/C,OAAO,KAAK,EAAE,IAAkB,EAAE,KAAmB,EAAqB,EAAE;QAC1E,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC;QACnB,OAAO,IAAI,QAAQ,CAAC,cAAc,EAAE;YAClC,MAAM,EAAE,GAAG;YACX,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;SAChD,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,iCAAiC,EAAE,GAAG,EAAE;IAC/C,SAAS,CAAC,GAAG,EAAE;QACb,cAAc,EAAE,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,kEAAkE;QAClE,mEAAmE;QACnE,4DAA4D;QAC5D,MAAM,CAAC,qBAAqB,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAClD,MAAM,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACvE,MAAM,OAAO,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,uBAAuB,CAAC,mBAAmB,EAAE;YAC5D,aAAa,EAAE,EAAE;YACjB,UAAU,EAAE,CAAC;YACb,SAAS,EAAE,aAAa,CAAC,OAAO,CAAC;SAClC,CAAC,CAAC;QAEH,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC;QAExB,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,OAAO,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,uBAAuB,CAAC,mBAAmB,EAAE;YAC5D,aAAa,EAAE,EAAE;YACjB,UAAU,EAAE,CAAC;YACb,SAAS,EAAE,aAAa,CAAC,OAAO,CAAC;SAClC,CAAC,CAAC;QAEH,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC;QACxB,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAElC,8DAA8D;QAC9D,6DAA6D;QAC7D,4CAA4C;QAC5C,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAE5C,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;QAC1E,8DAA8D;QAC9D,4DAA4D;QAC5D,8DAA8D;QAC9D,6BAA6B;QAC7B,MAAM,OAAO,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,uBAAuB,CAAC,mBAAmB,EAAE;YAC5D,aAAa,EAAE,EAAE;YACjB,UAAU,EAAE,CAAC;YACb,SAAS,EAAE,aAAa,CAAC,OAAO,CAAC;SAClC,CAAC,CAAC;QAEH,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC;QACxB,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAE9B,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5C,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC;QAExB,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,SAAS,CAAC,GAAG,EAAE;QACb,cAAc,EAAE,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACtE,kEAAkE;QAClE,2DAA2D;QAC3D,yDAAyD;QACzD,uBAAuB;QACvB,MAAM,MAAM,CACV,cAAc,CAAC,gBAAgB,EAAE;YAC/B,MAAM,EAAE,mBAAmB;YAC3B,QAAQ,EAAE,yBAAyB;SACpC,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/dist/lib/jwt.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createRemoteJWKSet } from "jose";
|
|
1
2
|
import type { JWTPayload } from "jose";
|
|
2
3
|
export interface Auth0Config {
|
|
3
4
|
domain: string;
|
|
@@ -6,8 +7,27 @@ export interface Auth0Config {
|
|
|
6
7
|
export interface Auth0JwtPayload extends JWTPayload {
|
|
7
8
|
sub: string;
|
|
8
9
|
email?: string;
|
|
10
|
+
email_verified?: boolean;
|
|
9
11
|
name?: string;
|
|
10
12
|
org_id?: string;
|
|
11
13
|
}
|
|
14
|
+
export declare const JWKS_CACHE_MAX_AGE_MS: number;
|
|
15
|
+
export declare const JWKS_COOLDOWN_MS: number;
|
|
16
|
+
export type JwksResolver = ReturnType<typeof createRemoteJWKSet>;
|
|
17
|
+
/**
|
|
18
|
+
* Build a remote JWKS resolver for an Auth0 domain with bounded caching.
|
|
19
|
+
* Exported for test injection; production callers use {@link getJWKS}.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createAuth0JwksResolver(domain: string, options?: {
|
|
22
|
+
cacheMaxAgeMs?: number;
|
|
23
|
+
cooldownMs?: number;
|
|
24
|
+
fetchImpl?: (url: URL | string, init?: RequestInit) => Promise<Response>;
|
|
25
|
+
}): JwksResolver;
|
|
26
|
+
/**
|
|
27
|
+
* Invalidate the per-process JWKS cache for a given Auth0 domain.
|
|
28
|
+
* Intended for tests and for manual revocation flows. Production auth
|
|
29
|
+
* flows rely on the bounded cacheMaxAge above to rotate keys.
|
|
30
|
+
*/
|
|
31
|
+
export declare function resetJwksCache(domain?: string): void;
|
|
12
32
|
export declare function verifyAuth0Jwt(token: string, config: Auth0Config): Promise<Auth0JwtPayload>;
|
|
13
33
|
//# sourceMappingURL=jwt.d.ts.map
|
package/dist/lib/jwt.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../src/lib/jwt.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../src/lib/jwt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAA0B,MAAM,MAAM,CAAC;AAClE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAEvC,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAgB,SAAQ,UAAU;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAsBD,eAAO,MAAM,qBAAqB,QAAgB,CAAC;AACnD,eAAO,MAAM,gBAAgB,QAAY,CAAC;AAE1C,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAIjE;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IACR,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;CAC1E,GACA,YAAY,CAcd;AAUD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAMpD;AAED,wBAAsB,cAAc,CAClC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,eAAe,CAAC,CAc1B"}
|
package/dist/lib/jwt.js
CHANGED
|
@@ -1,13 +1,66 @@
|
|
|
1
|
-
import { createRemoteJWKSet, jwtVerify } from "jose";
|
|
1
|
+
import { createRemoteJWKSet, customFetch, jwtVerify } from "jose";
|
|
2
|
+
// Bounded JWKS cache for Auth0 signing keys (closes finding M6).
|
|
3
|
+
//
|
|
4
|
+
// jose's createRemoteJWKSet has three relevant knobs: cooldownDuration
|
|
5
|
+
// (minimum gap between HTTP refetches triggered by kid misses),
|
|
6
|
+
// cacheMaxAge (maximum age before a refetch is mandatory regardless of
|
|
7
|
+
// kid state), and reload() (manual invalidation). We configure the
|
|
8
|
+
// first two explicitly so the security bounds are visible at the call
|
|
9
|
+
// site instead of inherited from whatever jose's defaults happen to be
|
|
10
|
+
// in the currently installed version.
|
|
11
|
+
//
|
|
12
|
+
// Exposure window for a compromised or rotated Auth0 signing key:
|
|
13
|
+
// - worst case ≤ JWKS_CACHE_MAX_AGE_MS (5 minutes) before jose
|
|
14
|
+
// force-refetches and drops the stale key from its internal cache.
|
|
15
|
+
// - best case: the next token Auth0 issues carries a kid not in
|
|
16
|
+
// cache, jose refetches immediately (subject to cooldown).
|
|
17
|
+
//
|
|
18
|
+
// We intentionally use a tighter cacheMaxAge than jose's 10-minute
|
|
19
|
+
// default because Auth0 key rotations and key compromises are both
|
|
20
|
+
// security-critical events where we'd rather hit jwks.json every few
|
|
21
|
+
// minutes than trust a stale key for longer.
|
|
22
|
+
export const JWKS_CACHE_MAX_AGE_MS = 5 * 60 * 1000;
|
|
23
|
+
export const JWKS_COOLDOWN_MS = 30 * 1000;
|
|
2
24
|
const jwksCache = new Map();
|
|
25
|
+
/**
|
|
26
|
+
* Build a remote JWKS resolver for an Auth0 domain with bounded caching.
|
|
27
|
+
* Exported for test injection; production callers use {@link getJWKS}.
|
|
28
|
+
*/
|
|
29
|
+
export function createAuth0JwksResolver(domain, options) {
|
|
30
|
+
const url = new URL(`https://${domain}/.well-known/jwks.json`);
|
|
31
|
+
const createOpts = {
|
|
32
|
+
cacheMaxAge: options?.cacheMaxAgeMs ?? JWKS_CACHE_MAX_AGE_MS,
|
|
33
|
+
cooldownDuration: options?.cooldownMs ?? JWKS_COOLDOWN_MS,
|
|
34
|
+
};
|
|
35
|
+
if (options?.fetchImpl) {
|
|
36
|
+
// jose exposes a named `customFetch` symbol for fetch injection;
|
|
37
|
+
// tests pass their mock in this way. Production callers never
|
|
38
|
+
// need it — the default fetch is used.
|
|
39
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
40
|
+
createOpts[customFetch] = options.fetchImpl;
|
|
41
|
+
}
|
|
42
|
+
return createRemoteJWKSet(url, createOpts);
|
|
43
|
+
}
|
|
3
44
|
function getJWKS(domain) {
|
|
4
45
|
const key = domain;
|
|
5
46
|
if (!jwksCache.has(key)) {
|
|
6
|
-
|
|
7
|
-
jwksCache.set(key, createRemoteJWKSet(url));
|
|
47
|
+
jwksCache.set(key, createAuth0JwksResolver(domain));
|
|
8
48
|
}
|
|
9
49
|
return jwksCache.get(key);
|
|
10
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Invalidate the per-process JWKS cache for a given Auth0 domain.
|
|
53
|
+
* Intended for tests and for manual revocation flows. Production auth
|
|
54
|
+
* flows rely on the bounded cacheMaxAge above to rotate keys.
|
|
55
|
+
*/
|
|
56
|
+
export function resetJwksCache(domain) {
|
|
57
|
+
if (domain) {
|
|
58
|
+
jwksCache.delete(domain);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
jwksCache.clear();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
11
64
|
export async function verifyAuth0Jwt(token, config) {
|
|
12
65
|
const jwks = getJWKS(config.domain);
|
|
13
66
|
const issuer = `https://${config.domain}/`;
|
package/dist/lib/jwt.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../src/lib/jwt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../src/lib/jwt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAgBlE,iEAAiE;AACjE,EAAE;AACF,uEAAuE;AACvE,gEAAgE;AAChE,uEAAuE;AACvE,mEAAmE;AACnE,sEAAsE;AACtE,uEAAuE;AACvE,sCAAsC;AACtC,EAAE;AACF,kEAAkE;AAClE,iEAAiE;AACjE,uEAAuE;AACvE,kEAAkE;AAClE,+DAA+D;AAC/D,EAAE;AACF,mEAAmE;AACnE,mEAAmE;AACnE,qEAAqE;AACrE,6CAA6C;AAC7C,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AACnD,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,GAAG,IAAI,CAAC;AAI1C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAwB,CAAC;AAElD;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CACrC,MAAc,EACd,OAIC;IAED,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,WAAW,MAAM,wBAAwB,CAAC,CAAC;IAC/D,MAAM,UAAU,GAA6C;QAC3D,WAAW,EAAE,OAAO,EAAE,aAAa,IAAI,qBAAqB;QAC5D,gBAAgB,EAAE,OAAO,EAAE,UAAU,IAAI,gBAAgB;KAC1D,CAAC;IACF,IAAI,OAAO,EAAE,SAAS,EAAE,CAAC;QACvB,iEAAiE;QACjE,8DAA8D;QAC9D,uCAAuC;QACvC,8DAA8D;QAC7D,UAAkB,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC;IACvD,CAAC;IACD,OAAO,kBAAkB,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,OAAO,CAAC,MAAc;IAC7B,MAAM,GAAG,GAAG,MAAM,CAAC;IACnB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,uBAAuB,CAAC,MAAM,CAAC,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,SAAS,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC;AAC7B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,MAAe;IAC5C,IAAI,MAAM,EAAE,CAAC;QACX,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC3B,CAAC;SAAM,CAAC;QACN,SAAS,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,KAAa,EACb,MAAmB;IAEnB,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,MAAM,GAAG,WAAW,MAAM,CAAC,MAAM,GAAG,CAAC;IAE3C,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE;QAC/C,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,MAAM;KACP,CAAC,CAAC;IAEH,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,OAA0B,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delegation-cleanup-service.test.d.ts","sourceRoot":"","sources":["../../../src/services/__tests__/delegation-cleanup-service.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { cancelOrphanedAgentRuns, } from "../delegation-cleanup-service.js";
|
|
3
|
+
/**
|
|
4
|
+
* Tiny in-memory fake that satisfies `DelegationCleanupDb`. Uses the
|
|
5
|
+
* actual Prisma call shapes so the production call sites stay honest
|
|
6
|
+
* — if the real service ever changes its call arguments, these tests
|
|
7
|
+
* will catch it via the narrow interface. Audit writes are captured
|
|
8
|
+
* in-memory so tests can assert on their content.
|
|
9
|
+
*/
|
|
10
|
+
function makeFakeDb(init) {
|
|
11
|
+
const auditCalls = [];
|
|
12
|
+
const updatedRuns = [];
|
|
13
|
+
const db = {
|
|
14
|
+
agentRun: {
|
|
15
|
+
findMany: vi.fn(async (_args) => init.pendingRuns.map((r) => ({
|
|
16
|
+
id: r.id,
|
|
17
|
+
organizationId: r.organizationId,
|
|
18
|
+
invokedByUserId: r.invokedByUserId,
|
|
19
|
+
}))),
|
|
20
|
+
updateMany: vi.fn(async (args) => {
|
|
21
|
+
if (init.failBulkUpdate) {
|
|
22
|
+
throw new Error("bulk update intentionally failing");
|
|
23
|
+
}
|
|
24
|
+
const ids = args.where.id.in;
|
|
25
|
+
updatedRuns.push(...ids);
|
|
26
|
+
return { count: ids.length };
|
|
27
|
+
}),
|
|
28
|
+
},
|
|
29
|
+
membership: {
|
|
30
|
+
findUnique: vi.fn(async (args) => {
|
|
31
|
+
const runId = [...init.pendingRuns]
|
|
32
|
+
.find((r) => r.invokedByUserId === args.where.userId_organizationId.userId &&
|
|
33
|
+
r.organizationId === args.where.userId_organizationId.organizationId)?.id;
|
|
34
|
+
if (runId && init.failMembershipLookup?.has(runId)) {
|
|
35
|
+
throw new Error(`membership lookup intentionally failing for ${runId}`);
|
|
36
|
+
}
|
|
37
|
+
const key = `${args.where.userId_organizationId.userId}:${args.where.userId_organizationId.organizationId}`;
|
|
38
|
+
return init.memberships.has(key) ? { id: `membership-${key}` } : null;
|
|
39
|
+
}),
|
|
40
|
+
},
|
|
41
|
+
auditEvent: {
|
|
42
|
+
create: vi.fn(async (args) => {
|
|
43
|
+
auditCalls.push(args.data);
|
|
44
|
+
return args.data;
|
|
45
|
+
}),
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
return { db, auditCalls, updatedRuns };
|
|
49
|
+
}
|
|
50
|
+
describe("cancelOrphanedAgentRuns", () => {
|
|
51
|
+
it("cancels runs whose invoking user has no membership in the org", async () => {
|
|
52
|
+
const { db, auditCalls, updatedRuns } = makeFakeDb({
|
|
53
|
+
pendingRuns: [
|
|
54
|
+
{
|
|
55
|
+
id: "run-1",
|
|
56
|
+
organizationId: "org-1",
|
|
57
|
+
invokedByUserId: "user-a",
|
|
58
|
+
status: "pending",
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
memberships: new Set(), // user-a has no memberships
|
|
62
|
+
});
|
|
63
|
+
const result = await cancelOrphanedAgentRuns(db);
|
|
64
|
+
expect(result.scannedCount).toBe(1);
|
|
65
|
+
expect(result.cancelledRunIds).toEqual(["run-1"]);
|
|
66
|
+
expect(updatedRuns).toEqual(["run-1"]);
|
|
67
|
+
expect(auditCalls).toHaveLength(1);
|
|
68
|
+
expect(auditCalls[0]).toMatchObject({
|
|
69
|
+
agentRunId: "run-1",
|
|
70
|
+
action: "delegation.revoke",
|
|
71
|
+
result: "allow",
|
|
72
|
+
principalType: "system",
|
|
73
|
+
principalId: "delegation-cleanup",
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
it("leaves runs whose invoking user still has a membership", async () => {
|
|
77
|
+
const { db, updatedRuns, auditCalls } = makeFakeDb({
|
|
78
|
+
pendingRuns: [
|
|
79
|
+
{
|
|
80
|
+
id: "run-active",
|
|
81
|
+
organizationId: "org-1",
|
|
82
|
+
invokedByUserId: "user-a",
|
|
83
|
+
status: "running",
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
memberships: new Set(["user-a:org-1"]),
|
|
87
|
+
});
|
|
88
|
+
const result = await cancelOrphanedAgentRuns(db);
|
|
89
|
+
expect(result.scannedCount).toBe(1);
|
|
90
|
+
expect(result.cancelledRunIds).toEqual([]);
|
|
91
|
+
expect(updatedRuns).toEqual([]);
|
|
92
|
+
expect(auditCalls).toEqual([]);
|
|
93
|
+
});
|
|
94
|
+
it("leaves runs whose invokedByUserId is null (API-key-authored)", async () => {
|
|
95
|
+
// findMany's WHERE already filters `invokedByUserId: not null`,
|
|
96
|
+
// so the fake wouldn't return these in practice — but the inner
|
|
97
|
+
// loop also has a belt-and-braces guard for `!run.invokedByUserId`
|
|
98
|
+
// and this test documents the intent.
|
|
99
|
+
const { db, updatedRuns } = makeFakeDb({
|
|
100
|
+
pendingRuns: [
|
|
101
|
+
{
|
|
102
|
+
id: "run-legacy",
|
|
103
|
+
organizationId: "org-1",
|
|
104
|
+
invokedByUserId: null,
|
|
105
|
+
status: "pending",
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
memberships: new Set(),
|
|
109
|
+
});
|
|
110
|
+
const result = await cancelOrphanedAgentRuns(db);
|
|
111
|
+
expect(result.cancelledRunIds).toEqual([]);
|
|
112
|
+
expect(updatedRuns).toEqual([]);
|
|
113
|
+
});
|
|
114
|
+
it("processes a mix of orphaned and active runs in one sweep", async () => {
|
|
115
|
+
const { db, updatedRuns, auditCalls } = makeFakeDb({
|
|
116
|
+
pendingRuns: [
|
|
117
|
+
{
|
|
118
|
+
id: "run-orphan",
|
|
119
|
+
organizationId: "org-1",
|
|
120
|
+
invokedByUserId: "user-gone",
|
|
121
|
+
status: "pending",
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
id: "run-active",
|
|
125
|
+
organizationId: "org-1",
|
|
126
|
+
invokedByUserId: "user-still-here",
|
|
127
|
+
status: "running",
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
id: "run-orphan-other-org",
|
|
131
|
+
organizationId: "org-2",
|
|
132
|
+
invokedByUserId: "user-still-here",
|
|
133
|
+
status: "pending",
|
|
134
|
+
},
|
|
135
|
+
],
|
|
136
|
+
memberships: new Set(["user-still-here:org-1"]),
|
|
137
|
+
});
|
|
138
|
+
const result = await cancelOrphanedAgentRuns(db);
|
|
139
|
+
expect(result.scannedCount).toBe(3);
|
|
140
|
+
expect(new Set(result.cancelledRunIds)).toEqual(new Set(["run-orphan", "run-orphan-other-org"]));
|
|
141
|
+
expect(new Set(updatedRuns)).toEqual(new Set(["run-orphan", "run-orphan-other-org"]));
|
|
142
|
+
expect(auditCalls).toHaveLength(2);
|
|
143
|
+
const auditedIds = auditCalls.map((a) => a.agentRunId).sort();
|
|
144
|
+
expect(auditedIds).toEqual(["run-orphan", "run-orphan-other-org"]);
|
|
145
|
+
});
|
|
146
|
+
it("continues the sweep when an individual membership lookup throws", async () => {
|
|
147
|
+
const { db, updatedRuns } = makeFakeDb({
|
|
148
|
+
pendingRuns: [
|
|
149
|
+
{
|
|
150
|
+
id: "run-bad",
|
|
151
|
+
organizationId: "org-1",
|
|
152
|
+
invokedByUserId: "user-bad",
|
|
153
|
+
status: "pending",
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
id: "run-good",
|
|
157
|
+
organizationId: "org-1",
|
|
158
|
+
invokedByUserId: "user-gone",
|
|
159
|
+
status: "pending",
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
memberships: new Set(),
|
|
163
|
+
failMembershipLookup: new Set(["run-bad"]),
|
|
164
|
+
});
|
|
165
|
+
// Suppress the expected console.error from the sweep's catch block.
|
|
166
|
+
const consoleErrorSpy = vi
|
|
167
|
+
.spyOn(console, "error")
|
|
168
|
+
.mockImplementation(() => { });
|
|
169
|
+
const result = await cancelOrphanedAgentRuns(db);
|
|
170
|
+
consoleErrorSpy.mockRestore();
|
|
171
|
+
// run-bad was skipped (lookup threw) and run-good was cancelled.
|
|
172
|
+
// scannedCount still reflects both because the sweep read both.
|
|
173
|
+
expect(result.scannedCount).toBe(2);
|
|
174
|
+
expect(result.cancelledRunIds).toEqual(["run-good"]);
|
|
175
|
+
expect(updatedRuns).toEqual(["run-good"]);
|
|
176
|
+
});
|
|
177
|
+
it("returns empty cancelledRunIds when the bulk update fails", async () => {
|
|
178
|
+
const { db, updatedRuns, auditCalls } = makeFakeDb({
|
|
179
|
+
pendingRuns: [
|
|
180
|
+
{
|
|
181
|
+
id: "run-1",
|
|
182
|
+
organizationId: "org-1",
|
|
183
|
+
invokedByUserId: "user-a",
|
|
184
|
+
status: "pending",
|
|
185
|
+
},
|
|
186
|
+
],
|
|
187
|
+
memberships: new Set(),
|
|
188
|
+
failBulkUpdate: true,
|
|
189
|
+
});
|
|
190
|
+
const consoleErrorSpy = vi
|
|
191
|
+
.spyOn(console, "error")
|
|
192
|
+
.mockImplementation(() => { });
|
|
193
|
+
const result = await cancelOrphanedAgentRuns(db);
|
|
194
|
+
consoleErrorSpy.mockRestore();
|
|
195
|
+
expect(result.cancelledRunIds).toEqual([]);
|
|
196
|
+
expect(updatedRuns).toEqual([]);
|
|
197
|
+
// No audit events because no runs successfully transitioned.
|
|
198
|
+
expect(auditCalls).toEqual([]);
|
|
199
|
+
});
|
|
200
|
+
it("is a no-op when there are no pending runs at all", async () => {
|
|
201
|
+
const { db, updatedRuns, auditCalls } = makeFakeDb({
|
|
202
|
+
pendingRuns: [],
|
|
203
|
+
memberships: new Set(),
|
|
204
|
+
});
|
|
205
|
+
const result = await cancelOrphanedAgentRuns(db);
|
|
206
|
+
expect(result).toEqual({ scannedCount: 0, cancelledRunIds: [] });
|
|
207
|
+
expect(updatedRuns).toEqual([]);
|
|
208
|
+
expect(auditCalls).toEqual([]);
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
//# sourceMappingURL=delegation-cleanup-service.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delegation-cleanup-service.test.js","sourceRoot":"","sources":["../../../src/services/__tests__/delegation-cleanup-service.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,17 +12,54 @@ export interface AgentRun {
|
|
|
12
12
|
completedAt: Date | null;
|
|
13
13
|
createdBy: string;
|
|
14
14
|
scheduleId: string | null;
|
|
15
|
+
/**
|
|
16
|
+
* FK to `OrgAgentType.id`. Populated by the Phase 1d spawn path for
|
|
17
|
+
* runs whose agent type resolves to a DB-backed row. Built-in agent
|
|
18
|
+
* types that have no org-level row stay `null`.
|
|
19
|
+
*/
|
|
20
|
+
agentId: string | null;
|
|
21
|
+
/**
|
|
22
|
+
* FK to `User.id`. Populated by the Phase 1d spawn path whenever a
|
|
23
|
+
* run is spawned from a user-authenticated request. API-key-authored
|
|
24
|
+
* runs stay `null` because there is no owning user.
|
|
25
|
+
*/
|
|
26
|
+
invokedByUserId: string | null;
|
|
27
|
+
/**
|
|
28
|
+
* The intersected rule set captured at spawn time (Phase 1d). The
|
|
29
|
+
* middleware rehydrates this into a `DelegatedAgentPrincipal` ability
|
|
30
|
+
* on every sandbox callback — see `buildAbility` in core/auth. Stored
|
|
31
|
+
* as `Json?`; surfaced here as `unknown` so callers must narrow it
|
|
32
|
+
* before use.
|
|
33
|
+
*/
|
|
34
|
+
capturedAbility: unknown;
|
|
35
|
+
}
|
|
36
|
+
export interface AgentRunCreateInput {
|
|
37
|
+
prompt: string;
|
|
38
|
+
type?: string;
|
|
39
|
+
model: string;
|
|
40
|
+
createdBy: string;
|
|
41
|
+
scheduleId?: string;
|
|
42
|
+
/**
|
|
43
|
+
* FK to `OrgAgentType.id` — only set when the agent type is a DB-
|
|
44
|
+
* backed row. Built-in types without an org override leave this unset.
|
|
45
|
+
*/
|
|
46
|
+
agentId?: string | null;
|
|
47
|
+
/**
|
|
48
|
+
* FK to `User.id` — only set for user-authenticated spawn paths.
|
|
49
|
+
*/
|
|
50
|
+
invokedByUserId?: string | null;
|
|
51
|
+
/**
|
|
52
|
+
* The captured CASL rule set, i.e. `intersect(userAbility,
|
|
53
|
+
* orgAgentType.intrinsicPolicy)`. Only set for user-authenticated
|
|
54
|
+
* spawn paths. API-key-authored runs leave this null and the legacy
|
|
55
|
+
* `OrgAgentPrincipal` path in the middleware grants `manage all`.
|
|
56
|
+
*/
|
|
57
|
+
capturedAbility?: unknown;
|
|
15
58
|
}
|
|
16
59
|
export declare class AgentRunService {
|
|
17
60
|
private db;
|
|
18
61
|
constructor(db: PrismaClient);
|
|
19
|
-
create(organizationId: string, input:
|
|
20
|
-
prompt: string;
|
|
21
|
-
type?: string;
|
|
22
|
-
model: string;
|
|
23
|
-
createdBy: string;
|
|
24
|
-
scheduleId?: string;
|
|
25
|
-
}): Promise<AgentRun>;
|
|
62
|
+
create(organizationId: string, input: AgentRunCreateInput): Promise<AgentRun>;
|
|
26
63
|
updateStatus(id: string, organizationId: string, update: {
|
|
27
64
|
status: string;
|
|
28
65
|
result?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-run-service.d.ts","sourceRoot":"","sources":["../../src/services/agent-run-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,IAAI,CAAC;IAChB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"agent-run-service.d.ts","sourceRoot":"","sources":["../../src/services/agent-run-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,IAAI,CAAC;IAChB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;;;;OAIG;IACH,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB;;;;OAIG;IACH,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B;;;;;;OAMG;IACH,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC;;;;;OAKG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,qBAAa,eAAe;IACd,OAAO,CAAC,EAAE;gBAAF,EAAE,EAAE,YAAY;IAE9B,MAAM,CACV,cAAc,EAAE,MAAM,EACtB,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAAC,QAAQ,CAAC;IA2Bd,YAAY,CAChB,EAAE,EAAE,MAAM,EACV,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE;QACN,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,IAAI,CAAC;KACpB,GACA,OAAO,CAAC,QAAQ,CAAC;IAcd,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAQrE,IAAI,CACR,cAAc,EAAE,MAAM,EACtB,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GACxD,OAAO,CAAC,QAAQ,EAAE,CAAC;IAatB,OAAO,CAAC,UAAU;CAmBnB"}
|
|
@@ -13,6 +13,17 @@ export class AgentRunService {
|
|
|
13
13
|
status: "pending",
|
|
14
14
|
createdBy: input.createdBy,
|
|
15
15
|
scheduleId: input.scheduleId ?? null,
|
|
16
|
+
agentId: input.agentId ?? null,
|
|
17
|
+
invokedByUserId: input.invokedByUserId ?? null,
|
|
18
|
+
// Prisma's typed `Json?` wants `undefined` to leave the column
|
|
19
|
+
// as its default (null) and a concrete object/array to write a
|
|
20
|
+
// value. `null` and `undefined` both collapse to "don't write
|
|
21
|
+
// anything" here; API-key spawn paths leave this unset and the
|
|
22
|
+
// resulting row has capturedAbility = null, which is the correct
|
|
23
|
+
// shape for legacy runs.
|
|
24
|
+
capturedAbility: input.capturedAbility == null
|
|
25
|
+
? undefined
|
|
26
|
+
: input.capturedAbility,
|
|
16
27
|
},
|
|
17
28
|
});
|
|
18
29
|
return this.toAgentRun(run);
|
|
@@ -64,6 +75,9 @@ export class AgentRunService {
|
|
|
64
75
|
completedAt: run.completedAt,
|
|
65
76
|
createdBy: run.createdBy,
|
|
66
77
|
scheduleId: run.scheduleId,
|
|
78
|
+
agentId: run.agentId ?? null,
|
|
79
|
+
invokedByUserId: run.invokedByUserId ?? null,
|
|
80
|
+
capturedAbility: run.capturedAbility ?? null,
|
|
67
81
|
};
|
|
68
82
|
}
|
|
69
83
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-run-service.js","sourceRoot":"","sources":["../../src/services/agent-run-service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"agent-run-service.js","sourceRoot":"","sources":["../../src/services/agent-run-service.ts"],"names":[],"mappings":"AA6DA,MAAM,OAAO,eAAe;IACN;IAApB,YAAoB,EAAgB;QAAhB,OAAE,GAAF,EAAE,CAAc;IAAG,CAAC;IAExC,KAAK,CAAC,MAAM,CACV,cAAsB,EACtB,KAA0B;QAE1B,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC;YACxC,IAAI,EAAE;gBACJ,cAAc;gBACd,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,YAAY;gBAChC,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,MAAM,EAAE,SAAS;gBACjB,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,IAAI;gBACpC,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,IAAI;gBAC9B,eAAe,EAAE,KAAK,CAAC,eAAe,IAAI,IAAI;gBAC9C,+DAA+D;gBAC/D,+DAA+D;gBAC/D,8DAA8D;gBAC9D,+DAA+D;gBAC/D,iEAAiE;gBACjE,yBAAyB;gBACzB,eAAe,EACb,KAAK,CAAC,eAAe,IAAI,IAAI;oBAC3B,CAAC,CAAC,SAAS;oBACX,CAAC,CAAE,KAAK,CAAC,eAA0B;aACxC;SACF,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,YAAY,CAChB,EAAU,EACV,cAAsB,EACtB,MAMC;QAED,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC;YACxC,KAAK,EAAE,EAAE,EAAE,EAAE,cAAc,EAAE;YAC7B,IAAI,EAAE;gBACJ,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,WAAW,EAAE,MAAM,CAAC,WAAW;aAChC;SACF,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,EAAU,EAAE,cAAsB;QAC9C,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;YAC3C,KAAK,EAAE,EAAE,EAAE,EAAE,cAAc,EAAE;SAC9B,CAAC,CAAC;QACH,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QACtB,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,IAAI,CACR,cAAsB,EACtB,IAAyD;QAEzD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAC3C,KAAK,EAAE;gBACL,cAAc;gBACd,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChD,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC3C;YACD,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE;YAC9B,IAAI,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE;SACxB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC;IAEO,UAAU,CAAC,GAAQ;QACzB,OAAO;YACL,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,UAAU,EAAE,GAAG,CAAC,UAAU;YAC1B,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,IAAI;YAC5B,eAAe,EAAE,GAAG,CAAC,eAAe,IAAI,IAAI;YAC5C,eAAe,EAAE,GAAG,CAAC,eAAe,IAAI,IAAI;SAC7C,CAAC;IACJ,CAAC;CACF"}
|