@inkeep/agents-manage-api 0.0.0-dev-20260118170655 → 0.0.0-dev-20260119163620
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/data/db/dbClient.d.ts +2 -2
- package/dist/data/db/runDbClient.d.ts +2 -2
- package/dist/factory.d.ts +2 -2
- package/dist/index.d.ts +82 -22
- package/dist/middleware/auth.d.ts +2 -2
- package/dist/middleware/project-access.d.ts +31 -0
- package/dist/middleware/project-access.js +118 -0
- package/dist/middleware/require-permission.d.ts +2 -2
- package/dist/middleware/session-auth.d.ts +2 -2
- package/dist/middleware/tenant-access.d.ts +2 -2
- package/dist/routes/agent.js +4 -4
- package/dist/routes/agentFull.js +4 -4
- package/dist/routes/agentToolRelations.js +4 -4
- package/dist/routes/apiKeys.js +4 -4
- package/dist/routes/artifactComponents.js +4 -4
- package/dist/routes/contextConfigs.js +4 -4
- package/dist/routes/conversations.d.ts +2 -2
- package/dist/routes/credentialStores.d.ts +2 -2
- package/dist/routes/credentialStores.js +5 -0
- package/dist/routes/credentials.js +4 -4
- package/dist/routes/dataComponents.js +4 -4
- package/dist/routes/evals/evaluationResults.d.ts +2 -2
- package/dist/routes/externalAgents.js +4 -4
- package/dist/routes/functionTools.js +4 -4
- package/dist/routes/functions.js +4 -4
- package/dist/routes/index.d.ts +2 -2
- package/dist/routes/index.js +6 -0
- package/dist/routes/playgroundToken.js +18 -3
- package/dist/routes/projectFull.js +3 -2
- package/dist/routes/projectMembers.d.ts +9 -0
- package/dist/routes/projectMembers.js +201 -0
- package/dist/routes/projectPermissions.d.ts +9 -0
- package/dist/routes/projectPermissions.js +64 -0
- package/dist/routes/projects.js +38 -7
- package/dist/routes/subAgentArtifactComponents.js +3 -3
- package/dist/routes/subAgentDataComponents.js +3 -3
- package/dist/routes/subAgentExternalAgentRelations.js +4 -4
- package/dist/routes/subAgentFunctionTools.js +3 -3
- package/dist/routes/subAgentRelations.js +4 -4
- package/dist/routes/subAgentTeamAgentRelations.js +4 -4
- package/dist/routes/subAgentToolRelations.js +4 -4
- package/dist/routes/subAgents.js +4 -4
- package/dist/routes/tools.js +4 -4
- package/package.json +3 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { requireProjectPermission } from "../middleware/project-access.js";
|
|
2
2
|
import { speakeasyOffsetLimitPagination } from "./shared.js";
|
|
3
3
|
import { OpenAPIHono, createRoute } from "@hono/zod-openapi";
|
|
4
4
|
import { CredentialReferenceApiInsertSchema, CredentialReferenceApiSelectSchema, CredentialReferenceApiUpdateSchema, CredentialReferenceListResponse, CredentialReferenceResponse, ErrorResponseSchema, ListResponseSchema, PaginationQueryParamsSchema, TenantProjectIdParamsSchema, TenantProjectParamsSchema, commonGetErrorResponses, createApiError, createCredentialReference, deleteCredentialReference, getCredentialReferenceById, getCredentialReferenceWithResources, getCredentialStoreLookupKeyFromRetrievalParams, listCredentialReferencesPaginated, updateCredentialReference } from "@inkeep/agents-core";
|
|
@@ -6,12 +6,12 @@ import { CredentialReferenceApiInsertSchema, CredentialReferenceApiSelectSchema,
|
|
|
6
6
|
//#region src/routes/credentials.ts
|
|
7
7
|
const app = new OpenAPIHono();
|
|
8
8
|
app.use("/", async (c, next) => {
|
|
9
|
-
if (c.req.method === "POST") return
|
|
9
|
+
if (c.req.method === "POST") return requireProjectPermission("edit")(c, next);
|
|
10
10
|
return next();
|
|
11
11
|
});
|
|
12
12
|
app.use("/:id", async (c, next) => {
|
|
13
|
-
if (c.req.method === "PATCH") return
|
|
14
|
-
if (c.req.method === "DELETE") return
|
|
13
|
+
if (c.req.method === "PATCH") return requireProjectPermission("edit")(c, next);
|
|
14
|
+
if (c.req.method === "DELETE") return requireProjectPermission("edit")(c, next);
|
|
15
15
|
return next();
|
|
16
16
|
});
|
|
17
17
|
app.openapi(createRoute({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { requireProjectPermission } from "../middleware/project-access.js";
|
|
2
2
|
import { speakeasyOffsetLimitPagination } from "./shared.js";
|
|
3
3
|
import { OpenAPIHono, createRoute } from "@hono/zod-openapi";
|
|
4
4
|
import { DataComponentApiInsertSchema, DataComponentApiUpdateSchema, DataComponentListResponse, DataComponentResponse, ErrorResponseSchema, PaginationQueryParamsSchema, TenantProjectIdParamsSchema, TenantProjectParamsSchema, commonGetErrorResponses, createApiError, createDataComponent, deleteDataComponent, getDataComponent, listDataComponentsPaginated, updateDataComponent, validatePropsAsJsonSchema } from "@inkeep/agents-core";
|
|
@@ -6,12 +6,12 @@ import { DataComponentApiInsertSchema, DataComponentApiUpdateSchema, DataCompone
|
|
|
6
6
|
//#region src/routes/dataComponents.ts
|
|
7
7
|
const app = new OpenAPIHono();
|
|
8
8
|
app.use("/", async (c, next) => {
|
|
9
|
-
if (c.req.method === "POST") return
|
|
9
|
+
if (c.req.method === "POST") return requireProjectPermission("edit")(c, next);
|
|
10
10
|
return next();
|
|
11
11
|
});
|
|
12
12
|
app.use("/:id", async (c, next) => {
|
|
13
|
-
if (c.req.method === "PATCH") return
|
|
14
|
-
if (c.req.method === "DELETE") return
|
|
13
|
+
if (c.req.method === "PATCH") return requireProjectPermission("edit")(c, next);
|
|
14
|
+
if (c.req.method === "DELETE") return requireProjectPermission("edit")(c, next);
|
|
15
15
|
return next();
|
|
16
16
|
});
|
|
17
17
|
app.openapi(createRoute({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { OpenAPIHono } from "@hono/zod-openapi";
|
|
2
|
-
import * as
|
|
2
|
+
import * as hono7 from "hono";
|
|
3
3
|
|
|
4
4
|
//#region src/routes/evals/evaluationResults.d.ts
|
|
5
|
-
declare const app: OpenAPIHono<
|
|
5
|
+
declare const app: OpenAPIHono<hono7.Env, {}, "/">;
|
|
6
6
|
//#endregion
|
|
7
7
|
export { app as default };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { requireProjectPermission } from "../middleware/project-access.js";
|
|
2
2
|
import { speakeasyOffsetLimitPagination } from "./shared.js";
|
|
3
3
|
import { OpenAPIHono, createRoute } from "@hono/zod-openapi";
|
|
4
4
|
import { ErrorResponseSchema, ExternalAgentApiInsertSchema, ExternalAgentApiUpdateSchema, ExternalAgentListResponse, ExternalAgentResponse, PaginationQueryParamsSchema, TenantProjectIdParamsSchema, TenantProjectParamsSchema, commonGetErrorResponses, createApiError, createExternalAgent, deleteExternalAgent, generateId, getExternalAgent, listExternalAgentsPaginated, updateExternalAgent } from "@inkeep/agents-core";
|
|
@@ -6,12 +6,12 @@ import { ErrorResponseSchema, ExternalAgentApiInsertSchema, ExternalAgentApiUpda
|
|
|
6
6
|
//#region src/routes/externalAgents.ts
|
|
7
7
|
const app = new OpenAPIHono();
|
|
8
8
|
app.use("/", async (c, next) => {
|
|
9
|
-
if (c.req.method === "POST") return
|
|
9
|
+
if (c.req.method === "POST") return requireProjectPermission("edit")(c, next);
|
|
10
10
|
return next();
|
|
11
11
|
});
|
|
12
12
|
app.use("/:id", async (c, next) => {
|
|
13
|
-
if (c.req.method === "PATCH") return
|
|
14
|
-
if (c.req.method === "DELETE") return
|
|
13
|
+
if (c.req.method === "PATCH") return requireProjectPermission("edit")(c, next);
|
|
14
|
+
if (c.req.method === "DELETE") return requireProjectPermission("edit")(c, next);
|
|
15
15
|
return next();
|
|
16
16
|
});
|
|
17
17
|
app.openapi(createRoute({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getLogger as getLogger$1 } from "../logger.js";
|
|
2
|
-
import {
|
|
2
|
+
import { requireProjectPermission } from "../middleware/project-access.js";
|
|
3
3
|
import { speakeasyOffsetLimitPagination } from "./shared.js";
|
|
4
4
|
import { OpenAPIHono, createRoute } from "@hono/zod-openapi";
|
|
5
5
|
import { FunctionToolApiInsertSchema, FunctionToolApiUpdateSchema, FunctionToolListResponse, FunctionToolResponse, PaginationQueryParamsSchema, TenantProjectAgentIdParamsSchema, TenantProjectAgentParamsSchema, commonGetErrorResponses, createApiError, createFunctionTool, deleteFunctionTool, generateId, getFunctionToolById, listFunctionTools, updateFunctionTool } from "@inkeep/agents-core";
|
|
@@ -8,12 +8,12 @@ import { FunctionToolApiInsertSchema, FunctionToolApiUpdateSchema, FunctionToolL
|
|
|
8
8
|
const logger = getLogger$1("functionTools");
|
|
9
9
|
const app = new OpenAPIHono();
|
|
10
10
|
app.use("/", async (c, next) => {
|
|
11
|
-
if (c.req.method === "POST") return
|
|
11
|
+
if (c.req.method === "POST") return requireProjectPermission("edit")(c, next);
|
|
12
12
|
return next();
|
|
13
13
|
});
|
|
14
14
|
app.use("/:id", async (c, next) => {
|
|
15
|
-
if (c.req.method === "PUT") return
|
|
16
|
-
if (c.req.method === "DELETE") return
|
|
15
|
+
if (c.req.method === "PUT") return requireProjectPermission("edit")(c, next);
|
|
16
|
+
if (c.req.method === "DELETE") return requireProjectPermission("edit")(c, next);
|
|
17
17
|
return next();
|
|
18
18
|
});
|
|
19
19
|
app.openapi(createRoute({
|
package/dist/routes/functions.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getLogger as getLogger$1 } from "../logger.js";
|
|
2
|
-
import {
|
|
2
|
+
import { requireProjectPermission } from "../middleware/project-access.js";
|
|
3
3
|
import { speakeasyOffsetLimitPagination } from "./shared.js";
|
|
4
4
|
import { OpenAPIHono, createRoute } from "@hono/zod-openapi";
|
|
5
5
|
import { FunctionApiInsertSchema, FunctionApiUpdateSchema, FunctionListResponse, FunctionResponse, PaginationQueryParamsSchema, TenantProjectIdParamsSchema, TenantProjectParamsSchema, commonGetErrorResponses, createApiError, deleteFunction, generateId, getFunction, listFunctionsPaginated, upsertFunction } from "@inkeep/agents-core";
|
|
@@ -8,12 +8,12 @@ import { FunctionApiInsertSchema, FunctionApiUpdateSchema, FunctionListResponse,
|
|
|
8
8
|
const logger = getLogger$1("functions");
|
|
9
9
|
const app = new OpenAPIHono();
|
|
10
10
|
app.use("/", async (c, next) => {
|
|
11
|
-
if (c.req.method === "POST") return
|
|
11
|
+
if (c.req.method === "POST") return requireProjectPermission("edit")(c, next);
|
|
12
12
|
return next();
|
|
13
13
|
});
|
|
14
14
|
app.use("/:id", async (c, next) => {
|
|
15
|
-
if (c.req.method === "PUT") return
|
|
16
|
-
if (c.req.method === "DELETE") return
|
|
15
|
+
if (c.req.method === "PUT") return requireProjectPermission("edit")(c, next);
|
|
16
|
+
if (c.req.method === "DELETE") return requireProjectPermission("edit")(c, next);
|
|
17
17
|
return next();
|
|
18
18
|
});
|
|
19
19
|
app.openapi(createRoute({
|
package/dist/routes/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { OpenAPIHono } from "@hono/zod-openapi";
|
|
2
|
-
import * as
|
|
2
|
+
import * as hono5 from "hono";
|
|
3
3
|
|
|
4
4
|
//#region src/routes/index.d.ts
|
|
5
|
-
declare const app: OpenAPIHono<
|
|
5
|
+
declare const app: OpenAPIHono<hono5.Env, {}, "/">;
|
|
6
6
|
//#endregion
|
|
7
7
|
export { app as default };
|
package/dist/routes/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { requireProjectPermission } from "../middleware/project-access.js";
|
|
1
2
|
import agent_default from "./agent.js";
|
|
2
3
|
import agentFull_default from "./agentFull.js";
|
|
3
4
|
import apiKeys_default from "./apiKeys.js";
|
|
@@ -12,6 +13,8 @@ import externalAgents_default from "./externalAgents.js";
|
|
|
12
13
|
import functions_default from "./functions.js";
|
|
13
14
|
import functionTools_default from "./functionTools.js";
|
|
14
15
|
import mcpCatalog_default from "./mcpCatalog.js";
|
|
16
|
+
import projectMembers_default from "./projectMembers.js";
|
|
17
|
+
import projectPermissions_default from "./projectPermissions.js";
|
|
15
18
|
import projects_default from "./projects.js";
|
|
16
19
|
import ref_default from "./ref.js";
|
|
17
20
|
import subAgentArtifactComponents_default from "./subAgentArtifactComponents.js";
|
|
@@ -29,8 +32,11 @@ import { OpenAPIHono } from "@hono/zod-openapi";
|
|
|
29
32
|
//#region src/routes/index.ts
|
|
30
33
|
const app = new OpenAPIHono();
|
|
31
34
|
app.route("/projects", projects_default);
|
|
35
|
+
app.use("/projects/:projectId/*", requireProjectPermission("view"));
|
|
32
36
|
app.route("/projects/:projectId/branches", branches_default);
|
|
33
37
|
app.route("/projects/:projectId/refs", ref_default);
|
|
38
|
+
app.route("/projects/:projectId/members", projectMembers_default);
|
|
39
|
+
app.route("/projects/:projectId/permissions", projectPermissions_default);
|
|
34
40
|
app.route("/projects/:projectId/agents/:agentId/sub-agents", subAgents_default);
|
|
35
41
|
app.route("/projects/:projectId/agents/:agentId/sub-agent-relations", subAgentRelations_default);
|
|
36
42
|
app.route("/projects/:projectId/agents/:agentId/sub-agents/:subAgentId/external-agent-relations", subAgentExternalAgentRelations_default);
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { env } from "../env.js";
|
|
2
2
|
import { getLogger as getLogger$1 } from "../logger.js";
|
|
3
|
-
import { requirePermission } from "../middleware/require-permission.js";
|
|
4
3
|
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
|
|
5
|
-
import { ErrorResponseSchema, TenantParamsSchema, createApiError, getAgentById, projectExists, signTempToken } from "@inkeep/agents-core";
|
|
4
|
+
import { ErrorResponseSchema, TenantParamsSchema, canUseProject, createApiError, getAgentById, projectExists, signTempToken } from "@inkeep/agents-core";
|
|
6
5
|
|
|
7
6
|
//#region src/routes/playgroundToken.ts
|
|
8
7
|
const logger = getLogger$1("playgroundToken");
|
|
9
8
|
const app = new OpenAPIHono();
|
|
10
|
-
app.use("/", requirePermission({ agent: ["create"] }));
|
|
11
9
|
const PlaygroundTokenRequestSchema = z.object({
|
|
12
10
|
projectId: z.string(),
|
|
13
11
|
agentId: z.string()
|
|
@@ -42,6 +40,7 @@ app.openapi(createRoute({
|
|
|
42
40
|
const db = c.get("db");
|
|
43
41
|
const userId = c.get("userId");
|
|
44
42
|
const tenantId = c.get("tenantId");
|
|
43
|
+
const tenantRole = c.get("tenantRole") || "member";
|
|
45
44
|
const { projectId, agentId } = c.req.valid("json");
|
|
46
45
|
logger.info({
|
|
47
46
|
userId,
|
|
@@ -49,6 +48,22 @@ app.openapi(createRoute({
|
|
|
49
48
|
projectId,
|
|
50
49
|
agentId
|
|
51
50
|
}, "Generating temporary JWT token for playground");
|
|
51
|
+
if (!await canUseProject({
|
|
52
|
+
tenantId,
|
|
53
|
+
userId,
|
|
54
|
+
projectId,
|
|
55
|
+
orgRole: tenantRole
|
|
56
|
+
})) {
|
|
57
|
+
logger.warn({
|
|
58
|
+
userId,
|
|
59
|
+
tenantId,
|
|
60
|
+
projectId
|
|
61
|
+
}, "User does not have use permission on project");
|
|
62
|
+
throw createApiError({
|
|
63
|
+
code: "not_found",
|
|
64
|
+
message: "Project not found"
|
|
65
|
+
});
|
|
66
|
+
}
|
|
52
67
|
if (!await projectExists(db)({
|
|
53
68
|
tenantId,
|
|
54
69
|
projectId
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { getLogger as getLogger$1 } from "../logger.js";
|
|
2
2
|
import runDbClient_default from "../data/db/runDbClient.js";
|
|
3
3
|
import dbClient_default from "../data/db/dbClient.js";
|
|
4
|
+
import { requireProjectPermission } from "../middleware/project-access.js";
|
|
4
5
|
import { requirePermission } from "../middleware/require-permission.js";
|
|
5
6
|
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
|
|
6
7
|
import { ErrorResponseSchema, FullProjectDefinitionSchema, FullProjectSelectResponse, FullProjectSelectWithRelationIdsResponse, TenantParamsSchema, TenantProjectParamsSchema, cascadeDeleteByProject, checkoutBranch, commonGetErrorResponses, createApiError, createFullProjectServerSide, createProjectMetadataAndBranch, deleteFullProject, deleteProjectWithBranch, doltCheckout, getFullProject, getFullProjectWithRelationIds, getProjectMainBranchName, getProjectMetadata, updateFullProjectServerSide } from "@inkeep/agents-core";
|
|
@@ -13,8 +14,8 @@ app.use("/project-full", async (c, next) => {
|
|
|
13
14
|
return next();
|
|
14
15
|
});
|
|
15
16
|
app.use("/project-full/:projectId", async (c, next) => {
|
|
16
|
-
if (c.req.method === "PUT") return
|
|
17
|
-
if (c.req.method === "DELETE") return
|
|
17
|
+
if (c.req.method === "PUT") return requireProjectPermission("edit")(c, next);
|
|
18
|
+
if (c.req.method === "DELETE") return requireProjectPermission("edit")(c, next);
|
|
18
19
|
return next();
|
|
19
20
|
});
|
|
20
21
|
app.openapi(createRoute({
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BaseAppVariables } from "../types/app.js";
|
|
2
|
+
import { OpenAPIHono } from "@hono/zod-openapi";
|
|
3
|
+
|
|
4
|
+
//#region src/routes/projectMembers.d.ts
|
|
5
|
+
declare const app: OpenAPIHono<{
|
|
6
|
+
Variables: BaseAppVariables;
|
|
7
|
+
}, {}, "/">;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { app as default };
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { requireProjectPermission } from "../middleware/project-access.js";
|
|
2
|
+
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
|
|
3
|
+
import { changeProjectRole, commonGetErrorResponses, createApiError, grantProjectAccess, isAuthzEnabled, listProjectMembers, revokeProjectAccess } from "@inkeep/agents-core";
|
|
4
|
+
|
|
5
|
+
//#region src/routes/projectMembers.ts
|
|
6
|
+
const app = new OpenAPIHono();
|
|
7
|
+
const ProjectMemberSchema = z.object({
|
|
8
|
+
userId: z.string().min(1),
|
|
9
|
+
role: z.enum([
|
|
10
|
+
"project_admin",
|
|
11
|
+
"project_member",
|
|
12
|
+
"project_viewer"
|
|
13
|
+
])
|
|
14
|
+
});
|
|
15
|
+
const ProjectMemberResponseSchema = z.object({ data: z.object({
|
|
16
|
+
userId: z.string(),
|
|
17
|
+
role: z.enum([
|
|
18
|
+
"project_admin",
|
|
19
|
+
"project_member",
|
|
20
|
+
"project_viewer"
|
|
21
|
+
]),
|
|
22
|
+
projectId: z.string()
|
|
23
|
+
}) });
|
|
24
|
+
const ProjectMemberParamsSchema = z.object({
|
|
25
|
+
tenantId: z.string(),
|
|
26
|
+
projectId: z.string()
|
|
27
|
+
});
|
|
28
|
+
const ProjectMemberUserParamsSchema = z.object({
|
|
29
|
+
tenantId: z.string(),
|
|
30
|
+
projectId: z.string(),
|
|
31
|
+
userId: z.string()
|
|
32
|
+
});
|
|
33
|
+
const UpdateRoleSchema = z.object({
|
|
34
|
+
role: z.enum([
|
|
35
|
+
"project_admin",
|
|
36
|
+
"project_member",
|
|
37
|
+
"project_viewer"
|
|
38
|
+
]),
|
|
39
|
+
previousRole: z.enum([
|
|
40
|
+
"project_admin",
|
|
41
|
+
"project_member",
|
|
42
|
+
"project_viewer"
|
|
43
|
+
]).optional()
|
|
44
|
+
});
|
|
45
|
+
app.openapi(createRoute({
|
|
46
|
+
method: "get",
|
|
47
|
+
path: "/",
|
|
48
|
+
summary: "List Project Members",
|
|
49
|
+
description: "List all users with explicit project access. Requires authz to be enabled.",
|
|
50
|
+
operationId: "list-project-members",
|
|
51
|
+
tags: ["Project Members"],
|
|
52
|
+
request: { params: ProjectMemberParamsSchema },
|
|
53
|
+
responses: {
|
|
54
|
+
200: {
|
|
55
|
+
description: "List of project members",
|
|
56
|
+
content: { "application/json": { schema: z.object({ data: z.array(z.object({
|
|
57
|
+
userId: z.string(),
|
|
58
|
+
role: z.enum([
|
|
59
|
+
"project_admin",
|
|
60
|
+
"project_member",
|
|
61
|
+
"project_viewer"
|
|
62
|
+
])
|
|
63
|
+
})) }) } }
|
|
64
|
+
},
|
|
65
|
+
...commonGetErrorResponses
|
|
66
|
+
}
|
|
67
|
+
}), async (c) => {
|
|
68
|
+
const { projectId, tenantId } = c.req.valid("param");
|
|
69
|
+
if (!isAuthzEnabled(tenantId)) return c.json({ data: [] });
|
|
70
|
+
const members = await listProjectMembers({
|
|
71
|
+
tenantId,
|
|
72
|
+
projectId
|
|
73
|
+
});
|
|
74
|
+
return c.json({ data: members });
|
|
75
|
+
});
|
|
76
|
+
app.use("/*", async (c, next) => {
|
|
77
|
+
if (c.req.method === "GET") return next();
|
|
78
|
+
return requireProjectPermission("edit")(c, next);
|
|
79
|
+
});
|
|
80
|
+
app.openapi(createRoute({
|
|
81
|
+
method: "post",
|
|
82
|
+
path: "/",
|
|
83
|
+
summary: "Add Project Member",
|
|
84
|
+
description: "Add a user to a project with a specified role. Requires authz to be enabled.",
|
|
85
|
+
operationId: "add-project-member",
|
|
86
|
+
tags: ["Project Members"],
|
|
87
|
+
request: {
|
|
88
|
+
params: ProjectMemberParamsSchema,
|
|
89
|
+
body: { content: { "application/json": { schema: ProjectMemberSchema } } }
|
|
90
|
+
},
|
|
91
|
+
responses: {
|
|
92
|
+
201: {
|
|
93
|
+
description: "Member added successfully",
|
|
94
|
+
content: { "application/json": { schema: ProjectMemberResponseSchema } }
|
|
95
|
+
},
|
|
96
|
+
...commonGetErrorResponses
|
|
97
|
+
}
|
|
98
|
+
}), async (c) => {
|
|
99
|
+
const { projectId, tenantId } = c.req.valid("param");
|
|
100
|
+
const { userId, role } = c.req.valid("json");
|
|
101
|
+
if (!isAuthzEnabled(tenantId)) throw createApiError({
|
|
102
|
+
code: "bad_request",
|
|
103
|
+
message: "Project member management requires authorization to be enabled (ENABLE_AUTHZ=true)"
|
|
104
|
+
});
|
|
105
|
+
await grantProjectAccess({
|
|
106
|
+
tenantId,
|
|
107
|
+
projectId,
|
|
108
|
+
userId,
|
|
109
|
+
role
|
|
110
|
+
});
|
|
111
|
+
return c.json({ data: {
|
|
112
|
+
userId,
|
|
113
|
+
role,
|
|
114
|
+
projectId
|
|
115
|
+
} }, 201);
|
|
116
|
+
});
|
|
117
|
+
app.openapi(createRoute({
|
|
118
|
+
method: "patch",
|
|
119
|
+
path: "/{userId}",
|
|
120
|
+
summary: "Update Project Member Role",
|
|
121
|
+
description: "Update a project member's role. Requires authz to be enabled. Include previousRole to specify which role to revoke.",
|
|
122
|
+
operationId: "update-project-member",
|
|
123
|
+
tags: ["Project Members"],
|
|
124
|
+
request: {
|
|
125
|
+
params: ProjectMemberUserParamsSchema,
|
|
126
|
+
body: { content: { "application/json": { schema: UpdateRoleSchema } } }
|
|
127
|
+
},
|
|
128
|
+
responses: {
|
|
129
|
+
200: {
|
|
130
|
+
description: "Member role updated successfully",
|
|
131
|
+
content: { "application/json": { schema: ProjectMemberResponseSchema } }
|
|
132
|
+
},
|
|
133
|
+
...commonGetErrorResponses
|
|
134
|
+
}
|
|
135
|
+
}), async (c) => {
|
|
136
|
+
const { projectId, userId, tenantId } = c.req.valid("param");
|
|
137
|
+
const { role: newRole, previousRole } = c.req.valid("json");
|
|
138
|
+
if (!isAuthzEnabled(tenantId)) throw createApiError({
|
|
139
|
+
code: "bad_request",
|
|
140
|
+
message: "Project member management requires authorization to be enabled (ENABLE_AUTHZ=true)"
|
|
141
|
+
});
|
|
142
|
+
if (!previousRole) throw createApiError({
|
|
143
|
+
code: "bad_request",
|
|
144
|
+
message: "previousRole is required to update a member role"
|
|
145
|
+
});
|
|
146
|
+
if (previousRole === newRole) return c.json({ data: {
|
|
147
|
+
userId,
|
|
148
|
+
role: newRole,
|
|
149
|
+
projectId
|
|
150
|
+
} });
|
|
151
|
+
await changeProjectRole({
|
|
152
|
+
tenantId,
|
|
153
|
+
projectId,
|
|
154
|
+
userId,
|
|
155
|
+
oldRole: previousRole,
|
|
156
|
+
newRole
|
|
157
|
+
});
|
|
158
|
+
return c.json({ data: {
|
|
159
|
+
userId,
|
|
160
|
+
role: newRole,
|
|
161
|
+
projectId
|
|
162
|
+
} });
|
|
163
|
+
});
|
|
164
|
+
app.openapi(createRoute({
|
|
165
|
+
method: "delete",
|
|
166
|
+
path: "/{userId}",
|
|
167
|
+
summary: "Remove Project Member",
|
|
168
|
+
description: "Remove a user from a project. Requires authz to be enabled. Pass role as query param to specify which role to revoke.",
|
|
169
|
+
operationId: "remove-project-member",
|
|
170
|
+
tags: ["Project Members"],
|
|
171
|
+
request: {
|
|
172
|
+
params: ProjectMemberUserParamsSchema,
|
|
173
|
+
query: z.object({ role: z.enum([
|
|
174
|
+
"project_admin",
|
|
175
|
+
"project_member",
|
|
176
|
+
"project_viewer"
|
|
177
|
+
]) })
|
|
178
|
+
},
|
|
179
|
+
responses: {
|
|
180
|
+
204: { description: "Member removed successfully" },
|
|
181
|
+
...commonGetErrorResponses
|
|
182
|
+
}
|
|
183
|
+
}), async (c) => {
|
|
184
|
+
const { projectId, userId, tenantId } = c.req.valid("param");
|
|
185
|
+
const { role } = c.req.valid("query");
|
|
186
|
+
if (!isAuthzEnabled(tenantId)) throw createApiError({
|
|
187
|
+
code: "bad_request",
|
|
188
|
+
message: "Project member management requires authorization to be enabled (ENABLE_AUTHZ=true)"
|
|
189
|
+
});
|
|
190
|
+
await revokeProjectAccess({
|
|
191
|
+
tenantId,
|
|
192
|
+
projectId,
|
|
193
|
+
userId,
|
|
194
|
+
role
|
|
195
|
+
});
|
|
196
|
+
return c.body(null, 204);
|
|
197
|
+
});
|
|
198
|
+
var projectMembers_default = app;
|
|
199
|
+
|
|
200
|
+
//#endregion
|
|
201
|
+
export { projectMembers_default as default };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BaseAppVariables } from "../types/app.js";
|
|
2
|
+
import { OpenAPIHono } from "@hono/zod-openapi";
|
|
3
|
+
|
|
4
|
+
//#region src/routes/projectPermissions.d.ts
|
|
5
|
+
declare const app: OpenAPIHono<{
|
|
6
|
+
Variables: BaseAppVariables;
|
|
7
|
+
}, {}, "/">;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { app as default };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
|
|
2
|
+
import { SpiceDbPermissions, SpiceDbResourceTypes, checkBulkPermissions, commonGetErrorResponses, isAuthzEnabled } from "@inkeep/agents-core";
|
|
3
|
+
|
|
4
|
+
//#region src/routes/projectPermissions.ts
|
|
5
|
+
const app = new OpenAPIHono();
|
|
6
|
+
const ProjectPermissionsParamsSchema = z.object({
|
|
7
|
+
tenantId: z.string(),
|
|
8
|
+
projectId: z.string()
|
|
9
|
+
});
|
|
10
|
+
const ProjectPermissionsResponseSchema = z.object({ data: z.object({
|
|
11
|
+
canView: z.boolean(),
|
|
12
|
+
canUse: z.boolean(),
|
|
13
|
+
canEdit: z.boolean()
|
|
14
|
+
}) });
|
|
15
|
+
app.openapi(createRoute({
|
|
16
|
+
method: "get",
|
|
17
|
+
path: "/",
|
|
18
|
+
summary: "Get Project Permissions",
|
|
19
|
+
description: "Get the current user's permissions for a project. Returns which actions the user can perform.",
|
|
20
|
+
operationId: "get-project-permissions",
|
|
21
|
+
tags: ["Project Permissions"],
|
|
22
|
+
request: { params: ProjectPermissionsParamsSchema },
|
|
23
|
+
responses: {
|
|
24
|
+
200: {
|
|
25
|
+
description: "Project permissions for the current user",
|
|
26
|
+
content: { "application/json": { schema: ProjectPermissionsResponseSchema } }
|
|
27
|
+
},
|
|
28
|
+
...commonGetErrorResponses
|
|
29
|
+
}
|
|
30
|
+
}), async (c) => {
|
|
31
|
+
const { projectId, tenantId } = c.req.valid("param");
|
|
32
|
+
const userId = c.get("userId");
|
|
33
|
+
const tenantRole = c.get("tenantRole");
|
|
34
|
+
if (tenantRole === "owner" || tenantRole === "admin") return c.json({ data: {
|
|
35
|
+
canView: true,
|
|
36
|
+
canUse: true,
|
|
37
|
+
canEdit: true
|
|
38
|
+
} });
|
|
39
|
+
if (!isAuthzEnabled(tenantId)) return c.json({ data: {
|
|
40
|
+
canView: true,
|
|
41
|
+
canUse: true,
|
|
42
|
+
canEdit: false
|
|
43
|
+
} });
|
|
44
|
+
const permissions = await checkBulkPermissions({
|
|
45
|
+
resourceType: SpiceDbResourceTypes.PROJECT,
|
|
46
|
+
resourceId: projectId,
|
|
47
|
+
permissions: [
|
|
48
|
+
SpiceDbPermissions.VIEW,
|
|
49
|
+
SpiceDbPermissions.USE,
|
|
50
|
+
SpiceDbPermissions.EDIT
|
|
51
|
+
],
|
|
52
|
+
subjectType: SpiceDbResourceTypes.USER,
|
|
53
|
+
subjectId: userId
|
|
54
|
+
});
|
|
55
|
+
return c.json({ data: {
|
|
56
|
+
canView: permissions[SpiceDbPermissions.VIEW] ?? false,
|
|
57
|
+
canUse: permissions[SpiceDbPermissions.USE] ?? false,
|
|
58
|
+
canEdit: permissions[SpiceDbPermissions.EDIT] ?? false
|
|
59
|
+
} });
|
|
60
|
+
});
|
|
61
|
+
var projectPermissions_default = app;
|
|
62
|
+
|
|
63
|
+
//#endregion
|
|
64
|
+
export { projectPermissions_default as default };
|
package/dist/routes/projects.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import runDbClient_default from "../data/db/runDbClient.js";
|
|
2
2
|
import dbClient_default from "../data/db/dbClient.js";
|
|
3
|
-
import {
|
|
3
|
+
import { requireProjectPermission } from "../middleware/project-access.js";
|
|
4
4
|
import { speakeasyOffsetLimitPagination } from "./shared.js";
|
|
5
|
+
import { requirePermission } from "../middleware/require-permission.js";
|
|
5
6
|
import { OpenAPIHono, createRoute } from "@hono/zod-openapi";
|
|
6
|
-
import { ErrorResponseSchema, PaginationQueryParamsSchema, ProjectApiInsertSchema, ProjectApiUpdateSchema, ProjectListResponse, ProjectResponse, TenantIdParamsSchema, TenantParamsSchema, cascadeDeleteByProject, commonGetErrorResponses, createApiError, createProject, createProjectMetadataAndBranch, deleteProject, deleteProjectWithBranch, doltCheckout, getProject, getProjectMainBranchName, listProjectsWithMetadataPaginated, updateProject } from "@inkeep/agents-core";
|
|
7
|
+
import { ErrorResponseSchema, PaginationQueryParamsSchema, ProjectApiInsertSchema, ProjectApiUpdateSchema, ProjectListResponse, ProjectResponse, TenantIdParamsSchema, TenantParamsSchema, cascadeDeleteByProject, commonGetErrorResponses, createApiError, createProject, createProjectMetadataAndBranch, deleteProject, deleteProjectWithBranch, doltCheckout, getProject, getProjectMainBranchName, isAuthzEnabled, listAccessibleProjectIds, listProjectsWithMetadataPaginated, removeProjectFromSpiceDb, syncProjectToSpiceDb, updateProject } from "@inkeep/agents-core";
|
|
7
8
|
|
|
8
9
|
//#region src/routes/projects.ts
|
|
9
10
|
const app = new OpenAPIHono();
|
|
@@ -12,15 +13,16 @@ app.use("/", async (c, next) => {
|
|
|
12
13
|
return next();
|
|
13
14
|
});
|
|
14
15
|
app.use("/:id", async (c, next) => {
|
|
15
|
-
if (c.req.method === "
|
|
16
|
-
if (c.req.method === "
|
|
16
|
+
if (c.req.method === "GET") return requireProjectPermission("view")(c, next);
|
|
17
|
+
if (c.req.method === "PATCH") return requireProjectPermission("edit")(c, next);
|
|
18
|
+
if (c.req.method === "DELETE") return requireProjectPermission("edit")(c, next);
|
|
17
19
|
return next();
|
|
18
20
|
});
|
|
19
21
|
app.openapi(createRoute({
|
|
20
22
|
method: "get",
|
|
21
23
|
path: "/",
|
|
22
24
|
summary: "List Projects",
|
|
23
|
-
description: "List all projects within a tenant with pagination",
|
|
25
|
+
description: "List all projects within a tenant with pagination. When authorization is enabled, only returns projects the user has access to.",
|
|
24
26
|
operationId: "list-projects",
|
|
25
27
|
tags: ["Projects"],
|
|
26
28
|
request: {
|
|
@@ -38,14 +40,26 @@ app.openapi(createRoute({
|
|
|
38
40
|
}), async (c) => {
|
|
39
41
|
const configDb = c.get("db");
|
|
40
42
|
const { tenantId } = c.req.valid("param");
|
|
43
|
+
const userId = c.get("userId");
|
|
44
|
+
const tenantRole = c.get("tenantRole") || "member";
|
|
41
45
|
const page = Number(c.req.query("page")) || 1;
|
|
42
46
|
const limit = Math.min(Number(c.req.query("limit")) || 10, 100);
|
|
47
|
+
let accessibleIds;
|
|
48
|
+
if (isAuthzEnabled(tenantId) && userId) {
|
|
49
|
+
const result$1 = await listAccessibleProjectIds({
|
|
50
|
+
tenantId,
|
|
51
|
+
userId,
|
|
52
|
+
orgRole: tenantRole
|
|
53
|
+
});
|
|
54
|
+
if (result$1 !== "all") accessibleIds = result$1;
|
|
55
|
+
}
|
|
43
56
|
const result = await listProjectsWithMetadataPaginated(runDbClient_default, configDb)({
|
|
44
57
|
tenantId,
|
|
45
58
|
pagination: {
|
|
46
59
|
page,
|
|
47
60
|
limit
|
|
48
|
-
}
|
|
61
|
+
},
|
|
62
|
+
projectIds: accessibleIds
|
|
49
63
|
});
|
|
50
64
|
const transformedData = result.data.map((project) => ({
|
|
51
65
|
id: project.id,
|
|
@@ -94,7 +108,7 @@ app.openapi(createRoute({
|
|
|
94
108
|
method: "post",
|
|
95
109
|
path: "/",
|
|
96
110
|
summary: "Create Project",
|
|
97
|
-
description: "Create a new project",
|
|
111
|
+
description: "Create a new project. When authorization is enabled, the creator is automatically granted admin role.",
|
|
98
112
|
operationId: "create-project",
|
|
99
113
|
tags: ["Projects"],
|
|
100
114
|
request: {
|
|
@@ -135,6 +149,15 @@ app.openapi(createRoute({
|
|
|
135
149
|
tenantId,
|
|
136
150
|
...body
|
|
137
151
|
});
|
|
152
|
+
if (isAuthzEnabled(tenantId)) try {
|
|
153
|
+
await syncProjectToSpiceDb({
|
|
154
|
+
tenantId,
|
|
155
|
+
projectId: body.id,
|
|
156
|
+
creatorUserId: userId
|
|
157
|
+
});
|
|
158
|
+
} catch (syncError) {
|
|
159
|
+
console.warn("Failed to sync project to SpiceDB:", syncError);
|
|
160
|
+
}
|
|
138
161
|
return c.json({ data: {
|
|
139
162
|
...projectConfig,
|
|
140
163
|
mainBranchName: runtimeProject.mainBranchName
|
|
@@ -227,6 +250,14 @@ app.openapi(createRoute({
|
|
|
227
250
|
code: "not_found",
|
|
228
251
|
message: "Project not found"
|
|
229
252
|
});
|
|
253
|
+
if (isAuthzEnabled(tenantId)) try {
|
|
254
|
+
await removeProjectFromSpiceDb({
|
|
255
|
+
tenantId,
|
|
256
|
+
projectId: id
|
|
257
|
+
});
|
|
258
|
+
} catch (syncError) {
|
|
259
|
+
console.warn("Failed to remove project from SpiceDB:", syncError);
|
|
260
|
+
}
|
|
230
261
|
return c.body(null, 204);
|
|
231
262
|
} catch (error) {
|
|
232
263
|
if (error.message?.includes("Cannot delete project with existing resources")) throw createApiError({
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { requireProjectPermission } from "../middleware/project-access.js";
|
|
2
2
|
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
|
|
3
3
|
import { ArtifactComponentArrayResponse, ComponentAssociationListResponse, ErrorResponseSchema, ExistsResponseSchema, RemovedResponseSchema, SubAgentArtifactComponentApiInsertSchema, SubAgentArtifactComponentResponse, TenantProjectAgentParamsSchema, TenantProjectAgentSubAgentParamsSchema, associateArtifactComponentWithAgent, commonGetErrorResponses, createApiError, getAgentsUsingArtifactComponent, getArtifactComponentById, getArtifactComponentsForAgent, getSubAgentById, isArtifactComponentAssociatedWithAgent, removeArtifactComponentFromAgent } from "@inkeep/agents-core";
|
|
4
4
|
|
|
5
5
|
//#region src/routes/subAgentArtifactComponents.ts
|
|
6
6
|
const app = new OpenAPIHono();
|
|
7
7
|
app.use("/", async (c, next) => {
|
|
8
|
-
if (c.req.method === "POST") return
|
|
8
|
+
if (c.req.method === "POST") return requireProjectPermission("edit")(c, next);
|
|
9
9
|
return next();
|
|
10
10
|
});
|
|
11
11
|
app.use("/agent/:subAgentId/component/:artifactComponentId", async (c, next) => {
|
|
12
|
-
if (c.req.method === "DELETE") return
|
|
12
|
+
if (c.req.method === "DELETE") return requireProjectPermission("edit")(c, next);
|
|
13
13
|
return next();
|
|
14
14
|
});
|
|
15
15
|
app.openapi(createRoute({
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { requireProjectPermission } from "../middleware/project-access.js";
|
|
2
2
|
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
|
|
3
3
|
import { ComponentAssociationListResponse, DataComponentArrayResponse, ErrorResponseSchema, ExistsResponseSchema, RemovedResponseSchema, SubAgentDataComponentApiInsertSchema, SubAgentDataComponentResponse, TenantProjectAgentParamsSchema, TenantProjectAgentSubAgentParamsSchema, associateDataComponentWithAgent, commonGetErrorResponses, createApiError, getAgentsUsingDataComponent, getDataComponent, getDataComponentsForAgent, getSubAgentById, isDataComponentAssociatedWithAgent, removeDataComponentFromAgent } from "@inkeep/agents-core";
|
|
4
4
|
|
|
5
5
|
//#region src/routes/subAgentDataComponents.ts
|
|
6
6
|
const app = new OpenAPIHono();
|
|
7
7
|
app.use("/", async (c, next) => {
|
|
8
|
-
if (c.req.method === "POST") return
|
|
8
|
+
if (c.req.method === "POST") return requireProjectPermission("edit")(c, next);
|
|
9
9
|
return next();
|
|
10
10
|
});
|
|
11
11
|
app.use("/agent/:subAgentId/component/:dataComponentId", async (c, next) => {
|
|
12
|
-
if (c.req.method === "DELETE") return
|
|
12
|
+
if (c.req.method === "DELETE") return requireProjectPermission("edit")(c, next);
|
|
13
13
|
return next();
|
|
14
14
|
});
|
|
15
15
|
app.openapi(createRoute({
|