mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
feat: updated folder, import, approvals and some more to projectid
This commit is contained in:
@@ -0,0 +1,293 @@
|
|||||||
|
import { nanoid } from "nanoid";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
import { ApproverType, BypasserType } from "@app/ee/services/access-approval-policy/access-approval-policy-types";
|
||||||
|
import { removeTrailingSlash } from "@app/lib/fn";
|
||||||
|
import { EnforcementLevel } from "@app/lib/types";
|
||||||
|
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
|
||||||
|
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||||
|
import { sapPubSchema } from "@app/server/routes/sanitizedSchemas";
|
||||||
|
import { AuthMode } from "@app/services/auth/auth-type";
|
||||||
|
|
||||||
|
export const registerDepreciatedSecretApprovalPolicyRouter = async (server: FastifyZodProvider) => {
|
||||||
|
server.route({
|
||||||
|
url: "/",
|
||||||
|
method: "POST",
|
||||||
|
config: {
|
||||||
|
rateLimit: writeLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
body: z
|
||||||
|
.object({
|
||||||
|
workspaceId: z.string(),
|
||||||
|
name: z.string().optional(),
|
||||||
|
environment: z.string().optional(),
|
||||||
|
environments: z.string().array().optional(),
|
||||||
|
secretPath: z
|
||||||
|
.string()
|
||||||
|
.min(1, { message: "Secret path cannot be empty" })
|
||||||
|
.transform((val) => removeTrailingSlash(val)),
|
||||||
|
approvers: z
|
||||||
|
.discriminatedUnion("type", [
|
||||||
|
z.object({ type: z.literal(ApproverType.Group), id: z.string() }),
|
||||||
|
z.object({
|
||||||
|
type: z.literal(ApproverType.User),
|
||||||
|
id: z.string().optional(),
|
||||||
|
username: z.string().optional()
|
||||||
|
})
|
||||||
|
])
|
||||||
|
.array()
|
||||||
|
.min(1, { message: "At least one approver should be provided" })
|
||||||
|
.max(100, "Cannot have more than 100 approvers"),
|
||||||
|
bypassers: z
|
||||||
|
.discriminatedUnion("type", [
|
||||||
|
z.object({ type: z.literal(BypasserType.Group), id: z.string() }),
|
||||||
|
z.object({
|
||||||
|
type: z.literal(BypasserType.User),
|
||||||
|
id: z.string().optional(),
|
||||||
|
username: z.string().optional()
|
||||||
|
})
|
||||||
|
])
|
||||||
|
.array()
|
||||||
|
.max(100, "Cannot have more than 100 bypassers")
|
||||||
|
.optional(),
|
||||||
|
approvals: z.number().min(1).default(1),
|
||||||
|
enforcementLevel: z.nativeEnum(EnforcementLevel).default(EnforcementLevel.Hard),
|
||||||
|
allowedSelfApprovals: z.boolean().default(true)
|
||||||
|
})
|
||||||
|
.refine((data) => data.environment || data.environments, "At least one environment should be provided"),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
approval: sapPubSchema
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const approval = await server.services.secretApprovalPolicy.createSecretApprovalPolicy({
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
projectId: req.body.workspaceId,
|
||||||
|
...req.body,
|
||||||
|
name: req.body.name ?? `${req.body.environment || req.body.environments?.join(",")}-${nanoid(3)}`,
|
||||||
|
enforcementLevel: req.body.enforcementLevel
|
||||||
|
});
|
||||||
|
return { approval };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
url: "/:sapId",
|
||||||
|
method: "PATCH",
|
||||||
|
config: {
|
||||||
|
rateLimit: writeLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
params: z.object({
|
||||||
|
sapId: z.string()
|
||||||
|
}),
|
||||||
|
body: z.object({
|
||||||
|
name: z.string().optional(),
|
||||||
|
approvers: z
|
||||||
|
.discriminatedUnion("type", [
|
||||||
|
z.object({ type: z.literal(ApproverType.Group), id: z.string() }),
|
||||||
|
z.object({ type: z.literal(ApproverType.User), id: z.string().optional(), username: z.string().optional() })
|
||||||
|
])
|
||||||
|
.array()
|
||||||
|
.min(1, { message: "At least one approver should be provided" })
|
||||||
|
.max(100, "Cannot have more than 100 approvers"),
|
||||||
|
bypassers: z
|
||||||
|
.discriminatedUnion("type", [
|
||||||
|
z.object({ type: z.literal(BypasserType.Group), id: z.string() }),
|
||||||
|
z.object({ type: z.literal(BypasserType.User), id: z.string().optional(), username: z.string().optional() })
|
||||||
|
])
|
||||||
|
.array()
|
||||||
|
.max(100, "Cannot have more than 100 bypassers")
|
||||||
|
.optional(),
|
||||||
|
approvals: z.number().min(1).default(1),
|
||||||
|
secretPath: z
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.min(1, { message: "Secret path cannot be empty" })
|
||||||
|
.optional()
|
||||||
|
.transform((val) => (val ? removeTrailingSlash(val) : undefined)),
|
||||||
|
enforcementLevel: z.nativeEnum(EnforcementLevel).optional(),
|
||||||
|
allowedSelfApprovals: z.boolean().default(true),
|
||||||
|
environments: z.array(z.string()).optional()
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
approval: sapPubSchema
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const approval = await server.services.secretApprovalPolicy.updateSecretApprovalPolicy({
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
...req.body,
|
||||||
|
secretPolicyId: req.params.sapId
|
||||||
|
});
|
||||||
|
return { approval };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
url: "/:sapId",
|
||||||
|
method: "DELETE",
|
||||||
|
config: {
|
||||||
|
rateLimit: writeLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
params: z.object({
|
||||||
|
sapId: z.string()
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
approval: sapPubSchema
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const approval = await server.services.secretApprovalPolicy.deleteSecretApprovalPolicy({
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
secretPolicyId: req.params.sapId
|
||||||
|
});
|
||||||
|
return { approval };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
url: "/",
|
||||||
|
method: "GET",
|
||||||
|
config: {
|
||||||
|
rateLimit: readLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
querystring: z.object({
|
||||||
|
workspaceId: z.string().trim()
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
approvals: sapPubSchema
|
||||||
|
.extend({
|
||||||
|
approvers: z
|
||||||
|
.object({
|
||||||
|
id: z.string().nullable().optional(),
|
||||||
|
type: z.nativeEnum(ApproverType)
|
||||||
|
})
|
||||||
|
.array(),
|
||||||
|
bypassers: z
|
||||||
|
.object({
|
||||||
|
id: z.string().nullable().optional(),
|
||||||
|
type: z.nativeEnum(BypasserType)
|
||||||
|
})
|
||||||
|
.array()
|
||||||
|
})
|
||||||
|
.array()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const approvals = await server.services.secretApprovalPolicy.getSecretApprovalPolicyByProjectId({
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
projectId: req.query.workspaceId
|
||||||
|
});
|
||||||
|
return { approvals };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
url: "/:sapId",
|
||||||
|
method: "GET",
|
||||||
|
config: {
|
||||||
|
rateLimit: readLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
params: z.object({
|
||||||
|
sapId: z.string()
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
approval: sapPubSchema.extend({
|
||||||
|
approvers: z
|
||||||
|
.object({
|
||||||
|
id: z.string().nullable().optional(),
|
||||||
|
type: z.nativeEnum(ApproverType),
|
||||||
|
username: z.string().nullable().optional()
|
||||||
|
})
|
||||||
|
.array(),
|
||||||
|
bypassers: z
|
||||||
|
.object({
|
||||||
|
id: z.string().nullable().optional(),
|
||||||
|
type: z.nativeEnum(BypasserType),
|
||||||
|
username: z.string().nullable().optional()
|
||||||
|
})
|
||||||
|
.array()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const approval = await server.services.secretApprovalPolicy.getSecretApprovalPolicyById({
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
...req.params
|
||||||
|
});
|
||||||
|
|
||||||
|
return { approval };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
url: "/board",
|
||||||
|
method: "GET",
|
||||||
|
config: {
|
||||||
|
rateLimit: readLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
querystring: z.object({
|
||||||
|
workspaceId: z.string().trim(),
|
||||||
|
environment: z.string().trim(),
|
||||||
|
secretPath: z.string().trim().transform(removeTrailingSlash)
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
policy: sapPubSchema
|
||||||
|
.extend({
|
||||||
|
userApprovers: z.object({ userId: z.string().nullable().optional() }).array()
|
||||||
|
})
|
||||||
|
.optional()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const policy = await server.services.secretApprovalPolicy.getSecretApprovalPolicyOfFolder({
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
projectId: req.query.workspaceId,
|
||||||
|
...req.query
|
||||||
|
});
|
||||||
|
return { policy };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -29,7 +29,7 @@ import { registerRateLimitRouter } from "./rate-limit-router";
|
|||||||
import { registerRelayRouter } from "./relay-router";
|
import { registerRelayRouter } from "./relay-router";
|
||||||
import { registerSamlRouter } from "./saml-router";
|
import { registerSamlRouter } from "./saml-router";
|
||||||
import { registerScimRouter } from "./scim-router";
|
import { registerScimRouter } from "./scim-router";
|
||||||
import { registerSecretApprovalPolicyRouter } from "./secret-approval-policy-router";
|
import { registerDepreciatedSecretApprovalPolicyRouter } from "./depreciated-secret-approval-policy-router";
|
||||||
import { registerSecretApprovalRequestRouter } from "./secret-approval-request-router";
|
import { registerSecretApprovalRequestRouter } from "./secret-approval-request-router";
|
||||||
import { registerSecretRotationProviderRouter } from "./secret-rotation-provider-router";
|
import { registerSecretRotationProviderRouter } from "./secret-rotation-provider-router";
|
||||||
import { registerSecretRotationRouter } from "./secret-rotation-router";
|
import { registerSecretRotationRouter } from "./secret-rotation-router";
|
||||||
@@ -71,7 +71,7 @@ export const registerV1EERoutes = async (server: FastifyZodProvider) => {
|
|||||||
|
|
||||||
await server.register(registerSnapshotRouter, { prefix: "/secret-snapshot" });
|
await server.register(registerSnapshotRouter, { prefix: "/secret-snapshot" });
|
||||||
await server.register(registerPITRouter, { prefix: "/pit" });
|
await server.register(registerPITRouter, { prefix: "/pit" });
|
||||||
await server.register(registerSecretApprovalPolicyRouter, { prefix: "/secret-approvals" });
|
await server.register(registerDepreciatedSecretApprovalPolicyRouter, { prefix: "/secret-approvals" });
|
||||||
await server.register(registerSecretApprovalRequestRouter, {
|
await server.register(registerSecretApprovalRequestRouter, {
|
||||||
prefix: "/secret-approval-requests"
|
prefix: "/secret-approval-requests"
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
|
|||||||
},
|
},
|
||||||
schema: {
|
schema: {
|
||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
workspaceId: z.string().trim(),
|
projectId: z.string().trim(),
|
||||||
environment: z.string().trim().optional(),
|
environment: z.string().trim().optional(),
|
||||||
committer: z.string().trim().optional(),
|
committer: z.string().trim().optional(),
|
||||||
search: z.string().trim().optional(),
|
search: z.string().trim().optional(),
|
||||||
@@ -80,7 +80,7 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
|
|||||||
actorAuthMethod: req.permission.authMethod,
|
actorAuthMethod: req.permission.authMethod,
|
||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
...req.query,
|
...req.query,
|
||||||
projectId: req.query.workspaceId
|
projectId: req.query.projectId
|
||||||
});
|
});
|
||||||
return { approvals, totalCount };
|
return { approvals, totalCount };
|
||||||
}
|
}
|
||||||
@@ -94,7 +94,7 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
|
|||||||
},
|
},
|
||||||
schema: {
|
schema: {
|
||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
workspaceId: z.string().trim(),
|
projectId: z.string().trim(),
|
||||||
policyId: z.string().trim().optional()
|
policyId: z.string().trim().optional()
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
@@ -113,7 +113,7 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
|
|||||||
actorId: req.permission.id,
|
actorId: req.permission.id,
|
||||||
actorAuthMethod: req.permission.authMethod,
|
actorAuthMethod: req.permission.authMethod,
|
||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
projectId: req.query.workspaceId,
|
projectId: req.query.projectId,
|
||||||
policyId: req.query.policyId
|
policyId: req.query.policyId
|
||||||
});
|
});
|
||||||
return { approvals };
|
return { approvals };
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
import { registerGatewayV2Router } from "./gateway-router";
|
import { registerGatewayV2Router } from "./gateway-router";
|
||||||
import { registerIdentityProjectAdditionalPrivilegeRouter } from "./identity-project-additional-privilege-router";
|
import { registerIdentityProjectAdditionalPrivilegeRouter } from "./identity-project-additional-privilege-router";
|
||||||
import { registerDepreciatedProjectRoleRouter } from "./depreciated-project-role-router";
|
import { registerDepreciatedProjectRoleRouter } from "./depreciated-project-role-router";
|
||||||
|
import { registerSecretApprovalPolicyRouter } from "./secret-approval-policy-router";
|
||||||
|
|
||||||
export const registerV2EERoutes = async (server: FastifyZodProvider) => {
|
export const registerV2EERoutes = async (server: FastifyZodProvider) => {
|
||||||
await server.register(
|
await server.register(
|
||||||
@@ -26,6 +27,8 @@ export const registerV2EERoutes = async (server: FastifyZodProvider) => {
|
|||||||
|
|
||||||
await server.register(registerGatewayV2Router, { prefix: "/gateways" });
|
await server.register(registerGatewayV2Router, { prefix: "/gateways" });
|
||||||
|
|
||||||
|
await server.register(registerSecretApprovalPolicyRouter, { prefix: "/secret-approvals" });
|
||||||
|
|
||||||
await server.register(
|
await server.register(
|
||||||
async (secretRotationV2Router) => {
|
async (secretRotationV2Router) => {
|
||||||
// register generic secret rotation endpoints
|
// register generic secret rotation endpoints
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export const registerSecretApprovalPolicyRouter = async (server: FastifyZodProvi
|
|||||||
schema: {
|
schema: {
|
||||||
body: z
|
body: z
|
||||||
.object({
|
.object({
|
||||||
workspaceId: z.string(),
|
projectId: z.string(),
|
||||||
name: z.string().optional(),
|
name: z.string().optional(),
|
||||||
environment: z.string().optional(),
|
environment: z.string().optional(),
|
||||||
environments: z.string().array().optional(),
|
environments: z.string().array().optional(),
|
||||||
@@ -69,7 +69,6 @@ export const registerSecretApprovalPolicyRouter = async (server: FastifyZodProvi
|
|||||||
actorId: req.permission.id,
|
actorId: req.permission.id,
|
||||||
actorAuthMethod: req.permission.authMethod,
|
actorAuthMethod: req.permission.authMethod,
|
||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
projectId: req.body.workspaceId,
|
|
||||||
...req.body,
|
...req.body,
|
||||||
name: req.body.name ?? `${req.body.environment || req.body.environments?.join(",")}-${nanoid(3)}`,
|
name: req.body.name ?? `${req.body.environment || req.body.environments?.join(",")}-${nanoid(3)}`,
|
||||||
enforcementLevel: req.body.enforcementLevel
|
enforcementLevel: req.body.enforcementLevel
|
||||||
@@ -174,7 +173,7 @@ export const registerSecretApprovalPolicyRouter = async (server: FastifyZodProvi
|
|||||||
},
|
},
|
||||||
schema: {
|
schema: {
|
||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
workspaceId: z.string().trim()
|
projectId: z.string().trim()
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
@@ -204,7 +203,7 @@ export const registerSecretApprovalPolicyRouter = async (server: FastifyZodProvi
|
|||||||
actorId: req.permission.id,
|
actorId: req.permission.id,
|
||||||
actorAuthMethod: req.permission.authMethod,
|
actorAuthMethod: req.permission.authMethod,
|
||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
projectId: req.query.workspaceId
|
projectId: req.query.projectId
|
||||||
});
|
});
|
||||||
return { approvals };
|
return { approvals };
|
||||||
}
|
}
|
||||||
@@ -263,7 +262,7 @@ export const registerSecretApprovalPolicyRouter = async (server: FastifyZodProvi
|
|||||||
},
|
},
|
||||||
schema: {
|
schema: {
|
||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
workspaceId: z.string().trim(),
|
projectId: z.string().trim(),
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
secretPath: z.string().trim().transform(removeTrailingSlash)
|
secretPath: z.string().trim().transform(removeTrailingSlash)
|
||||||
}),
|
}),
|
||||||
@@ -284,7 +283,6 @@ export const registerSecretApprovalPolicyRouter = async (server: FastifyZodProvi
|
|||||||
actorId: req.permission.id,
|
actorId: req.permission.id,
|
||||||
actorAuthMethod: req.permission.authMethod,
|
actorAuthMethod: req.permission.authMethod,
|
||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
projectId: req.query.workspaceId,
|
|
||||||
...req.query
|
...req.query
|
||||||
});
|
});
|
||||||
return { policy };
|
return { policy };
|
||||||
@@ -901,7 +901,7 @@ export const ENVIRONMENTS = {
|
|||||||
|
|
||||||
export const FOLDERS = {
|
export const FOLDERS = {
|
||||||
LIST: {
|
LIST: {
|
||||||
workspaceId: "The ID of the project to list folders from.",
|
projectId: "The ID of the project to list folders from.",
|
||||||
environment: "The slug of the environment to list folders from.",
|
environment: "The slug of the environment to list folders from.",
|
||||||
path: "The path to list folders from.",
|
path: "The path to list folders from.",
|
||||||
directory: "The directory to list folders from. (Deprecated in favor of path)",
|
directory: "The directory to list folders from. (Deprecated in favor of path)",
|
||||||
@@ -913,7 +913,7 @@ export const FOLDERS = {
|
|||||||
folderId: "The ID of the folder to get details."
|
folderId: "The ID of the folder to get details."
|
||||||
},
|
},
|
||||||
CREATE: {
|
CREATE: {
|
||||||
workspaceId: "The ID of the project to create the folder in.",
|
projectId: "The ID of the project to create the folder in.",
|
||||||
environment: "The slug of the environment to create the folder in.",
|
environment: "The slug of the environment to create the folder in.",
|
||||||
name: "The name of the folder to create.",
|
name: "The name of the folder to create.",
|
||||||
path: "The path of the folder to create.",
|
path: "The path of the folder to create.",
|
||||||
@@ -927,12 +927,12 @@ export const FOLDERS = {
|
|||||||
path: "The path of the folder to update.",
|
path: "The path of the folder to update.",
|
||||||
directory: "The new directory of the folder to update. (Deprecated in favor of path)",
|
directory: "The new directory of the folder to update. (Deprecated in favor of path)",
|
||||||
projectSlug: "The slug of the project where the folder is located.",
|
projectSlug: "The slug of the project where the folder is located.",
|
||||||
workspaceId: "The ID of the project where the folder is located.",
|
projectId: "The ID of the project where the folder is located.",
|
||||||
description: "An optional description label for the folder."
|
description: "An optional description label for the folder."
|
||||||
},
|
},
|
||||||
DELETE: {
|
DELETE: {
|
||||||
folderIdOrName: "The ID or name of the folder to delete.",
|
folderIdOrName: "The ID or name of the folder to delete.",
|
||||||
workspaceId: "The ID of the project to delete the folder from.",
|
projectId: "The ID of the project to delete the folder from.",
|
||||||
environment: "The slug of the environment where the folder is located.",
|
environment: "The slug of the environment where the folder is located.",
|
||||||
directory: "The directory of the folder to delete. (Deprecated in favor of path)",
|
directory: "The directory of the folder to delete. (Deprecated in favor of path)",
|
||||||
path: "The path of the folder to delete."
|
path: "The path of the folder to delete."
|
||||||
@@ -1043,7 +1043,7 @@ export const RAW_SECRETS = {
|
|||||||
|
|
||||||
export const SECRET_IMPORTS = {
|
export const SECRET_IMPORTS = {
|
||||||
LIST: {
|
LIST: {
|
||||||
workspaceId: "The ID of the project to list secret imports from.",
|
projectId: "The ID of the project to list secret imports from.",
|
||||||
environment: "The slug of the environment to list secret imports from.",
|
environment: "The slug of the environment to list secret imports from.",
|
||||||
path: "The path to list secret imports from."
|
path: "The path to list secret imports from."
|
||||||
},
|
},
|
||||||
@@ -1053,7 +1053,7 @@ export const SECRET_IMPORTS = {
|
|||||||
CREATE: {
|
CREATE: {
|
||||||
environment: "The slug of the environment to import into.",
|
environment: "The slug of the environment to import into.",
|
||||||
path: "The path to import into.",
|
path: "The path to import into.",
|
||||||
workspaceId: "The ID of the project you are working in.",
|
projectId: "The ID of the project you are working in.",
|
||||||
isReplication:
|
isReplication:
|
||||||
"When true, secrets from the source will be automatically sent to the destination. If approval policies exist at the destination, the secrets will be sent as approval requests instead of being applied immediately.",
|
"When true, secrets from the source will be automatically sent to the destination. If approval policies exist at the destination, the secrets will be sent as approval requests instead of being applied immediately.",
|
||||||
import: {
|
import: {
|
||||||
@@ -1070,10 +1070,10 @@ export const SECRET_IMPORTS = {
|
|||||||
position: "The new position of the secret import. The lowest number will be displayed as the first import."
|
position: "The new position of the secret import. The lowest number will be displayed as the first import."
|
||||||
},
|
},
|
||||||
path: "The path of the secret import to update.",
|
path: "The path of the secret import to update.",
|
||||||
workspaceId: "The ID of the project where the secret import is located."
|
projectId: "The ID of the project where the secret import is located."
|
||||||
},
|
},
|
||||||
DELETE: {
|
DELETE: {
|
||||||
workspaceId: "The ID of the project to delete the secret import from.",
|
projectId: "The ID of the project to delete the secret import from.",
|
||||||
secretImportId: "The ID of the secret import to delete.",
|
secretImportId: "The ID of the secret import to delete.",
|
||||||
environment: "The slug of the environment where the secret import is located.",
|
environment: "The slug of the environment where the secret import is located.",
|
||||||
path: "The path of the secret import to delete."
|
path: "The path of the secret import to delete."
|
||||||
|
|||||||
444
backend/src/server/routes/v1/depreciated-secret-folder-router.ts
Normal file
444
backend/src/server/routes/v1/depreciated-secret-folder-router.ts
Normal file
@@ -0,0 +1,444 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
import { SecretFoldersSchema } from "@app/db/schemas";
|
||||||
|
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
||||||
|
import { ApiDocsTags, FOLDERS } from "@app/lib/api-docs";
|
||||||
|
import { prefixWithSlash, removeTrailingSlash } from "@app/lib/fn";
|
||||||
|
import { isValidFolderName } from "@app/lib/validator";
|
||||||
|
import { readLimit, secretsLimit } from "@app/server/config/rateLimiter";
|
||||||
|
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||||
|
import { AuthMode } from "@app/services/auth/auth-type";
|
||||||
|
|
||||||
|
import { booleanSchema } from "../sanitizedSchemas";
|
||||||
|
|
||||||
|
export const registerDepreciatedSecretFolderRouter = async (server: FastifyZodProvider) => {
|
||||||
|
server.route({
|
||||||
|
url: "/",
|
||||||
|
method: "POST",
|
||||||
|
config: {
|
||||||
|
rateLimit: secretsLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
hide: false,
|
||||||
|
tags: [ApiDocsTags.Folders],
|
||||||
|
description: "Create folders",
|
||||||
|
security: [
|
||||||
|
{
|
||||||
|
bearerAuth: []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
body: z.object({
|
||||||
|
workspaceId: z.string().trim().describe(FOLDERS.CREATE.projectId),
|
||||||
|
environment: z.string().trim().describe(FOLDERS.CREATE.environment),
|
||||||
|
name: z
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.describe(FOLDERS.CREATE.name)
|
||||||
|
.refine((name) => isValidFolderName(name), {
|
||||||
|
message: "Invalid folder name. Only alphanumeric characters, dashes, and underscores are allowed."
|
||||||
|
}),
|
||||||
|
path: z
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.default("/")
|
||||||
|
.transform(prefixWithSlash) // Transformations get skipped if path is undefined
|
||||||
|
.transform(removeTrailingSlash)
|
||||||
|
.describe(FOLDERS.CREATE.path)
|
||||||
|
.optional(),
|
||||||
|
// backward compatibility with cli
|
||||||
|
directory: z
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.default("/")
|
||||||
|
.transform(prefixWithSlash) // Transformations get skipped if directory is undefined
|
||||||
|
.transform(removeTrailingSlash)
|
||||||
|
.describe(FOLDERS.CREATE.directory)
|
||||||
|
.optional(),
|
||||||
|
description: z.string().optional().nullable().describe(FOLDERS.CREATE.description)
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
folder: SecretFoldersSchema.extend({
|
||||||
|
path: z.string()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const path = req.body.path || req.body.directory || "/";
|
||||||
|
const folder = await server.services.folder.createFolder({
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
...req.body,
|
||||||
|
projectId: req.body.workspaceId,
|
||||||
|
path,
|
||||||
|
description: req.body.description
|
||||||
|
});
|
||||||
|
await server.services.auditLog.createAuditLog({
|
||||||
|
...req.auditLogInfo,
|
||||||
|
projectId: req.body.workspaceId,
|
||||||
|
event: {
|
||||||
|
type: EventType.CREATE_FOLDER,
|
||||||
|
metadata: {
|
||||||
|
environment: req.body.environment,
|
||||||
|
folderId: folder.id,
|
||||||
|
folderName: folder.name,
|
||||||
|
folderPath: path,
|
||||||
|
...(req.body.description ? { description: req.body.description } : {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return { folder };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
url: "/:folderId",
|
||||||
|
method: "PATCH",
|
||||||
|
config: {
|
||||||
|
rateLimit: secretsLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
hide: false,
|
||||||
|
tags: [ApiDocsTags.Folders],
|
||||||
|
description: "Update folder",
|
||||||
|
security: [
|
||||||
|
{
|
||||||
|
bearerAuth: []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
params: z.object({
|
||||||
|
// old way this was name
|
||||||
|
folderId: z.string().describe(FOLDERS.UPDATE.folderId)
|
||||||
|
}),
|
||||||
|
body: z.object({
|
||||||
|
workspaceId: z.string().trim().describe(FOLDERS.UPDATE.projectId),
|
||||||
|
environment: z.string().trim().describe(FOLDERS.UPDATE.environment),
|
||||||
|
name: z
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.describe(FOLDERS.UPDATE.name)
|
||||||
|
.refine((name) => isValidFolderName(name), {
|
||||||
|
message: "Invalid folder name. Only alphanumeric characters, dashes, and underscores are allowed."
|
||||||
|
}),
|
||||||
|
path: z
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.default("/")
|
||||||
|
.transform(prefixWithSlash) // Transformations get skipped if path is undefined
|
||||||
|
.transform(removeTrailingSlash)
|
||||||
|
.describe(FOLDERS.UPDATE.path)
|
||||||
|
.optional(),
|
||||||
|
// backward compatibility with cli
|
||||||
|
directory: z
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.default("/")
|
||||||
|
.transform(prefixWithSlash) // Transformations get skipped if directory is undefined
|
||||||
|
.transform(removeTrailingSlash)
|
||||||
|
.describe(FOLDERS.UPDATE.directory)
|
||||||
|
.optional(),
|
||||||
|
description: z.string().optional().nullable().describe(FOLDERS.UPDATE.description)
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
folder: SecretFoldersSchema.extend({
|
||||||
|
path: z.string()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const path = req.body.path || req.body.directory || "/";
|
||||||
|
const { folder, old } = await server.services.folder.updateFolder({
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
...req.body,
|
||||||
|
projectId: req.body.workspaceId,
|
||||||
|
id: req.params.folderId,
|
||||||
|
path
|
||||||
|
});
|
||||||
|
await server.services.auditLog.createAuditLog({
|
||||||
|
...req.auditLogInfo,
|
||||||
|
projectId: req.body.workspaceId,
|
||||||
|
event: {
|
||||||
|
type: EventType.UPDATE_FOLDER,
|
||||||
|
metadata: {
|
||||||
|
environment: req.body.environment,
|
||||||
|
folderId: folder.id,
|
||||||
|
folderPath: path,
|
||||||
|
newFolderName: folder.name,
|
||||||
|
oldFolderName: old.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return { folder };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
url: "/batch",
|
||||||
|
method: "PATCH",
|
||||||
|
config: {
|
||||||
|
rateLimit: secretsLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
hide: false,
|
||||||
|
tags: [ApiDocsTags.Folders],
|
||||||
|
description: "Update folders by batch",
|
||||||
|
security: [
|
||||||
|
{
|
||||||
|
bearerAuth: []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
body: z.object({
|
||||||
|
projectSlug: z.string().trim().describe(FOLDERS.UPDATE.projectSlug),
|
||||||
|
folders: z
|
||||||
|
.object({
|
||||||
|
id: z.string().describe(FOLDERS.UPDATE.folderId),
|
||||||
|
environment: z.string().trim().describe(FOLDERS.UPDATE.environment),
|
||||||
|
name: z
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.describe(FOLDERS.UPDATE.name)
|
||||||
|
.refine((name) => isValidFolderName(name), {
|
||||||
|
message: "Invalid folder name. Only alphanumeric characters, dashes, and underscores are allowed."
|
||||||
|
}),
|
||||||
|
path: z
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.default("/")
|
||||||
|
.transform(prefixWithSlash)
|
||||||
|
.transform(removeTrailingSlash)
|
||||||
|
.describe(FOLDERS.UPDATE.path),
|
||||||
|
description: z.string().optional().nullable().describe(FOLDERS.UPDATE.description)
|
||||||
|
})
|
||||||
|
.array()
|
||||||
|
.min(1)
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
folders: SecretFoldersSchema.array()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const { newFolders, oldFolders, projectId } = await server.services.folder.updateManyFolders({
|
||||||
|
...req.body,
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
actorOrgId: req.permission.orgId
|
||||||
|
});
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
req.body.folders.map(async (folder, index) => {
|
||||||
|
await server.services.auditLog.createAuditLog({
|
||||||
|
...req.auditLogInfo,
|
||||||
|
projectId,
|
||||||
|
event: {
|
||||||
|
type: EventType.UPDATE_FOLDER,
|
||||||
|
metadata: {
|
||||||
|
environment: oldFolders[index].envId,
|
||||||
|
folderId: oldFolders[index].id,
|
||||||
|
folderPath: folder.path,
|
||||||
|
newFolderName: newFolders[index].name,
|
||||||
|
oldFolderName: oldFolders[index].name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
return { folders: newFolders };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO(daniel): Expose this route in api reference and write docs for it.
|
||||||
|
server.route({
|
||||||
|
method: "DELETE",
|
||||||
|
url: "/:folderIdOrName",
|
||||||
|
config: {
|
||||||
|
rateLimit: secretsLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
hide: false,
|
||||||
|
tags: [ApiDocsTags.Folders],
|
||||||
|
description: "Delete a folder",
|
||||||
|
security: [
|
||||||
|
{
|
||||||
|
bearerAuth: []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
params: z.object({
|
||||||
|
folderIdOrName: z.string().describe(FOLDERS.DELETE.folderIdOrName)
|
||||||
|
}),
|
||||||
|
body: z.object({
|
||||||
|
workspaceId: z.string().trim().describe(FOLDERS.DELETE.projectId),
|
||||||
|
environment: z.string().trim().describe(FOLDERS.DELETE.environment),
|
||||||
|
path: z
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.default("/")
|
||||||
|
.transform(prefixWithSlash) // Transformations get skipped if path is undefined
|
||||||
|
.transform(removeTrailingSlash)
|
||||||
|
.describe(FOLDERS.DELETE.path)
|
||||||
|
.optional(),
|
||||||
|
// keep this here as cli need directory
|
||||||
|
directory: z
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.default("/")
|
||||||
|
.transform(prefixWithSlash) // Transformations get skipped if directory is undefined
|
||||||
|
.transform(removeTrailingSlash)
|
||||||
|
.describe(FOLDERS.DELETE.directory)
|
||||||
|
.optional()
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
folder: SecretFoldersSchema
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const path = req.body.path || req.body.directory || "/";
|
||||||
|
const folder = await server.services.folder.deleteFolder({
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
...req.body,
|
||||||
|
projectId: req.body.workspaceId,
|
||||||
|
idOrName: req.params.folderIdOrName,
|
||||||
|
path
|
||||||
|
});
|
||||||
|
await server.services.auditLog.createAuditLog({
|
||||||
|
...req.auditLogInfo,
|
||||||
|
projectId: req.body.workspaceId,
|
||||||
|
event: {
|
||||||
|
type: EventType.DELETE_FOLDER,
|
||||||
|
metadata: {
|
||||||
|
environment: req.body.environment,
|
||||||
|
folderId: folder.id,
|
||||||
|
folderPath: path,
|
||||||
|
folderName: folder.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return { folder };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
method: "GET",
|
||||||
|
url: "/",
|
||||||
|
config: {
|
||||||
|
rateLimit: readLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
hide: false,
|
||||||
|
tags: [ApiDocsTags.Folders],
|
||||||
|
description: "Get folders",
|
||||||
|
security: [
|
||||||
|
{
|
||||||
|
bearerAuth: []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
querystring: z.object({
|
||||||
|
workspaceId: z.string().trim().describe(FOLDERS.LIST.projectId),
|
||||||
|
environment: z.string().trim().describe(FOLDERS.LIST.environment),
|
||||||
|
lastSecretModified: z.string().datetime().trim().optional().describe(FOLDERS.LIST.lastSecretModified),
|
||||||
|
path: z
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.transform(prefixWithSlash) // Transformations get skipped if path is undefined
|
||||||
|
.transform(removeTrailingSlash)
|
||||||
|
.describe(FOLDERS.LIST.path)
|
||||||
|
.optional(),
|
||||||
|
// backward compatibility with cli
|
||||||
|
directory: z
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.transform(prefixWithSlash) // Transformations get skipped if directory is undefined
|
||||||
|
.transform(removeTrailingSlash)
|
||||||
|
.describe(FOLDERS.LIST.directory)
|
||||||
|
.optional(),
|
||||||
|
recursive: booleanSchema.default(false).describe(FOLDERS.LIST.recursive)
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
folders: SecretFoldersSchema.extend({
|
||||||
|
relativePath: z.string().optional()
|
||||||
|
}).array()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const path = req.query.path || req.query.directory || "/";
|
||||||
|
const folders = await server.services.folder.getFolders({
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
...req.query,
|
||||||
|
projectId: req.query.workspaceId,
|
||||||
|
path
|
||||||
|
});
|
||||||
|
return { folders };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
method: "GET",
|
||||||
|
url: "/:id",
|
||||||
|
config: {
|
||||||
|
rateLimit: readLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
hide: false,
|
||||||
|
tags: [ApiDocsTags.Folders],
|
||||||
|
description: "Get folder by id",
|
||||||
|
security: [
|
||||||
|
{
|
||||||
|
bearerAuth: []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
params: z.object({
|
||||||
|
id: z.string().trim().describe(FOLDERS.GET_BY_ID.folderId)
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
folder: SecretFoldersSchema.extend({
|
||||||
|
environment: z.object({
|
||||||
|
envId: z.string(),
|
||||||
|
envName: z.string(),
|
||||||
|
envSlug: z.string()
|
||||||
|
}),
|
||||||
|
path: z.string(),
|
||||||
|
projectId: z.string()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const folder = await server.services.folder.getFolderById({
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
id: req.params.id
|
||||||
|
});
|
||||||
|
return { folder };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
472
backend/src/server/routes/v1/depreciated-secret-import-router.ts
Normal file
472
backend/src/server/routes/v1/depreciated-secret-import-router.ts
Normal file
@@ -0,0 +1,472 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
import { SecretImportsSchema, SecretsSchema } from "@app/db/schemas";
|
||||||
|
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
||||||
|
import { ApiDocsTags, SECRET_IMPORTS } from "@app/lib/api-docs";
|
||||||
|
import { removeTrailingSlash } from "@app/lib/fn";
|
||||||
|
import { readLimit, secretsLimit } from "@app/server/config/rateLimiter";
|
||||||
|
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||||
|
import { AuthMode } from "@app/services/auth/auth-type";
|
||||||
|
|
||||||
|
import { secretRawSchema } from "../sanitizedSchemas";
|
||||||
|
|
||||||
|
export const registerDepreciatedSecretImportRouter = async (server: FastifyZodProvider) => {
|
||||||
|
server.route({
|
||||||
|
method: "POST",
|
||||||
|
url: "/",
|
||||||
|
config: {
|
||||||
|
rateLimit: secretsLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
hide: false,
|
||||||
|
tags: [ApiDocsTags.SecretImports],
|
||||||
|
description: "Create secret imports",
|
||||||
|
security: [
|
||||||
|
{
|
||||||
|
bearerAuth: []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
body: z.object({
|
||||||
|
workspaceId: z.string().trim().describe(SECRET_IMPORTS.CREATE.projectId),
|
||||||
|
environment: z.string().trim().describe(SECRET_IMPORTS.CREATE.environment),
|
||||||
|
path: z.string().trim().default("/").transform(removeTrailingSlash).describe(SECRET_IMPORTS.CREATE.path),
|
||||||
|
import: z.object({
|
||||||
|
environment: z.string().trim().describe(SECRET_IMPORTS.CREATE.import.environment),
|
||||||
|
path: z.string().trim().transform(removeTrailingSlash).describe(SECRET_IMPORTS.CREATE.import.path)
|
||||||
|
}),
|
||||||
|
isReplication: z.boolean().default(false).describe(SECRET_IMPORTS.CREATE.isReplication)
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
message: z.string(),
|
||||||
|
secretImport: SecretImportsSchema.omit({ importEnv: true }).merge(
|
||||||
|
z.object({
|
||||||
|
importEnv: z.object({ name: z.string(), slug: z.string(), id: z.string() })
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const secretImport = await server.services.secretImport.createImport({
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
...req.body,
|
||||||
|
projectId: req.body.workspaceId,
|
||||||
|
data: req.body.import
|
||||||
|
});
|
||||||
|
|
||||||
|
await server.services.auditLog.createAuditLog({
|
||||||
|
...req.auditLogInfo,
|
||||||
|
projectId: req.body.workspaceId,
|
||||||
|
event: {
|
||||||
|
type: EventType.CREATE_SECRET_IMPORT,
|
||||||
|
metadata: {
|
||||||
|
secretImportId: secretImport.id,
|
||||||
|
folderId: secretImport.folderId,
|
||||||
|
importFromSecretPath: secretImport.importPath,
|
||||||
|
importFromEnvironment: secretImport.importEnv.slug,
|
||||||
|
importToEnvironment: req.body.environment,
|
||||||
|
importToSecretPath: req.body.path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return { message: "Successfully created secret import", secretImport };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
method: "PATCH",
|
||||||
|
url: "/:secretImportId",
|
||||||
|
config: {
|
||||||
|
rateLimit: secretsLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
hide: false,
|
||||||
|
tags: [ApiDocsTags.SecretImports],
|
||||||
|
description: "Update secret imports",
|
||||||
|
security: [
|
||||||
|
{
|
||||||
|
bearerAuth: []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
params: z.object({
|
||||||
|
secretImportId: z.string().trim().describe(SECRET_IMPORTS.UPDATE.secretImportId)
|
||||||
|
}),
|
||||||
|
body: z.object({
|
||||||
|
workspaceId: z.string().trim().describe(SECRET_IMPORTS.UPDATE.projectId),
|
||||||
|
environment: z.string().trim().describe(SECRET_IMPORTS.UPDATE.environment),
|
||||||
|
path: z.string().trim().default("/").transform(removeTrailingSlash).describe(SECRET_IMPORTS.UPDATE.path),
|
||||||
|
import: z.object({
|
||||||
|
environment: z.string().trim().optional().describe(SECRET_IMPORTS.UPDATE.import.environment),
|
||||||
|
path: z
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.optional()
|
||||||
|
.transform((val) => (val ? removeTrailingSlash(val) : val))
|
||||||
|
.describe(SECRET_IMPORTS.UPDATE.import.path),
|
||||||
|
position: z.number().optional().describe(SECRET_IMPORTS.UPDATE.import.position)
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
message: z.string(),
|
||||||
|
secretImport: SecretImportsSchema.omit({ importEnv: true }).merge(
|
||||||
|
z.object({
|
||||||
|
importEnv: z.object({ name: z.string(), slug: z.string(), id: z.string() })
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const secretImport = await server.services.secretImport.updateImport({
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
id: req.params.secretImportId,
|
||||||
|
...req.body,
|
||||||
|
projectId: req.body.workspaceId,
|
||||||
|
data: req.body.import
|
||||||
|
});
|
||||||
|
|
||||||
|
await server.services.auditLog.createAuditLog({
|
||||||
|
...req.auditLogInfo,
|
||||||
|
projectId: req.body.workspaceId,
|
||||||
|
event: {
|
||||||
|
type: EventType.UPDATE_SECRET_IMPORT,
|
||||||
|
metadata: {
|
||||||
|
secretImportId: secretImport.id,
|
||||||
|
folderId: secretImport.folderId,
|
||||||
|
position: secretImport.position,
|
||||||
|
importToEnvironment: req.body.environment,
|
||||||
|
importToSecretPath: req.body.path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return { message: "Successfully updated secret import", secretImport };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
method: "DELETE",
|
||||||
|
url: "/:secretImportId",
|
||||||
|
config: {
|
||||||
|
rateLimit: secretsLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
hide: false,
|
||||||
|
tags: [ApiDocsTags.SecretImports],
|
||||||
|
description: "Delete secret imports",
|
||||||
|
security: [
|
||||||
|
{
|
||||||
|
bearerAuth: []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
params: z.object({
|
||||||
|
secretImportId: z.string().trim().describe(SECRET_IMPORTS.DELETE.secretImportId)
|
||||||
|
}),
|
||||||
|
body: z.object({
|
||||||
|
workspaceId: z.string().trim().describe(SECRET_IMPORTS.DELETE.projectId),
|
||||||
|
environment: z.string().trim().describe(SECRET_IMPORTS.DELETE.environment),
|
||||||
|
path: z.string().trim().default("/").transform(removeTrailingSlash).describe(SECRET_IMPORTS.DELETE.path)
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
message: z.string(),
|
||||||
|
secretImport: SecretImportsSchema.omit({ importEnv: true }).merge(
|
||||||
|
z.object({
|
||||||
|
importEnv: z.object({ name: z.string(), slug: z.string(), id: z.string() })
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const secretImport = await server.services.secretImport.deleteImport({
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
id: req.params.secretImportId,
|
||||||
|
...req.body,
|
||||||
|
projectId: req.body.workspaceId
|
||||||
|
});
|
||||||
|
|
||||||
|
await server.services.auditLog.createAuditLog({
|
||||||
|
...req.auditLogInfo,
|
||||||
|
projectId: req.body.workspaceId,
|
||||||
|
event: {
|
||||||
|
type: EventType.DELETE_SECRET_IMPORT,
|
||||||
|
metadata: {
|
||||||
|
secretImportId: secretImport.id,
|
||||||
|
folderId: secretImport.folderId,
|
||||||
|
importFromEnvironment: secretImport.importEnv.slug,
|
||||||
|
importFromSecretPath: secretImport.importPath,
|
||||||
|
importToEnvironment: req.body.environment,
|
||||||
|
importToSecretPath: req.body.path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return { message: "Successfully deleted secret import", secretImport };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
method: "POST",
|
||||||
|
url: "/:secretImportId/replication-resync",
|
||||||
|
config: {
|
||||||
|
rateLimit: secretsLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
description: "Resync secret replication of secret imports",
|
||||||
|
security: [
|
||||||
|
{
|
||||||
|
bearerAuth: []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
params: z.object({
|
||||||
|
secretImportId: z.string().trim().describe(SECRET_IMPORTS.UPDATE.secretImportId)
|
||||||
|
}),
|
||||||
|
body: z.object({
|
||||||
|
workspaceId: z.string().trim().describe(SECRET_IMPORTS.UPDATE.projectId),
|
||||||
|
environment: z.string().trim().describe(SECRET_IMPORTS.UPDATE.environment),
|
||||||
|
path: z.string().trim().default("/").transform(removeTrailingSlash).describe(SECRET_IMPORTS.UPDATE.path)
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
message: z.string()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const { message } = await server.services.secretImport.resyncSecretImportReplication({
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
id: req.params.secretImportId,
|
||||||
|
...req.body,
|
||||||
|
projectId: req.body.workspaceId
|
||||||
|
});
|
||||||
|
|
||||||
|
return { message };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
method: "GET",
|
||||||
|
url: "/",
|
||||||
|
config: {
|
||||||
|
rateLimit: readLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
hide: false,
|
||||||
|
tags: [ApiDocsTags.SecretImports],
|
||||||
|
description: "Get secret imports",
|
||||||
|
security: [
|
||||||
|
{
|
||||||
|
bearerAuth: []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
querystring: z.object({
|
||||||
|
workspaceId: z.string().trim().describe(SECRET_IMPORTS.LIST.projectId),
|
||||||
|
environment: z.string().trim().describe(SECRET_IMPORTS.LIST.environment),
|
||||||
|
path: z.string().trim().default("/").transform(removeTrailingSlash).describe(SECRET_IMPORTS.LIST.path)
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
message: z.string(),
|
||||||
|
secretImports: SecretImportsSchema.omit({ importEnv: true })
|
||||||
|
.extend({
|
||||||
|
importEnv: z.object({ name: z.string(), slug: z.string(), id: z.string() })
|
||||||
|
})
|
||||||
|
.array()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const secretImports = await server.services.secretImport.getImports({
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
...req.query,
|
||||||
|
projectId: req.query.workspaceId
|
||||||
|
});
|
||||||
|
|
||||||
|
await server.services.auditLog.createAuditLog({
|
||||||
|
...req.auditLogInfo,
|
||||||
|
projectId: req.query.workspaceId,
|
||||||
|
event: {
|
||||||
|
type: EventType.GET_SECRET_IMPORTS,
|
||||||
|
metadata: {
|
||||||
|
environment: req.query.environment,
|
||||||
|
folderId: secretImports?.[0]?.folderId,
|
||||||
|
numberOfImports: secretImports.length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return { message: "Successfully fetched secret imports", secretImports };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
url: "/:secretImportId",
|
||||||
|
method: "GET",
|
||||||
|
config: {
|
||||||
|
rateLimit: readLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
hide: false,
|
||||||
|
tags: [ApiDocsTags.SecretImports],
|
||||||
|
description: "Get single secret import",
|
||||||
|
security: [
|
||||||
|
{
|
||||||
|
bearerAuth: []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
params: z.object({
|
||||||
|
secretImportId: z.string().trim().describe(SECRET_IMPORTS.GET.secretImportId)
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
secretImport: SecretImportsSchema.omit({ importEnv: true }).extend({
|
||||||
|
environment: z.object({
|
||||||
|
id: z.string(),
|
||||||
|
name: z.string(),
|
||||||
|
slug: z.string()
|
||||||
|
}),
|
||||||
|
projectId: z.string(),
|
||||||
|
importEnv: z.object({ name: z.string(), slug: z.string(), id: z.string() }),
|
||||||
|
secretPath: z.string()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const secretImport = await server.services.secretImport.getImportById({
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
id: req.params.secretImportId
|
||||||
|
});
|
||||||
|
|
||||||
|
await server.services.auditLog.createAuditLog({
|
||||||
|
...req.auditLogInfo,
|
||||||
|
projectId: secretImport.projectId,
|
||||||
|
event: {
|
||||||
|
type: EventType.GET_SECRET_IMPORT,
|
||||||
|
metadata: {
|
||||||
|
secretImportId: secretImport.id,
|
||||||
|
folderId: secretImport.folderId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return { secretImport };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
url: "/secrets",
|
||||||
|
method: "GET",
|
||||||
|
config: {
|
||||||
|
rateLimit: secretsLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
querystring: z.object({
|
||||||
|
workspaceId: z.string().trim(),
|
||||||
|
environment: z.string().trim(),
|
||||||
|
path: z.string().trim().default("/").transform(removeTrailingSlash)
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
secrets: z
|
||||||
|
.object({
|
||||||
|
secretPath: z.string(),
|
||||||
|
environment: z.string(),
|
||||||
|
environmentInfo: z.object({
|
||||||
|
id: z.string(),
|
||||||
|
name: z.string(),
|
||||||
|
slug: z.string()
|
||||||
|
}),
|
||||||
|
folderId: z.string().optional(),
|
||||||
|
secrets: SecretsSchema.omit({ secretBlindIndex: true }).array()
|
||||||
|
})
|
||||||
|
.array()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const importedSecrets = await server.services.secretImport.getSecretsFromImports({
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
...req.query,
|
||||||
|
projectId: req.query.workspaceId
|
||||||
|
});
|
||||||
|
return { secrets: importedSecrets };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
url: "/secrets/raw",
|
||||||
|
method: "GET",
|
||||||
|
config: {
|
||||||
|
rateLimit: secretsLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
hide: false,
|
||||||
|
tags: [ApiDocsTags.SecretImports],
|
||||||
|
querystring: z.object({
|
||||||
|
workspaceId: z.string().trim(),
|
||||||
|
environment: z.string().trim(),
|
||||||
|
path: z.string().trim().default("/").transform(removeTrailingSlash)
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
secrets: z
|
||||||
|
.object({
|
||||||
|
secretPath: z.string(),
|
||||||
|
environment: z.string(),
|
||||||
|
environmentInfo: z.object({
|
||||||
|
id: z.string(),
|
||||||
|
name: z.string(),
|
||||||
|
slug: z.string()
|
||||||
|
}),
|
||||||
|
folderId: z.string().optional(),
|
||||||
|
secrets: secretRawSchema.array()
|
||||||
|
})
|
||||||
|
.array()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const importedSecrets = await server.services.secretImport.getRawSecretsFromImports({
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
...req.query,
|
||||||
|
projectId: req.query.workspaceId
|
||||||
|
});
|
||||||
|
return { secrets: importedSecrets };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -50,8 +50,8 @@ import { registerProjectKeyRouter } from "./project-key-router";
|
|||||||
import { registerProjectMembershipRouter } from "./project-membership-router";
|
import { registerProjectMembershipRouter } from "./project-membership-router";
|
||||||
import { registerProjectRouter } from "./project-router";
|
import { registerProjectRouter } from "./project-router";
|
||||||
import { SECRET_REMINDER_REGISTER_ROUTER_MAP } from "./reminder-routers";
|
import { SECRET_REMINDER_REGISTER_ROUTER_MAP } from "./reminder-routers";
|
||||||
import { registerSecretFolderRouter } from "./secret-folder-router";
|
import { registerDepreciatedSecretFolderRouter } from "./depreciated-secret-folder-router";
|
||||||
import { registerSecretImportRouter } from "./secret-import-router";
|
import { registerDepreciatedSecretImportRouter } from "./depreciated-secret-import-router";
|
||||||
import { registerSecretRequestsRouter } from "./secret-requests-router";
|
import { registerSecretRequestsRouter } from "./secret-requests-router";
|
||||||
import { registerSecretSharingRouter } from "./secret-sharing-router";
|
import { registerSecretSharingRouter } from "./secret-sharing-router";
|
||||||
import { registerSecretTagRouter } from "./secret-tag-router";
|
import { registerSecretTagRouter } from "./secret-tag-router";
|
||||||
@@ -93,8 +93,8 @@ export const registerV1Routes = async (server: FastifyZodProvider) => {
|
|||||||
await server.register(registerNotificationRouter, { prefix: "/notifications" });
|
await server.register(registerNotificationRouter, { prefix: "/notifications" });
|
||||||
await server.register(registerInviteOrgRouter, { prefix: "/invite-org" });
|
await server.register(registerInviteOrgRouter, { prefix: "/invite-org" });
|
||||||
await server.register(registerUserActionRouter, { prefix: "/user-action" });
|
await server.register(registerUserActionRouter, { prefix: "/user-action" });
|
||||||
await server.register(registerSecretImportRouter, { prefix: "/secret-imports" });
|
await server.register(registerDepreciatedSecretImportRouter, { prefix: "/secret-imports" });
|
||||||
await server.register(registerSecretFolderRouter, { prefix: "/folders" });
|
await server.register(registerDepreciatedSecretFolderRouter, { prefix: "/folders" });
|
||||||
|
|
||||||
await server.register(
|
await server.register(
|
||||||
async (workflowIntegrationRouter) => {
|
async (workflowIntegrationRouter) => {
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ export const registerWebhookRouter = async (server: FastifyZodProvider) => {
|
|||||||
body: z
|
body: z
|
||||||
.object({
|
.object({
|
||||||
type: z.nativeEnum(WebhookType).default(WebhookType.GENERAL),
|
type: z.nativeEnum(WebhookType).default(WebhookType.GENERAL),
|
||||||
workspaceId: z.string().trim(),
|
projectId: z.string().trim(),
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
webhookUrl: z.string().url().trim(),
|
webhookUrl: z.string().url().trim(),
|
||||||
webhookSecretKey: z.string().trim().optional(),
|
webhookSecretKey: z.string().trim().optional(),
|
||||||
@@ -67,13 +67,12 @@ export const registerWebhookRouter = async (server: FastifyZodProvider) => {
|
|||||||
actorId: req.permission.id,
|
actorId: req.permission.id,
|
||||||
actorAuthMethod: req.permission.authMethod,
|
actorAuthMethod: req.permission.authMethod,
|
||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
projectId: req.body.workspaceId,
|
|
||||||
...req.body
|
...req.body
|
||||||
});
|
});
|
||||||
|
|
||||||
await server.services.auditLog.createAuditLog({
|
await server.services.auditLog.createAuditLog({
|
||||||
...req.auditLogInfo,
|
...req.auditLogInfo,
|
||||||
projectId: req.body.workspaceId,
|
projectId: req.body.projectId,
|
||||||
event: {
|
event: {
|
||||||
type: EventType.CREATE_WEBHOOK,
|
type: EventType.CREATE_WEBHOOK,
|
||||||
metadata: {
|
metadata: {
|
||||||
@@ -216,7 +215,7 @@ export const registerWebhookRouter = async (server: FastifyZodProvider) => {
|
|||||||
onRequest: verifyAuth([AuthMode.JWT]),
|
onRequest: verifyAuth([AuthMode.JWT]),
|
||||||
schema: {
|
schema: {
|
||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
workspaceId: z.string().trim(),
|
projectId: z.string().trim(),
|
||||||
environment: z.string().trim().optional(),
|
environment: z.string().trim().optional(),
|
||||||
secretPath: z
|
secretPath: z
|
||||||
.string()
|
.string()
|
||||||
@@ -238,7 +237,7 @@ export const registerWebhookRouter = async (server: FastifyZodProvider) => {
|
|||||||
actorAuthMethod: req.permission.authMethod,
|
actorAuthMethod: req.permission.authMethod,
|
||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
...req.query,
|
...req.query,
|
||||||
projectId: req.query.workspaceId
|
projectId: req.query.projectId
|
||||||
});
|
});
|
||||||
return { message: "Successfully fetched webhook", webhooks };
|
return { message: "Successfully fetched webhook", webhooks };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import { registerDepreciatedProjectMembershipRouter } from "./depreciated-projec
|
|||||||
import { registerDepreciatedProjectRouter } from "./depreciated-project-router";
|
import { registerDepreciatedProjectRouter } from "./depreciated-project-router";
|
||||||
import { registerServiceTokenRouter } from "./service-token-router";
|
import { registerServiceTokenRouter } from "./service-token-router";
|
||||||
import { registerUserRouter } from "./user-router";
|
import { registerUserRouter } from "./user-router";
|
||||||
|
import { registerSecretFolderRouter } from "./secret-folder-router";
|
||||||
|
import { registerSecretImportRouter } from "./secret-import-router";
|
||||||
|
|
||||||
export const registerV2Routes = async (server: FastifyZodProvider) => {
|
export const registerV2Routes = async (server: FastifyZodProvider) => {
|
||||||
await server.register(registerMfaRouter, { prefix: "/auth" });
|
await server.register(registerMfaRouter, { prefix: "/auth" });
|
||||||
@@ -33,6 +35,9 @@ export const registerV2Routes = async (server: FastifyZodProvider) => {
|
|||||||
{ prefix: "/organizations" }
|
{ prefix: "/organizations" }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await server.register(registerSecretFolderRouter, { prefix: "/folders" });
|
||||||
|
await server.register(registerSecretImportRouter, { prefix: "/secret-imports" });
|
||||||
|
|
||||||
// moved to v1/projects
|
// moved to v1/projects
|
||||||
await server.register(
|
await server.register(
|
||||||
async (projectServer) => {
|
async (projectServer) => {
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
body: z.object({
|
body: z.object({
|
||||||
workspaceId: z.string().trim().describe(FOLDERS.CREATE.workspaceId),
|
projectId: z.string().trim().describe(FOLDERS.CREATE.projectId),
|
||||||
environment: z.string().trim().describe(FOLDERS.CREATE.environment),
|
environment: z.string().trim().describe(FOLDERS.CREATE.environment),
|
||||||
name: z
|
name: z
|
||||||
.string()
|
.string()
|
||||||
@@ -43,17 +43,7 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
|
|||||||
.default("/")
|
.default("/")
|
||||||
.transform(prefixWithSlash) // Transformations get skipped if path is undefined
|
.transform(prefixWithSlash) // Transformations get skipped if path is undefined
|
||||||
.transform(removeTrailingSlash)
|
.transform(removeTrailingSlash)
|
||||||
.describe(FOLDERS.CREATE.path)
|
.describe(FOLDERS.CREATE.path),
|
||||||
.optional(),
|
|
||||||
// backward compatibility with cli
|
|
||||||
directory: z
|
|
||||||
.string()
|
|
||||||
.trim()
|
|
||||||
.default("/")
|
|
||||||
.transform(prefixWithSlash) // Transformations get skipped if directory is undefined
|
|
||||||
.transform(removeTrailingSlash)
|
|
||||||
.describe(FOLDERS.CREATE.directory)
|
|
||||||
.optional(),
|
|
||||||
description: z.string().optional().nullable().describe(FOLDERS.CREATE.description)
|
description: z.string().optional().nullable().describe(FOLDERS.CREATE.description)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
@@ -66,27 +56,24 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
|
|||||||
},
|
},
|
||||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
handler: async (req) => {
|
handler: async (req) => {
|
||||||
const path = req.body.path || req.body.directory || "/";
|
|
||||||
const folder = await server.services.folder.createFolder({
|
const folder = await server.services.folder.createFolder({
|
||||||
actorId: req.permission.id,
|
actorId: req.permission.id,
|
||||||
actor: req.permission.type,
|
actor: req.permission.type,
|
||||||
actorAuthMethod: req.permission.authMethod,
|
actorAuthMethod: req.permission.authMethod,
|
||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
...req.body,
|
...req.body,
|
||||||
projectId: req.body.workspaceId,
|
|
||||||
path,
|
|
||||||
description: req.body.description
|
description: req.body.description
|
||||||
});
|
});
|
||||||
await server.services.auditLog.createAuditLog({
|
await server.services.auditLog.createAuditLog({
|
||||||
...req.auditLogInfo,
|
...req.auditLogInfo,
|
||||||
projectId: req.body.workspaceId,
|
projectId: req.body.projectId,
|
||||||
event: {
|
event: {
|
||||||
type: EventType.CREATE_FOLDER,
|
type: EventType.CREATE_FOLDER,
|
||||||
metadata: {
|
metadata: {
|
||||||
environment: req.body.environment,
|
environment: req.body.environment,
|
||||||
folderId: folder.id,
|
folderId: folder.id,
|
||||||
folderName: folder.name,
|
folderName: folder.name,
|
||||||
folderPath: path,
|
folderPath: req.body.path,
|
||||||
...(req.body.description ? { description: req.body.description } : {})
|
...(req.body.description ? { description: req.body.description } : {})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,7 +102,7 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
|
|||||||
folderId: z.string().describe(FOLDERS.UPDATE.folderId)
|
folderId: z.string().describe(FOLDERS.UPDATE.folderId)
|
||||||
}),
|
}),
|
||||||
body: z.object({
|
body: z.object({
|
||||||
workspaceId: z.string().trim().describe(FOLDERS.UPDATE.workspaceId),
|
projectId: z.string().trim().describe(FOLDERS.UPDATE.projectId),
|
||||||
environment: z.string().trim().describe(FOLDERS.UPDATE.environment),
|
environment: z.string().trim().describe(FOLDERS.UPDATE.environment),
|
||||||
name: z
|
name: z
|
||||||
.string()
|
.string()
|
||||||
@@ -130,17 +117,7 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
|
|||||||
.default("/")
|
.default("/")
|
||||||
.transform(prefixWithSlash) // Transformations get skipped if path is undefined
|
.transform(prefixWithSlash) // Transformations get skipped if path is undefined
|
||||||
.transform(removeTrailingSlash)
|
.transform(removeTrailingSlash)
|
||||||
.describe(FOLDERS.UPDATE.path)
|
.describe(FOLDERS.UPDATE.path),
|
||||||
.optional(),
|
|
||||||
// backward compatibility with cli
|
|
||||||
directory: z
|
|
||||||
.string()
|
|
||||||
.trim()
|
|
||||||
.default("/")
|
|
||||||
.transform(prefixWithSlash) // Transformations get skipped if directory is undefined
|
|
||||||
.transform(removeTrailingSlash)
|
|
||||||
.describe(FOLDERS.UPDATE.directory)
|
|
||||||
.optional(),
|
|
||||||
description: z.string().optional().nullable().describe(FOLDERS.UPDATE.description)
|
description: z.string().optional().nullable().describe(FOLDERS.UPDATE.description)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
@@ -153,26 +130,23 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
|
|||||||
},
|
},
|
||||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
handler: async (req) => {
|
handler: async (req) => {
|
||||||
const path = req.body.path || req.body.directory || "/";
|
|
||||||
const { folder, old } = await server.services.folder.updateFolder({
|
const { folder, old } = await server.services.folder.updateFolder({
|
||||||
actorId: req.permission.id,
|
actorId: req.permission.id,
|
||||||
actor: req.permission.type,
|
actor: req.permission.type,
|
||||||
actorAuthMethod: req.permission.authMethod,
|
actorAuthMethod: req.permission.authMethod,
|
||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
...req.body,
|
...req.body,
|
||||||
projectId: req.body.workspaceId,
|
id: req.params.folderId
|
||||||
id: req.params.folderId,
|
|
||||||
path
|
|
||||||
});
|
});
|
||||||
await server.services.auditLog.createAuditLog({
|
await server.services.auditLog.createAuditLog({
|
||||||
...req.auditLogInfo,
|
...req.auditLogInfo,
|
||||||
projectId: req.body.workspaceId,
|
projectId: req.body.projectId,
|
||||||
event: {
|
event: {
|
||||||
type: EventType.UPDATE_FOLDER,
|
type: EventType.UPDATE_FOLDER,
|
||||||
metadata: {
|
metadata: {
|
||||||
environment: req.body.environment,
|
environment: req.body.environment,
|
||||||
folderId: folder.id,
|
folderId: folder.id,
|
||||||
folderPath: path,
|
folderPath: req.body.path,
|
||||||
newFolderName: folder.name,
|
newFolderName: folder.name,
|
||||||
oldFolderName: old.name
|
oldFolderName: old.name
|
||||||
}
|
}
|
||||||
@@ -198,7 +172,7 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
body: z.object({
|
body: z.object({
|
||||||
projectSlug: z.string().trim().describe(FOLDERS.UPDATE.projectSlug),
|
projectId: z.string().trim().describe(FOLDERS.UPDATE.projectId),
|
||||||
folders: z
|
folders: z
|
||||||
.object({
|
.object({
|
||||||
id: z.string().describe(FOLDERS.UPDATE.folderId),
|
id: z.string().describe(FOLDERS.UPDATE.folderId),
|
||||||
@@ -281,7 +255,7 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
|
|||||||
folderIdOrName: z.string().describe(FOLDERS.DELETE.folderIdOrName)
|
folderIdOrName: z.string().describe(FOLDERS.DELETE.folderIdOrName)
|
||||||
}),
|
}),
|
||||||
body: z.object({
|
body: z.object({
|
||||||
workspaceId: z.string().trim().describe(FOLDERS.DELETE.workspaceId),
|
projectId: z.string().trim().describe(FOLDERS.DELETE.projectId),
|
||||||
environment: z.string().trim().describe(FOLDERS.DELETE.environment),
|
environment: z.string().trim().describe(FOLDERS.DELETE.environment),
|
||||||
path: z
|
path: z
|
||||||
.string()
|
.string()
|
||||||
@@ -290,16 +264,6 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
|
|||||||
.transform(prefixWithSlash) // Transformations get skipped if path is undefined
|
.transform(prefixWithSlash) // Transformations get skipped if path is undefined
|
||||||
.transform(removeTrailingSlash)
|
.transform(removeTrailingSlash)
|
||||||
.describe(FOLDERS.DELETE.path)
|
.describe(FOLDERS.DELETE.path)
|
||||||
.optional(),
|
|
||||||
// keep this here as cli need directory
|
|
||||||
directory: z
|
|
||||||
.string()
|
|
||||||
.trim()
|
|
||||||
.default("/")
|
|
||||||
.transform(prefixWithSlash) // Transformations get skipped if directory is undefined
|
|
||||||
.transform(removeTrailingSlash)
|
|
||||||
.describe(FOLDERS.DELETE.directory)
|
|
||||||
.optional()
|
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
@@ -309,26 +273,23 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
|
|||||||
},
|
},
|
||||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
handler: async (req) => {
|
handler: async (req) => {
|
||||||
const path = req.body.path || req.body.directory || "/";
|
|
||||||
const folder = await server.services.folder.deleteFolder({
|
const folder = await server.services.folder.deleteFolder({
|
||||||
actorId: req.permission.id,
|
actorId: req.permission.id,
|
||||||
actor: req.permission.type,
|
actor: req.permission.type,
|
||||||
actorAuthMethod: req.permission.authMethod,
|
actorAuthMethod: req.permission.authMethod,
|
||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
...req.body,
|
...req.body,
|
||||||
projectId: req.body.workspaceId,
|
idOrName: req.params.folderIdOrName
|
||||||
idOrName: req.params.folderIdOrName,
|
|
||||||
path
|
|
||||||
});
|
});
|
||||||
await server.services.auditLog.createAuditLog({
|
await server.services.auditLog.createAuditLog({
|
||||||
...req.auditLogInfo,
|
...req.auditLogInfo,
|
||||||
projectId: req.body.workspaceId,
|
projectId: req.body.projectId,
|
||||||
event: {
|
event: {
|
||||||
type: EventType.DELETE_FOLDER,
|
type: EventType.DELETE_FOLDER,
|
||||||
metadata: {
|
metadata: {
|
||||||
environment: req.body.environment,
|
environment: req.body.environment,
|
||||||
folderId: folder.id,
|
folderId: folder.id,
|
||||||
folderPath: path,
|
folderPath: req.body.path,
|
||||||
folderName: folder.name
|
folderName: folder.name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -353,7 +314,7 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
workspaceId: z.string().trim().describe(FOLDERS.LIST.workspaceId),
|
projectId: z.string().trim().describe(FOLDERS.LIST.projectId),
|
||||||
environment: z.string().trim().describe(FOLDERS.LIST.environment),
|
environment: z.string().trim().describe(FOLDERS.LIST.environment),
|
||||||
lastSecretModified: z.string().datetime().trim().optional().describe(FOLDERS.LIST.lastSecretModified),
|
lastSecretModified: z.string().datetime().trim().optional().describe(FOLDERS.LIST.lastSecretModified),
|
||||||
path: z
|
path: z
|
||||||
@@ -361,16 +322,7 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
|
|||||||
.trim()
|
.trim()
|
||||||
.transform(prefixWithSlash) // Transformations get skipped if path is undefined
|
.transform(prefixWithSlash) // Transformations get skipped if path is undefined
|
||||||
.transform(removeTrailingSlash)
|
.transform(removeTrailingSlash)
|
||||||
.describe(FOLDERS.LIST.path)
|
.describe(FOLDERS.LIST.path),
|
||||||
.optional(),
|
|
||||||
// backward compatibility with cli
|
|
||||||
directory: z
|
|
||||||
.string()
|
|
||||||
.trim()
|
|
||||||
.transform(prefixWithSlash) // Transformations get skipped if directory is undefined
|
|
||||||
.transform(removeTrailingSlash)
|
|
||||||
.describe(FOLDERS.LIST.directory)
|
|
||||||
.optional(),
|
|
||||||
recursive: booleanSchema.default(false).describe(FOLDERS.LIST.recursive)
|
recursive: booleanSchema.default(false).describe(FOLDERS.LIST.recursive)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
@@ -383,15 +335,12 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
|
|||||||
},
|
},
|
||||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
handler: async (req) => {
|
handler: async (req) => {
|
||||||
const path = req.query.path || req.query.directory || "/";
|
|
||||||
const folders = await server.services.folder.getFolders({
|
const folders = await server.services.folder.getFolders({
|
||||||
actorId: req.permission.id,
|
actorId: req.permission.id,
|
||||||
actor: req.permission.type,
|
actor: req.permission.type,
|
||||||
actorAuthMethod: req.permission.authMethod,
|
actorAuthMethod: req.permission.authMethod,
|
||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
...req.query,
|
...req.query
|
||||||
projectId: req.query.workspaceId,
|
|
||||||
path
|
|
||||||
});
|
});
|
||||||
return { folders };
|
return { folders };
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { SecretImportsSchema, SecretsSchema } from "@app/db/schemas";
|
import { SecretImportsSchema } from "@app/db/schemas";
|
||||||
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
||||||
import { ApiDocsTags, SECRET_IMPORTS } from "@app/lib/api-docs";
|
import { ApiDocsTags, SECRET_IMPORTS } from "@app/lib/api-docs";
|
||||||
import { removeTrailingSlash } from "@app/lib/fn";
|
import { removeTrailingSlash } from "@app/lib/fn";
|
||||||
@@ -27,7 +27,7 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
body: z.object({
|
body: z.object({
|
||||||
workspaceId: z.string().trim().describe(SECRET_IMPORTS.CREATE.workspaceId),
|
projectId: z.string().trim().describe(SECRET_IMPORTS.CREATE.projectId),
|
||||||
environment: z.string().trim().describe(SECRET_IMPORTS.CREATE.environment),
|
environment: z.string().trim().describe(SECRET_IMPORTS.CREATE.environment),
|
||||||
path: z.string().trim().default("/").transform(removeTrailingSlash).describe(SECRET_IMPORTS.CREATE.path),
|
path: z.string().trim().default("/").transform(removeTrailingSlash).describe(SECRET_IMPORTS.CREATE.path),
|
||||||
import: z.object({
|
import: z.object({
|
||||||
@@ -55,13 +55,13 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
|
|||||||
actorAuthMethod: req.permission.authMethod,
|
actorAuthMethod: req.permission.authMethod,
|
||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
...req.body,
|
...req.body,
|
||||||
projectId: req.body.workspaceId,
|
projectId: req.body.projectId,
|
||||||
data: req.body.import
|
data: req.body.import
|
||||||
});
|
});
|
||||||
|
|
||||||
await server.services.auditLog.createAuditLog({
|
await server.services.auditLog.createAuditLog({
|
||||||
...req.auditLogInfo,
|
...req.auditLogInfo,
|
||||||
projectId: req.body.workspaceId,
|
projectId: req.body.projectId,
|
||||||
event: {
|
event: {
|
||||||
type: EventType.CREATE_SECRET_IMPORT,
|
type: EventType.CREATE_SECRET_IMPORT,
|
||||||
metadata: {
|
metadata: {
|
||||||
@@ -97,7 +97,7 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
|
|||||||
secretImportId: z.string().trim().describe(SECRET_IMPORTS.UPDATE.secretImportId)
|
secretImportId: z.string().trim().describe(SECRET_IMPORTS.UPDATE.secretImportId)
|
||||||
}),
|
}),
|
||||||
body: z.object({
|
body: z.object({
|
||||||
workspaceId: z.string().trim().describe(SECRET_IMPORTS.UPDATE.workspaceId),
|
projectId: z.string().trim().describe(SECRET_IMPORTS.UPDATE.projectId),
|
||||||
environment: z.string().trim().describe(SECRET_IMPORTS.UPDATE.environment),
|
environment: z.string().trim().describe(SECRET_IMPORTS.UPDATE.environment),
|
||||||
path: z.string().trim().default("/").transform(removeTrailingSlash).describe(SECRET_IMPORTS.UPDATE.path),
|
path: z.string().trim().default("/").transform(removeTrailingSlash).describe(SECRET_IMPORTS.UPDATE.path),
|
||||||
import: z.object({
|
import: z.object({
|
||||||
@@ -131,13 +131,13 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
|
|||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
id: req.params.secretImportId,
|
id: req.params.secretImportId,
|
||||||
...req.body,
|
...req.body,
|
||||||
projectId: req.body.workspaceId,
|
projectId: req.body.projectId,
|
||||||
data: req.body.import
|
data: req.body.import
|
||||||
});
|
});
|
||||||
|
|
||||||
await server.services.auditLog.createAuditLog({
|
await server.services.auditLog.createAuditLog({
|
||||||
...req.auditLogInfo,
|
...req.auditLogInfo,
|
||||||
projectId: req.body.workspaceId,
|
projectId: req.body.projectId,
|
||||||
event: {
|
event: {
|
||||||
type: EventType.UPDATE_SECRET_IMPORT,
|
type: EventType.UPDATE_SECRET_IMPORT,
|
||||||
metadata: {
|
metadata: {
|
||||||
@@ -173,7 +173,7 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
|
|||||||
secretImportId: z.string().trim().describe(SECRET_IMPORTS.DELETE.secretImportId)
|
secretImportId: z.string().trim().describe(SECRET_IMPORTS.DELETE.secretImportId)
|
||||||
}),
|
}),
|
||||||
body: z.object({
|
body: z.object({
|
||||||
workspaceId: z.string().trim().describe(SECRET_IMPORTS.DELETE.workspaceId),
|
projectId: z.string().trim().describe(SECRET_IMPORTS.DELETE.projectId),
|
||||||
environment: z.string().trim().describe(SECRET_IMPORTS.DELETE.environment),
|
environment: z.string().trim().describe(SECRET_IMPORTS.DELETE.environment),
|
||||||
path: z.string().trim().default("/").transform(removeTrailingSlash).describe(SECRET_IMPORTS.DELETE.path)
|
path: z.string().trim().default("/").transform(removeTrailingSlash).describe(SECRET_IMPORTS.DELETE.path)
|
||||||
}),
|
}),
|
||||||
@@ -197,12 +197,12 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
|
|||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
id: req.params.secretImportId,
|
id: req.params.secretImportId,
|
||||||
...req.body,
|
...req.body,
|
||||||
projectId: req.body.workspaceId
|
projectId: req.body.projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
await server.services.auditLog.createAuditLog({
|
await server.services.auditLog.createAuditLog({
|
||||||
...req.auditLogInfo,
|
...req.auditLogInfo,
|
||||||
projectId: req.body.workspaceId,
|
projectId: req.body.projectId,
|
||||||
event: {
|
event: {
|
||||||
type: EventType.DELETE_SECRET_IMPORT,
|
type: EventType.DELETE_SECRET_IMPORT,
|
||||||
metadata: {
|
metadata: {
|
||||||
@@ -236,7 +236,7 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
|
|||||||
secretImportId: z.string().trim().describe(SECRET_IMPORTS.UPDATE.secretImportId)
|
secretImportId: z.string().trim().describe(SECRET_IMPORTS.UPDATE.secretImportId)
|
||||||
}),
|
}),
|
||||||
body: z.object({
|
body: z.object({
|
||||||
workspaceId: z.string().trim().describe(SECRET_IMPORTS.UPDATE.workspaceId),
|
projectId: z.string().trim().describe(SECRET_IMPORTS.UPDATE.projectId),
|
||||||
environment: z.string().trim().describe(SECRET_IMPORTS.UPDATE.environment),
|
environment: z.string().trim().describe(SECRET_IMPORTS.UPDATE.environment),
|
||||||
path: z.string().trim().default("/").transform(removeTrailingSlash).describe(SECRET_IMPORTS.UPDATE.path)
|
path: z.string().trim().default("/").transform(removeTrailingSlash).describe(SECRET_IMPORTS.UPDATE.path)
|
||||||
}),
|
}),
|
||||||
@@ -255,7 +255,7 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
|
|||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
id: req.params.secretImportId,
|
id: req.params.secretImportId,
|
||||||
...req.body,
|
...req.body,
|
||||||
projectId: req.body.workspaceId
|
projectId: req.body.projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
return { message };
|
return { message };
|
||||||
@@ -278,7 +278,7 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
workspaceId: z.string().trim().describe(SECRET_IMPORTS.LIST.workspaceId),
|
projectId: z.string().trim().describe(SECRET_IMPORTS.LIST.projectId),
|
||||||
environment: z.string().trim().describe(SECRET_IMPORTS.LIST.environment),
|
environment: z.string().trim().describe(SECRET_IMPORTS.LIST.environment),
|
||||||
path: z.string().trim().default("/").transform(removeTrailingSlash).describe(SECRET_IMPORTS.LIST.path)
|
path: z.string().trim().default("/").transform(removeTrailingSlash).describe(SECRET_IMPORTS.LIST.path)
|
||||||
}),
|
}),
|
||||||
@@ -301,12 +301,12 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
|
|||||||
actorAuthMethod: req.permission.authMethod,
|
actorAuthMethod: req.permission.authMethod,
|
||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
...req.query,
|
...req.query,
|
||||||
projectId: req.query.workspaceId
|
projectId: req.query.projectId
|
||||||
});
|
});
|
||||||
|
|
||||||
await server.services.auditLog.createAuditLog({
|
await server.services.auditLog.createAuditLog({
|
||||||
...req.auditLogInfo,
|
...req.auditLogInfo,
|
||||||
projectId: req.query.workspaceId,
|
projectId: req.query.projectId,
|
||||||
event: {
|
event: {
|
||||||
type: EventType.GET_SECRET_IMPORTS,
|
type: EventType.GET_SECRET_IMPORTS,
|
||||||
metadata: {
|
metadata: {
|
||||||
@@ -386,55 +386,11 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
|
|||||||
config: {
|
config: {
|
||||||
rateLimit: secretsLimit
|
rateLimit: secretsLimit
|
||||||
},
|
},
|
||||||
schema: {
|
|
||||||
querystring: z.object({
|
|
||||||
workspaceId: z.string().trim(),
|
|
||||||
environment: z.string().trim(),
|
|
||||||
path: z.string().trim().default("/").transform(removeTrailingSlash)
|
|
||||||
}),
|
|
||||||
response: {
|
|
||||||
200: z.object({
|
|
||||||
secrets: z
|
|
||||||
.object({
|
|
||||||
secretPath: z.string(),
|
|
||||||
environment: z.string(),
|
|
||||||
environmentInfo: z.object({
|
|
||||||
id: z.string(),
|
|
||||||
name: z.string(),
|
|
||||||
slug: z.string()
|
|
||||||
}),
|
|
||||||
folderId: z.string().optional(),
|
|
||||||
secrets: SecretsSchema.omit({ secretBlindIndex: true }).array()
|
|
||||||
})
|
|
||||||
.array()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
|
||||||
handler: async (req) => {
|
|
||||||
const importedSecrets = await server.services.secretImport.getSecretsFromImports({
|
|
||||||
actorId: req.permission.id,
|
|
||||||
actor: req.permission.type,
|
|
||||||
actorAuthMethod: req.permission.authMethod,
|
|
||||||
actorOrgId: req.permission.orgId,
|
|
||||||
...req.query,
|
|
||||||
projectId: req.query.workspaceId
|
|
||||||
});
|
|
||||||
return { secrets: importedSecrets };
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
server.route({
|
|
||||||
url: "/secrets/raw",
|
|
||||||
method: "GET",
|
|
||||||
config: {
|
|
||||||
rateLimit: secretsLimit
|
|
||||||
},
|
|
||||||
schema: {
|
schema: {
|
||||||
hide: false,
|
hide: false,
|
||||||
tags: [ApiDocsTags.SecretImports],
|
tags: [ApiDocsTags.SecretImports],
|
||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
workspaceId: z.string().trim(),
|
projectId: z.string().trim(),
|
||||||
environment: z.string().trim(),
|
environment: z.string().trim(),
|
||||||
path: z.string().trim().default("/").transform(removeTrailingSlash)
|
path: z.string().trim().default("/").transform(removeTrailingSlash)
|
||||||
}),
|
}),
|
||||||
@@ -463,8 +419,7 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
|
|||||||
actor: req.permission.type,
|
actor: req.permission.type,
|
||||||
actorAuthMethod: req.permission.authMethod,
|
actorAuthMethod: req.permission.authMethod,
|
||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
...req.query,
|
...req.query
|
||||||
projectId: req.query.workspaceId
|
|
||||||
});
|
});
|
||||||
return { secrets: importedSecrets };
|
return { secrets: importedSecrets };
|
||||||
}
|
}
|
||||||
@@ -11,7 +11,7 @@ export const useCreateSecretApprovalPolicy = () => {
|
|||||||
return useMutation<object, object, TCreateSecretPolicyDTO>({
|
return useMutation<object, object, TCreateSecretPolicyDTO>({
|
||||||
mutationFn: async ({
|
mutationFn: async ({
|
||||||
environments,
|
environments,
|
||||||
workspaceId,
|
projectId,
|
||||||
approvals,
|
approvals,
|
||||||
approvers,
|
approvers,
|
||||||
bypassers,
|
bypassers,
|
||||||
@@ -20,9 +20,9 @@ export const useCreateSecretApprovalPolicy = () => {
|
|||||||
enforcementLevel,
|
enforcementLevel,
|
||||||
allowedSelfApprovals
|
allowedSelfApprovals
|
||||||
}) => {
|
}) => {
|
||||||
const { data } = await apiRequest.post("/api/v1/secret-approvals", {
|
const { data } = await apiRequest.post("/api/v2/secret-approvals", {
|
||||||
environments,
|
environments,
|
||||||
workspaceId,
|
projectId,
|
||||||
approvals,
|
approvals,
|
||||||
approvers,
|
approvers,
|
||||||
bypassers,
|
bypassers,
|
||||||
@@ -33,9 +33,9 @@ export const useCreateSecretApprovalPolicy = () => {
|
|||||||
});
|
});
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { workspaceId }) => {
|
onSuccess: (_, { projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: secretApprovalKeys.getApprovalPolicies(workspaceId)
|
queryKey: secretApprovalKeys.getApprovalPolicies(projectId)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -56,7 +56,7 @@ export const useUpdateSecretApprovalPolicy = () => {
|
|||||||
allowedSelfApprovals,
|
allowedSelfApprovals,
|
||||||
environments
|
environments
|
||||||
}) => {
|
}) => {
|
||||||
const { data } = await apiRequest.patch(`/api/v1/secret-approvals/${id}`, {
|
const { data } = await apiRequest.patch(`/api/v2/secret-approvals/${id}`, {
|
||||||
approvals,
|
approvals,
|
||||||
approvers,
|
approvers,
|
||||||
bypassers,
|
bypassers,
|
||||||
@@ -68,9 +68,9 @@ export const useUpdateSecretApprovalPolicy = () => {
|
|||||||
});
|
});
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { workspaceId }) => {
|
onSuccess: (_, { projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: secretApprovalKeys.getApprovalPolicies(workspaceId)
|
queryKey: secretApprovalKeys.getApprovalPolicies(projectId)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -81,12 +81,12 @@ export const useDeleteSecretApprovalPolicy = () => {
|
|||||||
|
|
||||||
return useMutation<object, object, TDeleteSecretPolicyDTO>({
|
return useMutation<object, object, TDeleteSecretPolicyDTO>({
|
||||||
mutationFn: async ({ id }) => {
|
mutationFn: async ({ id }) => {
|
||||||
const { data } = await apiRequest.delete(`/api/v1/secret-approvals/${id}`);
|
const { data } = await apiRequest.delete(`/api/v2/secret-approvals/${id}`);
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { workspaceId }) => {
|
onSuccess: (_, { projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: secretApprovalKeys.getApprovalPolicies(workspaceId)
|
queryKey: secretApprovalKeys.getApprovalPolicies(projectId)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,54 +10,53 @@ import {
|
|||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
export const secretApprovalKeys = {
|
export const secretApprovalKeys = {
|
||||||
getApprovalPolicies: (workspaceId: string) =>
|
getApprovalPolicies: (projectId: string) => [{ projectId }, "secret-approval-policies"] as const,
|
||||||
[{ workspaceId }, "secret-approval-policies"] as const,
|
getApprovalPolicyOfABoard: (projectId: string, environment: string, secretPath: string) => [
|
||||||
getApprovalPolicyOfABoard: (workspaceId: string, environment: string, secretPath: string) => [
|
{ projectId, environment, secretPath },
|
||||||
{ workspaceId, environment, secretPath },
|
|
||||||
"Secret-approval-policy"
|
"Secret-approval-policy"
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchApprovalPolicies = async (workspaceId: string) => {
|
const fetchApprovalPolicies = async (projectId: string) => {
|
||||||
const { data } = await apiRequest.get<{ approvals: TSecretApprovalPolicy[] }>(
|
const { data } = await apiRequest.get<{ approvals: TSecretApprovalPolicy[] }>(
|
||||||
"/api/v1/secret-approvals",
|
"/api/v2/secret-approvals",
|
||||||
{ params: { workspaceId } }
|
{ params: { projectId } }
|
||||||
);
|
);
|
||||||
return data.approvals;
|
return data.approvals;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetSecretApprovalPolicies = ({
|
export const useGetSecretApprovalPolicies = ({
|
||||||
workspaceId,
|
projectId,
|
||||||
options = {}
|
options = {}
|
||||||
}: TGetSecretApprovalPoliciesDTO & TReactQueryOptions) =>
|
}: TGetSecretApprovalPoliciesDTO & TReactQueryOptions) =>
|
||||||
useQuery({
|
useQuery({
|
||||||
queryKey: secretApprovalKeys.getApprovalPolicies(workspaceId),
|
queryKey: secretApprovalKeys.getApprovalPolicies(projectId),
|
||||||
queryFn: () => fetchApprovalPolicies(workspaceId),
|
queryFn: () => fetchApprovalPolicies(projectId),
|
||||||
...options,
|
...options,
|
||||||
enabled: Boolean(workspaceId) && (options?.enabled ?? true)
|
enabled: Boolean(projectId) && (options?.enabled ?? true)
|
||||||
});
|
});
|
||||||
|
|
||||||
const fetchApprovalPolicyOfABoard = async (
|
const fetchApprovalPolicyOfABoard = async (
|
||||||
workspaceId: string,
|
projectId: string,
|
||||||
environment: string,
|
environment: string,
|
||||||
secretPath: string
|
secretPath: string
|
||||||
) => {
|
) => {
|
||||||
const { data } = await apiRequest.get<{ policy: TSecretApprovalPolicy }>(
|
const { data } = await apiRequest.get<{ policy: TSecretApprovalPolicy }>(
|
||||||
"/api/v1/secret-approvals/board",
|
"/api/v2/secret-approvals/board",
|
||||||
{ params: { workspaceId, environment, secretPath } }
|
{ params: { projectId, environment, secretPath } }
|
||||||
);
|
);
|
||||||
return data.policy || "";
|
return data.policy || "";
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetSecretApprovalPolicyOfABoard = ({
|
export const useGetSecretApprovalPolicyOfABoard = ({
|
||||||
workspaceId,
|
projectId,
|
||||||
secretPath = "/",
|
secretPath = "/",
|
||||||
environment,
|
environment,
|
||||||
options = {}
|
options = {}
|
||||||
}: TGetSecretApprovalPolicyOfBoardDTO & TReactQueryOptions) =>
|
}: TGetSecretApprovalPolicyOfBoardDTO & TReactQueryOptions) =>
|
||||||
useQuery({
|
useQuery({
|
||||||
queryKey: secretApprovalKeys.getApprovalPolicyOfABoard(workspaceId, environment, secretPath),
|
queryKey: secretApprovalKeys.getApprovalPolicyOfABoard(projectId, environment, secretPath),
|
||||||
queryFn: () => fetchApprovalPolicyOfABoard(workspaceId, environment, secretPath),
|
queryFn: () => fetchApprovalPolicyOfABoard(projectId, environment, secretPath),
|
||||||
...options,
|
...options,
|
||||||
enabled: Boolean(workspaceId && secretPath && environment) && (options?.enabled ?? true)
|
enabled: Boolean(projectId && secretPath && environment) && (options?.enabled ?? true)
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { WorkspaceEnv } from "../workspace/types";
|
|||||||
|
|
||||||
export type TSecretApprovalPolicy = {
|
export type TSecretApprovalPolicy = {
|
||||||
id: string;
|
id: string;
|
||||||
workspace: string;
|
project: string;
|
||||||
name: string;
|
name: string;
|
||||||
environments: WorkspaceEnv[];
|
environments: WorkspaceEnv[];
|
||||||
secretPath?: string;
|
secretPath?: string;
|
||||||
@@ -36,17 +36,17 @@ export type Bypasser = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type TGetSecretApprovalPoliciesDTO = {
|
export type TGetSecretApprovalPoliciesDTO = {
|
||||||
workspaceId: string;
|
projectId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TGetSecretApprovalPolicyOfBoardDTO = {
|
export type TGetSecretApprovalPolicyOfBoardDTO = {
|
||||||
workspaceId: string;
|
projectId: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
secretPath: string;
|
secretPath: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TCreateSecretPolicyDTO = {
|
export type TCreateSecretPolicyDTO = {
|
||||||
workspaceId: string;
|
projectId: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
environments: string[];
|
environments: string[];
|
||||||
secretPath: string;
|
secretPath: string;
|
||||||
@@ -67,12 +67,12 @@ export type TUpdateSecretPolicyDTO = {
|
|||||||
allowedSelfApprovals?: boolean;
|
allowedSelfApprovals?: boolean;
|
||||||
enforcementLevel?: EnforcementLevel;
|
enforcementLevel?: EnforcementLevel;
|
||||||
// for invalidating list
|
// for invalidating list
|
||||||
workspaceId: string;
|
projectId: string;
|
||||||
environments?: string[];
|
environments?: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TDeleteSecretPolicyDTO = {
|
export type TDeleteSecretPolicyDTO = {
|
||||||
id: string;
|
id: string;
|
||||||
// for invalidating list
|
// for invalidating list
|
||||||
workspaceId: string;
|
projectId: string;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -36,9 +36,9 @@ export const useUpdateSecretApprovalRequestStatus = () => {
|
|||||||
});
|
});
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { id, workspaceId }) => {
|
onSuccess: (_, { id, projectId }) => {
|
||||||
queryClient.invalidateQueries({ queryKey: secretApprovalRequestKeys.detail({ id }) });
|
queryClient.invalidateQueries({ queryKey: secretApprovalRequestKeys.detail({ id }) });
|
||||||
queryClient.invalidateQueries({ queryKey: secretApprovalRequestKeys.count({ workspaceId }) });
|
queryClient.invalidateQueries({ queryKey: secretApprovalRequestKeys.count({ projectId }) });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -53,10 +53,10 @@ export const usePerformSecretApprovalRequestMerge = () => {
|
|||||||
});
|
});
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { id, workspaceId }) => {
|
onSuccess: (_, { id, projectId }) => {
|
||||||
queryClient.invalidateQueries({ queryKey: secretApprovalRequestKeys.detail({ id }) });
|
queryClient.invalidateQueries({ queryKey: secretApprovalRequestKeys.detail({ id }) });
|
||||||
queryClient.invalidateQueries({ queryKey: secretApprovalRequestKeys.list({ workspaceId }) });
|
queryClient.invalidateQueries({ queryKey: secretApprovalRequestKeys.list({ projectId }) });
|
||||||
queryClient.invalidateQueries({ queryKey: secretApprovalRequestKeys.count({ workspaceId }) });
|
queryClient.invalidateQueries({ queryKey: secretApprovalRequestKeys.count({ projectId }) });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import {
|
|||||||
|
|
||||||
export const secretApprovalRequestKeys = {
|
export const secretApprovalRequestKeys = {
|
||||||
list: ({
|
list: ({
|
||||||
workspaceId,
|
projectId,
|
||||||
environment,
|
environment,
|
||||||
status,
|
status,
|
||||||
committer,
|
committer,
|
||||||
@@ -23,20 +23,20 @@ export const secretApprovalRequestKeys = {
|
|||||||
search
|
search
|
||||||
}: TGetSecretApprovalRequestList) =>
|
}: TGetSecretApprovalRequestList) =>
|
||||||
[
|
[
|
||||||
{ workspaceId, environment, status, committer, offset, limit, search },
|
{ projectId, environment, status, committer, offset, limit, search },
|
||||||
"secret-approval-requests"
|
"secret-approval-requests"
|
||||||
] as const,
|
] as const,
|
||||||
detail: ({ id }: Omit<TGetSecretApprovalRequestDetails, "decryptKey">) =>
|
detail: ({ id }: Omit<TGetSecretApprovalRequestDetails, "decryptKey">) =>
|
||||||
[{ id }, "secret-approval-request-detail"] as const,
|
[{ id }, "secret-approval-request-detail"] as const,
|
||||||
count: ({ workspaceId, policyId }: TGetSecretApprovalRequestCount) => [
|
count: ({ projectId, policyId }: TGetSecretApprovalRequestCount) => [
|
||||||
{ workspaceId },
|
{ projectId },
|
||||||
"secret-approval-request-count",
|
"secret-approval-request-count",
|
||||||
...(policyId ? [policyId] : [])
|
...(policyId ? [policyId] : [])
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchSecretApprovalRequestList = async ({
|
const fetchSecretApprovalRequestList = async ({
|
||||||
workspaceId,
|
projectId,
|
||||||
environment,
|
environment,
|
||||||
committer,
|
committer,
|
||||||
status = "open",
|
status = "open",
|
||||||
@@ -49,7 +49,7 @@ const fetchSecretApprovalRequestList = async ({
|
|||||||
totalCount: number;
|
totalCount: number;
|
||||||
}>("/api/v1/secret-approval-requests", {
|
}>("/api/v1/secret-approval-requests", {
|
||||||
params: {
|
params: {
|
||||||
workspaceId,
|
projectId,
|
||||||
environment,
|
environment,
|
||||||
committer,
|
committer,
|
||||||
status,
|
status,
|
||||||
@@ -63,7 +63,7 @@ const fetchSecretApprovalRequestList = async ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const useGetSecretApprovalRequests = ({
|
export const useGetSecretApprovalRequests = ({
|
||||||
workspaceId,
|
projectId,
|
||||||
environment,
|
environment,
|
||||||
options = {},
|
options = {},
|
||||||
status,
|
status,
|
||||||
@@ -74,7 +74,7 @@ export const useGetSecretApprovalRequests = ({
|
|||||||
}: TGetSecretApprovalRequestList & TReactQueryOptions) =>
|
}: TGetSecretApprovalRequestList & TReactQueryOptions) =>
|
||||||
useQuery({
|
useQuery({
|
||||||
queryKey: secretApprovalRequestKeys.list({
|
queryKey: secretApprovalRequestKeys.list({
|
||||||
workspaceId,
|
projectId,
|
||||||
environment,
|
environment,
|
||||||
committer,
|
committer,
|
||||||
status,
|
status,
|
||||||
@@ -84,7 +84,7 @@ export const useGetSecretApprovalRequests = ({
|
|||||||
}),
|
}),
|
||||||
queryFn: () =>
|
queryFn: () =>
|
||||||
fetchSecretApprovalRequestList({
|
fetchSecretApprovalRequestList({
|
||||||
workspaceId,
|
projectId,
|
||||||
environment,
|
environment,
|
||||||
status,
|
status,
|
||||||
committer,
|
committer,
|
||||||
@@ -92,7 +92,7 @@ export const useGetSecretApprovalRequests = ({
|
|||||||
offset,
|
offset,
|
||||||
search
|
search
|
||||||
}),
|
}),
|
||||||
enabled: Boolean(workspaceId) && (options?.enabled ?? true),
|
enabled: Boolean(projectId) && (options?.enabled ?? true),
|
||||||
placeholderData: (previousData) => previousData
|
placeholderData: (previousData) => previousData
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -127,19 +127,19 @@ export const useGetSecretApprovalRequestDetails = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const fetchSecretApprovalRequestCount = async ({
|
const fetchSecretApprovalRequestCount = async ({
|
||||||
workspaceId,
|
projectId,
|
||||||
policyId
|
policyId
|
||||||
}: TGetSecretApprovalRequestCount) => {
|
}: TGetSecretApprovalRequestCount) => {
|
||||||
const { data } = await apiRequest.get<{ approvals: TSecretApprovalRequestCount }>(
|
const { data } = await apiRequest.get<{ approvals: TSecretApprovalRequestCount }>(
|
||||||
"/api/v1/secret-approval-requests/count",
|
"/api/v1/secret-approval-requests/count",
|
||||||
{ params: { workspaceId, policyId } }
|
{ params: { projectId, policyId } }
|
||||||
);
|
);
|
||||||
|
|
||||||
return data.approvals;
|
return data.approvals;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetSecretApprovalRequestCount = ({
|
export const useGetSecretApprovalRequestCount = ({
|
||||||
workspaceId,
|
projectId,
|
||||||
policyId,
|
policyId,
|
||||||
options = {}
|
options = {}
|
||||||
}: TGetSecretApprovalRequestCount & {
|
}: TGetSecretApprovalRequestCount & {
|
||||||
@@ -154,8 +154,8 @@ export const useGetSecretApprovalRequestCount = ({
|
|||||||
>;
|
>;
|
||||||
}) =>
|
}) =>
|
||||||
useQuery({
|
useQuery({
|
||||||
queryKey: secretApprovalRequestKeys.count({ workspaceId, policyId }),
|
queryKey: secretApprovalRequestKeys.count({ projectId, policyId }),
|
||||||
refetchInterval: 15000,
|
refetchInterval: 15000,
|
||||||
queryFn: () => fetchSecretApprovalRequestCount({ workspaceId, policyId }),
|
queryFn: () => fetchSecretApprovalRequestCount({ projectId, policyId }),
|
||||||
enabled: Boolean(workspaceId) && (options?.enabled ?? true)
|
enabled: Boolean(projectId) && (options?.enabled ?? true)
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ export type TSecretApprovalRequest = {
|
|||||||
username: string;
|
username: string;
|
||||||
isOrgMembershipActive: boolean;
|
isOrgMembershipActive: boolean;
|
||||||
}[];
|
}[];
|
||||||
workspace: string;
|
project: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
folderId: string;
|
folderId: string;
|
||||||
secretPath: string;
|
secretPath: string;
|
||||||
@@ -110,7 +110,7 @@ export type TSecretApprovalRequestCount = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type TGetSecretApprovalRequestList = {
|
export type TGetSecretApprovalRequestList = {
|
||||||
workspaceId: string;
|
projectId: string;
|
||||||
environment?: string;
|
environment?: string;
|
||||||
status?: "open" | "close";
|
status?: "open" | "close";
|
||||||
committer?: string;
|
committer?: string;
|
||||||
@@ -120,7 +120,7 @@ export type TGetSecretApprovalRequestList = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type TGetSecretApprovalRequestCount = {
|
export type TGetSecretApprovalRequestCount = {
|
||||||
workspaceId: string;
|
projectId: string;
|
||||||
policyId?: string;
|
policyId?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -137,11 +137,11 @@ export type TUpdateSecretApprovalReviewStatusDTO = {
|
|||||||
export type TUpdateSecretApprovalRequestStatusDTO = {
|
export type TUpdateSecretApprovalRequestStatusDTO = {
|
||||||
status: "open" | "close";
|
status: "open" | "close";
|
||||||
id: string;
|
id: string;
|
||||||
workspaceId: string;
|
projectId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TPerformSecretApprovalRequestMerge = {
|
export type TPerformSecretApprovalRequestMerge = {
|
||||||
id: string;
|
id: string;
|
||||||
workspaceId: string;
|
projectId: string;
|
||||||
bypassReason?: string;
|
bypassReason?: string;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -30,10 +30,10 @@ export const folderQueryKeys = {
|
|||||||
["secret-folders", "environment", projectId] as const
|
["secret-folders", "environment", projectId] as const
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchProjectFolders = async (workspaceId: string, environment: string, path = "/") => {
|
const fetchProjectFolders = async (projectId: string, environment: string, path = "/") => {
|
||||||
const { data } = await apiRequest.get<{ folders: TSecretFolder[] }>("/api/v1/folders", {
|
const { data } = await apiRequest.get<{ folders: TSecretFolder[] }>("/api/v2/folders", {
|
||||||
params: {
|
params: {
|
||||||
workspaceId,
|
projectId,
|
||||||
environment,
|
environment,
|
||||||
path
|
path
|
||||||
}
|
}
|
||||||
@@ -145,9 +145,9 @@ export const useCreateFolder = () => {
|
|||||||
|
|
||||||
return useMutation<object, object, TCreateFolderDTO>({
|
return useMutation<object, object, TCreateFolderDTO>({
|
||||||
mutationFn: async (dto) => {
|
mutationFn: async (dto) => {
|
||||||
const { data } = await apiRequest.post("/api/v1/folders", {
|
const { data } = await apiRequest.post("/api/v2/folders", {
|
||||||
...dto,
|
...dto,
|
||||||
workspaceId: dto.projectId
|
projectId: dto.projectId
|
||||||
});
|
});
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
@@ -179,10 +179,10 @@ export const useUpdateFolder = () => {
|
|||||||
|
|
||||||
return useMutation<object, object, TUpdateFolderDTO>({
|
return useMutation<object, object, TUpdateFolderDTO>({
|
||||||
mutationFn: async ({ path = "/", folderId, name, environment, projectId, description }) => {
|
mutationFn: async ({ path = "/", folderId, name, environment, projectId, description }) => {
|
||||||
const { data } = await apiRequest.patch(`/api/v1/folders/${folderId}`, {
|
const { data } = await apiRequest.patch(`/api/v2/folders/${folderId}`, {
|
||||||
name,
|
name,
|
||||||
environment,
|
environment,
|
||||||
workspaceId: projectId,
|
projectId,
|
||||||
path,
|
path,
|
||||||
description
|
description
|
||||||
});
|
});
|
||||||
@@ -219,10 +219,10 @@ export const useDeleteFolder = () => {
|
|||||||
|
|
||||||
return useMutation<object, object, TDeleteFolderDTO>({
|
return useMutation<object, object, TDeleteFolderDTO>({
|
||||||
mutationFn: async ({ path = "/", folderId, environment, projectId }) => {
|
mutationFn: async ({ path = "/", folderId, environment, projectId }) => {
|
||||||
const { data } = await apiRequest.delete(`/api/v1/folders/${folderId}`, {
|
const { data } = await apiRequest.delete(`/api/v2/folders/${folderId}`, {
|
||||||
data: {
|
data: {
|
||||||
environment,
|
environment,
|
||||||
workspaceId: projectId,
|
projectId,
|
||||||
path
|
path
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -259,7 +259,7 @@ export const useUpdateFolderBatch = () => {
|
|||||||
|
|
||||||
return useMutation<object, object, TUpdateFolderBatchDTO>({
|
return useMutation<object, object, TUpdateFolderBatchDTO>({
|
||||||
mutationFn: async ({ projectSlug, folders }) => {
|
mutationFn: async ({ projectSlug, folders }) => {
|
||||||
const { data } = await apiRequest.patch("/api/v1/folders/batch", {
|
const { data } = await apiRequest.patch("/api/v2/folders/batch", {
|
||||||
projectSlug,
|
projectSlug,
|
||||||
folders
|
folders
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ export const useCreateSecretImport = () => {
|
|||||||
|
|
||||||
return useMutation<object, object, TCreateSecretImportDTO>({
|
return useMutation<object, object, TCreateSecretImportDTO>({
|
||||||
mutationFn: async ({ import: secretImport, environment, isReplication, projectId, path }) => {
|
mutationFn: async ({ import: secretImport, environment, isReplication, projectId, path }) => {
|
||||||
const { data } = await apiRequest.post("/api/v1/secret-imports", {
|
const { data } = await apiRequest.post("/api/v2/secret-imports", {
|
||||||
import: secretImport,
|
import: secretImport,
|
||||||
environment,
|
environment,
|
||||||
workspaceId: projectId,
|
projectId,
|
||||||
path,
|
path,
|
||||||
isReplication
|
isReplication
|
||||||
});
|
});
|
||||||
@@ -44,11 +44,11 @@ export const useUpdateSecretImport = () => {
|
|||||||
|
|
||||||
return useMutation<object, object, TUpdateSecretImportDTO>({
|
return useMutation<object, object, TUpdateSecretImportDTO>({
|
||||||
mutationFn: async ({ environment, import: secretImports, projectId, path, id }) => {
|
mutationFn: async ({ environment, import: secretImports, projectId, path, id }) => {
|
||||||
const { data } = await apiRequest.patch(`/api/v1/secret-imports/${id}`, {
|
const { data } = await apiRequest.patch(`/api/v2/secret-imports/${id}`, {
|
||||||
import: secretImports,
|
import: secretImports,
|
||||||
environment,
|
environment,
|
||||||
path,
|
path,
|
||||||
workspaceId: projectId
|
projectId
|
||||||
});
|
});
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
@@ -69,10 +69,10 @@ export const useUpdateSecretImport = () => {
|
|||||||
export const useResyncSecretReplication = () => {
|
export const useResyncSecretReplication = () => {
|
||||||
return useMutation<object, object, TResyncSecretReplicationDTO>({
|
return useMutation<object, object, TResyncSecretReplicationDTO>({
|
||||||
mutationFn: async ({ environment, projectId, path, id }) => {
|
mutationFn: async ({ environment, projectId, path, id }) => {
|
||||||
const { data } = await apiRequest.post(`/api/v1/secret-imports/${id}/replication-resync`, {
|
const { data } = await apiRequest.post(`/api/v2/secret-imports/${id}/replication-resync`, {
|
||||||
environment,
|
environment,
|
||||||
path,
|
path,
|
||||||
workspaceId: projectId
|
projectId
|
||||||
});
|
});
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
@@ -84,9 +84,9 @@ export const useDeleteSecretImport = () => {
|
|||||||
|
|
||||||
return useMutation<object, object, TDeleteSecretImportDTO>({
|
return useMutation<object, object, TDeleteSecretImportDTO>({
|
||||||
mutationFn: async ({ id, projectId, path, environment }) => {
|
mutationFn: async ({ id, projectId, path, environment }) => {
|
||||||
const { data } = await apiRequest.delete(`/api/v1/secret-imports/${id}`, {
|
const { data } = await apiRequest.delete(`/api/v2/secret-imports/${id}`, {
|
||||||
data: {
|
data: {
|
||||||
workspaceId: projectId,
|
projectId,
|
||||||
path,
|
path,
|
||||||
environment
|
environment
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,10 +30,10 @@ export const secretImportKeys = {
|
|||||||
|
|
||||||
const fetchSecretImport = async ({ projectId, environment, path = "/" }: TGetSecretImports) => {
|
const fetchSecretImport = async ({ projectId, environment, path = "/" }: TGetSecretImports) => {
|
||||||
const { data } = await apiRequest.get<{ secretImports: TSecretImport[] }>(
|
const { data } = await apiRequest.get<{ secretImports: TSecretImport[] }>(
|
||||||
"/api/v1/secret-imports",
|
"/api/v2/secret-imports",
|
||||||
{
|
{
|
||||||
params: {
|
params: {
|
||||||
workspaceId: projectId,
|
projectId,
|
||||||
environment,
|
environment,
|
||||||
path
|
path
|
||||||
}
|
}
|
||||||
@@ -65,16 +65,12 @@ export const useGetSecretImports = ({
|
|||||||
queryFn: () => fetchSecretImport({ path, projectId, environment })
|
queryFn: () => fetchSecretImport({ path, projectId, environment })
|
||||||
});
|
});
|
||||||
|
|
||||||
const fetchImportedSecrets = async (
|
const fetchImportedSecrets = async (projectId: string, environment: string, directory?: string) => {
|
||||||
workspaceId: string,
|
|
||||||
environment: string,
|
|
||||||
directory?: string
|
|
||||||
) => {
|
|
||||||
const { data } = await apiRequest.get<{ secrets: TImportedSecrets[] }>(
|
const { data } = await apiRequest.get<{ secrets: TImportedSecrets[] }>(
|
||||||
"/api/v1/secret-imports/secrets/raw",
|
"/api/v2/secret-imports/secrets",
|
||||||
{
|
{
|
||||||
params: {
|
params: {
|
||||||
workspaceId,
|
projectId,
|
||||||
environment,
|
environment,
|
||||||
path: directory
|
path: directory
|
||||||
}
|
}
|
||||||
@@ -89,10 +85,10 @@ const fetchImportedFolders = async ({
|
|||||||
path
|
path
|
||||||
}: TGetImportedFoldersByEnvDTO) => {
|
}: TGetImportedFoldersByEnvDTO) => {
|
||||||
const { data } = await apiRequest.get<{ secretImports: TSecretImport[] }>(
|
const { data } = await apiRequest.get<{ secretImports: TSecretImport[] }>(
|
||||||
"/api/v1/secret-imports",
|
"/api/v2/secret-imports",
|
||||||
{
|
{
|
||||||
params: {
|
params: {
|
||||||
workspaceId: projectId,
|
projectId,
|
||||||
environment,
|
environment,
|
||||||
path
|
path
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ export const useCreateWebhook = () => {
|
|||||||
const { data } = await apiRequest.post("/api/v1/webhooks", dto);
|
const { data } = await apiRequest.post("/api/v1/webhooks", dto);
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { workspaceId }) => {
|
onSuccess: (_, { projectId }) => {
|
||||||
queryClient.invalidateQueries({ queryKey: queryKeys.getWebhooks(workspaceId) });
|
queryClient.invalidateQueries({ queryKey: queryKeys.getWebhooks(projectId) });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -27,11 +27,11 @@ export const useTestWebhook = () => {
|
|||||||
const { data } = await apiRequest.post(`/api/v1/webhooks/${webhookId}/test`);
|
const { data } = await apiRequest.post(`/api/v1/webhooks/${webhookId}/test`);
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { workspaceId }) => {
|
onSuccess: (_, { projectId }) => {
|
||||||
queryClient.invalidateQueries({ queryKey: queryKeys.getWebhooks(workspaceId) });
|
queryClient.invalidateQueries({ queryKey: queryKeys.getWebhooks(projectId) });
|
||||||
},
|
},
|
||||||
onError: (_, { workspaceId }) => {
|
onError: (_, { projectId }) => {
|
||||||
queryClient.invalidateQueries({ queryKey: queryKeys.getWebhooks(workspaceId) });
|
queryClient.invalidateQueries({ queryKey: queryKeys.getWebhooks(projectId) });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -46,8 +46,8 @@ export const useUpdateWebhook = () => {
|
|||||||
});
|
});
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { workspaceId }) => {
|
onSuccess: (_, { projectId }) => {
|
||||||
queryClient.invalidateQueries({ queryKey: queryKeys.getWebhooks(workspaceId) });
|
queryClient.invalidateQueries({ queryKey: queryKeys.getWebhooks(projectId) });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -60,8 +60,8 @@ export const useDeleteWebhook = () => {
|
|||||||
const { data } = await apiRequest.delete(`/api/v1/webhooks/${dto.webhookId}`);
|
const { data } = await apiRequest.delete(`/api/v1/webhooks/${dto.webhookId}`);
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { workspaceId }) => {
|
onSuccess: (_, { projectId }) => {
|
||||||
queryClient.invalidateQueries({ queryKey: queryKeys.getWebhooks(workspaceId) });
|
queryClient.invalidateQueries({ queryKey: queryKeys.getWebhooks(projectId) });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export type TWebhook = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type TCreateWebhookDto = {
|
export type TCreateWebhookDto = {
|
||||||
workspaceId: string;
|
projectId: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
webhookUrl: string;
|
webhookUrl: string;
|
||||||
webhookSecretKey?: string;
|
webhookSecretKey?: string;
|
||||||
@@ -33,16 +33,16 @@ export type TCreateWebhookDto = {
|
|||||||
|
|
||||||
export type TUpdateWebhookDto = {
|
export type TUpdateWebhookDto = {
|
||||||
webhookId: string;
|
webhookId: string;
|
||||||
workspaceId: string;
|
projectId: string;
|
||||||
isDisabled?: boolean;
|
isDisabled?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TDeleteWebhookDto = {
|
export type TDeleteWebhookDto = {
|
||||||
webhookId: string;
|
webhookId: string;
|
||||||
workspaceId: string;
|
projectId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TTestWebhookDTO = {
|
export type TTestWebhookDTO = {
|
||||||
webhookId: string;
|
webhookId: string;
|
||||||
workspaceId: string;
|
projectId: string;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ export const WebhooksTab = withProjectPermission(
|
|||||||
try {
|
try {
|
||||||
await createWebhook({
|
await createWebhook({
|
||||||
...data,
|
...data,
|
||||||
workspaceId
|
projectId: workspaceId
|
||||||
});
|
});
|
||||||
handlePopUpClose("addWebhook");
|
handlePopUpClose("addWebhook");
|
||||||
createNotification({
|
createNotification({
|
||||||
@@ -82,7 +82,7 @@ export const WebhooksTab = withProjectPermission(
|
|||||||
try {
|
try {
|
||||||
await updateWebhook({
|
await updateWebhook({
|
||||||
webhookId,
|
webhookId,
|
||||||
workspaceId,
|
projectId: workspaceId,
|
||||||
isDisabled
|
isDisabled
|
||||||
});
|
});
|
||||||
createNotification({
|
createNotification({
|
||||||
@@ -103,7 +103,7 @@ export const WebhooksTab = withProjectPermission(
|
|||||||
const webhookId = popUp?.deleteWebhook?.data as string;
|
const webhookId = popUp?.deleteWebhook?.data as string;
|
||||||
await deleteWebhook({
|
await deleteWebhook({
|
||||||
webhookId,
|
webhookId,
|
||||||
workspaceId
|
projectId: workspaceId
|
||||||
});
|
});
|
||||||
handlePopUpClose("deleteWebhook");
|
handlePopUpClose("deleteWebhook");
|
||||||
createNotification({
|
createNotification({
|
||||||
@@ -123,7 +123,7 @@ export const WebhooksTab = withProjectPermission(
|
|||||||
try {
|
try {
|
||||||
await testWebhook({
|
await testWebhook({
|
||||||
webhookId,
|
webhookId,
|
||||||
workspaceId
|
projectId: workspaceId
|
||||||
});
|
});
|
||||||
createNotification({
|
createNotification({
|
||||||
type: "success",
|
type: "success",
|
||||||
|
|||||||
Reference in New Issue
Block a user