@cat-factory/server 0.333.0 → 0.335.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +6 -0
- package/dist/app.js.map +1 -1
- package/dist/config/types.d.ts +6 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/http/cors.d.ts +2 -0
- package/dist/http/cors.d.ts.map +1 -1
- package/dist/http/cors.js +3 -0
- package/dist/http/cors.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/modules/publicApi/PublicApiKeyController.d.ts.map +1 -1
- package/dist/modules/publicApi/PublicApiKeyController.js +55 -28
- package/dist/modules/publicApi/PublicApiKeyController.js.map +1 -1
- package/dist/modules/publicApi/PublicDirectoryController.d.ts +4 -0
- package/dist/modules/publicApi/PublicDirectoryController.d.ts.map +1 -0
- package/dist/modules/publicApi/PublicDirectoryController.js +107 -0
- package/dist/modules/publicApi/PublicDirectoryController.js.map +1 -0
- package/dist/modules/publicApi/PublicDiscoveryController.d.ts.map +1 -1
- package/dist/modules/publicApi/PublicDiscoveryController.js +2 -2
- package/dist/modules/publicApi/PublicDiscoveryController.js.map +1 -1
- package/dist/modules/publicApi/PublicKeyController.d.ts.map +1 -1
- package/dist/modules/publicApi/PublicKeyController.js +22 -11
- package/dist/modules/publicApi/PublicKeyController.js.map +1 -1
- package/dist/modules/publicApi/PublicPrAssessmentController.d.ts +4 -0
- package/dist/modules/publicApi/PublicPrAssessmentController.d.ts.map +1 -0
- package/dist/modules/publicApi/PublicPrAssessmentController.js +26 -0
- package/dist/modules/publicApi/PublicPrAssessmentController.js.map +1 -0
- package/dist/modules/publicApi/decisions/scope.d.ts +1 -1
- package/dist/modules/publicApi/decisions/scope.d.ts.map +1 -1
- package/dist/modules/publicApi/keyProjection.d.ts +15 -13
- package/dist/modules/publicApi/keyProjection.d.ts.map +1 -1
- package/dist/modules/publicApi/keyProjection.js +32 -12
- package/dist/modules/publicApi/keyProjection.js.map +1 -1
- package/dist/modules/publicApi/openapiDocument.generated.d.ts +1 -1
- package/dist/modules/publicApi/openapiDocument.generated.d.ts.map +1 -1
- package/dist/modules/publicApi/openapiDocument.generated.js +1 -1
- package/dist/modules/publicApi/openapiDocument.generated.js.map +1 -1
- package/dist/modules/publicApi/publicApiAuth.d.ts +24 -9
- package/dist/modules/publicApi/publicApiAuth.d.ts.map +1 -1
- package/dist/modules/publicApi/publicApiAuth.js +61 -4
- package/dist/modules/publicApi/publicApiAuth.js.map +1 -1
- package/dist/persistence/rpc-allowlist.d.ts.map +1 -1
- package/dist/persistence/rpc-allowlist.js +20 -0
- package/dist/persistence/rpc-allowlist.js.map +1 -1
- package/dist/runtime/directoryWebhooks.d.ts +12 -0
- package/dist/runtime/directoryWebhooks.d.ts.map +1 -0
- package/dist/runtime/directoryWebhooks.js +18 -0
- package/dist/runtime/directoryWebhooks.js.map +1 -0
- package/package.json +8 -8
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { deleteDirectoryWebhookContract, listDirectoryAccountMembershipsContract, listDirectoryChangesContract, listDirectoryReposContract, listDirectoryUsersContract, listDirectoryWorkspaceMembershipsContract, listDirectoryWebhooksContract, listDirectoryWorkspacesContract, putDirectoryWebhookContract, } from '@cat-factory/contracts';
|
|
2
|
+
import { ForbiddenError } from '@cat-factory/kernel';
|
|
3
|
+
import { buildHonoRoute } from '@toad-contracts/hono';
|
|
4
|
+
import { Hono } from 'hono';
|
|
5
|
+
import { requireCapability } from '../../http/guards.js';
|
|
6
|
+
import { authorizeAccount, refuse } from './publicApiAuth.js';
|
|
7
|
+
// The public DIRECTORY surface (`/api/v1/directory/*`): an account's workspaces, users,
|
|
8
|
+
// memberships and linked repositories, and the change feed that keeps a mirror of them current.
|
|
9
|
+
// Account-scoped, so no workspace header is read; the key's workspace reach becomes the reader's
|
|
10
|
+
// filter. The rules (visibility, cursor expiry, the snapshot watermark) are `DirectoryService`'s.
|
|
11
|
+
// Design: backend/docs/adr/0067-directory-sync.md.
|
|
12
|
+
export function publicDirectoryController() {
|
|
13
|
+
const app = new Hono();
|
|
14
|
+
buildHonoRoute(app, listDirectoryChangesContract, async (c) => {
|
|
15
|
+
const gate = await authorizeAccount(c, listDirectoryChangesContract.minScope);
|
|
16
|
+
if ('fail' in gate)
|
|
17
|
+
return refuse(c, gate.fail);
|
|
18
|
+
const { after, limit } = c.req.valid('query');
|
|
19
|
+
const page = await c.get('container').directory.changes(reader(gate.auth), after ?? 0, limit);
|
|
20
|
+
return c.json(page, 200);
|
|
21
|
+
});
|
|
22
|
+
buildHonoRoute(app, listDirectoryWorkspacesContract, async (c) => {
|
|
23
|
+
const gate = await authorizeAccount(c, listDirectoryWorkspacesContract.minScope);
|
|
24
|
+
if ('fail' in gate)
|
|
25
|
+
return refuse(c, gate.fail);
|
|
26
|
+
const { cursor, limit } = c.req.valid('query');
|
|
27
|
+
return c.json(await c.get('container').directory.workspaces(reader(gate.auth), cursor, limit), 200);
|
|
28
|
+
});
|
|
29
|
+
buildHonoRoute(app, listDirectoryUsersContract, async (c) => {
|
|
30
|
+
const gate = await authorizeAccount(c, listDirectoryUsersContract.minScope);
|
|
31
|
+
if ('fail' in gate)
|
|
32
|
+
return refuse(c, gate.fail);
|
|
33
|
+
const { cursor, limit } = c.req.valid('query');
|
|
34
|
+
return c.json(await c.get('container').directory.users(reader(gate.auth), cursor, limit), 200);
|
|
35
|
+
});
|
|
36
|
+
buildHonoRoute(app, listDirectoryAccountMembershipsContract, async (c) => {
|
|
37
|
+
const gate = await authorizeAccount(c, listDirectoryAccountMembershipsContract.minScope);
|
|
38
|
+
if ('fail' in gate)
|
|
39
|
+
return refuse(c, gate.fail);
|
|
40
|
+
const { cursor, limit } = c.req.valid('query');
|
|
41
|
+
const page = await c
|
|
42
|
+
.get('container')
|
|
43
|
+
.directory.accountMemberships(reader(gate.auth), cursor, limit);
|
|
44
|
+
return c.json(page, 200);
|
|
45
|
+
});
|
|
46
|
+
buildHonoRoute(app, listDirectoryWorkspaceMembershipsContract, async (c) => {
|
|
47
|
+
const gate = await authorizeAccount(c, listDirectoryWorkspaceMembershipsContract.minScope);
|
|
48
|
+
if ('fail' in gate)
|
|
49
|
+
return refuse(c, gate.fail);
|
|
50
|
+
const { cursor, limit } = c.req.valid('query');
|
|
51
|
+
const page = await c
|
|
52
|
+
.get('container')
|
|
53
|
+
.directory.workspaceMemberships(reader(gate.auth), cursor, limit);
|
|
54
|
+
return c.json(page, 200);
|
|
55
|
+
});
|
|
56
|
+
buildHonoRoute(app, listDirectoryReposContract, async (c) => {
|
|
57
|
+
const gate = await authorizeAccount(c, listDirectoryReposContract.minScope);
|
|
58
|
+
if ('fail' in gate)
|
|
59
|
+
return refuse(c, gate.fail);
|
|
60
|
+
const { cursor, limit } = c.req.valid('query');
|
|
61
|
+
return c.json(await c.get('container').directory.repos(reader(gate.auth), cursor, limit), 200);
|
|
62
|
+
});
|
|
63
|
+
// ---- Directory webhooks: account-level push endpoints --------------------------------------
|
|
64
|
+
// `admin` and account-wide only: an endpoint receives every directory change in the account, so
|
|
65
|
+
// a key limited to some workspaces could otherwise read the rest through a push it registered.
|
|
66
|
+
buildHonoRoute(app, listDirectoryWebhooksContract, async (c) => {
|
|
67
|
+
const gate = await authorizeAccount(c, listDirectoryWebhooksContract.minScope);
|
|
68
|
+
if ('fail' in gate)
|
|
69
|
+
return refuse(c, gate.fail);
|
|
70
|
+
const accountId = requireAccountWide(gate.auth);
|
|
71
|
+
return c.json({ webhooks: await webhooks(c).list(accountId) }, 200);
|
|
72
|
+
});
|
|
73
|
+
buildHonoRoute(app, putDirectoryWebhookContract, async (c) => {
|
|
74
|
+
const gate = await authorizeAccount(c, putDirectoryWebhookContract.minScope);
|
|
75
|
+
if ('fail' in gate)
|
|
76
|
+
return refuse(c, gate.fail);
|
|
77
|
+
const accountId = requireAccountWide(gate.auth);
|
|
78
|
+
const { webhookId } = c.req.valid('param');
|
|
79
|
+
return c.json(await webhooks(c).put(accountId, webhookId, c.req.valid('json')), 200);
|
|
80
|
+
});
|
|
81
|
+
buildHonoRoute(app, deleteDirectoryWebhookContract, async (c) => {
|
|
82
|
+
const gate = await authorizeAccount(c, deleteDirectoryWebhookContract.minScope);
|
|
83
|
+
if ('fail' in gate)
|
|
84
|
+
return refuse(c, gate.fail);
|
|
85
|
+
const accountId = requireAccountWide(gate.auth);
|
|
86
|
+
await webhooks(c).delete(accountId, c.req.valid('param').webhookId);
|
|
87
|
+
return c.body(null, 204);
|
|
88
|
+
});
|
|
89
|
+
return app;
|
|
90
|
+
}
|
|
91
|
+
function webhooks(c) {
|
|
92
|
+
return requireCapability(c.get('container').directoryWebhooks, 'Directory webhooks are not served here: they need ENCRYPTION_KEY to seal signing secrets, and a mothership-mode node leaves them to the mothership');
|
|
93
|
+
}
|
|
94
|
+
/** The key's account, refusing a key limited to some workspaces. */
|
|
95
|
+
function requireAccountWide(auth) {
|
|
96
|
+
if (auth.workspaceIds !== null) {
|
|
97
|
+
throw new ForbiddenError('Directory webhooks need a key that reaches every workspace', {
|
|
98
|
+
reason: 'account_scope_required',
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
return auth.accountId;
|
|
102
|
+
}
|
|
103
|
+
/** The directory reader a key is: its account, and its workspace reach as the filter. */
|
|
104
|
+
function reader(auth) {
|
|
105
|
+
return { accountId: auth.accountId, workspaceIds: auth.workspaceIds };
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=PublicDirectoryController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PublicDirectoryController.js","sourceRoot":"","sources":["../../../src/modules/publicApi/PublicDirectoryController.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PublicDiscoveryController.d.ts","sourceRoot":"","sources":["../../../src/modules/publicApi/PublicDiscoveryController.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAkB/C,wBAAgB,yBAAyB,IAAI,IAAI,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"PublicDiscoveryController.d.ts","sourceRoot":"","sources":["../../../src/modules/publicApi/PublicDiscoveryController.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAkB/C,wBAAgB,yBAAyB,IAAI,IAAI,CAAC,MAAM,CAAC,CAgExD"}
|
|
@@ -26,10 +26,10 @@ export function publicDiscoveryController() {
|
|
|
26
26
|
const gate = await authorize(c, getPublicIdentityContract.minScope);
|
|
27
27
|
if ('fail' in gate)
|
|
28
28
|
return refuse(c, gate.fail);
|
|
29
|
-
const { keyId, accountId, workspaceId, scope, label, externalIdentity, createdAt } = gate.auth;
|
|
29
|
+
const { keyId, accountId, workspaceId, workspaceIds, scope, label, externalIdentity, createdAt, } = gate.auth;
|
|
30
30
|
// Straight off the auth result: `authenticate` already loaded the row, so self-description
|
|
31
31
|
// costs no read of its own.
|
|
32
|
-
return c.json({ keyId, accountId, workspaceId, scope, label, externalIdentity, createdAt }, 200);
|
|
32
|
+
return c.json({ keyId, accountId, workspaceId, workspaceIds, scope, label, externalIdentity, createdAt }, 200);
|
|
33
33
|
});
|
|
34
34
|
buildHonoRoute(app, listPublicTaskTypesContract, async (c) => {
|
|
35
35
|
// `read`, like every other discovery call: knowing what may be created is not creating it, and
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PublicDiscoveryController.js","sourceRoot":"","sources":["../../../src/modules/publicApi/PublicDiscoveryController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAA;AAC/F,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAE3B,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAE3D,iGAAiG;AACjG,gEAAgE;AAChE,EAAE;AACF,mGAAmG;AACnG,mGAAmG;AACnG,mGAAmG;AACnG,kGAAkG;AAClG,qFAAqF;AACrF,EAAE;AACF,kGAAkG;AAClG,mGAAmG;AACnG,4FAA4F;AAE5F,MAAM,UAAU,yBAAyB;IACvC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAU,CAAA;IAE9B,cAAc,CAAC,GAAG,EAAE,yBAAyB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACzD,8FAA8F;QAC9F,4FAA4F;QAC5F,6BAA6B;QAC7B,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,CAAC,EAAE,yBAAyB,CAAC,QAAQ,CAAC,CAAA;QACnE,IAAI,MAAM,IAAI,IAAI;YAAE,OAAO,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;QAC/C,MAAM,
|
|
1
|
+
{"version":3,"file":"PublicDiscoveryController.js","sourceRoot":"","sources":["../../../src/modules/publicApi/PublicDiscoveryController.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PublicKeyController.d.ts","sourceRoot":"","sources":["../../../src/modules/publicApi/PublicKeyController.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PublicKeyController.d.ts","sourceRoot":"","sources":["../../../src/modules/publicApi/PublicKeyController.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAE3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAqD/C,wBAAgB,mBAAmB,IAAI,IAAI,CAAC,MAAM,CAAC,CA0ElD"}
|
|
@@ -2,7 +2,7 @@ import { createPublicKeyContract, listPublicKeysContract, revokePublicKeyContrac
|
|
|
2
2
|
import { buildHonoRoute } from '@toad-contracts/hono';
|
|
3
3
|
import { Hono } from 'hono';
|
|
4
4
|
import { requireCapability } from '../../http/guards.js';
|
|
5
|
-
import { publicApiKeyToWire } from './keyProjection.js';
|
|
5
|
+
import { assertReachCovers, assertWorkspacesInAccount, publicApiKeyToWire, } from './keyProjection.js';
|
|
6
6
|
import { authorize, refuse } from './publicApiAuth.js';
|
|
7
7
|
// HEADLESS key provisioning (`GET|POST|DELETE /api/v1/keys`): the external counterpart of the
|
|
8
8
|
// session-authed `/workspaces/:ws/public-api-keys` routes, delegating to the SAME
|
|
@@ -51,20 +51,25 @@ export function publicKeyController() {
|
|
|
51
51
|
const gate = await authorize(c, listPublicKeysContract.minScope);
|
|
52
52
|
if ('fail' in gate)
|
|
53
53
|
return refuse(c, gate.fail);
|
|
54
|
-
const
|
|
55
|
-
|
|
54
|
+
const { accountId, workspaceId } = gate.auth;
|
|
55
|
+
const keys = await keyStore(c).listReaching(accountId, workspaceId);
|
|
56
|
+
return c.json({ keys: keys.map((key) => publicApiKeyToWire(key, workspaceId)) }, 200);
|
|
56
57
|
});
|
|
57
58
|
buildHonoRoute(app, createPublicKeyContract, async (c) => {
|
|
58
59
|
const gate = await authorize(c, createPublicKeyContract.minScope);
|
|
59
60
|
if ('fail' in gate)
|
|
60
61
|
return refuse(c, gate.fail);
|
|
61
62
|
const keys = keyStore(c);
|
|
62
|
-
const { label, scope, externalIdentity } = c.req.valid('json');
|
|
63
|
-
// The account
|
|
64
|
-
//
|
|
63
|
+
const { label, scope, externalIdentity, workspaceIds } = c.req.valid('json');
|
|
64
|
+
// The account comes from the KEY, never from the body. The reach defaults to the workspace this
|
|
65
|
+
// request acts on (what every mint produced before keys could span workspaces) and can never
|
|
66
|
+
// exceed the minting key's own.
|
|
67
|
+
const reach = workspaceIds === undefined ? [gate.auth.workspaceId] : workspaceIds;
|
|
68
|
+
assertReachCovers(gate.auth.workspaceIds, reach, 'mint a key with that reach');
|
|
69
|
+
await assertWorkspacesInAccount(c.get('container').workspaceService, gate.auth.accountId, reach);
|
|
65
70
|
const { record, secret } = await keys.issue({
|
|
66
71
|
accountId: gate.auth.accountId,
|
|
67
|
-
|
|
72
|
+
workspaceIds: reach,
|
|
68
73
|
// No user minted this one. Attributing it to the human who minted the PARENT key would
|
|
69
74
|
// be a guess dressed as provenance. The key is what acted, so the key is what is
|
|
70
75
|
// recorded, and that is also what the revocation cascade follows.
|
|
@@ -82,21 +87,27 @@ export function publicKeyController() {
|
|
|
82
87
|
// An integration that needs one asks the person to mint it.
|
|
83
88
|
actsAsUserId: null,
|
|
84
89
|
}, label, scope ?? DEFAULT_MINTED_SCOPE);
|
|
85
|
-
return c.json({ key: publicApiKeyToWire(record), secret }, 201);
|
|
90
|
+
return c.json({ key: publicApiKeyToWire(record, gate.auth.workspaceId), secret }, 201);
|
|
86
91
|
});
|
|
87
92
|
buildHonoRoute(app, revokePublicKeyContract, async (c) => {
|
|
88
93
|
const gate = await authorize(c, revokePublicKeyContract.minScope);
|
|
89
94
|
if ('fail' in gate)
|
|
90
95
|
return refuse(c, gate.fail);
|
|
91
|
-
// Scoped to the caller's
|
|
92
|
-
//
|
|
96
|
+
// Scoped to the caller's account, and idempotent, so an unknown id is a 204 rather than a 404:
|
|
97
|
+
// this surface must not become an oracle for which key ids exist. A key reaching workspaces
|
|
98
|
+
// the caller cannot is refused, so a restricted admin key cannot retire a wider credential.
|
|
93
99
|
//
|
|
94
100
|
// Revoking the CALLING key is allowed on purpose: a provisioning credential retiring itself at
|
|
95
101
|
// the end of a run is the case, and the request is already authorized by the time it lands.
|
|
96
102
|
// That key is always an app-minted `admin` one, since revoking needs the rung this surface
|
|
97
103
|
// cannot mint. Self-revocation is the PROVISIONER standing down (taking everything it
|
|
98
104
|
// handed out with it), never a provisioned key handing itself back.
|
|
99
|
-
|
|
105
|
+
const keys = keyStore(c);
|
|
106
|
+
const target = await keys.getLive(gate.auth.accountId, c.req.valid('param').keyId);
|
|
107
|
+
if (target) {
|
|
108
|
+
assertReachCovers(gate.auth.workspaceIds, target.workspaceIds, 'revoke that key');
|
|
109
|
+
await keys.revoke(gate.auth.accountId, target.id);
|
|
110
|
+
}
|
|
100
111
|
return c.body(null, 204);
|
|
101
112
|
});
|
|
102
113
|
return app;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PublicKeyController.js","sourceRoot":"","sources":["../../../src/modules/publicApi/PublicKeyController.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PublicKeyController.js","sourceRoot":"","sources":["../../../src/modules/publicApi/PublicKeyController.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PublicPrAssessmentController.d.ts","sourceRoot":"","sources":["../../../src/modules/publicApi/PublicPrAssessmentController.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAQ/C,wBAAgB,4BAA4B,IAAI,IAAI,CAAC,MAAM,CAAC,CAyB3D"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { assessPublicPullRequestContract } from '@cat-factory/contracts';
|
|
2
|
+
import { buildHonoRoute } from '@toad-contracts/hono';
|
|
3
|
+
import { Hono } from 'hono';
|
|
4
|
+
import { requireCapability } from '../../http/guards.js';
|
|
5
|
+
import { keyInitiatorRole } from '../../http/runAdmission.js';
|
|
6
|
+
import { authorize, refuse } from './publicApiAuth.js';
|
|
7
|
+
// The public PR assessment (`POST /api/v1/pr-assessments`): one synchronous model call that scores
|
|
8
|
+
// a pull request and says whether a risk policy would land it. Every rule lives in the service.
|
|
9
|
+
export function publicPrAssessmentController() {
|
|
10
|
+
const app = new Hono();
|
|
11
|
+
buildHonoRoute(app, assessPublicPullRequestContract, async (c) => {
|
|
12
|
+
const gate = await authorize(c, assessPublicPullRequestContract.minScope);
|
|
13
|
+
if ('fail' in gate)
|
|
14
|
+
return refuse(c, gate.fail);
|
|
15
|
+
// Same reason the risk-policy list answers with: the verdict is judged against that library.
|
|
16
|
+
const { service } = requireCapability(c.get('container').prAssessment, 'Risk policies are not configured', 'risk_policies_unwired');
|
|
17
|
+
// A key bound to a person reads the PR and calls the model as them, and is judged under their
|
|
18
|
+
// role as a run it starts would be; an unbound key runs on the workspace's credentials.
|
|
19
|
+
const { workspaceId, actsAsUserId } = gate.auth;
|
|
20
|
+
const role = await keyInitiatorRole(c.get('container'), workspaceId, actsAsUserId);
|
|
21
|
+
const assessment = await service.assess(workspaceId, { userId: actsAsUserId, role }, c.req.valid('json'));
|
|
22
|
+
return c.json(assessment, 200);
|
|
23
|
+
});
|
|
24
|
+
return app;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=PublicPrAssessmentController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PublicPrAssessmentController.js","sourceRoot":"","sources":["../../../src/modules/publicApi/PublicPrAssessmentController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,+BAA+B,EAAE,MAAM,wBAAwB,CAAA;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAE3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAEtD,mGAAmG;AACnG,gGAAgG;AAEhG,MAAM,UAAU,4BAA4B;IAC1C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAU,CAAA;IAE9B,cAAc,CAAC,GAAG,EAAE,+BAA+B,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC/D,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,CAAC,EAAE,+BAA+B,CAAC,QAAQ,CAAC,CAAA;QACzE,IAAI,MAAM,IAAI,IAAI;YAAE,OAAO,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;QAC/C,6FAA6F;QAC7F,MAAM,EAAE,OAAO,EAAE,GAAG,iBAAiB,CACnC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,YAAY,EAC/B,kCAAkC,EAClC,uBAAuB,CACxB,CAAA;QACD,8FAA8F;QAC9F,wFAAwF;QACxF,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC,IAAI,CAAA;QAC/C,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,WAAW,EAAE,YAAY,CAAC,CAAA;QAClF,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,MAAM,CACrC,WAAW,EACX,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,EAC9B,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CACpB,CAAA;QACD,OAAO,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,CAAA;IAChC,CAAC,CAAC,CAAA;IAEF,OAAO,GAAG,CAAA;AACZ,CAAC"}
|
|
@@ -55,7 +55,7 @@ export declare function requireScopedRun<E extends AppEnv>(c: Context<E>, worksp
|
|
|
55
55
|
/** The error a gate rejected with, kept as DATA so each handler emits its own typed `c.json`. */
|
|
56
56
|
export type GateFailure = {
|
|
57
57
|
fail: {
|
|
58
|
-
status: 401 | 403 | 404 | 428 | 503;
|
|
58
|
+
status: 401 | 403 | 404 | 422 | 428 | 503;
|
|
59
59
|
code: string;
|
|
60
60
|
message: string;
|
|
61
61
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../../../src/modules/publicApi/decisions/scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAA2B,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAC5E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AACjE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAEnC,OAAO,KAAK,EACV,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,kBAAkB,EACnB,MAAM,4BAA4B,CAAA;AACnC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAgBlD,6EAA6E;AAC7E,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,iBAAiB,CAAA;IAC5B,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,aAAa,CAAC,CAAC,SAAS,MAAM,EAClD,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EACb,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAQ3B;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,UAAW,MAAM,KAAG,aACkB,CAAA;AAE9D;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,SAAS,MAAM,EACrD,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EACb,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,SAAS,CAAC,CAIpB;AAED,iGAAiG;AACjG,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE;QACJ,MAAM,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;
|
|
1
|
+
{"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../../../src/modules/publicApi/decisions/scope.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import type
|
|
1
|
+
import { type PublicApiKey } from '@cat-factory/contracts';
|
|
2
|
+
import { type PublicApiKeyRecord } from '@cat-factory/kernel';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* A key on the wire. `workspaceId` is the workspace the listing or mint was made for.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* wire type has no place for, so an explicit projection (never a spread of the row) is what keeps
|
|
14
|
-
* a future column from arriving on the wire by default.
|
|
6
|
+
* `secretHash` is the field this exists to leave behind, so it is an explicit projection and never
|
|
7
|
+
* a spread of the row: a future column must not arrive on the wire by default.
|
|
8
|
+
*/
|
|
9
|
+
export declare function publicApiKeyToWire(record: PublicApiKeyRecord, workspaceId: string): PublicApiKey;
|
|
10
|
+
/**
|
|
11
|
+
* Refuse a requested reach naming any workspace outside `accountId`, in one batched read. A
|
|
12
|
+
* foreign board and a missing one answer the same 404, so the check cannot be used as a probe.
|
|
15
13
|
*/
|
|
16
|
-
export declare function
|
|
14
|
+
export declare function assertWorkspacesInAccount(workspaces: {
|
|
15
|
+
accountIdsOf(ids: string[]): Promise<Record<string, string | null>>;
|
|
16
|
+
}, accountId: string, workspaceIds: string[] | null): Promise<void>;
|
|
17
|
+
/** Refuse an operation on a reach the caller's own reach does not cover. */
|
|
18
|
+
export declare function assertReachCovers(holder: string[] | null, requested: string[] | null, action: string): void;
|
|
17
19
|
//# sourceMappingURL=keyProjection.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyProjection.d.ts","sourceRoot":"","sources":["../../../src/modules/publicApi/keyProjection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"keyProjection.d.ts","sourceRoot":"","sources":["../../../src/modules/publicApi/keyProjection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwC,KAAK,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAEhG,OAAO,EAAiC,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAK5F;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,GAAG,YAAY,CAgBhG;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE;IAAE,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAA;CAAE,EACnF,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EAAE,GAAG,IAAI,GAC5B,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,4EAA4E;AAC5E,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,EACvB,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,EAC1B,MAAM,EAAE,MAAM,GACb,IAAI,CAMN"}
|
|
@@ -1,21 +1,20 @@
|
|
|
1
|
+
import { PUBLIC_API_KEY_REACH_EXCEEDED_REASON } from '@cat-factory/contracts';
|
|
2
|
+
import { reachCovers } from '@cat-factory/integrations';
|
|
3
|
+
import { ForbiddenError, NotFoundError } from '@cat-factory/kernel';
|
|
4
|
+
// Shared by the session-authed key panel and the headless `/api/v1/keys` surface, so the two
|
|
5
|
+
// project a key and judge a requested reach identically.
|
|
1
6
|
/**
|
|
2
|
-
*
|
|
7
|
+
* A key on the wire. `workspaceId` is the workspace the listing or mint was made for.
|
|
3
8
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* had a copy each, which is how a field comes to be echoed on one and silently absent on the
|
|
7
|
-
* other: `externalIdentity` is set by the headless mint and read on both, so a caller listing its
|
|
8
|
-
* keys in the app would have seen every one of them claim to act for nobody.
|
|
9
|
-
*
|
|
10
|
-
* `secretHash` is the field this exists to leave behind. It is the only member of the record the
|
|
11
|
-
* wire type has no place for, so an explicit projection (never a spread of the row) is what keeps
|
|
12
|
-
* a future column from arriving on the wire by default.
|
|
9
|
+
* `secretHash` is the field this exists to leave behind, so it is an explicit projection and never
|
|
10
|
+
* a spread of the row: a future column must not arrive on the wire by default.
|
|
13
11
|
*/
|
|
14
|
-
export function publicApiKeyToWire(record) {
|
|
12
|
+
export function publicApiKeyToWire(record, workspaceId) {
|
|
15
13
|
return {
|
|
16
14
|
id: record.id,
|
|
17
15
|
accountId: record.accountId,
|
|
18
|
-
workspaceId
|
|
16
|
+
workspaceId,
|
|
17
|
+
workspaceIds: record.workspaceIds,
|
|
19
18
|
label: record.label,
|
|
20
19
|
scope: record.scope,
|
|
21
20
|
createdByUserId: record.createdByUserId,
|
|
@@ -27,4 +26,25 @@ export function publicApiKeyToWire(record) {
|
|
|
27
26
|
revokedAt: record.revokedAt,
|
|
28
27
|
};
|
|
29
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Refuse a requested reach naming any workspace outside `accountId`, in one batched read. A
|
|
31
|
+
* foreign board and a missing one answer the same 404, so the check cannot be used as a probe.
|
|
32
|
+
*/
|
|
33
|
+
export async function assertWorkspacesInAccount(workspaces, accountId, workspaceIds) {
|
|
34
|
+
if (workspaceIds === null)
|
|
35
|
+
return;
|
|
36
|
+
const owners = await workspaces.accountIdsOf(workspaceIds);
|
|
37
|
+
const foreign = workspaceIds.find((id) => owners[id] !== accountId);
|
|
38
|
+
if (foreign !== undefined) {
|
|
39
|
+
throw new NotFoundError('Workspace', foreign, { reason: 'workspace_not_found' });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/** Refuse an operation on a reach the caller's own reach does not cover. */
|
|
43
|
+
export function assertReachCovers(holder, requested, action) {
|
|
44
|
+
if (!reachCovers(holder, requested)) {
|
|
45
|
+
throw new ForbiddenError(`This key cannot ${action}: it reaches workspaces this key does not`, {
|
|
46
|
+
reason: PUBLIC_API_KEY_REACH_EXCEEDED_REASON,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
30
50
|
//# sourceMappingURL=keyProjection.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyProjection.js","sourceRoot":"","sources":["../../../src/modules/publicApi/keyProjection.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"keyProjection.js","sourceRoot":"","sources":["../../../src/modules/publicApi/keyProjection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oCAAoC,EAAqB,MAAM,wBAAwB,CAAA;AAChG,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AACvD,OAAO,EAAE,cAAc,EAAE,aAAa,EAA2B,MAAM,qBAAqB,CAAA;AAE5F,6FAA6F;AAC7F,yDAAyD;AAEzD;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAA0B,EAAE,WAAmB;IAChF,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,WAAW;QACX,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,eAAe,EAAE,MAAM,CAAC,eAAe;QACvC,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,UAAmF,EACnF,SAAiB,EACjB,YAA6B;IAE7B,IAAI,YAAY,KAAK,IAAI;QAAE,OAAM;IACjC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,YAAY,CAAC,YAAY,CAAC,CAAA;IAC1D,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,SAAS,CAAC,CAAA;IACnE,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,IAAI,aAAa,CAAC,WAAW,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,qBAAqB,EAAE,CAAC,CAAA;IAClF,CAAC;AACH,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,iBAAiB,CAC/B,MAAuB,EACvB,SAA0B,EAC1B,MAAc;IAEd,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,cAAc,CAAC,mBAAmB,MAAM,2CAA2C,EAAE;YAC7F,MAAM,EAAE,oCAAoC;SAC7C,CAAC,CAAA;IACJ,CAAC;AACH,CAAC"}
|