@stigmer/server 3.22.0 → 3.22.1-dev.20260922095755
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/authorization/authorizer.d.ts +4 -8
- package/dist/authorization/authorizer.d.ts.map +1 -1
- package/dist/authorization/authorizer.js +5 -9
- package/dist/authorization/authorizer.js.map +1 -1
- package/dist/authorization/derived-tuples.d.ts.map +1 -1
- package/dist/authorization/derived-tuples.js +10 -25
- package/dist/authorization/derived-tuples.js.map +1 -1
- package/dist/authorization/evaluator.d.ts +7 -8
- package/dist/authorization/evaluator.d.ts.map +1 -1
- package/dist/authorization/evaluator.js +4 -20
- package/dist/authorization/evaluator.js.map +1 -1
- package/dist/authorization/list-read-scope.d.ts.map +1 -1
- package/dist/authorization/list-read-scope.js +5 -9
- package/dist/authorization/list-read-scope.js.map +1 -1
- package/dist/authorization/model/agent.d.ts.map +1 -1
- package/dist/authorization/model/agent.js +4 -5
- package/dist/authorization/model/agent.js.map +1 -1
- package/dist/authorization/model/agent_instance.d.ts.map +1 -1
- package/dist/authorization/model/agent_instance.js +2 -2
- package/dist/authorization/model/agent_instance.js.map +1 -1
- package/dist/authorization/model/mcp_server.d.ts.map +1 -1
- package/dist/authorization/model/mcp_server.js +2 -2
- package/dist/authorization/model/mcp_server.js.map +1 -1
- package/dist/authorization/model/plugin.d.ts.map +1 -1
- package/dist/authorization/model/plugin.js +3 -4
- package/dist/authorization/model/plugin.js.map +1 -1
- package/dist/authorization/model/rewrite.d.ts +8 -10
- package/dist/authorization/model/rewrite.d.ts.map +1 -1
- package/dist/authorization/model/rewrite.js +0 -3
- package/dist/authorization/model/rewrite.js.map +1 -1
- package/dist/authorization/model/skill.d.ts.map +1 -1
- package/dist/authorization/model/skill.js +2 -2
- package/dist/authorization/model/skill.js.map +1 -1
- package/dist/authorization/model/workflow.d.ts.map +1 -1
- package/dist/authorization/model/workflow.js +2 -2
- package/dist/authorization/model/workflow.js.map +1 -1
- package/dist/authorization/model/workflow_instance.d.ts.map +1 -1
- package/dist/authorization/model/workflow_instance.js +2 -2
- package/dist/authorization/model/workflow_instance.js.map +1 -1
- package/dist/authorization/organization-directory.d.ts.map +1 -1
- package/dist/authorization/organization-directory.js +2 -3
- package/dist/authorization/organization-directory.js.map +1 -1
- package/dist/authorization/store-test-kit.d.ts +0 -6
- package/dist/authorization/store-test-kit.d.ts.map +1 -1
- package/dist/authorization/store-test-kit.js +16 -62
- package/dist/authorization/store-test-kit.js.map +1 -1
- package/dist/authorization/tuples.d.ts +13 -32
- package/dist/authorization/tuples.d.ts.map +1 -1
- package/dist/authorization/tuples.js +3 -11
- package/dist/authorization/tuples.js.map +1 -1
- package/dist/domain/agent/controller.d.ts.map +1 -1
- package/dist/domain/agent/controller.js +4 -4
- package/dist/domain/agent/controller.js.map +1 -1
- package/dist/domain/agentchannel/controller.d.ts.map +1 -1
- package/dist/domain/agentchannel/controller.js +3 -1
- package/dist/domain/agentchannel/controller.js.map +1 -1
- package/dist/domain/agentexecution/controller.d.ts.map +1 -1
- package/dist/domain/agentexecution/controller.js +3 -1
- package/dist/domain/agentexecution/controller.js.map +1 -1
- package/dist/domain/agentinstance/controller.d.ts.map +1 -1
- package/dist/domain/agentinstance/controller.js +3 -4
- package/dist/domain/agentinstance/controller.js.map +1 -1
- package/dist/domain/agentshare/constants.d.ts +6 -11
- package/dist/domain/agentshare/constants.d.ts.map +1 -1
- package/dist/domain/agentshare/constants.js +8 -16
- package/dist/domain/agentshare/constants.js.map +1 -1
- package/dist/domain/agentshare/controller.d.ts.map +1 -1
- package/dist/domain/agentshare/controller.js +3 -1
- package/dist/domain/agentshare/controller.js.map +1 -1
- package/dist/domain/agentshare/steps.d.ts +18 -25
- package/dist/domain/agentshare/steps.d.ts.map +1 -1
- package/dist/domain/agentshare/steps.js +41 -142
- package/dist/domain/agentshare/steps.js.map +1 -1
- package/dist/domain/environment/controller.d.ts.map +1 -1
- package/dist/domain/environment/controller.js +2 -3
- package/dist/domain/environment/controller.js.map +1 -1
- package/dist/domain/executioncontext/controller.d.ts.map +1 -1
- package/dist/domain/executioncontext/controller.js +2 -1
- package/dist/domain/executioncontext/controller.js.map +1 -1
- package/dist/domain/mcpserver/controller.d.ts.map +1 -1
- package/dist/domain/mcpserver/controller.js +3 -4
- package/dist/domain/mcpserver/controller.js.map +1 -1
- package/dist/domain/plugin/controller.d.ts.map +1 -1
- package/dist/domain/plugin/controller.js +1 -3
- package/dist/domain/plugin/controller.js.map +1 -1
- package/dist/domain/plugin/push.d.ts +7 -5
- package/dist/domain/plugin/push.d.ts.map +1 -1
- package/dist/domain/plugin/push.js +8 -14
- package/dist/domain/plugin/push.js.map +1 -1
- package/dist/domain/schedule/controller.d.ts.map +1 -1
- package/dist/domain/schedule/controller.js +3 -1
- package/dist/domain/schedule/controller.js.map +1 -1
- package/dist/domain/session/controller.d.ts.map +1 -1
- package/dist/domain/session/controller.js +3 -2
- package/dist/domain/session/controller.js.map +1 -1
- package/dist/domain/skill/controller.d.ts.map +1 -1
- package/dist/domain/skill/controller.js +0 -2
- package/dist/domain/skill/controller.js.map +1 -1
- package/dist/domain/workflow/agent-call-references.d.ts +54 -0
- package/dist/domain/workflow/agent-call-references.d.ts.map +1 -0
- package/dist/domain/workflow/agent-call-references.js +97 -0
- package/dist/domain/workflow/agent-call-references.js.map +1 -0
- package/dist/domain/workflow/controller.d.ts.map +1 -1
- package/dist/domain/workflow/controller.js +14 -6
- package/dist/domain/workflow/controller.js.map +1 -1
- package/dist/domain/workflow/registry/data/task-kind-registry.json +1 -1
- package/dist/domain/workflow/validation/task-config-constraints.d.ts +10 -1
- package/dist/domain/workflow/validation/task-config-constraints.d.ts.map +1 -1
- package/dist/domain/workflow/validation/task-config-constraints.js +3 -2
- package/dist/domain/workflow/validation/task-config-constraints.js.map +1 -1
- package/dist/domain/workflowexecution/controller.d.ts.map +1 -1
- package/dist/domain/workflowexecution/controller.js +4 -2
- package/dist/domain/workflowexecution/controller.js.map +1 -1
- package/dist/domain/workflowinstance/controller.d.ts.map +1 -1
- package/dist/domain/workflowinstance/controller.js +3 -4
- package/dist/domain/workflowinstance/controller.js.map +1 -1
- package/dist/extensions/authorization-queries.d.ts +6 -5
- package/dist/extensions/authorization-queries.d.ts.map +1 -1
- package/dist/extensions/list-read-scope.d.ts +1 -1
- package/dist/extensions/resource-authorization.d.ts +3 -2
- package/dist/extensions/resource-authorization.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/pipeline/apiresource-meta.d.ts +12 -3
- package/dist/pipeline/apiresource-meta.d.ts.map +1 -1
- package/dist/pipeline/apiresource-meta.js +21 -10
- package/dist/pipeline/apiresource-meta.js.map +1 -1
- package/dist/pipeline/steps/authorization-tuples.d.ts +9 -3
- package/dist/pipeline/steps/authorization-tuples.d.ts.map +1 -1
- package/dist/pipeline/steps/authorization-tuples.js +9 -11
- package/dist/pipeline/steps/authorization-tuples.js.map +1 -1
- package/dist/pipeline/steps/references.d.ts +178 -20
- package/dist/pipeline/steps/references.d.ts.map +1 -1
- package/dist/pipeline/steps/references.js +344 -43
- package/dist/pipeline/steps/references.js.map +1 -1
- package/dist/query/search/controller.js +0 -1
- package/dist/query/search/controller.js.map +1 -1
- package/dist/query/search/criteria.d.ts +1 -5
- package/dist/query/search/criteria.d.ts.map +1 -1
- package/dist/query/search/criteria.js +3 -13
- package/dist/query/search/criteria.js.map +1 -1
- package/dist/query/search/handler.d.ts +5 -4
- package/dist/query/search/handler.d.ts.map +1 -1
- package/dist/query/search/handler.js +7 -6
- package/dist/query/search/handler.js.map +1 -1
- package/dist/query/search/query-store.d.ts.map +1 -1
- package/dist/query/search/query-store.js +0 -2
- package/dist/query/search/query-store.js.map +1 -1
- package/dist/store/interface.d.ts +3 -6
- package/dist/store/interface.d.ts.map +1 -1
- package/dist/store/interface.js.map +1 -1
- package/dist/store/postgres/migrations.d.ts +3 -1
- package/dist/store/postgres/migrations.d.ts.map +1 -1
- package/dist/store/postgres/migrations.js +35 -1
- package/dist/store/postgres/migrations.js.map +1 -1
- package/dist/store/postgres/store.d.ts.map +1 -1
- package/dist/store/postgres/store.js +4 -9
- package/dist/store/postgres/store.js.map +1 -1
- package/dist/store/public-visibility-retired.d.ts +67 -0
- package/dist/store/public-visibility-retired.d.ts.map +1 -0
- package/dist/store/public-visibility-retired.js +55 -0
- package/dist/store/public-visibility-retired.js.map +1 -0
- package/dist/store/sqlite/migrations.d.ts +3 -1
- package/dist/store/sqlite/migrations.d.ts.map +1 -1
- package/dist/store/sqlite/migrations.js +36 -1
- package/dist/store/sqlite/migrations.js.map +1 -1
- package/dist/store/sqlite/store.d.ts.map +1 -1
- package/dist/store/sqlite/store.js +4 -8
- package/dist/store/sqlite/store.js.map +1 -1
- package/package.json +6 -6
- package/src/authorization/README.md +24 -26
- package/src/authorization/__tests__/authorizer.test.ts +10 -9
- package/src/authorization/__tests__/derived-tuples.test.ts +4 -11
- package/src/authorization/__tests__/evaluator.test.ts +14 -73
- package/src/authorization/__tests__/facts.test.ts +2 -2
- package/src/authorization/__tests__/fixtures/fga/blueprint-private-visibility.fga.yaml +6 -98
- package/src/authorization/__tests__/fixtures/fga/default-instance-inheritance.fga.yaml +4 -61
- package/src/authorization/__tests__/fixtures/fga/org-admin-owner-inheritance.fga.yaml +1 -21
- package/src/authorization/__tests__/fixtures/fga/platform-visibility.fga.yaml +1 -25
- package/src/authorization/__tests__/fixtures/fga/workflow-execution-sharing.fga.yaml +1 -3
- package/src/authorization/__tests__/list-read-scope.test.ts +18 -17
- package/src/authorization/__tests__/store-tests.test.ts +1 -6
- package/src/authorization/__tests__/tuples.test.ts +12 -11
- package/src/authorization/authorizer.ts +4 -9
- package/src/authorization/derived-tuples.ts +14 -31
- package/src/authorization/evaluator.ts +8 -44
- package/src/authorization/list-read-scope.ts +5 -11
- package/src/authorization/model/agent.ts +2 -5
- package/src/authorization/model/agent_instance.ts +0 -2
- package/src/authorization/model/mcp_server.ts +0 -2
- package/src/authorization/model/plugin.ts +1 -4
- package/src/authorization/model/rewrite.ts +8 -13
- package/src/authorization/model/skill.ts +0 -2
- package/src/authorization/model/workflow.ts +0 -2
- package/src/authorization/model/workflow_instance.ts +0 -2
- package/src/authorization/organization-directory.ts +1 -3
- package/src/authorization/store-test-kit.ts +16 -75
- package/src/authorization/tuples.ts +16 -39
- package/src/domain/agent/__tests__/agent.test.ts +11 -4
- package/src/domain/agent/controller.ts +7 -7
- package/src/domain/agentchannel/__tests__/agentchannel.test.ts +223 -48
- package/src/domain/agentchannel/controller.ts +6 -1
- package/src/domain/agentexecution/controller.ts +6 -1
- package/src/domain/agentinstance/controller.ts +6 -12
- package/src/domain/agentshare/__tests__/agentshare.test.ts +196 -172
- package/src/domain/agentshare/__tests__/create-authorization.test.ts +16 -31
- package/src/domain/agentshare/constants.ts +14 -26
- package/src/domain/agentshare/controller.ts +6 -1
- package/src/domain/agentshare/steps.ts +41 -194
- package/src/domain/environment/controller.ts +5 -8
- package/src/domain/executioncontext/controller.ts +5 -1
- package/src/domain/mcpserver/__tests__/mcpserver.test.ts +115 -28
- package/src/domain/mcpserver/__tests__/oauth-handshake.test.ts +53 -18
- package/src/domain/mcpserver/controller.ts +6 -12
- package/src/domain/plugin/controller.ts +1 -8
- package/src/domain/plugin/push.ts +8 -16
- package/src/domain/schedule/controller.ts +6 -1
- package/src/domain/session/controller.ts +12 -4
- package/src/domain/skill/controller.ts +0 -7
- package/src/domain/workflow/__tests__/agent-call-references.test.ts +222 -0
- package/src/domain/workflow/agent-call-references.ts +157 -0
- package/src/domain/workflow/controller.ts +28 -10
- package/src/domain/workflow/registry/data/task-kind-registry.json +1 -1
- package/src/domain/workflow/validation/task-config-constraints.ts +7 -3
- package/src/domain/workflowexecution/controller.ts +7 -2
- package/src/domain/workflowinstance/controller.ts +6 -12
- package/src/extensions/__tests__/built-in-authorization-composed.test.ts +32 -19
- package/src/extensions/__tests__/extension-composition.test.ts +4 -4
- package/src/extensions/__tests__/list-read-scope-composed.test.ts +9 -6
- package/src/extensions/authorization-queries.ts +6 -5
- package/src/extensions/list-read-scope.ts +1 -1
- package/src/extensions/resource-authorization.ts +3 -5
- package/src/index.ts +0 -1
- package/src/pipeline/__tests__/supports-visibility.test.ts +112 -0
- package/src/pipeline/apiresource-meta.ts +21 -10
- package/src/pipeline/steps/__tests__/authorization-tuples.test.ts +18 -31
- package/src/pipeline/steps/__tests__/references.test.ts +703 -0
- package/src/pipeline/steps/authorization-tuples.ts +9 -11
- package/src/pipeline/steps/references.ts +578 -70
- package/src/query/search/__tests__/criteria.test.ts +0 -4
- package/src/query/search/__tests__/query-store.test.ts +11 -40
- package/src/query/search/controller.ts +0 -1
- package/src/query/search/criteria.ts +0 -14
- package/src/query/search/handler.ts +6 -7
- package/src/query/search/query-store.ts +0 -2
- package/src/store/__tests__/public-visibility-retired.test.ts +127 -0
- package/src/store/__tests__/store-contract.ts +6 -51
- package/src/store/interface.ts +3 -6
- package/src/store/postgres/__tests__/migrations.test.ts +187 -6
- package/src/store/postgres/__tests__/store-contract.test.ts +0 -2
- package/src/store/postgres/migrations.ts +48 -1
- package/src/store/postgres/store.ts +4 -11
- package/src/store/public-visibility-retired.ts +119 -0
- package/src/store/sqlite/__tests__/migrations.test.ts +191 -5
- package/src/store/sqlite/migrations.ts +45 -1
- package/src/store/sqlite/store.ts +4 -10
- package/dist/pipeline/steps/visibility-gates.d.ts +0 -27
- package/dist/pipeline/steps/visibility-gates.d.ts.map +0 -1
- package/dist/pipeline/steps/visibility-gates.js +0 -139
- package/dist/pipeline/steps/visibility-gates.js.map +0 -1
- package/src/authorization/__tests__/fixtures/fga/cross-org-share-creation.fga.yaml +0 -98
- package/src/authorization/__tests__/fixtures/fga/public-visibility-setter.fga.yaml +0 -52
- package/src/pipeline/steps/__tests__/visibility-gates.test.ts +0 -187
- package/src/pipeline/steps/visibility-gates.ts +0 -174
|
@@ -41,7 +41,11 @@ import { composeServer } from "../../../boot/compose.js";
|
|
|
41
41
|
import type { ComposedServer } from "../../../boot/compose.js";
|
|
42
42
|
import { createLogger } from "../../../boot/logger.js";
|
|
43
43
|
|
|
44
|
-
const silentLogger = createLogger({
|
|
44
|
+
const silentLogger = createLogger({
|
|
45
|
+
level: "error",
|
|
46
|
+
pretty: false,
|
|
47
|
+
write: () => {},
|
|
48
|
+
});
|
|
45
49
|
|
|
46
50
|
const API_VERSION = "agentic.stigmer.ai/v1";
|
|
47
51
|
const KIND = "McpServer";
|
|
@@ -128,7 +132,11 @@ function serverInput(overrides?: {
|
|
|
128
132
|
};
|
|
129
133
|
}
|
|
130
134
|
|
|
131
|
-
async function expectCode(
|
|
135
|
+
async function expectCode(
|
|
136
|
+
promise: Promise<unknown>,
|
|
137
|
+
code: Code,
|
|
138
|
+
arm: string,
|
|
139
|
+
): Promise<ConnectError> {
|
|
132
140
|
try {
|
|
133
141
|
await promise;
|
|
134
142
|
} catch (error) {
|
|
@@ -157,7 +165,10 @@ async function seedCapabilities(
|
|
|
157
165
|
serverId,
|
|
158
166
|
McpServerSchema,
|
|
159
167
|
);
|
|
160
|
-
const patched = fromBinary(
|
|
168
|
+
const patched = fromBinary(
|
|
169
|
+
McpServerSchema,
|
|
170
|
+
toBinary(McpServerSchema, stored),
|
|
171
|
+
);
|
|
161
172
|
patched.status ??= create(McpServerStatusSchema, {});
|
|
162
173
|
patched.status.discoveredCapabilities = create(DiscoveredCapabilitiesSchema, {
|
|
163
174
|
tools: tools.map((name) => ({ name })),
|
|
@@ -176,13 +187,19 @@ describe("CRUD", () => {
|
|
|
176
187
|
const created = await command.create(serverInput({ name: "GitHub Tools" }));
|
|
177
188
|
expect(created.metadata?.id).toMatch(/^mcp_[0-9a-z]{26}$/);
|
|
178
189
|
expect(created.metadata?.slug).toBe("github-tools");
|
|
179
|
-
expect(created.metadata?.visibility).toBe(
|
|
190
|
+
expect(created.metadata?.visibility).toBe(
|
|
191
|
+
ApiResourceVisibility.visibility_org,
|
|
192
|
+
);
|
|
180
193
|
});
|
|
181
194
|
|
|
182
195
|
it("rejects a duplicate create by slug within the org; a different org reuses the slug", async () => {
|
|
183
196
|
const name = `Dup Target ${++counter}`;
|
|
184
197
|
await command.create(serverInput({ name }));
|
|
185
|
-
await expectCode(
|
|
198
|
+
await expectCode(
|
|
199
|
+
command.create(serverInput({ name })),
|
|
200
|
+
Code.AlreadyExists,
|
|
201
|
+
"duplicate create",
|
|
202
|
+
);
|
|
186
203
|
const other = await command.create(serverInput({ name, org: "other-org" }));
|
|
187
204
|
expect(other.metadata?.org).toBe("other-org");
|
|
188
205
|
});
|
|
@@ -201,10 +218,17 @@ describe("CRUD", () => {
|
|
|
201
218
|
it("get and getByReference resolve the same resource; unknowns answer NotFound", async () => {
|
|
202
219
|
const created = await command.create(serverInput());
|
|
203
220
|
const byId = await query.get({ value: created.metadata!.id });
|
|
204
|
-
const byRef = await query.getByReference({
|
|
221
|
+
const byRef = await query.getByReference({
|
|
222
|
+
org: ORG,
|
|
223
|
+
slug: created.metadata!.slug,
|
|
224
|
+
});
|
|
205
225
|
expect(byId.metadata?.id).toBe(created.metadata?.id);
|
|
206
226
|
expect(byRef.metadata?.id).toBe(created.metadata?.id);
|
|
207
|
-
await expectCode(
|
|
227
|
+
await expectCode(
|
|
228
|
+
query.get({ value: "mcps_missing" }),
|
|
229
|
+
Code.NotFound,
|
|
230
|
+
"get unknown",
|
|
231
|
+
);
|
|
208
232
|
await expectCode(
|
|
209
233
|
query.getByReference({ org: ORG, slug: "never-created" }),
|
|
210
234
|
Code.NotFound,
|
|
@@ -216,7 +240,11 @@ describe("CRUD", () => {
|
|
|
216
240
|
const created = await command.create(serverInput());
|
|
217
241
|
const deleted = await command.delete({ resourceId: created.metadata!.id });
|
|
218
242
|
expect(deleted.metadata?.id).toBe(created.metadata?.id);
|
|
219
|
-
await expectCode(
|
|
243
|
+
await expectCode(
|
|
244
|
+
query.get({ value: created.metadata!.id }),
|
|
245
|
+
Code.NotFound,
|
|
246
|
+
"get after delete",
|
|
247
|
+
);
|
|
220
248
|
});
|
|
221
249
|
|
|
222
250
|
it("update of a non-existent server and delete of a non-existent server answer NotFound; delete with an empty id is InvalidArgument", async () => {
|
|
@@ -233,7 +261,11 @@ describe("CRUD", () => {
|
|
|
233
261
|
Code.NotFound,
|
|
234
262
|
"delete non-existent",
|
|
235
263
|
);
|
|
236
|
-
await expectCode(
|
|
264
|
+
await expectCode(
|
|
265
|
+
command.delete({}),
|
|
266
|
+
Code.InvalidArgument,
|
|
267
|
+
"delete empty id",
|
|
268
|
+
);
|
|
237
269
|
});
|
|
238
270
|
});
|
|
239
271
|
|
|
@@ -244,13 +276,17 @@ describe("updateVisibility (no conformance coverage for this domain — the D4-d
|
|
|
244
276
|
resourceId: created.metadata!.id,
|
|
245
277
|
visibility: ApiResourceVisibility.visibility_private,
|
|
246
278
|
});
|
|
247
|
-
expect(updated.metadata?.visibility).toBe(
|
|
279
|
+
expect(updated.metadata?.visibility).toBe(
|
|
280
|
+
ApiResourceVisibility.visibility_private,
|
|
281
|
+
);
|
|
248
282
|
expect(updated.spec?.description).toBe(created.spec?.description);
|
|
249
283
|
// A visibility change is a STATUS mutation: status_audit re-stamped
|
|
250
284
|
// (updated event, fresh timestamp bounds are creation-or-later),
|
|
251
285
|
// spec_audit byte-untouched.
|
|
252
286
|
expect(updated.status?.audit?.statusAudit?.event).toBe("updated");
|
|
253
|
-
expect(updated.status?.audit?.specAudit).toEqual(
|
|
287
|
+
expect(updated.status?.audit?.specAudit).toEqual(
|
|
288
|
+
created.status?.audit?.specAudit,
|
|
289
|
+
);
|
|
254
290
|
});
|
|
255
291
|
|
|
256
292
|
it("answers NotFound for an unknown id", async () => {
|
|
@@ -296,7 +332,9 @@ describe("ValidateDefaultEnabledTools (#402)", () => {
|
|
|
296
332
|
it("accepts names the server exposes; skips when the list is empty or the server never connected", async () => {
|
|
297
333
|
// Never connected: any names pass (no authoritative toolset yet).
|
|
298
334
|
const fresh = await command.create(serverInput());
|
|
299
|
-
const freshUpdate = await command.update(
|
|
335
|
+
const freshUpdate = await command.update(
|
|
336
|
+
updateInput(fresh, ["anything-goes"]),
|
|
337
|
+
);
|
|
300
338
|
expect(freshUpdate.spec?.defaultEnabledTools).toEqual(["anything-goes"]);
|
|
301
339
|
|
|
302
340
|
// Connected: valid names pass.
|
|
@@ -308,7 +346,11 @@ describe("ValidateDefaultEnabledTools (#402)", () => {
|
|
|
308
346
|
|
|
309
347
|
it("rejects unknown tools and resource templates with the byte-pinned teaching copy", async () => {
|
|
310
348
|
const created = await command.create(serverInput());
|
|
311
|
-
await seedCapabilities(
|
|
349
|
+
await seedCapabilities(
|
|
350
|
+
created.metadata!.id,
|
|
351
|
+
["search", "fetch"],
|
|
352
|
+
["files"],
|
|
353
|
+
);
|
|
312
354
|
|
|
313
355
|
const err = await expectCode(
|
|
314
356
|
command.update(updateInput(created, ["serch", "files"])),
|
|
@@ -334,7 +376,10 @@ describe("EnrichOAuthStatus (#523) — response-only oauth_status", () => {
|
|
|
334
376
|
OAuthAppSchema,
|
|
335
377
|
create(OAuthAppSchema, {
|
|
336
378
|
metadata: { id, org: ORG, slug, name: slug },
|
|
337
|
-
spec: {
|
|
379
|
+
spec: {
|
|
380
|
+
vendorApprovalStatus: approval,
|
|
381
|
+
vendorApprovalDocsUrl: docsUrl,
|
|
382
|
+
},
|
|
338
383
|
}),
|
|
339
384
|
);
|
|
340
385
|
}
|
|
@@ -346,14 +391,25 @@ describe("EnrichOAuthStatus (#523) — response-only oauth_status", () => {
|
|
|
346
391
|
});
|
|
347
392
|
|
|
348
393
|
it("a missing OAuthApp skips enrichment (the initiate path owns refusing)", async () => {
|
|
349
|
-
|
|
394
|
+
// The app must exist when the server is written (the reference rule);
|
|
395
|
+
// a reference dangles when its target leaves afterwards.
|
|
396
|
+
await seedOAuthApp("never-applied", VendorApprovalStatus.UNSPECIFIED, "");
|
|
397
|
+
const created = await command.create(
|
|
398
|
+
serverInput({ oauthAppSlug: "never-applied" }),
|
|
399
|
+
);
|
|
400
|
+
await server.store.deleteResource(
|
|
401
|
+
ApiResourceKind.oauth_app,
|
|
402
|
+
"oaa_neverapplied",
|
|
403
|
+
);
|
|
350
404
|
const got = await query.get({ value: created.metadata!.id });
|
|
351
405
|
expect(got.status?.oauthStatus).toBeUndefined();
|
|
352
406
|
});
|
|
353
407
|
|
|
354
408
|
it("nothing-to-report means ABSENT — presence itself is the SDK's signal", async () => {
|
|
355
409
|
await seedOAuthApp("plain-app", VendorApprovalStatus.UNSPECIFIED, "");
|
|
356
|
-
const created = await command.create(
|
|
410
|
+
const created = await command.create(
|
|
411
|
+
serverInput({ oauthAppSlug: "plain-app" }),
|
|
412
|
+
);
|
|
357
413
|
const got = await query.get({ value: created.metadata!.id });
|
|
358
414
|
expect(got.status?.oauthStatus).toBeUndefined();
|
|
359
415
|
});
|
|
@@ -363,24 +419,42 @@ describe("EnrichOAuthStatus (#523) — response-only oauth_status", () => {
|
|
|
363
419
|
// alone must enrich (Go enrich_oauth_status_test.go's docs-only and
|
|
364
420
|
// status-only arms — the executable spec of the #523 shared contract).
|
|
365
421
|
it("a docs URL ALONE enriches, even with an UNSPECIFIED approval status", async () => {
|
|
366
|
-
await seedOAuthApp(
|
|
367
|
-
|
|
422
|
+
await seedOAuthApp(
|
|
423
|
+
"docs-only-app",
|
|
424
|
+
VendorApprovalStatus.UNSPECIFIED,
|
|
425
|
+
"https://vendor.example/setup",
|
|
426
|
+
);
|
|
427
|
+
const created = await command.create(
|
|
428
|
+
serverInput({ oauthAppSlug: "docs-only-app" }),
|
|
429
|
+
);
|
|
368
430
|
const got = await query.get({ value: created.metadata!.id });
|
|
369
|
-
expect(got.status?.oauthStatus?.vendorApprovalStatus).toBe(
|
|
370
|
-
|
|
431
|
+
expect(got.status?.oauthStatus?.vendorApprovalStatus).toBe(
|
|
432
|
+
VendorApprovalStatus.UNSPECIFIED,
|
|
433
|
+
);
|
|
434
|
+
expect(got.status?.oauthStatus?.vendorApprovalDocsUrl).toBe(
|
|
435
|
+
"https://vendor.example/setup",
|
|
436
|
+
);
|
|
371
437
|
});
|
|
372
438
|
|
|
373
439
|
it("a non-default approval status ALONE enriches — REJECTED and even APPROVED are reported", async () => {
|
|
374
440
|
await seedOAuthApp("rejected-app", VendorApprovalStatus.REJECTED, "");
|
|
375
|
-
const rejected = await command.create(
|
|
441
|
+
const rejected = await command.create(
|
|
442
|
+
serverInput({ oauthAppSlug: "rejected-app" }),
|
|
443
|
+
);
|
|
376
444
|
const gotRejected = await query.get({ value: rejected.metadata!.id });
|
|
377
|
-
expect(gotRejected.status?.oauthStatus?.vendorApprovalStatus).toBe(
|
|
445
|
+
expect(gotRejected.status?.oauthStatus?.vendorApprovalStatus).toBe(
|
|
446
|
+
VendorApprovalStatus.REJECTED,
|
|
447
|
+
);
|
|
378
448
|
expect(gotRejected.status?.oauthStatus?.vendorApprovalDocsUrl).toBe("");
|
|
379
449
|
|
|
380
450
|
await seedOAuthApp("approved-app", VendorApprovalStatus.APPROVED, "");
|
|
381
|
-
const approved = await command.create(
|
|
451
|
+
const approved = await command.create(
|
|
452
|
+
serverInput({ oauthAppSlug: "approved-app" }),
|
|
453
|
+
);
|
|
382
454
|
const gotApproved = await query.get({ value: approved.metadata!.id });
|
|
383
|
-
expect(gotApproved.status?.oauthStatus?.vendorApprovalStatus).toBe(
|
|
455
|
+
expect(gotApproved.status?.oauthStatus?.vendorApprovalStatus).toBe(
|
|
456
|
+
VendorApprovalStatus.APPROVED,
|
|
457
|
+
);
|
|
384
458
|
});
|
|
385
459
|
|
|
386
460
|
it("an auth block WITHOUT an oauth_app_ref (the DCR arm) is untouched", async () => {
|
|
@@ -391,8 +465,14 @@ describe("EnrichOAuthStatus (#523) — response-only oauth_status", () => {
|
|
|
391
465
|
});
|
|
392
466
|
|
|
393
467
|
it("a gating approval status or docs URL enriches BOTH read paths, response-only", async () => {
|
|
394
|
-
await seedOAuthApp(
|
|
395
|
-
|
|
468
|
+
await seedOAuthApp(
|
|
469
|
+
"gated-app",
|
|
470
|
+
VendorApprovalStatus.PENDING,
|
|
471
|
+
"https://vendor.example/approval",
|
|
472
|
+
);
|
|
473
|
+
const created = await command.create(
|
|
474
|
+
serverInput({ oauthAppSlug: "gated-app" }),
|
|
475
|
+
);
|
|
396
476
|
|
|
397
477
|
for (const loaded of [
|
|
398
478
|
await query.get({ value: created.metadata!.id }),
|
|
@@ -430,7 +510,12 @@ describe("org-OAuth-app surface — UNIMPLEMENTED by design (#558, DD-019)", ()
|
|
|
430
510
|
expect(getErr.rawMessage).toBe("method GetOrgOAuthApp not implemented");
|
|
431
511
|
|
|
432
512
|
const setErr = await expectCode(
|
|
433
|
-
command.setOrgOAuthApp({
|
|
513
|
+
command.setOrgOAuthApp({
|
|
514
|
+
resourceId: "mcps_test",
|
|
515
|
+
org: ORG,
|
|
516
|
+
clientId: "x",
|
|
517
|
+
clientSecret: "y",
|
|
518
|
+
}),
|
|
434
519
|
Code.Unimplemented,
|
|
435
520
|
"setOrgOAuthApp",
|
|
436
521
|
);
|
|
@@ -441,6 +526,8 @@ describe("org-OAuth-app surface — UNIMPLEMENTED by design (#558, DD-019)", ()
|
|
|
441
526
|
Code.Unimplemented,
|
|
442
527
|
"deleteOrgOAuthApp",
|
|
443
528
|
);
|
|
444
|
-
expect(deleteErr.rawMessage).toBe(
|
|
529
|
+
expect(deleteErr.rawMessage).toBe(
|
|
530
|
+
"method DeleteOrgOAuthApp not implemented",
|
|
531
|
+
);
|
|
445
532
|
});
|
|
446
533
|
});
|
|
@@ -41,7 +41,11 @@ import { composeServer } from "../../../boot/compose.js";
|
|
|
41
41
|
import type { ComposedServer } from "../../../boot/compose.js";
|
|
42
42
|
import { createLogger } from "../../../boot/logger.js";
|
|
43
43
|
|
|
44
|
-
const silentLogger = createLogger({
|
|
44
|
+
const silentLogger = createLogger({
|
|
45
|
+
level: "error",
|
|
46
|
+
pretty: false,
|
|
47
|
+
write: () => {},
|
|
48
|
+
});
|
|
45
49
|
|
|
46
50
|
const REDIRECT_URI = "http://127.0.0.1:8234/auth/oauth/callback";
|
|
47
51
|
const ORG = "acme";
|
|
@@ -368,20 +372,30 @@ describe("initiateOAuthConnect", () => {
|
|
|
368
372
|
"OAuth sign-in is unavailable: the platform's OAuth app for 'exampleco' is pending approval by the vendor. This server only accepts OAuth sign-in; an org admin can configure your own OAuth app instead.",
|
|
369
373
|
],
|
|
370
374
|
];
|
|
371
|
-
it.each(refusals)(
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
375
|
+
it.each(refusals)(
|
|
376
|
+
"vendor arm refuses %s",
|
|
377
|
+
async (_label, status, oauthOnly, copy) => {
|
|
378
|
+
const slug = `vendor-${status}-${oauthOnly ? "only" : "manual"}`;
|
|
379
|
+
await seedOAuthApp(slug, status);
|
|
380
|
+
const id = await applyServer({ vendorSlug: slug, oauthOnly });
|
|
381
|
+
const error = await expectCode(
|
|
382
|
+
command.initiateOAuthConnect({ mcpServerId: id, org: ORG }),
|
|
383
|
+
Code.FailedPrecondition,
|
|
384
|
+
copy,
|
|
385
|
+
);
|
|
386
|
+
expect(error.rawMessage).toBe(copy);
|
|
387
|
+
},
|
|
388
|
+
);
|
|
382
389
|
|
|
383
390
|
it("vendor arm answers NotFound for an unresolvable oauth_app_ref", async () => {
|
|
391
|
+
// The app must exist when the server is written (the reference rule);
|
|
392
|
+
// the reference becomes unresolvable when its target leaves afterwards.
|
|
393
|
+
await seedOAuthApp("no-such-app", VendorApprovalStatus.APPROVED);
|
|
384
394
|
const id = await applyServer({ vendorSlug: "no-such-app" });
|
|
395
|
+
await server.store.deleteResource(
|
|
396
|
+
ApiResourceKind.oauth_app,
|
|
397
|
+
"oap_no-such-app",
|
|
398
|
+
);
|
|
385
399
|
await expectCode(
|
|
386
400
|
command.initiateOAuthConnect({ mcpServerId: id, org: ORG }),
|
|
387
401
|
Code.NotFound,
|
|
@@ -406,17 +420,29 @@ describe("initiateOAuthConnect", () => {
|
|
|
406
420
|
describe("completeOAuthConnect → grant → disconnect (the full lifecycle)", () => {
|
|
407
421
|
it("guards its inputs (proto rules answer first, exactly as on Go)", async () => {
|
|
408
422
|
await expectCode(
|
|
409
|
-
command.completeOAuthConnect({
|
|
423
|
+
command.completeOAuthConnect({
|
|
424
|
+
mcpServerId: "",
|
|
425
|
+
state: "s",
|
|
426
|
+
authorizationCode: "c",
|
|
427
|
+
}),
|
|
410
428
|
Code.InvalidArgument,
|
|
411
429
|
"mcp_server_id: value is required [required]",
|
|
412
430
|
);
|
|
413
431
|
await expectCode(
|
|
414
|
-
command.completeOAuthConnect({
|
|
432
|
+
command.completeOAuthConnect({
|
|
433
|
+
mcpServerId: "m",
|
|
434
|
+
state: "",
|
|
435
|
+
authorizationCode: "c",
|
|
436
|
+
}),
|
|
415
437
|
Code.InvalidArgument,
|
|
416
438
|
"state:",
|
|
417
439
|
);
|
|
418
440
|
await expectCode(
|
|
419
|
-
command.completeOAuthConnect({
|
|
441
|
+
command.completeOAuthConnect({
|
|
442
|
+
mcpServerId: "m",
|
|
443
|
+
state: "s",
|
|
444
|
+
authorizationCode: "",
|
|
445
|
+
}),
|
|
420
446
|
Code.InvalidArgument,
|
|
421
447
|
"authorization_code:",
|
|
422
448
|
);
|
|
@@ -500,7 +526,10 @@ describe("completeOAuthConnect → grant → disconnect (the full lifecycle)", (
|
|
|
500
526
|
|
|
501
527
|
// The grant is queryable and HEALTHY; the refresh-token env var is
|
|
502
528
|
// stamped unconditionally (oss#863's precondition, ported as-is).
|
|
503
|
-
const status = await query.getOAuthGrantStatus({
|
|
529
|
+
const status = await query.getOAuthGrantStatus({
|
|
530
|
+
resourceId: id,
|
|
531
|
+
org: ORG,
|
|
532
|
+
});
|
|
504
533
|
expect(status.connected).toBe(true);
|
|
505
534
|
expect(status.targetEnvVar).toBe("EXAMPLE_TOKEN");
|
|
506
535
|
expect(status.authMethod).toBe("mcp_oauth");
|
|
@@ -514,7 +543,10 @@ describe("completeOAuthConnect → grant → disconnect (the full lifecycle)", (
|
|
|
514
543
|
expect(firstEnvId).not.toBe("");
|
|
515
544
|
|
|
516
545
|
// Re-connect reuses the managed environment.
|
|
517
|
-
const again = await command.initiateOAuthConnect({
|
|
546
|
+
const again = await command.initiateOAuthConnect({
|
|
547
|
+
mcpServerId: id,
|
|
548
|
+
org: ORG,
|
|
549
|
+
});
|
|
518
550
|
await command.completeOAuthConnect({
|
|
519
551
|
mcpServerId: id,
|
|
520
552
|
state: again.state,
|
|
@@ -525,7 +557,10 @@ describe("completeOAuthConnect → grant → disconnect (the full lifecycle)", (
|
|
|
525
557
|
|
|
526
558
|
// Disconnect tears down grant + environment; a second disconnect is
|
|
527
559
|
// the idempotent no-grant arm.
|
|
528
|
-
const disconnected = await command.disconnectOAuth({
|
|
560
|
+
const disconnected = await command.disconnectOAuth({
|
|
561
|
+
resourceId: id,
|
|
562
|
+
org: ORG,
|
|
563
|
+
});
|
|
529
564
|
expect(disconnected.disconnected).toBe(true);
|
|
530
565
|
expect(await server.store.oauthGrants.find("", id, ORG)).toBeUndefined();
|
|
531
566
|
const againDisconnected = await command.disconnectOAuth({
|
|
@@ -58,10 +58,6 @@ import {
|
|
|
58
58
|
newAuthorizeResolvedTargetStep,
|
|
59
59
|
} from "../../pipeline/steps/authorize-resolved-target.js";
|
|
60
60
|
import { newGuardReservedLabelsStep } from "../../pipeline/steps/guard-reserved-labels.js";
|
|
61
|
-
import {
|
|
62
|
-
newAuthorizeVisibilityTransitionStep,
|
|
63
|
-
newGuardPublicVisibilityStep,
|
|
64
|
-
} from "../../pipeline/steps/visibility-gates.js";
|
|
65
61
|
import {
|
|
66
62
|
setAuditFieldsForUpdate,
|
|
67
63
|
newBuildNewStateStep,
|
|
@@ -92,7 +88,10 @@ import {
|
|
|
92
88
|
TARGET_RESOURCE_KEY,
|
|
93
89
|
newLoadTargetStep,
|
|
94
90
|
} from "../../pipeline/steps/load-target.js";
|
|
95
|
-
import {
|
|
91
|
+
import {
|
|
92
|
+
newNormalizeReferencesStep,
|
|
93
|
+
newValidateReferencesStep,
|
|
94
|
+
} from "../../pipeline/steps/references.js";
|
|
96
95
|
import {
|
|
97
96
|
newCleanupIamPoliciesStep,
|
|
98
97
|
newCreateAuthorizationTuplesStep,
|
|
@@ -241,13 +240,13 @@ async function createMcpServer(
|
|
|
241
240
|
.addStep(newResolveSlugStep())
|
|
242
241
|
.addStep(newCheckDuplicateStep(deps.store))
|
|
243
242
|
.addStep(newBuildNewStateStep())
|
|
244
|
-
.addStep(newGuardPublicVisibilityStep(deps.authorizer))
|
|
245
243
|
// A URL-only server is asked once whether it wants OAuth and completed
|
|
246
244
|
// when it does; immediately before GuardReservedLabels because the
|
|
247
245
|
// provenance label it stamps is one the guard diffs.
|
|
248
246
|
.addStep(newCompleteEndpointAuthStep(endpointAuthDeps(deps)))
|
|
249
247
|
.addStep(newGuardReservedLabelsStep(deps.authorizer))
|
|
250
248
|
.addStep(newNormalizeReferencesStep())
|
|
249
|
+
.addStep(newValidateReferencesStep(deps.store))
|
|
251
250
|
.addStep(newPersistStep(deps.store))
|
|
252
251
|
.addStep(
|
|
253
252
|
newCreateAuthorizationTuplesStep(
|
|
@@ -300,6 +299,7 @@ async function update(
|
|
|
300
299
|
.addStep(newGuardReservedLabelsStep(deps.authorizer))
|
|
301
300
|
.addStep(newValidateDefaultEnabledToolsStep())
|
|
302
301
|
.addStep(newNormalizeReferencesStep())
|
|
302
|
+
.addStep(newValidateReferencesStep(deps.store))
|
|
303
303
|
.addStep(newPersistStep(deps.store))
|
|
304
304
|
.addStep(
|
|
305
305
|
newIndexSearchStep(deps.store, mcpServerSearchExtractor, deps.logger),
|
|
@@ -463,12 +463,6 @@ async function updateVisibility(
|
|
|
463
463
|
newRecordVisibilityBeforeUpdateStep(UPDATE_VISIBILITY_MCP_SERVER_KEY),
|
|
464
464
|
)
|
|
465
465
|
.addStep(newValidateVisibilityUpdateStep())
|
|
466
|
-
.addStep(
|
|
467
|
-
newAuthorizeVisibilityTransitionStep(
|
|
468
|
-
UPDATE_VISIBILITY_MCP_SERVER_KEY,
|
|
469
|
-
deps.authorizer,
|
|
470
|
-
),
|
|
471
|
-
)
|
|
472
466
|
.addStep(newSetMcpServerVisibilityStep())
|
|
473
467
|
.addStep(newPersistMcpServerForVisibilityUpdateStep(deps.store))
|
|
474
468
|
.addStep(
|
|
@@ -103,7 +103,6 @@ import {
|
|
|
103
103
|
newAuthorizeResolvedTargetStep,
|
|
104
104
|
} from "../../pipeline/steps/authorize-resolved-target.js";
|
|
105
105
|
import type { VersionHistoryBinding } from "../../pipeline/steps/version-history.js";
|
|
106
|
-
import { newAuthorizeVisibilityTransitionStep } from "../../pipeline/steps/visibility-gates.js";
|
|
107
106
|
import { metadataOf } from "../../pipeline/steps/shapes.js";
|
|
108
107
|
import type { Store } from "../../store/interface.js";
|
|
109
108
|
import { uploadUrl } from "../skill/transfer/handler.js";
|
|
@@ -226,7 +225,7 @@ async function push(
|
|
|
226
225
|
.addStep(newParseOverlayDocumentsStep())
|
|
227
226
|
.addStep(newSanitizePluginMetadataStep(deps.authorizer))
|
|
228
227
|
.addStep(newPlanMaterializationStep(deps.store, deps.authorizer))
|
|
229
|
-
.addStep(newGuardPluginVisibilityStep(
|
|
228
|
+
.addStep(newGuardPluginVisibilityStep())
|
|
230
229
|
.addStep(newResolveConvergenceStep())
|
|
231
230
|
.build()
|
|
232
231
|
.execute(reqCtx);
|
|
@@ -359,12 +358,6 @@ async function updateVisibility(
|
|
|
359
358
|
.addStep(newLoadPluginByIdStep(deps.store, UPDATE_VISIBILITY_PLUGIN_KEY))
|
|
360
359
|
.addStep(newRecordVisibilityBeforeUpdateStep(UPDATE_VISIBILITY_PLUGIN_KEY))
|
|
361
360
|
.addStep(newValidateVisibilityUpdateStep())
|
|
362
|
-
.addStep(
|
|
363
|
-
newAuthorizeVisibilityTransitionStep(
|
|
364
|
-
UPDATE_VISIBILITY_PLUGIN_KEY,
|
|
365
|
-
deps.authorizer,
|
|
366
|
-
),
|
|
367
|
-
)
|
|
368
361
|
.addStep(newSetPluginVisibilityStep())
|
|
369
362
|
.addStep(
|
|
370
363
|
newPersistPluginStep(
|
|
@@ -94,7 +94,6 @@ import { ARTIFACT_BYTES_KEY } from "../../pipeline/steps/resolve-artifact-source
|
|
|
94
94
|
import { generateSlug } from "../../pipeline/steps/slug.js";
|
|
95
95
|
import { rejectUnsupportedVisibility } from "../../pipeline/steps/validate-visibility.js";
|
|
96
96
|
import { newArchiveCurrentVersionStep } from "../../pipeline/steps/version-archive.js";
|
|
97
|
-
import { requireOperatorMaySetPublic } from "../../pipeline/steps/visibility-gates.js";
|
|
98
97
|
import { ResourceNotFoundError } from "../../store/interface.js";
|
|
99
98
|
import type { Store } from "../../store/interface.js";
|
|
100
99
|
import { openPluginArchive } from "./archive.js";
|
|
@@ -493,30 +492,23 @@ export function newPlanMaterializationStep(
|
|
|
493
492
|
|
|
494
493
|
/**
|
|
495
494
|
* GuardPluginVisibility — the requested level must be one the plugin and
|
|
496
|
-
* every planned member kind support
|
|
497
|
-
*
|
|
498
|
-
*
|
|
499
|
-
*
|
|
495
|
+
* every planned member kind support: the push chain's counterpart of the
|
|
496
|
+
* ValidateVisibility step on the resource create chains, asked here for
|
|
497
|
+
* the head and for each member kind before anything is written, so a
|
|
498
|
+
* plugin cannot be installed at a level one of its members may not hold.
|
|
499
|
+
* Each member's own chain checks again in-process; refusing here keeps the
|
|
500
|
+
* head from being written before the answer is known.
|
|
500
501
|
*/
|
|
501
|
-
export function newGuardPluginVisibilityStep(
|
|
502
|
-
authorizer: Authorizer,
|
|
503
|
-
): PipelineStep<PushDesc> {
|
|
502
|
+
export function newGuardPluginVisibilityStep(): PipelineStep<PushDesc> {
|
|
504
503
|
return {
|
|
505
504
|
name: "GuardPluginVisibility",
|
|
506
|
-
|
|
505
|
+
execute(ctx: RequestContext<PushDesc>): void {
|
|
507
506
|
const level = requestedVisibility(ctx);
|
|
508
507
|
const plan = ctx.get(PLUGIN_PLAN_KEY) as MaterializationPlan;
|
|
509
508
|
rejectUnsupportedVisibility(ctx.apiResourceKind, level);
|
|
510
509
|
for (const kind of new Set(plan.members.map((member) => member.kind))) {
|
|
511
510
|
rejectUnsupportedVisibility(kind, level);
|
|
512
511
|
}
|
|
513
|
-
if (level !== ApiResourceVisibility.visibility_public) {
|
|
514
|
-
return;
|
|
515
|
-
}
|
|
516
|
-
if (ctx.callerIdentity.callerClass === "internal") {
|
|
517
|
-
return;
|
|
518
|
-
}
|
|
519
|
-
await requireOperatorMaySetPublic(authorizer, ctx.callerIdentity);
|
|
520
512
|
},
|
|
521
513
|
};
|
|
522
514
|
}
|
|
@@ -97,7 +97,10 @@ import {
|
|
|
97
97
|
newCreateAuthorizationTuplesStep,
|
|
98
98
|
} from "../../pipeline/steps/authorization-tuples.js";
|
|
99
99
|
import { newPersistStep } from "../../pipeline/steps/persist.js";
|
|
100
|
-
import {
|
|
100
|
+
import {
|
|
101
|
+
newNormalizeReferencesStep,
|
|
102
|
+
newValidateReferencesStep,
|
|
103
|
+
} from "../../pipeline/steps/references.js";
|
|
101
104
|
import { newResolveSlugStep } from "../../pipeline/steps/slug.js";
|
|
102
105
|
import { newValidateProtoStep } from "../../pipeline/steps/validation.js";
|
|
103
106
|
import { newValidateVisibilityStep } from "../../pipeline/steps/validate-visibility.js";
|
|
@@ -220,6 +223,7 @@ async function createSchedule(
|
|
|
220
223
|
.addStep(newBuildNewStateStep())
|
|
221
224
|
.addStep(newGuardReservedLabelsStep(deps.authorizer))
|
|
222
225
|
.addStep(newNormalizeReferencesStep())
|
|
226
|
+
.addStep(newValidateReferencesStep(deps.store))
|
|
223
227
|
.addStep(newPersistStep(deps.store))
|
|
224
228
|
.addStep(
|
|
225
229
|
newCreateAuthorizationTuplesStep(
|
|
@@ -259,6 +263,7 @@ async function update(
|
|
|
259
263
|
.addStep(newBuildUpdateStateStep())
|
|
260
264
|
.addStep(newGuardReservedLabelsStep(deps.authorizer))
|
|
261
265
|
.addStep(newNormalizeReferencesStep())
|
|
266
|
+
.addStep(newValidateReferencesStep(deps.store))
|
|
262
267
|
.addStep(newPersistScheduleUpdateStep(deps.store))
|
|
263
268
|
.addStep(newArmScheduleStep(deps.clock, deps.logger))
|
|
264
269
|
.build()
|
|
@@ -85,7 +85,10 @@ import {
|
|
|
85
85
|
TARGET_RESOURCE_KEY,
|
|
86
86
|
newLoadTargetStep,
|
|
87
87
|
} from "../../pipeline/steps/load-target.js";
|
|
88
|
-
import {
|
|
88
|
+
import {
|
|
89
|
+
newNormalizeReferencesStep,
|
|
90
|
+
newValidateReferencesStep,
|
|
91
|
+
} from "../../pipeline/steps/references.js";
|
|
89
92
|
import {
|
|
90
93
|
newCleanupIamPoliciesStep,
|
|
91
94
|
newCreateAuthorizationTuplesStep,
|
|
@@ -208,7 +211,8 @@ async function createSession(
|
|
|
208
211
|
.addStep(newCheckDuplicateStep(deps.store))
|
|
209
212
|
.addStep(newBuildNewStateStep())
|
|
210
213
|
.addStep(newGuardReservedLabelsStep(deps.authorizer))
|
|
211
|
-
.addStep(newNormalizeReferencesStep())
|
|
214
|
+
.addStep(newNormalizeReferencesStep())
|
|
215
|
+
.addStep(newValidateReferencesStep(deps.store));
|
|
212
216
|
// The ratified pre-side-effect gate slot (blueprint 03 §3a; O4; Q2
|
|
213
217
|
// ruling — see the create doc comment). Empty in OSS.
|
|
214
218
|
for (const step of stepsForSlot<typeof SessionSchema>(
|
|
@@ -499,7 +503,9 @@ async function list(
|
|
|
499
503
|
newAuthorizeStep(SessionQueryController.method.list, deps.authorizer),
|
|
500
504
|
)
|
|
501
505
|
.addStep(newValidateProtoStep())
|
|
502
|
-
.addStep(
|
|
506
|
+
.addStep(
|
|
507
|
+
newListAllSessionsStep(deps.store, deps.logger, deps.listReadScope),
|
|
508
|
+
)
|
|
503
509
|
.build()
|
|
504
510
|
.execute(reqCtx);
|
|
505
511
|
return requireListResult(reqCtx.get(LIST_RESULT_KEY));
|
|
@@ -559,7 +565,9 @@ async function listByChannel(
|
|
|
559
565
|
)
|
|
560
566
|
.addStep(newValidateProtoStep())
|
|
561
567
|
.addStep(newAuthorizeChannelAccessStep(deps.authorizer))
|
|
562
|
-
.addStep(
|
|
568
|
+
.addStep(
|
|
569
|
+
newFilterByChannelStep(deps.store, deps.logger, deps.listReadScope),
|
|
570
|
+
)
|
|
563
571
|
.build()
|
|
564
572
|
.execute(reqCtx);
|
|
565
573
|
return requireListResult(reqCtx.get(LIST_RESULT_KEY));
|
|
@@ -75,7 +75,6 @@ import {
|
|
|
75
75
|
newAuthorizeResolvedTargetStep,
|
|
76
76
|
} from "../../pipeline/steps/authorize-resolved-target.js";
|
|
77
77
|
import { versionHistoryTarget } from "../../pipeline/steps/version-history.js";
|
|
78
|
-
import { newAuthorizeVisibilityTransitionStep } from "../../pipeline/steps/visibility-gates.js";
|
|
79
78
|
import {
|
|
80
79
|
newCleanupIamPoliciesStep,
|
|
81
80
|
newRecordVisibilityBeforeUpdateStep,
|
|
@@ -450,12 +449,6 @@ async function updateVisibility(
|
|
|
450
449
|
)
|
|
451
450
|
.addStep(newRecordVisibilityBeforeUpdateStep(UPDATE_VISIBILITY_SKILL_KEY))
|
|
452
451
|
.addStep(newValidateVisibilityUpdateStep())
|
|
453
|
-
.addStep(
|
|
454
|
-
newAuthorizeVisibilityTransitionStep(
|
|
455
|
-
UPDATE_VISIBILITY_SKILL_KEY,
|
|
456
|
-
deps.authorizer,
|
|
457
|
-
),
|
|
458
|
-
)
|
|
459
452
|
.addStep(newSetVisibilityStep())
|
|
460
453
|
.addStep(newPersistSkillForVisibilityUpdateStep(deps.store))
|
|
461
454
|
.addStep(
|