mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 06:28:11 +00:00
feat: completed v1 projects prefixed one with projects and switched in
frontend
This commit is contained in:
@@ -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 };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -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" }
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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.",
|
||||||
|
|||||||
@@ -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
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user