feat: completed v1 projects prefixed one with projects and switched in

frontend
This commit is contained in:
=
2025-09-16 00:08:40 +05:30
parent 024e16ac60
commit 2509890bab
9 changed files with 266 additions and 192 deletions
@@ -0,0 +1,195 @@
import { z } from "zod";
import { AuditLogsSchema, SecretSnapshotsSchema } from "@app/db/schemas";
import { EventType, UserAgentType } from "@app/ee/services/audit-log/audit-log-types";
import { ApiDocsTags, AUDIT_LOGS, PROJECTS } from "@app/lib/api-docs";
import { getLastMidnightDateISO, removeTrailingSlash } from "@app/lib/fn";
import { readLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
export const registerDepreciatedProjectRouter = async (server: FastifyZodProvider) => {
server.route({
method: "GET",
url: "/:workspaceId/secret-snapshots",
config: {
rateLimit: readLimit
},
schema: {
hide: false,
tags: [ApiDocsTags.Projects],
description: "Return project secret snapshots ids",
security: [
{
bearerAuth: []
}
],
params: z.object({
workspaceId: z.string().trim().describe(PROJECTS.GET_SNAPSHOTS.projectId)
}),
querystring: z.object({
environment: z.string().trim().describe(PROJECTS.GET_SNAPSHOTS.environment),
path: z.string().trim().default("/").transform(removeTrailingSlash).describe(PROJECTS.GET_SNAPSHOTS.path),
offset: z.coerce.number().default(0).describe(PROJECTS.GET_SNAPSHOTS.offset),
limit: z.coerce.number().default(20).describe(PROJECTS.GET_SNAPSHOTS.limit)
}),
response: {
200: z.object({
secretSnapshots: SecretSnapshotsSchema.array()
})
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const secretSnapshots = await server.services.snapshot.listSnapshots({
actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorId: req.permission.id,
actorOrgId: req.permission.orgId,
projectId: req.params.workspaceId,
...req.query
});
return { secretSnapshots };
}
});
server.route({
method: "GET",
url: "/:workspaceId/secret-snapshots/count",
config: {
rateLimit: readLimit
},
schema: {
params: z.object({
workspaceId: z.string().trim()
}),
querystring: z.object({
environment: z.string().trim(),
path: z.string().trim().default("/").transform(removeTrailingSlash)
}),
response: {
200: z.object({
count: z.number()
})
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const count = await server.services.snapshot.projectSecretSnapshotCount({
actor: req.permission.type,
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
projectId: req.params.workspaceId,
environment: req.query.environment,
path: req.query.path
});
return { count };
}
});
/*
* Daniel: This endpoint is no longer is use.
* We are keeping it for now because it has been exposed in our public api docs for a while, so by removing it we are likely to break users workflows.
*
* Please refer to the new endpoint, GET /api/v1/organization/audit-logs, for the same (and more) functionality.
*/
server.route({
method: "GET",
url: "/:workspaceId/audit-logs",
config: {
rateLimit: readLimit
},
schema: {
description: "Return audit logs",
security: [
{
bearerAuth: []
}
],
params: z.object({
workspaceId: z.string().trim().describe(AUDIT_LOGS.EXPORT.projectId)
}),
querystring: z
.object({
eventType: z.nativeEnum(EventType).optional().describe(AUDIT_LOGS.EXPORT.eventType),
userAgentType: z.nativeEnum(UserAgentType).optional().describe(AUDIT_LOGS.EXPORT.userAgentType),
startDate: z.string().datetime().optional().describe(AUDIT_LOGS.EXPORT.startDate),
endDate: z.string().datetime().optional().describe(AUDIT_LOGS.EXPORT.endDate),
offset: z.coerce.number().default(0).describe(AUDIT_LOGS.EXPORT.offset),
limit: z.coerce.number().max(1000).default(20).describe(AUDIT_LOGS.EXPORT.limit),
actor: z.string().optional().describe(AUDIT_LOGS.EXPORT.actor)
})
.superRefine((el, ctx) => {
if (el.endDate && el.startDate) {
const startDate = new Date(el.startDate);
const endDate = new Date(el.endDate);
const maxAllowedDate = new Date(startDate);
maxAllowedDate.setMonth(maxAllowedDate.getMonth() + 3);
if (endDate < startDate) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["endDate"],
message: "End date cannot be before start date"
});
}
if (endDate > maxAllowedDate) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["endDate"],
message: "Dates must be within 3 months"
});
}
}
}),
response: {
200: z.object({
auditLogs: AuditLogsSchema.omit({
eventMetadata: true,
eventType: true,
actor: true,
actorMetadata: true
})
.merge(
z.object({
project: z
.object({
name: z.string(),
slug: z.string()
})
.optional(),
event: z.object({
type: z.string(),
metadata: z.any()
}),
actor: z.object({
type: z.string(),
metadata: z.any()
})
})
)
.array()
})
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const auditLogs = await server.services.auditLog.listAuditLogs({
actorId: req.permission.id,
actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
actor: req.permission.type,
filter: {
...req.query,
projectId: req.params.workspaceId,
endDate: req.query.endDate || new Date().toISOString(),
startDate: req.query.startDate || getLastMidnightDateISO(),
auditLogActorId: req.query.actor,
eventType: req.query.eventType ? [req.query.eventType] : undefined
}
});
return { auditLogs };
}
});
};
+5 -1
View File
@@ -24,6 +24,7 @@ import { registerPITRouter } from "./pit-router";
import { registerProjectRoleRouter } from "./project-role-router"; import { registerProjectRoleRouter } from "./project-role-router";
import { registerDepreciatedProjectRoleRouter } from "./depreciated-project-role-router"; import { registerDepreciatedProjectRoleRouter } from "./depreciated-project-role-router";
import { registerProjectRouter } from "./project-router"; import { registerProjectRouter } from "./project-router";
import { registerDepreciatedProjectRouter } from "./depreciated-project-router";
import { registerRateLimitRouter } from "./rate-limit-router"; 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";
@@ -48,10 +49,12 @@ export const registerV1EERoutes = async (server: FastifyZodProvider) => {
// org role starts with organization // org role starts with organization
await server.register(registerOrgRoleRouter, { prefix: "/organization" }); await server.register(registerOrgRoleRouter, { prefix: "/organization" });
await server.register(registerLicenseRouter, { prefix: "/organizations" }); await server.register(registerLicenseRouter, { prefix: "/organizations" });
// depreciated in favour of infisical workspace
await server.register( await server.register(
async (projectRouter) => { async (projectRouter) => {
await projectRouter.register(registerDepreciatedProjectRoleRouter); await projectRouter.register(registerDepreciatedProjectRoleRouter);
await projectRouter.register(registerProjectRouter); await projectRouter.register(registerDepreciatedProjectRouter);
}, },
{ prefix: "/workspace" } { prefix: "/workspace" }
); );
@@ -61,6 +64,7 @@ export const registerV1EERoutes = async (server: FastifyZodProvider) => {
await projectRouter.register(registerProjectRoleRouter); await projectRouter.register(registerProjectRoleRouter);
await projectRouter.register(registerTrustedIpRouter); await projectRouter.register(registerTrustedIpRouter);
await projectRouter.register(registerAssumePrivilegeRouter); await projectRouter.register(registerAssumePrivilegeRouter);
await projectRouter.register(registerProjectRouter);
}, },
{ prefix: "/projects" } { prefix: "/projects" }
); );
+28 -153
View File
@@ -1,9 +1,9 @@
import { z } from "zod"; import { z } from "zod";
import { AuditLogsSchema, SecretSnapshotsSchema } from "@app/db/schemas"; import { SecretSnapshotsSchema } from "@app/db/schemas";
import { EventType, UserAgentType } from "@app/ee/services/audit-log/audit-log-types"; import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { ApiDocsTags, AUDIT_LOGS, PROJECTS } from "@app/lib/api-docs"; import { ApiDocsTags, PROJECTS } from "@app/lib/api-docs";
import { getLastMidnightDateISO, removeTrailingSlash } from "@app/lib/fn"; import { removeTrailingSlash } from "@app/lib/fn";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type"; import { AuthMode } from "@app/services/auth/auth-type";
@@ -12,7 +12,7 @@ import { KmsType } from "@app/services/kms/kms-types";
export const registerProjectRouter = async (server: FastifyZodProvider) => { export const registerProjectRouter = async (server: FastifyZodProvider) => {
server.route({ server.route({
method: "GET", method: "GET",
url: "/:workspaceId/secret-snapshots", url: "/:projectId/secret-snapshots",
config: { config: {
rateLimit: readLimit rateLimit: readLimit
}, },
@@ -26,7 +26,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
} }
], ],
params: z.object({ params: z.object({
workspaceId: z.string().trim().describe(PROJECTS.GET_SNAPSHOTS.workspaceId) projectId: z.string().trim().describe(PROJECTS.GET_SNAPSHOTS.projectId)
}), }),
querystring: z.object({ querystring: z.object({
environment: z.string().trim().describe(PROJECTS.GET_SNAPSHOTS.environment), environment: z.string().trim().describe(PROJECTS.GET_SNAPSHOTS.environment),
@@ -47,7 +47,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
actorAuthMethod: req.permission.authMethod, actorAuthMethod: req.permission.authMethod,
actorId: req.permission.id, actorId: req.permission.id,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.params.workspaceId, projectId: req.params.projectId,
...req.query ...req.query
}); });
return { secretSnapshots }; return { secretSnapshots };
@@ -56,13 +56,13 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
server.route({ server.route({
method: "GET", method: "GET",
url: "/:workspaceId/secret-snapshots/count", url: "/:projectId/secret-snapshots/count",
config: { config: {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
params: z.object({ params: z.object({
workspaceId: z.string().trim() projectId: z.string().trim()
}), }),
querystring: z.object({ querystring: z.object({
environment: z.string().trim(), environment: z.string().trim(),
@@ -81,7 +81,7 @@ export const registerProjectRouter = 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.params.workspaceId, projectId: req.params.projectId,
environment: req.query.environment, environment: req.query.environment,
path: req.query.path path: req.query.path
}); });
@@ -89,140 +89,15 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
} }
}); });
/*
* Daniel: This endpoint is no longer is use.
* We are keeping it for now because it has been exposed in our public api docs for a while, so by removing it we are likely to break users workflows.
*
* Please refer to the new endpoint, GET /api/v1/organization/audit-logs, for the same (and more) functionality.
*/
server.route({ server.route({
method: "GET", method: "GET",
url: "/:workspaceId/audit-logs", url: "/:projectId/kms",
config: {
rateLimit: readLimit
},
schema: {
description: "Return audit logs",
security: [
{
bearerAuth: []
}
],
params: z.object({
workspaceId: z.string().trim().describe(AUDIT_LOGS.EXPORT.projectId)
}),
querystring: z
.object({
eventType: z.nativeEnum(EventType).optional().describe(AUDIT_LOGS.EXPORT.eventType),
userAgentType: z.nativeEnum(UserAgentType).optional().describe(AUDIT_LOGS.EXPORT.userAgentType),
startDate: z.string().datetime().optional().describe(AUDIT_LOGS.EXPORT.startDate),
endDate: z.string().datetime().optional().describe(AUDIT_LOGS.EXPORT.endDate),
offset: z.coerce.number().default(0).describe(AUDIT_LOGS.EXPORT.offset),
limit: z.coerce.number().max(1000).default(20).describe(AUDIT_LOGS.EXPORT.limit),
actor: z.string().optional().describe(AUDIT_LOGS.EXPORT.actor)
})
.superRefine((el, ctx) => {
if (el.endDate && el.startDate) {
const startDate = new Date(el.startDate);
const endDate = new Date(el.endDate);
const maxAllowedDate = new Date(startDate);
maxAllowedDate.setMonth(maxAllowedDate.getMonth() + 3);
if (endDate < startDate) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["endDate"],
message: "End date cannot be before start date"
});
}
if (endDate > maxAllowedDate) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["endDate"],
message: "Dates must be within 3 months"
});
}
}
}),
response: {
200: z.object({
auditLogs: AuditLogsSchema.omit({
eventMetadata: true,
eventType: true,
actor: true,
actorMetadata: true
})
.merge(
z.object({
project: z
.object({
name: z.string(),
slug: z.string()
})
.optional(),
event: z.object({
type: z.string(),
metadata: z.any()
}),
actor: z.object({
type: z.string(),
metadata: z.any()
})
})
)
.array()
})
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const auditLogs = await server.services.auditLog.listAuditLogs({
actorId: req.permission.id,
actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
actor: req.permission.type,
filter: {
...req.query,
projectId: req.params.workspaceId,
endDate: req.query.endDate || new Date().toISOString(),
startDate: req.query.startDate || getLastMidnightDateISO(),
auditLogActorId: req.query.actor,
eventType: req.query.eventType ? [req.query.eventType] : undefined
}
});
return { auditLogs };
}
});
server.route({
method: "GET",
url: "/:workspaceId/audit-logs/filters/actors",
config: { config: {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
params: z.object({ params: z.object({
workspaceId: z.string().trim() projectId: z.string().trim()
}),
response: {
200: z.object({
actors: z.string().array()
})
}
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async () => ({ actors: [] })
});
server.route({
method: "GET",
url: "/:workspaceId/kms",
config: {
rateLimit: readLimit
},
schema: {
params: z.object({
workspaceId: z.string().trim()
}), }),
response: { response: {
200: z.object({ 200: z.object({
@@ -241,7 +116,7 @@ export const registerProjectRouter = 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.params.workspaceId projectId: req.params.projectId
}); });
return kmsKey; return kmsKey;
@@ -250,13 +125,13 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
server.route({ server.route({
method: "PATCH", method: "PATCH",
url: "/:workspaceId/kms", url: "/:projectId/kms",
config: { config: {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
params: z.object({ params: z.object({
workspaceId: z.string().trim() projectId: z.string().trim()
}), }),
body: z.object({ body: z.object({
kms: z.discriminatedUnion("type", [ kms: z.discriminatedUnion("type", [
@@ -281,13 +156,13 @@ export const registerProjectRouter = 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.params.workspaceId, projectId: req.params.projectId,
...req.body ...req.body
}); });
await server.services.auditLog.createAuditLog({ await server.services.auditLog.createAuditLog({
...req.auditLogInfo, ...req.auditLogInfo,
projectId: req.params.workspaceId, projectId: req.params.projectId,
event: { event: {
type: EventType.UPDATE_PROJECT_KMS, type: EventType.UPDATE_PROJECT_KMS,
metadata: { metadata: {
@@ -307,13 +182,13 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
server.route({ server.route({
method: "GET", method: "GET",
url: "/:workspaceId/kms/backup", url: "/:projectId/kms/backup",
config: { config: {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
params: z.object({ params: z.object({
workspaceId: z.string().trim() projectId: z.string().trim()
}), }),
response: { response: {
200: z.object({ 200: z.object({
@@ -328,12 +203,12 @@ export const registerProjectRouter = 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.params.workspaceId projectId: req.params.projectId
}); });
await server.services.auditLog.createAuditLog({ await server.services.auditLog.createAuditLog({
...req.auditLogInfo, ...req.auditLogInfo,
projectId: req.params.workspaceId, projectId: req.params.projectId,
event: { event: {
type: EventType.GET_PROJECT_KMS_BACKUP, type: EventType.GET_PROJECT_KMS_BACKUP,
metadata: {} metadata: {}
@@ -346,13 +221,13 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
server.route({ server.route({
method: "POST", method: "POST",
url: "/:workspaceId/kms/backup", url: "/:projectId/kms/backup",
config: { config: {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
params: z.object({ params: z.object({
workspaceId: z.string().trim() projectId: z.string().trim()
}), }),
body: z.object({ body: z.object({
backup: z.string().min(1) backup: z.string().min(1)
@@ -374,13 +249,13 @@ export const registerProjectRouter = 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.params.workspaceId, projectId: req.params.projectId,
backup: req.body.backup backup: req.body.backup
}); });
await server.services.auditLog.createAuditLog({ await server.services.auditLog.createAuditLog({
...req.auditLogInfo, ...req.auditLogInfo,
projectId: req.params.workspaceId, projectId: req.params.projectId,
event: { event: {
type: EventType.LOAD_PROJECT_KMS_BACKUP, type: EventType.LOAD_PROJECT_KMS_BACKUP,
metadata: {} metadata: {}
@@ -393,13 +268,13 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
server.route({ server.route({
method: "POST", method: "POST",
url: "/:workspaceId/migrate-v3", url: "/:projectId/migrate-v3",
config: { config: {
rateLimit: writeLimit rateLimit: writeLimit
}, },
schema: { schema: {
params: z.object({ params: z.object({
workspaceId: z.string().trim() projectId: z.string().trim()
}), }),
response: { response: {
@@ -415,7 +290,7 @@ export const registerProjectRouter = 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.params.workspaceId projectId: req.params.projectId
}); });
return migration; return migration;
+1 -1
View File
@@ -732,7 +732,7 @@ export const PROJECTS = {
workspaceId: "The ID of the project to get the key from." workspaceId: "The ID of the project to get the key from."
}, },
GET_SNAPSHOTS: { GET_SNAPSHOTS: {
workspaceId: "The ID of the project to get snapshots from.", projectId: "The ID of the project to get snapshots from.",
environment: "The environment to get snapshots from.", environment: "The environment to get snapshots from.",
path: "The secret path to get snapshots from.", path: "The secret path to get snapshots from.",
offset: "The offset to start from. If you enter 10, it will start from the 10th snapshot.", offset: "The offset to start from. If you enter 10, it will start from the 10th snapshot.",
+2 -2
View File
@@ -75,7 +75,7 @@ export const useUpdateProjectKms = (projectId: string) => {
mutationFn: async ( mutationFn: async (
updatedData: { type: KmsType.Internal } | { type: KmsType.External; kmsId: string } updatedData: { type: KmsType.Internal } | { type: KmsType.External; kmsId: string }
) => { ) => {
const { data } = await apiRequest.patch(`/api/v1/workspace/${projectId}/kms`, { const { data } = await apiRequest.patch(`/api/v1/projects/${projectId}/kms`, {
kms: updatedData kms: updatedData
}); });
@@ -91,7 +91,7 @@ export const useLoadProjectKmsBackup = (projectId: string) => {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
return useMutation({ return useMutation({
mutationFn: async (backup: string) => { mutationFn: async (backup: string) => {
const { data } = await apiRequest.post(`/api/v1/workspace/${projectId}/kms/backup`, { const { data } = await apiRequest.post(`/api/v1/projects/${projectId}/kms/backup`, {
backup backup
}); });
+2 -2
View File
@@ -49,7 +49,7 @@ export const useGetActiveProjectKms = (projectId: string) => {
name: string; name: string;
isExternal: string; isExternal: string;
}; };
}>(`/api/v1/workspace/${projectId}/kms`); }>(`/api/v1/projects/${projectId}/kms`);
return secretManagerKmsKey; return secretManagerKmsKey;
} }
}); });
@@ -58,7 +58,7 @@ export const useGetActiveProjectKms = (projectId: string) => {
export const fetchProjectKmsBackup = async (projectId: string) => { export const fetchProjectKmsBackup = async (projectId: string) => {
const { data } = await apiRequest.get<{ const { data } = await apiRequest.get<{
secretManager: string; secretManager: string;
}>(`/api/v1/workspace/${projectId}/kms/backup`); }>(`/api/v1/projects/${projectId}/kms/backup`);
return data; return data;
}; };
@@ -14,25 +14,25 @@ import {
} from "./types"; } from "./types";
export const secretSnapshotKeys = { export const secretSnapshotKeys = {
list: ({ workspaceId, environment, directory }: Omit<TGetSecretSnapshotsDTO, "limit">) => list: ({ projectId, environment, directory }: Omit<TGetSecretSnapshotsDTO, "limit">) =>
[{ workspaceId, environment, directory }, "secret-snapshot"] as const, [{ projectId, environment, directory }, "secret-snapshot"] as const,
snapshotData: (snapshotId: string) => [{ snapshotId }, "secret-snapshot"] as const, snapshotData: (snapshotId: string) => [{ snapshotId }, "secret-snapshot"] as const,
count: ({ environment, workspaceId, directory }: Omit<TGetSecretSnapshotsDTO, "limit">) => [ count: ({ environment, projectId, directory }: Omit<TGetSecretSnapshotsDTO, "limit">) => [
{ workspaceId, environment, directory }, { projectId, environment, directory },
"count", "count",
"secret-snapshot" "secret-snapshot"
] ]
}; };
const fetchWorkspaceSnaphots = async ({ const fetchWorkspaceSnaphots = async ({
workspaceId, projectId,
environment, environment,
directory = "/", directory = "/",
limit = 10, limit = 10,
offset = 0 offset = 0
}: TGetSecretSnapshotsDTO & { offset: number }) => { }: TGetSecretSnapshotsDTO & { offset: number }) => {
const res = await apiRequest.get<{ secretSnapshots: TSecretSnapshot[] }>( const res = await apiRequest.get<{ secretSnapshots: TSecretSnapshot[] }>(
`/api/v1/workspace/${workspaceId}/secret-snapshots`, `/api/v1/projects/${projectId}/secret-snapshots`,
{ {
params: { params: {
limit, limit,
@@ -49,7 +49,7 @@ const fetchWorkspaceSnaphots = async ({
export const useGetWorkspaceSnapshotList = (dto: TGetSecretSnapshotsDTO & { isPaused?: boolean }) => export const useGetWorkspaceSnapshotList = (dto: TGetSecretSnapshotsDTO & { isPaused?: boolean }) =>
useInfiniteQuery({ useInfiniteQuery({
initialPageParam: 0, initialPageParam: 0,
enabled: Boolean(dto.workspaceId && dto.environment) && !dto.isPaused, enabled: Boolean(dto.projectId && dto.environment) && !dto.isPaused,
queryKey: secretSnapshotKeys.list({ ...dto }), queryKey: secretSnapshotKeys.list({ ...dto }),
queryFn: ({ pageParam }) => fetchWorkspaceSnaphots({ ...dto, offset: pageParam }), queryFn: ({ pageParam }) => fetchWorkspaceSnaphots({ ...dto, offset: pageParam }),
getNextPageParam: (lastPage, pages) => getNextPageParam: (lastPage, pages) =>
@@ -115,12 +115,12 @@ export const useGetSnapshotSecrets = ({ snapshotId }: TSnapshotDataProps) =>
}); });
const fetchWorkspaceSecretSnaphotCount = async ( const fetchWorkspaceSecretSnaphotCount = async (
workspaceId: string, projectId: string,
environment: string, environment: string,
directory = "/" directory = "/"
) => { ) => {
const res = await apiRequest.get<{ count: number }>( const res = await apiRequest.get<{ count: number }>(
`/api/v1/workspace/${workspaceId}/secret-snapshots/count`, `/api/v1/projects/${projectId}/secret-snapshots/count`,
{ {
params: { params: {
environment, environment,
@@ -132,15 +132,15 @@ const fetchWorkspaceSecretSnaphotCount = async (
}; };
export const useGetWsSnapshotCount = ({ export const useGetWsSnapshotCount = ({
workspaceId, projectId,
environment, environment,
directory, directory,
isPaused isPaused
}: Omit<TGetSecretSnapshotsDTO, "limit"> & { isPaused?: boolean }) => }: Omit<TGetSecretSnapshotsDTO, "limit"> & { isPaused?: boolean }) =>
useQuery({ useQuery({
enabled: Boolean(workspaceId && environment) && !isPaused, enabled: Boolean(projectId && environment) && !isPaused,
queryKey: secretSnapshotKeys.count({ workspaceId, environment, directory }), queryKey: secretSnapshotKeys.count({ projectId, environment, directory }),
queryFn: () => fetchWorkspaceSecretSnaphotCount(workspaceId, environment, directory) queryFn: () => fetchWorkspaceSecretSnaphotCount(projectId, environment, directory)
}); });
export const usePerformSecretRollback = () => { export const usePerformSecretRollback = () => {
@@ -151,22 +151,22 @@ export const usePerformSecretRollback = () => {
const { data } = await apiRequest.post(`/api/v1/secret-snapshot/${snapshotId}/rollback`); const { data } = await apiRequest.post(`/api/v1/secret-snapshot/${snapshotId}/rollback`);
return data; return data;
}, },
onSuccess: (_, { workspaceId, environment, directory }) => { onSuccess: (_, { projectId, environment, directory }) => {
queryClient.invalidateQueries({ queryClient.invalidateQueries({
queryKey: [{ workspaceId, environment, secretPath: directory }, "secrets"] queryKey: [{ projectId, environment, secretPath: directory }, "secrets"]
}); });
queryClient.invalidateQueries({ queryClient.invalidateQueries({
queryKey: ["secret-folders", { projectId: workspaceId, environment, path: directory }] queryKey: ["secret-folders", { projectId, environment, path: directory }]
}); });
queryClient.invalidateQueries({ queryClient.invalidateQueries({
queryKey: secretSnapshotKeys.list({ workspaceId, environment, directory }) queryKey: secretSnapshotKeys.list({ projectId, environment, directory })
}); });
queryClient.invalidateQueries({ queryClient.invalidateQueries({
queryKey: secretSnapshotKeys.count({ workspaceId, environment, directory }) queryKey: secretSnapshotKeys.count({ projectId, environment, directory })
}); });
queryClient.invalidateQueries({ queryClient.invalidateQueries({
queryKey: dashboardKeys.getDashboardSecrets({ queryKey: dashboardKeys.getDashboardSecrets({
projectId: workspaceId, projectId,
secretPath: directory ?? "/" secretPath: directory ?? "/"
}) })
}); });
@@ -3,7 +3,7 @@ import { WorkspaceEnv } from "../types";
export type TSecretSnapshot = { export type TSecretSnapshot = {
id: string; id: string;
workspace: string; projectId: string;
secretVersions: string[]; secretVersions: string[];
createdAt: string; createdAt: string;
updatedAt: string; updatedAt: string;
@@ -22,7 +22,7 @@ export type TSnapshotDataProps = {
}; };
export type TGetSecretSnapshotsDTO = { export type TGetSecretSnapshotsDTO = {
workspaceId: string; projectId: string;
limit: number; limit: number;
environment: string; environment: string;
directory?: string; directory?: string;
@@ -30,7 +30,7 @@ export type TGetSecretSnapshotsDTO = {
export type TSecretRollbackDTO = { export type TSecretRollbackDTO = {
snapshotId: string; snapshotId: string;
workspaceId: string; projectId: string;
environment: string; environment: string;
directory?: string; directory?: string;
}; };
+11 -11
View File
@@ -3,7 +3,7 @@ import { useMutation, useQueryClient } from "@tanstack/react-query";
import { apiRequest } from "@app/config/request"; import { apiRequest } from "@app/config/request";
import { userKeys } from "../users/query-keys"; import { userKeys } from "../users/query-keys";
import { workspaceKeys } from "./query-keys"; import { workspaceKeys as projectKeys } from "./query-keys";
import { import {
TProjectSshConfig, TProjectSshConfig,
TUpdateProjectSshConfigDTO, TUpdateProjectSshConfigDTO,
@@ -32,7 +32,7 @@ export const useAddGroupToWorkspace = () => {
}, },
onSuccess: (_, { projectId }) => { onSuccess: (_, { projectId }) => {
queryClient.invalidateQueries({ queryClient.invalidateQueries({
queryKey: workspaceKeys.getWorkspaceGroupMemberships(projectId) queryKey: projectKeys.getWorkspaceGroupMemberships(projectId)
}); });
} }
}); });
@@ -52,10 +52,10 @@ export const useUpdateGroupWorkspaceRole = () => {
}, },
onSuccess: (_, { projectId, groupId }) => { onSuccess: (_, { projectId, groupId }) => {
queryClient.invalidateQueries({ queryClient.invalidateQueries({
queryKey: workspaceKeys.getWorkspaceGroupMemberships(projectId) queryKey: projectKeys.getWorkspaceGroupMemberships(projectId)
}); });
queryClient.invalidateQueries({ queryClient.invalidateQueries({
queryKey: workspaceKeys.getWorkspaceGroupMembershipDetails(projectId, groupId) queryKey: projectKeys.getWorkspaceGroupMembershipDetails(projectId, groupId)
}); });
} }
}); });
@@ -79,7 +79,7 @@ export const useDeleteGroupFromWorkspace = () => {
}, },
onSuccess: (_, { projectId, username }) => { onSuccess: (_, { projectId, username }) => {
queryClient.invalidateQueries({ queryClient.invalidateQueries({
queryKey: workspaceKeys.getWorkspaceGroupMemberships(projectId) queryKey: projectKeys.getWorkspaceGroupMemberships(projectId)
}); });
if (username) { if (username) {
@@ -96,20 +96,20 @@ export const useLeaveProject = () => {
return apiRequest.delete(`/api/v1/workspace/${workspaceId}/leave`); return apiRequest.delete(`/api/v1/workspace/${workspaceId}/leave`);
}, },
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({ queryKey: workspaceKeys.getAllUserWorkspace() }); queryClient.invalidateQueries({ queryKey: projectKeys.getAllUserWorkspace() });
} }
}); });
}; };
export const useMigrateProjectToV3 = () => { export const useMigrateProjectToV3 = () => {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
return useMutation<object, object, { workspaceId: string }>({ return useMutation<object, object, { projectId: string }>({
mutationFn: ({ workspaceId }) => { mutationFn: ({ projectId }) => {
return apiRequest.post(`/api/v1/workspace/${workspaceId}/migrate-v3`); return apiRequest.post(`/api/v1/projects/${projectId}/migrate-v3`);
}, },
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries({ queryClient.invalidateQueries({
queryKey: workspaceKeys.getAllUserWorkspace() queryKey: projectKeys.getAllUserWorkspace()
}); });
} }
}); });
@@ -136,7 +136,7 @@ export const useUpdateProjectSshConfig = () => {
}, },
onSuccess: (_, { projectId }) => { onSuccess: (_, { projectId }) => {
queryClient.invalidateQueries({ queryClient.invalidateQueries({
queryKey: workspaceKeys.getProjectSshConfig(projectId) queryKey: projectKeys.getProjectSshConfig(projectId)
}); });
} }
}); });