feat: resolved backend ts issues

This commit is contained in:
=
2025-09-16 00:08:41 +05:30
parent 5f902229f6
commit 37a80fa1ac
17 changed files with 512 additions and 271 deletions
+2 -2
View File
@@ -964,7 +964,7 @@ export const RAW_SECRETS = {
expand: "Whether or not to expand secret references.", expand: "Whether or not to expand secret references.",
recursive: recursive:
"Whether or not to fetch all secrets from the specified base path, and all of its subdirectories. Note, the max depth is 20 deep.", "Whether or not to fetch all secrets from the specified base path, and all of its subdirectories. Note, the max depth is 20 deep.",
workspaceId: "The ID of the project to list secrets from.", projectId: "The ID of the project to list secrets from.",
workspaceSlug: workspaceSlug:
"The slug of the project to list secrets from. This parameter is only applicable by machine identities.", "The slug of the project to list secrets from. This parameter is only applicable by machine identities.",
environment: "The slug of the environment to list secrets from.", environment: "The slug of the environment to list secrets from.",
@@ -1029,7 +1029,7 @@ export const RAW_SECRETS = {
}, },
GET_REFERENCE_TREE: { GET_REFERENCE_TREE: {
secretName: "The name of the secret to get the reference tree for.", secretName: "The name of the secret to get the reference tree for.",
workspaceId: "The ID of the project where the secret is located.", projectId: "The ID of the project where the secret is located.",
environment: "The slug of the environment where the the secret is located.", environment: "The slug of the environment where the the secret is located.",
secretPath: "The folder path where the secret is located." secretPath: "The folder path where the secret is located."
}, },
@@ -207,7 +207,7 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
const environments = req.query.environments.split(","); const environments = req.query.environments.split(",");
if (!projectId || environments.length === 0) if (!projectId || environments.length === 0)
throw new BadRequestError({ message: "Missing workspace id or environment(s)" }); throw new BadRequestError({ message: "Missing project id or environment(s)" });
const { shouldUseSecretV2Bridge } = await server.services.projectBot.getBotKey(projectId); const { shouldUseSecretV2Bridge } = await server.services.projectBot.getBotKey(projectId);
@@ -696,7 +696,7 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
includeSecretRotations includeSecretRotations
} = req.query; } = req.query;
if (!projectId || !environment) throw new BadRequestError({ message: "Missing workspace id or environment" }); if (!projectId || !environment) throw new BadRequestError({ message: "Missing project id or environment" });
const { shouldUseSecretV2Bridge } = await server.services.projectBot.getBotKey(projectId); const { shouldUseSecretV2Bridge } = await server.services.projectBot.getBotKey(projectId);
@@ -85,7 +85,7 @@ export const registerDepreciatedProjectRouter = async (server: FastifyZodProvide
} }
], ],
params: z.object({ params: z.object({
workspaceId: z.string().trim().describe(PROJECTS.GET.workspaceId) workspaceId: z.string().trim().describe(PROJECTS.GET.projectId)
}), }),
response: { response: {
200: z.object({ 200: z.object({
@@ -176,7 +176,7 @@ export const registerDepreciatedProjectRouter = async (server: FastifyZodProvide
} }
], ],
params: z.object({ params: z.object({
workspaceId: z.string().trim().describe(PROJECTS.UPDATE.workspaceId) workspaceId: z.string().trim().describe(PROJECTS.UPDATE.projectId)
}), }),
body: z.object({ body: z.object({
name: z name: z
@@ -284,7 +284,11 @@ export const registerDepreciatedProjectRouter = async (server: FastifyZodProvide
actor: req.permission.type, actor: req.permission.type,
actorAuthMethod: req.permission.authMethod, actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
workspaceSlug: req.params.workspaceSlug, filter: {
type: ProjectFilterType.SLUG,
slug: req.params.workspaceSlug,
orgId: req.permission.orgId
},
auditLogsRetentionDays: req.body.auditLogsRetentionDays auditLogsRetentionDays: req.body.auditLogsRetentionDays
}); });
@@ -321,7 +325,7 @@ export const registerDepreciatedProjectRouter = async (server: FastifyZodProvide
} }
], ],
params: z.object({ params: z.object({
workspaceId: z.string().trim().describe(PROJECTS.LIST_INTEGRATION.workspaceId) workspaceId: z.string().trim().describe(PROJECTS.LIST_INTEGRATION.projectId)
}), }),
response: { response: {
200: z.object({ 200: z.object({
@@ -366,7 +370,7 @@ export const registerDepreciatedProjectRouter = async (server: FastifyZodProvide
} }
], ],
params: z.object({ params: z.object({
workspaceId: z.string().trim().describe(PROJECTS.LIST_INTEGRATION_AUTHORIZATION.workspaceId) workspaceId: z.string().trim().describe(PROJECTS.LIST_INTEGRATION_AUTHORIZATION.projectId)
}), }),
response: { response: {
200: z.object({ 200: z.object({
+424 -207
View File
@@ -2,7 +2,10 @@ import slugify from "@sindresorhus/slugify";
import { z } from "zod"; import { z } from "zod";
import { import {
CertificatesSchema,
IntegrationsSchema, IntegrationsSchema,
PkiAlertsSchema,
PkiCollectionsSchema,
ProjectEnvironmentsSchema, ProjectEnvironmentsSchema,
ProjectMembershipsSchema, ProjectMembershipsSchema,
ProjectRolesSchema, ProjectRolesSchema,
@@ -27,9 +30,25 @@ import { ProjectFilterType, SearchProjectSortBy } from "@app/services/project/pr
import { validateSlackChannelsField } from "@app/services/slack/slack-auth-validators"; import { validateSlackChannelsField } from "@app/services/slack/slack-auth-validators";
import { WorkflowIntegration } from "@app/services/workflow-integration/workflow-integration-types"; import { WorkflowIntegration } from "@app/services/workflow-integration/workflow-integration-types";
import { integrationAuthPubSchema, SanitizedProjectSchema } from "../sanitizedSchemas"; import {
integrationAuthPubSchema,
InternalCertificateAuthorityResponseSchema,
SanitizedProjectSchema
} from "../sanitizedSchemas";
import { sanitizedServiceTokenSchema } from "../v2/service-token-router"; import { sanitizedServiceTokenSchema } from "../v2/service-token-router";
import { slugSchema } from "@app/server/lib/schemas"; import { slugSchema } from "@app/server/lib/schemas";
import { CaStatus } from "@app/services/certificate-authority/certificate-authority-enums";
import { sanitizedCertificateTemplate } from "@app/services/certificate-template/certificate-template-schema";
import { sanitizedSshCertificate } from "@app/ee/services/ssh-certificate/ssh-certificate-schema";
import { sanitizedSshCertificateTemplate } from "@app/ee/services/ssh-certificate-template/ssh-certificate-template-schema";
import { sanitizedSshCa } from "@app/ee/services/ssh/ssh-certificate-authority-schema";
import { loginMappingSchema, sanitizedSshHost } from "@app/ee/services/ssh-host/ssh-host-schema";
import { LoginMappingSource } from "@app/ee/services/ssh-host/ssh-host-types";
import { sanitizedSshHostGroup } from "@app/ee/services/ssh-host-group/ssh-host-group-schema";
import { InfisicalProjectTemplate } from "@app/ee/services/project-template/project-template-types";
import { PostHogEventTypes } from "@app/services/telemetry/telemetry-types";
import { getTelemetryDistinctId } from "@app/server/lib/telemetry";
import { sanitizedPkiSubscriber } from "@app/services/pki-subscriber/pki-subscriber-schema";
const projectWithEnv = SanitizedProjectSchema.merge( const projectWithEnv = SanitizedProjectSchema.merge(
z.object({ z.object({
@@ -158,8 +177,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod, actorAuthMethod: req.permission.authMethod,
workspaceName: req.body.projectName, projectName: req.body.projectName,
workspaceDescription: req.body.projectDescription, projectDescription: req.body.projectDescription,
slug: req.body.slug, slug: req.body.slug,
kmsKeyId: req.body.kmsKeyId, kmsKeyId: req.body.kmsKeyId,
template: req.body.template, template: req.body.template,
@@ -365,58 +384,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
} }
}); });
/* Delete a project by slug */ // TODO(depri): replcae frontned auto cap and delete protection with this patch
server.route({
method: "DELETE",
url: "/slug/:slug",
config: {
rateLimit: writeLimit
},
schema: {
hide: false,
tags: [ApiDocsTags.Projects],
description: "Delete project",
security: [
{
bearerAuth: []
}
],
params: z.object({
slug: slugSchema({ min: 5, max: 36 }).describe("The slug of the project to delete.")
}),
response: {
200: SanitizedProjectSchema
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const project = await server.services.project.deleteProject({
filter: {
type: ProjectFilterType.SLUG,
slug: req.params.slug,
orgId: req.permission.orgId
},
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
actor: req.permission.type
});
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: req.permission.orgId,
projectId: project.id,
event: {
type: EventType.DELETE_PROJECT,
metadata: project
}
});
return project;
}
});
server.route({ server.route({
method: "PATCH", method: "PATCH",
url: "/:projectId", url: "/:projectId",
@@ -462,11 +430,11 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
.describe(PROJECTS.UPDATE.slug), .describe(PROJECTS.UPDATE.slug),
secretSharing: z.boolean().optional().describe(PROJECTS.UPDATE.secretSharing), secretSharing: z.boolean().optional().describe(PROJECTS.UPDATE.secretSharing),
showSnapshotsLegacy: z.boolean().optional().describe(PROJECTS.UPDATE.showSnapshotsLegacy), showSnapshotsLegacy: z.boolean().optional().describe(PROJECTS.UPDATE.showSnapshotsLegacy),
defaultProduct: z.nativeEnum(ProjectType).optional().describe(PROJECTS.UPDATE.defaultProduct),
secretDetectionIgnoreValues: z secretDetectionIgnoreValues: z
.array(z.string()) .array(z.string())
.optional() .optional()
.describe(PROJECTS.UPDATE.secretDetectionIgnoreValues) .describe(PROJECTS.UPDATE.secretDetectionIgnoreValues),
pitVersionLimit: z.number().min(1).max(100).optional()
}), }),
response: { response: {
200: z.object({ 200: z.object({
@@ -485,12 +453,12 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
name: req.body.name, name: req.body.name,
description: req.body.description, description: req.body.description,
autoCapitalization: req.body.autoCapitalization, autoCapitalization: req.body.autoCapitalization,
defaultProduct: req.body.defaultProduct,
hasDeleteProtection: req.body.hasDeleteProtection, hasDeleteProtection: req.body.hasDeleteProtection,
slug: req.body.slug, slug: req.body.slug,
secretSharing: req.body.secretSharing, secretSharing: req.body.secretSharing,
showSnapshotsLegacy: req.body.showSnapshotsLegacy, showSnapshotsLegacy: req.body.showSnapshotsLegacy,
secretDetectionIgnoreValues: req.body.secretDetectionIgnoreValues secretDetectionIgnoreValues: req.body.secretDetectionIgnoreValues,
pitVersionLimit: req.body.pitVersionLimit
}, },
actorAuthMethod: req.permission.authMethod, actorAuthMethod: req.permission.authMethod,
actorId: req.permission.id, actorId: req.permission.id,
@@ -515,8 +483,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
}); });
server.route({ server.route({
method: "POST", method: "PUT",
url: "/:projectId/auto-capitalization", url: "/:projectId/audit-logs-retention",
config: { config: {
rateLimit: writeLimit rateLimit: writeLimit
}, },
@@ -524,150 +492,6 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
params: z.object({ params: z.object({
projectId: z.string().trim() projectId: z.string().trim()
}), }),
body: z.object({
autoCapitalization: z.boolean()
}),
response: {
200: z.object({
message: z.string(),
project: SanitizedProjectSchema
})
}
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => {
const project = await server.services.project.toggleAutoCapitalization({
actorId: req.permission.id,
actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
projectId: req.params.projectId,
autoCapitalization: req.body.autoCapitalization
});
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: req.permission.orgId,
projectId: req.params.projectId,
event: {
type: EventType.UPDATE_PROJECT,
metadata: req.body
}
});
return {
message: "Successfully changed project settings",
project
};
}
});
server.route({
method: "POST",
url: "/:projectId/delete-protection",
config: {
rateLimit: writeLimit
},
schema: {
params: z.object({
projectId: z.string().trim()
}),
body: z.object({
hasDeleteProtection: z.boolean()
}),
response: {
200: z.object({
message: z.string(),
project: SanitizedProjectSchema
})
}
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => {
const project = await server.services.project.toggleDeleteProtection({
actorId: req.permission.id,
actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
projectId: req.params.projectId,
hasDeleteProtection: req.body.hasDeleteProtection
});
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: req.permission.orgId,
projectId: req.params.projectId,
event: {
type: EventType.UPDATE_PROJECT,
metadata: req.body
}
});
return {
message: "Successfully changed project settings",
project
};
}
});
server.route({
method: "PUT",
url: "/:workspaceSlug/version-limit",
config: {
rateLimit: writeLimit
},
schema: {
params: z.object({
workspaceSlug: z.string().trim()
}),
body: z.object({
pitVersionLimit: z.number().min(1).max(100)
}),
response: {
200: z.object({
message: z.string(),
project: SanitizedProjectSchema
})
}
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => {
const project = await server.services.project.updateVersionLimit({
actorId: req.permission.id,
actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
pitVersionLimit: req.body.pitVersionLimit,
workspaceSlug: req.params.workspaceSlug
});
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: req.permission.orgId,
projectId: project.id,
event: {
type: EventType.UPDATE_PROJECT,
metadata: req.body
}
});
return {
message: "Successfully changed project version limit",
project
};
}
});
server.route({
method: "PUT",
url: "/:workspaceSlug/audit-logs-retention",
config: {
rateLimit: writeLimit
},
schema: {
params: z.object({
workspaceSlug: z.string().trim()
}),
body: z.object({ body: z.object({
auditLogsRetentionDays: z.number().min(0) auditLogsRetentionDays: z.number().min(0)
}), }),
@@ -685,8 +509,11 @@ export const registerProjectRouter = 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,
workspaceSlug: req.params.workspaceSlug, auditLogsRetentionDays: req.body.auditLogsRetentionDays,
auditLogsRetentionDays: req.body.auditLogsRetentionDays filter: {
projectId: req.params.projectId,
type: ProjectFilterType.ID
}
}); });
await server.services.auditLog.createAuditLog({ await server.services.auditLog.createAuditLog({
@@ -1303,4 +1130,394 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
return { status }; return { status };
} }
}); });
server.route({
method: "GET",
url: "/:projectId/cas",
config: {
rateLimit: readLimit
},
schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateAuthorities],
params: z.object({
projectId: z.string().trim()
}),
querystring: z.object({
status: z.enum([CaStatus.ACTIVE, CaStatus.PENDING_CERTIFICATE]).optional().describe(PROJECTS.LIST_CAS.status),
friendlyName: z.string().optional().describe(PROJECTS.LIST_CAS.friendlyName),
commonName: z.string().optional().describe(PROJECTS.LIST_CAS.commonName),
offset: z.coerce.number().min(0).max(100).default(0).describe(PROJECTS.LIST_CAS.offset),
limit: z.coerce.number().min(1).max(100).default(25).describe(PROJECTS.LIST_CAS.limit)
}),
response: {
200: z.object({
cas: z.array(InternalCertificateAuthorityResponseSchema)
})
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const cas = await server.services.project.listProjectCas({
filter: {
projectId: req.params.projectId,
type: ProjectFilterType.ID
},
actorId: req.permission.id,
actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
actor: req.permission.type,
...req.query
});
return { cas };
}
});
server.route({
method: "GET",
url: "/:projectId/certificates",
config: {
rateLimit: readLimit
},
schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificates],
params: z.object({
projectId: z.string().trim()
}),
querystring: z.object({
friendlyName: z.string().optional().describe(PROJECTS.LIST_CERTIFICATES.friendlyName),
commonName: z.string().optional().describe(PROJECTS.LIST_CERTIFICATES.commonName),
offset: z.coerce.number().min(0).max(100).default(0).describe(PROJECTS.LIST_CERTIFICATES.offset),
limit: z.coerce.number().min(1).max(100).default(25).describe(PROJECTS.LIST_CERTIFICATES.limit)
}),
response: {
200: z.object({
certificates: z.array(CertificatesSchema),
totalCount: z.number()
})
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const { certificates, totalCount } = await server.services.project.listProjectCertificates({
filter: {
projectId: req.params.projectId,
type: ProjectFilterType.ID
},
actorId: req.permission.id,
actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
actor: req.permission.type,
...req.query
});
return { certificates, totalCount };
}
});
server.route({
method: "GET",
url: "/:projectId/pki-alerts",
config: {
rateLimit: readLimit
},
schema: {
hide: false,
tags: [ApiDocsTags.PkiAlerting],
params: z.object({
projectId: z.string().trim()
}),
response: {
200: z.object({
alerts: z.array(PkiAlertsSchema)
})
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const { alerts } = await server.services.project.listProjectAlerts({
projectId: req.params.projectId,
actorId: req.permission.id,
actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
actor: req.permission.type
});
return { alerts };
}
});
server.route({
method: "GET",
url: "/:projectId/pki-collections",
config: {
rateLimit: readLimit
},
schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateCollections],
params: z.object({
projectId: z.string().trim()
}),
response: {
200: z.object({
collections: z.array(PkiCollectionsSchema)
})
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const { pkiCollections } = await server.services.project.listProjectPkiCollections({
projectId: req.params.projectId,
actorId: req.permission.id,
actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
actor: req.permission.type
});
return { collections: pkiCollections };
}
});
server.route({
method: "GET",
url: "/:projectId/pki-subscribers",
config: {
rateLimit: readLimit
},
schema: {
hide: false,
tags: [ApiDocsTags.PkiSubscribers],
params: z.object({
projectId: z.string().trim().describe(PROJECTS.LIST_PKI_SUBSCRIBERS.projectId)
}),
response: {
200: z.object({
subscribers: z.array(sanitizedPkiSubscriber)
})
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const subscribers = await server.services.project.listProjectPkiSubscribers({
actorId: req.permission.id,
actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
actor: req.permission.type,
projectId: req.params.projectId
});
return { subscribers };
}
});
server.route({
method: "GET",
url: "/:projectId/certificate-templates",
config: {
rateLimit: readLimit
},
schema: {
hide: false,
tags: [ApiDocsTags.PkiCertificateTemplates],
params: z.object({
projectId: z.string().trim()
}),
response: {
200: z.object({
certificateTemplates: sanitizedCertificateTemplate.array()
})
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const { certificateTemplates } = await server.services.project.listProjectCertificateTemplates({
projectId: req.params.projectId,
actorId: req.permission.id,
actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
actor: req.permission.type
});
return { certificateTemplates };
}
});
server.route({
method: "GET",
url: "/:projectId/ssh-certificates",
config: {
rateLimit: readLimit
},
schema: {
params: z.object({
projectId: z.string().trim().describe(PROJECTS.LIST_SSH_CAS.projectId)
}),
querystring: z.object({
offset: z.coerce.number().default(0).describe(PROJECTS.LIST_SSH_CERTIFICATES.offset),
limit: z.coerce.number().default(25).describe(PROJECTS.LIST_SSH_CERTIFICATES.limit)
}),
response: {
200: z.object({
certificates: z.array(sanitizedSshCertificate),
totalCount: z.number()
})
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const { certificates, totalCount } = await server.services.project.listProjectSshCertificates({
actorId: req.permission.id,
actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
actor: req.permission.type,
projectId: req.params.projectId,
offset: req.query.offset,
limit: req.query.limit
});
return { certificates, totalCount };
}
});
server.route({
method: "GET",
url: "/:projectId/ssh-certificate-templates",
config: {
rateLimit: readLimit
},
schema: {
hide: false,
tags: [ApiDocsTags.SshCertificateTemplates],
params: z.object({
projectId: z.string().trim().describe(PROJECTS.LIST_SSH_CERTIFICATE_TEMPLATES.projectId)
}),
response: {
200: z.object({
certificateTemplates: z.array(sanitizedSshCertificateTemplate)
})
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const { certificateTemplates } = await server.services.project.listProjectSshCertificateTemplates({
actorId: req.permission.id,
actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
actor: req.permission.type,
projectId: req.params.projectId
});
return { certificateTemplates };
}
});
server.route({
method: "GET",
url: "/:projectId/ssh-cas",
config: {
rateLimit: readLimit
},
schema: {
hide: false,
tags: [ApiDocsTags.SshCertificateAuthorities],
params: z.object({
projectId: z.string().trim().describe(PROJECTS.LIST_SSH_CAS.projectId)
}),
response: {
200: z.object({
cas: z.array(sanitizedSshCa)
})
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const cas = await server.services.project.listProjectSshCas({
actorId: req.permission.id,
actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
actor: req.permission.type,
projectId: req.params.projectId
});
return { cas };
}
});
server.route({
method: "GET",
url: "/:projectId/ssh-hosts",
config: {
rateLimit: readLimit
},
schema: {
hide: false,
tags: [ApiDocsTags.SshHosts],
params: z.object({
projectId: z.string().trim().describe(PROJECTS.LIST_SSH_HOSTS.projectId)
}),
response: {
200: z.object({
hosts: z.array(
sanitizedSshHost.extend({
loginMappings: loginMappingSchema
.extend({
source: z.nativeEnum(LoginMappingSource)
})
.array()
})
)
})
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const hosts = await server.services.project.listProjectSshHosts({
actorId: req.permission.id,
actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
actor: req.permission.type,
projectId: req.params.projectId
});
return { hosts };
}
});
server.route({
method: "GET",
url: "/:projectId/ssh-host-groups",
config: {
rateLimit: readLimit
},
schema: {
hide: false,
tags: [ApiDocsTags.SshHostGroups],
params: z.object({
projectId: z.string().trim().describe(PROJECTS.LIST_SSH_HOST_GROUPS.projectId)
}),
response: {
200: z.object({
groups: z.array(
sanitizedSshHostGroup.extend({
loginMappings: loginMappingSchema.array(),
hostCount: z.number()
})
)
})
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const groups = await server.services.project.listProjectSshHostGroups({
actorId: req.permission.id,
actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
actor: req.permission.type,
projectId: req.params.projectId
});
return { groups };
}
});
}; };
@@ -47,7 +47,7 @@ export const registerDepreciatedProjectRouter = async (server: FastifyZodProvide
schema: { schema: {
description: "Return encrypted project key", description: "Return encrypted project key",
params: z.object({ params: z.object({
workspaceId: z.string().trim().describe(PROJECTS.GET_KEY.workspaceId) workspaceId: z.string().trim().describe(PROJECTS.GET_KEY.projectId)
}), }),
response: { response: {
200: ProjectKeysSchema.merge( 200: ProjectKeysSchema.merge(
@@ -125,8 +125,8 @@ export const registerDepreciatedProjectRouter = async (server: FastifyZodProvide
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod, actorAuthMethod: req.permission.authMethod,
workspaceName: req.body.projectName, projectName: req.body.projectName,
workspaceDescription: req.body.projectDescription, projectDescription: req.body.projectDescription,
slug: req.body.slug, slug: req.body.slug,
kmsKeyId: req.body.kmsKeyId, kmsKeyId: req.body.kmsKeyId,
template: req.body.template, template: req.body.template,
@@ -39,7 +39,7 @@ const SecretReferenceNodeTree: z.ZodType<TSecretReferenceNode> = SecretReference
children: z.lazy(() => SecretReferenceNodeTree.array()) children: z.lazy(() => SecretReferenceNodeTree.array())
}); });
export const registerSecretRouter = async (server: FastifyZodProvider) => { export const registerDepreciatedSecretRouter = async (server: FastifyZodProvider) => {
server.route({ server.route({
method: "POST", method: "POST",
url: "/tags/:secretName", url: "/tags/:secretName",
@@ -230,7 +230,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
} }
}) })
.describe(RAW_SECRETS.LIST.metadataFilter), .describe(RAW_SECRETS.LIST.metadataFilter),
workspaceId: z.string().trim().optional().describe(RAW_SECRETS.LIST.workspaceId), workspaceId: z.string().trim().optional().describe(RAW_SECRETS.LIST.projectId),
workspaceSlug: z.string().trim().optional().describe(RAW_SECRETS.LIST.workspaceSlug), workspaceSlug: z.string().trim().optional().describe(RAW_SECRETS.LIST.workspaceSlug),
environment: z.string().trim().optional().describe(RAW_SECRETS.LIST.environment), environment: z.string().trim().optional().describe(RAW_SECRETS.LIST.environment),
secretPath: z.string().trim().default("/").transform(removeTrailingSlash).describe(RAW_SECRETS.LIST.secretPath), secretPath: z.string().trim().default("/").transform(removeTrailingSlash).describe(RAW_SECRETS.LIST.secretPath),
+2 -2
View File
@@ -1,6 +1,6 @@
import { registerExternalMigrationRouter } from "./external-migration-router"; import { registerExternalMigrationRouter } from "./external-migration-router";
import { registerLoginRouter } from "./login-router"; import { registerLoginRouter } from "./login-router";
import { registerSecretRouter } from "./secret-router"; import { registerDepreciatedSecretRouter } from "./depreciated-secret-router";
import { registerSignupRouter } from "./signup-router"; import { registerSignupRouter } from "./signup-router";
import { registerUserRouter } from "./user-router"; import { registerUserRouter } from "./user-router";
@@ -8,6 +8,6 @@ export const registerV3Routes = async (server: FastifyZodProvider) => {
await server.register(registerSignupRouter, { prefix: "/signup" }); await server.register(registerSignupRouter, { prefix: "/signup" });
await server.register(registerLoginRouter, { prefix: "/auth" }); await server.register(registerLoginRouter, { prefix: "/auth" });
await server.register(registerUserRouter, { prefix: "/users" }); await server.register(registerUserRouter, { prefix: "/users" });
await server.register(registerSecretRouter, { prefix: "/secrets" }); await server.register(registerDepreciatedSecretRouter, { prefix: "/secrets" });
await server.register(registerExternalMigrationRouter, { prefix: "/external-migration" }); await server.register(registerExternalMigrationRouter, { prefix: "/external-migration" });
}; };
@@ -117,7 +117,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
} }
}) })
.describe(RAW_SECRETS.LIST.metadataFilter), .describe(RAW_SECRETS.LIST.metadataFilter),
projectId: z.string().trim().optional().describe(RAW_SECRETS.LIST.workspaceId), projectId: z.string().trim().optional().describe(RAW_SECRETS.LIST.projectId),
environment: z.string().trim().optional().describe(RAW_SECRETS.LIST.environment), environment: z.string().trim().optional().describe(RAW_SECRETS.LIST.environment),
secretPath: z.string().trim().default("/").transform(removeTrailingSlash).describe(RAW_SECRETS.LIST.secretPath), secretPath: z.string().trim().default("/").transform(removeTrailingSlash).describe(RAW_SECRETS.LIST.secretPath),
viewSecretValue: convertStringBoolean(true).describe(RAW_SECRETS.LIST.viewSecretValue), viewSecretValue: convertStringBoolean(true).describe(RAW_SECRETS.LIST.viewSecretValue),
@@ -901,7 +901,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
); );
await server.services.auditLog.createAuditLog({ await server.services.auditLog.createAuditLog({
projectId: secrets[0].workspace, projectId: req.body.projectId,
...req.auditLogInfo, ...req.auditLogInfo,
event: { event: {
type: EventType.CREATE_SECRETS, type: EventType.CREATE_SECRETS,
@@ -924,7 +924,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
organizationId: req.permission.orgId, organizationId: req.permission.orgId,
properties: { properties: {
numberOfSecrets: secrets.length, numberOfSecrets: secrets.length,
projectId: secrets[0].workspace, projectId: req.body.projectId,
environment: req.body.environment, environment: req.body.environment,
secretPath: req.body.secretPath, secretPath: req.body.secretPath,
channel: getUserAgentType(req.headers["user-agent"]), channel: getUserAgentType(req.headers["user-agent"]),
@@ -1050,7 +1050,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
); );
await server.services.auditLog.createAuditLog({ await server.services.auditLog.createAuditLog({
projectId: secrets[0].workspace, projectId: req.body.projectId,
...req.auditLogInfo, ...req.auditLogInfo,
event: { event: {
type: EventType.UPDATE_SECRETS, type: EventType.UPDATE_SECRETS,
@@ -1072,7 +1072,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
const createdSecrets = secrets.filter((el) => el.version === 1); const createdSecrets = secrets.filter((el) => el.version === 1);
if (createdSecrets.length) { if (createdSecrets.length) {
await server.services.auditLog.createAuditLog({ await server.services.auditLog.createAuditLog({
projectId: secrets[0].workspace, projectId: req.body.projectId,
...req.auditLogInfo, ...req.auditLogInfo,
event: { event: {
type: EventType.CREATE_SECRETS, type: EventType.CREATE_SECRETS,
@@ -1097,7 +1097,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
organizationId: req.permission.orgId, organizationId: req.permission.orgId,
properties: { properties: {
numberOfSecrets: secrets.length, numberOfSecrets: secrets.length,
projectId: secrets[0].workspace, projectId: req.body.projectId,
environment: req.body.environment, environment: req.body.environment,
secretPath: req.body.secretPath, secretPath: req.body.secretPath,
channel: getUserAgentType(req.headers["user-agent"]), channel: getUserAgentType(req.headers["user-agent"]),
@@ -1243,7 +1243,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
secretName: z.string().trim().describe(RAW_SECRETS.GET_REFERENCE_TREE.secretName) secretName: z.string().trim().describe(RAW_SECRETS.GET_REFERENCE_TREE.secretName)
}), }),
querystring: z.object({ querystring: z.object({
projectId: z.string().trim().describe(RAW_SECRETS.GET_REFERENCE_TREE.workspaceId), projectId: z.string().trim().describe(RAW_SECRETS.GET_REFERENCE_TREE.projectId),
environment: z.string().trim().describe(RAW_SECRETS.GET_REFERENCE_TREE.environment), environment: z.string().trim().describe(RAW_SECRETS.GET_REFERENCE_TREE.environment),
secretPath: z secretPath: z
.string() .string()
@@ -1262,13 +1262,13 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
onRequest: verifyAuth([AuthMode.JWT]), onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => { handler: async (req) => {
const { secretName } = req.params; const { secretName } = req.params;
const { secretPath, environment, projectId: workspaceId } = req.query; const { secretPath, environment, projectId } = req.query;
const { tree, value } = await server.services.secret.getSecretReferenceTree({ const { tree, value } = await server.services.secret.getSecretReferenceTree({
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,
projectId: workspaceId, projectId,
secretName, secretName,
secretPath, secretPath,
environment environment
@@ -55,7 +55,7 @@ export const importDataIntoInfisicalFn = async ({
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod, actorAuthMethod,
workspaceName: project.name, projectName: project.name,
createDefaultEnvs: false, createDefaultEnvs: false,
tx tx
}) })
@@ -237,8 +237,8 @@ export const projectServiceFactory = ({
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod, actorAuthMethod,
workspaceName, projectName: workspaceName,
workspaceDescription, projectDescription: workspaceDescription,
slug: projectSlug, slug: projectSlug,
kmsKeyId, kmsKeyId,
tx: trx, tx: trx,
@@ -591,7 +591,8 @@ export const projectServiceFactory = ({
secretSharing: update.secretSharing, secretSharing: update.secretSharing,
defaultProduct: update.defaultProduct, defaultProduct: update.defaultProduct,
showSnapshotsLegacy: update.showSnapshotsLegacy, showSnapshotsLegacy: update.showSnapshotsLegacy,
secretDetectionIgnoreValues: update.secretDetectionIgnoreValues secretDetectionIgnoreValues: update.secretDetectionIgnoreValues,
pitVersionLimit: update.pitVersionLimit
}); });
return updatedProject; return updatedProject;
@@ -684,19 +685,21 @@ export const projectServiceFactory = ({
actorOrgId, actorOrgId,
actorAuthMethod, actorAuthMethod,
auditLogsRetentionDays, auditLogsRetentionDays,
workspaceSlug filter
}: TUpdateAuditLogsRetentionDTO) => { }: TUpdateAuditLogsRetentionDTO) => {
const project = await projectDAL.findProjectBySlug(workspaceSlug, actorOrgId); const project = await projectDAL.findProjectByFilter(filter);
const projectId = project.id;
if (!project) { if (!project) {
throw new NotFoundError({ throw new NotFoundError({
message: `Project with slug '${workspaceSlug}' not found` message: `Project not found`
}); });
} }
const { hasRole } = await permissionService.getProjectPermission({ const { hasRole } = await permissionService.getProjectPermission({
actor, actor,
actorId, actorId,
projectId: project.id, projectId,
actorAuthMethod, actorAuthMethod,
actorOrgId, actorOrgId,
actionProjectType: ActionProjectType.Any actionProjectType: ActionProjectType.Any
@@ -42,12 +42,13 @@ export type TCreateProjectDTO = {
actorAuthMethod: ActorAuthMethod; actorAuthMethod: ActorAuthMethod;
actorId: string; actorId: string;
actorOrgId?: string; actorOrgId?: string;
workspaceName: string; projectName: string;
workspaceDescription?: string; projectDescription?: string;
slug?: string; slug?: string;
kmsKeyId?: string; kmsKeyId?: string;
createDefaultEnvs?: boolean; createDefaultEnvs?: boolean;
template?: string; template?: string;
pitVersionLimit?: number;
tx?: Knex; tx?: Knex;
type?: ProjectType; type?: ProjectType;
}; };
@@ -78,7 +79,7 @@ export type TUpdateProjectVersionLimitDTO = {
export type TUpdateAuditLogsRetentionDTO = { export type TUpdateAuditLogsRetentionDTO = {
auditLogsRetentionDays: number; auditLogsRetentionDays: number;
workspaceSlug: string; filter: Filter;
} & Omit<TProjectPermission, "projectId">; } & Omit<TProjectPermission, "projectId">;
export type TUpdateProjectNameDTO = { export type TUpdateProjectNameDTO = {
@@ -90,6 +91,7 @@ export type TUpdateProjectDTO = {
update: { update: {
name?: string; name?: string;
description?: string; description?: string;
pitVersionLimit?: number;
autoCapitalization?: boolean; autoCapitalization?: boolean;
hasDeleteProtection?: boolean; hasDeleteProtection?: boolean;
defaultProduct?: ProjectType; defaultProduct?: ProjectType;
+14 -5
View File
@@ -2970,14 +2970,23 @@ export const secretServiceFactory = ({
actor, actor,
actorId, actorId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId,
projectId: inputProjectId
}: TMoveSecretsDTO) => { }: TMoveSecretsDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId); let project;
if (projectSlug) {
project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
} else if (inputProjectId) {
project = await projectDAL.findById(inputProjectId);
}
if (!project) { if (!project) {
throw new NotFoundError({ throw new NotFoundError({
message: `Project with slug '${projectSlug}' not found` message: `Project with slug '${projectSlug}' not found`
}); });
} }
const projectId = project.id;
if (project.version === ProjectVersion.V3) { if (project.version === ProjectVersion.V3) {
return secretV2BridgeService.moveSecrets({ return secretV2BridgeService.moveSecrets({
sourceEnvironment, sourceEnvironment,
@@ -3170,7 +3179,7 @@ export const secretServiceFactory = ({
}); });
} }
const destinationFolderPolicy = await secretApprovalPolicyService.getSecretApprovalPolicy( const destinationFolderPolicy = await secretApprovalPolicyService.getSecretApprovalPolicy(
project.id, projectId,
destinationFolder.environment.slug, destinationFolder.environment.slug,
destinationFolder.path destinationFolder.path
); );
@@ -3257,7 +3266,7 @@ export const secretServiceFactory = ({
} }
if (locallyUpdatedSecrets.length) { if (locallyUpdatedSecrets.length) {
await fnSecretBulkUpdate({ await fnSecretBulkUpdate({
projectId: project.id, projectId,
folderId: destinationFolder.id, folderId: destinationFolder.id,
secretVersionDAL, secretVersionDAL,
secretDAL, secretDAL,
@@ -3300,7 +3309,7 @@ export const secretServiceFactory = ({
const locallyDeletedSecrets = decryptedSourceSecrets.map((el) => ({ ...el, operation: SecretOperations.Delete })); const locallyDeletedSecrets = decryptedSourceSecrets.map((el) => ({ ...el, operation: SecretOperations.Delete }));
const sourceFolderPolicy = await secretApprovalPolicyService.getSecretApprovalPolicy( const sourceFolderPolicy = await secretApprovalPolicyService.getSecretApprovalPolicy(
project.id, projectId,
sourceFolder.environment.slug, sourceFolder.environment.slug,
sourceFolder.path sourceFolder.path
); );
+16 -12
View File
@@ -245,7 +245,9 @@ export const useUpdateProject = () => {
newSlug, newSlug,
secretSharing, secretSharing,
showSnapshotsLegacy, showSnapshotsLegacy,
secretDetectionIgnoreValues secretDetectionIgnoreValues,
autoCapitalization,
pitVersionLimit
}) => { }) => {
const { data } = await apiRequest.patch<{ project: Project }>( const { data } = await apiRequest.patch<{ project: Project }>(
`/api/v1/projects/${projectID}`, `/api/v1/projects/${projectID}`,
@@ -255,7 +257,9 @@ export const useUpdateProject = () => {
slug: newSlug, slug: newSlug,
secretSharing, secretSharing,
showSnapshotsLegacy, showSnapshotsLegacy,
secretDetectionIgnoreValues secretDetectionIgnoreValues,
autoCapitalization,
pitVersionLimit
} }
); );
return data.project; return data.project;
@@ -682,15 +686,15 @@ export const useListWorkspaceGroups = (projectId: string) => {
}; };
export const useListWorkspaceCas = ({ export const useListWorkspaceCas = ({
projectSlug, projectId,
status status
}: { }: {
projectSlug: string; projectId: string;
status?: CaStatus; status?: CaStatus;
}) => { }) => {
return useQuery({ return useQuery({
queryKey: projectKeys.specificWorkspaceCas({ queryKey: projectKeys.specificWorkspaceCas({
projectSlug, projectId,
status status
}), }),
queryFn: async () => { queryFn: async () => {
@@ -701,29 +705,29 @@ export const useListWorkspaceCas = ({
const { const {
data: { cas } data: { cas }
} = await apiRequest.get<{ cas: TCertificateAuthority[] }>( } = await apiRequest.get<{ cas: TCertificateAuthority[] }>(
`/api/v1/projects/${projectSlug}/cas`, `/api/v1/projects/${projectId}/cas`,
{ {
params params
} }
); );
return cas; return cas;
}, },
enabled: Boolean(projectSlug) enabled: Boolean(projectId)
}); });
}; };
export const useListWorkspaceCertificates = ({ export const useListWorkspaceCertificates = ({
projectSlug, projectId,
offset, offset,
limit limit
}: { }: {
projectSlug: string; projectId: string;
offset: number; offset: number;
limit: number; limit: number;
}) => { }) => {
return useQuery({ return useQuery({
queryKey: projectKeys.specificWorkspaceCertificates({ queryKey: projectKeys.specificWorkspaceCertificates({
slug: projectSlug, projectId,
offset, offset,
limit limit
}), }),
@@ -736,7 +740,7 @@ export const useListWorkspaceCertificates = ({
const { const {
data: { certificates, totalCount } data: { certificates, totalCount }
} = await apiRequest.get<{ certificates: TCertificate[]; totalCount: number }>( } = await apiRequest.get<{ certificates: TCertificate[]; totalCount: number }>(
`/api/v1/projects/${projectSlug}/certificates`, `/api/v1/projects/${projectId}/certificates`,
{ {
params params
} }
@@ -744,7 +748,7 @@ export const useListWorkspaceCertificates = ({
return { certificates, totalCount }; return { certificates, totalCount };
}, },
enabled: Boolean(projectSlug) enabled: Boolean(projectId)
}); });
}; };
@@ -34,22 +34,22 @@ export const projectKeys = {
getWorkspaceGroupMemberships: (projectId: string) => [{ projectId }, "project-groups"] as const, getWorkspaceGroupMemberships: (projectId: string) => [{ projectId }, "project-groups"] as const,
getWorkspaceGroupMembershipDetails: (projectId: string, groupId: string) => getWorkspaceGroupMembershipDetails: (projectId: string, groupId: string) =>
[{ projectId, groupId }, "project-group-membership-details"] as const, [{ projectId, groupId }, "project-group-membership-details"] as const,
getWorkspaceCas: ({ projectSlug }: { projectSlug: string }) => getWorkspaceCas: ({ projectId }: { projectId: string }) =>
[{ projectSlug }, "project-cas"] as const, [{ projectId }, "project-cas"] as const,
specificWorkspaceCas: ({ projectSlug, status }: { projectSlug: string; status?: CaStatus }) => specificWorkspaceCas: ({ projectId, status }: { projectId: string; status?: CaStatus }) =>
[...projectKeys.getWorkspaceCas({ projectSlug }), { status }] as const, [...projectKeys.getWorkspaceCas({ projectId }), { status }] as const,
allWorkspaceCertificates: () => ["project-certificates"] as const, allWorkspaceCertificates: () => ["project-certificates"] as const,
forWorkspaceCertificates: (slug: string) => forWorkspaceCertificates: (projectId: string) =>
[...projectKeys.allWorkspaceCertificates(), slug] as const, [...projectKeys.allWorkspaceCertificates(), projectId] as const,
specificWorkspaceCertificates: ({ specificWorkspaceCertificates: ({
slug, projectId,
offset, offset,
limit limit
}: { }: {
slug: string; projectId: string;
offset: number; offset: number;
limit: number; limit: number;
}) => [...projectKeys.forWorkspaceCertificates(slug), { offset, limit }] as const, }) => [...projectKeys.forWorkspaceCertificates(projectId), { offset, limit }] as const,
getWorkspacePkiAlerts: (projectId: string) => [{ projectId }, "project-pki-alerts"] as const, getWorkspacePkiAlerts: (projectId: string) => [{ projectId }, "project-pki-alerts"] as const,
getWorkspacePkiSubscribers: (projectId: string) => getWorkspacePkiSubscribers: (projectId: string) =>
[{ projectId }, "project-pki-subscribers"] as const, [{ projectId }, "project-pki-subscribers"] as const,
@@ -83,6 +83,8 @@ export type UpdateProjectDTO = {
secretSharing?: boolean; secretSharing?: boolean;
showSnapshotsLegacy?: boolean; showSnapshotsLegacy?: boolean;
secretDetectionIgnoreValues?: string[]; secretDetectionIgnoreValues?: string[];
pitVersionLimit?: number;
autoCapitalization?: boolean;
}; };
export type UpdatePitVersionLimitDTO = { projectSlug: string; pitVersionLimit: number }; export type UpdatePitVersionLimitDTO = { projectSlug: string; pitVersionLimit: number };
@@ -64,7 +64,7 @@ export const CertificatesTable = ({ handlePopUpOpen }: Props) => {
const { currentWorkspace } = useWorkspace(); const { currentWorkspace } = useWorkspace();
const { data, isPending } = useListWorkspaceCertificates({ const { data, isPending } = useListWorkspaceCertificates({
projectSlug: currentWorkspace?.slug ?? "", projectId: currentWorkspace?.slug ?? "",
offset: (page - 1) * perPage, offset: (page - 1) * perPage,
limit: perPage limit: perPage
}); });
@@ -49,7 +49,7 @@ export const AddPkiCollectionItemModal = ({
}); });
const { data } = useListWorkspaceCertificates({ const { data } = useListWorkspaceCertificates({
projectSlug: currentWorkspace?.slug || "", projectId: currentWorkspace?.slug || "",
offset: 0, offset: 0,
limit: 25 limit: 25
}); });