From e3e62430ba3986589a40ecec0fe7496b3cf14792 Mon Sep 17 00:00:00 2001 From: Akhil Mohan Date: Fri, 22 Mar 2024 14:18:12 +0530 Subject: [PATCH] feat: changed the whole api from projectid to slug --- backend/src/@types/fastify.d.ts | 2 +- backend/src/lib/types/index.ts | 2 +- .../server/plugins/auth/inject-identity.ts | 4 +- backend/src/server/routes/index.ts | 2 + .../routes/v1/dynamic-secret-lease-router.ts | 38 ++++---- .../server/routes/v1/dynamic-secret-router.ts | 57 +++++++++--- .../dynamic-secret-lease-dal.ts | 67 +++++++++++++- .../dynamic-secret-lease-service.ts | 88 ++++++++++++++----- .../dynamic-secret-lease-types.ts | 19 +++- .../dynamic-secret/dynamic-secret-service.ts | 37 ++++++-- .../dynamic-secret/dynamic-secret-types.ts | 15 ++-- .../dynamic-secret/providers/sql-database.ts | 4 +- .../src/hooks/api/dynamicSecret/mutation.ts | 12 +-- .../src/hooks/api/dynamicSecret/queries.ts | 26 +++--- frontend/src/hooks/api/dynamicSecret/types.ts | 10 +-- .../hooks/api/dynamicSecretLease/mutation.ts | 12 +-- .../hooks/api/dynamicSecretLease/queries.ts | 14 +-- .../src/hooks/api/dynamicSecretLease/types.ts | 8 +- .../views/SecretMainPage/SecretMainPage.tsx | 6 +- .../components/ActionBar/ActionBar.tsx | 5 +- .../CreateDynamicSecretForm.tsx | 6 +- .../SqlDatabaseInputForm.tsx | 6 +- .../CreateDynamicSecretLease.tsx | 40 ++++----- .../DynamicSecretLease.tsx | 10 +-- .../DynamicSecretListView.tsx | 12 +-- .../EditDynamicSecretForm.tsx | 8 +- .../EditDynamicSecretSqlProviderForm.tsx | 6 +- .../RenewDynamicSecretLease.tsx | 6 +- 28 files changed, 357 insertions(+), 165 deletions(-) diff --git a/backend/src/@types/fastify.d.ts b/backend/src/@types/fastify.d.ts index 136462cca..8f5c12e3a 100644 --- a/backend/src/@types/fastify.d.ts +++ b/backend/src/@types/fastify.d.ts @@ -64,7 +64,7 @@ declare module "fastify" { authMethod: ActorAuthMethod; type: ActorType; id: string; - orgId?: string; + orgId: string; }; // passport data passportUser: { diff --git a/backend/src/lib/types/index.ts b/backend/src/lib/types/index.ts index 7a34222a6..7d26a5e5d 100644 --- a/backend/src/lib/types/index.ts +++ b/backend/src/lib/types/index.ts @@ -13,7 +13,7 @@ export type TProjectPermission = { actorId: string; projectId: string; actorAuthMethod: ActorAuthMethod; - actorOrgId: string | undefined; + actorOrgId: string; }; export type RequiredKeys = { diff --git a/backend/src/server/plugins/auth/inject-identity.ts b/backend/src/server/plugins/auth/inject-identity.ts index dceb31c03..4c0683797 100644 --- a/backend/src/server/plugins/auth/inject-identity.ts +++ b/backend/src/server/plugins/auth/inject-identity.ts @@ -16,7 +16,7 @@ export type TAuthMode = userId: string; tokenVersionId: string; // the session id of token used user: TUsers; - orgId?: string; + orgId: string; authMethod: AuthMethod; } | { @@ -119,7 +119,7 @@ export const injectIdentity = fp(async (server: FastifyZodProvider) => { userId: user.id, tokenVersionId, actor, - orgId, + orgId: orgId as string, authMethod: token.authMethod }; break; diff --git a/backend/src/server/routes/index.ts b/backend/src/server/routes/index.ts index 90fbd875b..498befd1b 100644 --- a/backend/src/server/routes/index.ts +++ b/backend/src/server/routes/index.ts @@ -566,6 +566,7 @@ export const registerRoutes = async ( dynamicSecretDAL }); const dynamicSecretService = dynamicSecretServiceFactory({ + projectDAL, dynamicSecretQueueService, dynamicSecretDAL, dynamicSecretLeaseDAL, @@ -574,6 +575,7 @@ export const registerRoutes = async ( permissionService }); const dynamicSecretLeaseService = dynamicSecretLeaseServiceFactory({ + projectDAL, permissionService, dynamicSecretQueueService, dynamicSecretDAL, diff --git a/backend/src/server/routes/v1/dynamic-secret-lease-router.ts b/backend/src/server/routes/v1/dynamic-secret-lease-router.ts index f9c30210e..bd8decab7 100644 --- a/backend/src/server/routes/v1/dynamic-secret-lease-router.ts +++ b/backend/src/server/routes/v1/dynamic-secret-lease-router.ts @@ -7,14 +7,16 @@ import { removeTrailingSlash } from "@app/lib/fn"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; +import { SanitizedDynamicSecretSchema } from "../sanitizedSchemas"; + export const registerDynamicSecretLeaseRouter = async (server: FastifyZodProvider) => { server.route({ url: "/", method: "POST", schema: { body: z.object({ - slug: z.string(), - projectId: z.string(), + slug: z.string().min(1), + projectSlug: z.string().min(1), ttl: z .string() .optional() @@ -27,7 +29,7 @@ export const registerDynamicSecretLeaseRouter = async (server: FastifyZodProvide ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" }); }), path: z.string().trim().default("/").transform(removeTrailingSlash), - environment: z.string() + environment: z.string().min(1) }), response: { 200: z.object({ @@ -57,9 +59,9 @@ export const registerDynamicSecretLeaseRouter = async (server: FastifyZodProvide leaseId: z.string() }), body: z.object({ - projectId: z.string(), - path: z.string().trim().default("/").transform(removeTrailingSlash), - environment: z.string() + projectSlug: z.string().min(1), + path: z.string().min(1).trim().default("/").transform(removeTrailingSlash), + environment: z.string().min(1) }), response: { 200: z.object({ @@ -100,9 +102,9 @@ export const registerDynamicSecretLeaseRouter = async (server: FastifyZodProvide if (valMs > daysToMillisecond(1)) ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" }); }), - projectId: z.string(), - path: z.string().trim().default("/").transform(removeTrailingSlash), - environment: z.string() + projectSlug: z.string().min(1), + path: z.string().min(1).trim().default("/").transform(removeTrailingSlash), + environment: z.string().min(1) }), response: { 200: z.object({ @@ -125,34 +127,36 @@ export const registerDynamicSecretLeaseRouter = async (server: FastifyZodProvide }); server.route({ - url: "/:slug", + url: "/:leaseId", method: "GET", schema: { params: z.object({ - slug: z.string() + leaseId: z.string() }), querystring: z.object({ - projectId: z.string(), + projectSlug: z.string().min(1), path: z.string().trim().default("/").transform(removeTrailingSlash), - environment: z.string() + environment: z.string().min(1) }), response: { 200: z.object({ - leases: DynamicSecretLeasesSchema.array() + lease: DynamicSecretLeasesSchema.extend({ + dynamicSecret: SanitizedDynamicSecretSchema + }) }) } }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { - const leases = await server.services.dynamicSecretLease.listLeases({ + const lease = await server.services.dynamicSecretLease.getLeaseDetails({ actor: req.permission.type, actorId: req.permission.id, actorAuthMethod: req.permission.authMethod, actorOrgId: req.permission.orgId, - slug: req.params.slug, + leaseId: req.params.leaseId, ...req.query }); - return { leases }; + return { lease }; } }); }; diff --git a/backend/src/server/routes/v1/dynamic-secret-router.ts b/backend/src/server/routes/v1/dynamic-secret-router.ts index 5b30b3556..4ab7e428f 100644 --- a/backend/src/server/routes/v1/dynamic-secret-router.ts +++ b/backend/src/server/routes/v1/dynamic-secret-router.ts @@ -1,6 +1,7 @@ import ms from "ms"; import { z } from "zod"; +import { DynamicSecretLeasesSchema } from "@app/db/schemas"; import { daysToMillisecond } from "@app/lib/dates"; import { removeTrailingSlash } from "@app/lib/fn"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; @@ -15,7 +16,7 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) => method: "POST", schema: { body: z.object({ - projectId: z.string(), + projectSlug: z.string().min(1), provider: DynamicSecretProviderSchema, defaultTTL: z.string().superRefine((val, ctx) => { const valMs = ms(val); @@ -37,8 +38,8 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) => }) .nullable(), path: z.string().trim().default("/").transform(removeTrailingSlash), - environment: z.string(), - slug: z.string().toLowerCase() + environment: z.string().min(1), + slug: z.string().min(1).toLowerCase() }), response: { 200: z.object({ @@ -67,9 +68,9 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) => slug: z.string() }), body: z.object({ - projectId: z.string(), + projectSlug: z.string().min(1), path: z.string().trim().default("/").transform(removeTrailingSlash), - environment: z.string(), + environment: z.string().min(1), data: z.object({ inputs: z.any().optional(), defaultTTL: z @@ -113,7 +114,7 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) => actorOrgId: req.permission.orgId, slug: req.params.slug, path: req.body.path, - projectId: req.body.projectId, + projectSlug: req.body.projectSlug, environment: req.body.environment, ...req.body.data }); @@ -129,9 +130,9 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) => slug: z.string() }), body: z.object({ - projectId: z.string(), + projectSlug: z.string().min(1), path: z.string().trim().default("/").transform(removeTrailingSlash), - environment: z.string() + environment: z.string().min(1) }), response: { 200: z.object({ @@ -161,9 +162,9 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) => slug: z.string() }), querystring: z.object({ - projectId: z.string(), + projectSlug: z.string().min(1), path: z.string().trim().default("/").transform(removeTrailingSlash), - environment: z.string() + environment: z.string().min(1) }), response: { 200: z.object({ @@ -192,9 +193,9 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) => method: "GET", schema: { querystring: z.object({ - projectId: z.string(), + projectSlug: z.string().min(1), path: z.string().trim().default("/").transform(removeTrailingSlash), - environment: z.string() + environment: z.string().min(1) }), response: { 200: z.object({ @@ -214,4 +215,36 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) => return { dynamicSecrets: dynamicSecretCfgs }; } }); + + server.route({ + url: "/:slug/leases", + method: "GET", + schema: { + params: z.object({ + slug: z.string() + }), + querystring: z.object({ + projectSlug: z.string().min(1), + path: z.string().trim().default("/").transform(removeTrailingSlash), + environment: z.string().min(1) + }), + response: { + 200: z.object({ + leases: DynamicSecretLeasesSchema.array() + }) + } + }, + onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), + handler: async (req) => { + const leases = await server.services.dynamicSecretLease.listLeases({ + actor: req.permission.type, + actorId: req.permission.id, + actorAuthMethod: req.permission.authMethod, + actorOrgId: req.permission.orgId, + slug: req.params.slug, + ...req.query + }); + return { leases }; + } + }); }; diff --git a/backend/src/services/dynamic-secret-lease/dynamic-secret-lease-dal.ts b/backend/src/services/dynamic-secret-lease/dynamic-secret-lease-dal.ts index acffc96a7..69c6686fd 100644 --- a/backend/src/services/dynamic-secret-lease/dynamic-secret-lease-dal.ts +++ b/backend/src/services/dynamic-secret-lease/dynamic-secret-lease-dal.ts @@ -1,10 +1,71 @@ +import { Knex } from "knex"; + import { TDbClient } from "@app/db"; -import { TableName } from "@app/db/schemas"; -import { ormify } from "@app/lib/knex"; +import { DynamicSecretLeasesSchema, TableName } from "@app/db/schemas"; +import { DatabaseError } from "@app/lib/errors"; +import { ormify, selectAllTableCols } from "@app/lib/knex"; export type TDynamicSecretLeaseDALFactory = ReturnType; export const dynamicSecretLeaseDALFactory = (db: TDbClient) => { const orm = ormify(db, TableName.DynamicSecretLease); - return orm; + + const findById = async (id: string, tx?: Knex) => { + try { + const doc = await (tx || db)(TableName.DynamicSecretLease) + .where({ id }) + .first() + .join( + TableName.DynamicSecret, + `${TableName.DynamicSecretLease}.dynamicSecretId`, + `${TableName.DynamicSecret}.id` + ) + .select(selectAllTableCols(TableName.DynamicSecretLease)) + .select( + db.ref("id").withSchema(TableName.DynamicSecret).as("dynId"), + db.ref("slug").withSchema(TableName.DynamicSecret).as("dynSlug"), + db.ref("version").withSchema(TableName.DynamicSecret).as("dynVersion"), + db.ref("type").withSchema(TableName.DynamicSecret).as("dynType"), + db.ref("defaultTTL").withSchema(TableName.DynamicSecret).as("dynDefaultTTL"), + db.ref("maxTTL").withSchema(TableName.DynamicSecret).as("dynMaxTTL"), + db.ref("inputIV").withSchema(TableName.DynamicSecret).as("dynInputIV"), + db.ref("inputTag").withSchema(TableName.DynamicSecret).as("dynInputTag"), + db.ref("inputCiphertext").withSchema(TableName.DynamicSecret).as("dynInputCiphertext"), + db.ref("algorithm").withSchema(TableName.DynamicSecret).as("dynAlgorithm"), + db.ref("keyEncoding").withSchema(TableName.DynamicSecret).as("dynKeyEncoding"), + db.ref("folderId").withSchema(TableName.DynamicSecret).as("dynFolderId"), + db.ref("status").withSchema(TableName.DynamicSecret).as("dynStatus"), + db.ref("statusDetails").withSchema(TableName.DynamicSecret).as("dynStatusDetails"), + db.ref("createdAt").withSchema(TableName.DynamicSecret).as("dynCreatedAt"), + db.ref("updatedAt").withSchema(TableName.DynamicSecret).as("dynUpdatedAt") + ); + if (!doc) return; + + return { + ...DynamicSecretLeasesSchema.parse(doc), + dynamicSecret: { + id: doc.dynId, + slug: doc.dynSlug, + version: doc.dynVersion, + type: doc.dynType, + defaultTTL: doc.dynDefaultTTL, + maxTTL: doc.dynMaxTTL, + inputIV: doc.dynInputIV, + inputTag: doc.dynInputTag, + inputCiphertext: doc.dynInputCiphertext, + algorithm: doc.dynAlgorithm, + keyEncoding: doc.dynKeyEncoding, + folderId: doc.dynFolderId, + status: doc.dynStatus, + statusDetails: doc.dynStatusDetails, + createdAt: doc.dynCreatedAt, + updatedAt: doc.dynUpdatedAt + } + }; + } catch (error) { + throw new DatabaseError({ error, name: "DynamicSecretLeaseFindById" }); + } + }; + + return { ...orm, findById }; }; diff --git a/backend/src/services/dynamic-secret-lease/dynamic-secret-lease-service.ts b/backend/src/services/dynamic-secret-lease/dynamic-secret-lease-service.ts index fe9957fdd..5e1ccd60b 100644 --- a/backend/src/services/dynamic-secret-lease/dynamic-secret-lease-service.ts +++ b/backend/src/services/dynamic-secret-lease/dynamic-secret-lease-service.ts @@ -9,12 +9,14 @@ import { BadRequestError } from "@app/lib/errors"; import { TDynamicSecretDALFactory } from "../dynamic-secret/dynamic-secret-dal"; import { DynamicSecretProviders, TDynamicProviderFns } from "../dynamic-secret/providers/models"; +import { TProjectDALFactory } from "../project/project-dal"; import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal"; import { TDynamicSecretLeaseDALFactory } from "./dynamic-secret-lease-dal"; import { TDynamicSecretLeaseQueueServiceFactory } from "./dynamic-secret-lease-queue"; import { TCreateDynamicSecretLeaseDTO, TDeleteDynamicSecretLeaseDTO, + TDetailsDynamicSecretLeaseDTO, TListDynamicSecretLeasesDTO, TRenewDynamicSecretLeaseDTO } from "./dynamic-secret-lease-types"; @@ -26,6 +28,7 @@ type TDynamicSecretLeaseServiceFactoryDep = { dynamicSecretQueueService: TDynamicSecretLeaseQueueServiceFactory; folderDAL: Pick; permissionService: Pick; + projectDAL: Pick; }; export type TDynamicSecretLeaseServiceFactory = ReturnType; @@ -36,19 +39,24 @@ export const dynamicSecretLeaseServiceFactory = ({ dynamicSecretDAL, folderDAL, permissionService, - dynamicSecretQueueService + dynamicSecretQueueService, + projectDAL }: TDynamicSecretLeaseServiceFactoryDep) => { const create = async ({ environment, path, slug, - projectId, + projectSlug, actor, actorId, actorOrgId, actorAuthMethod, ttl }: TCreateDynamicSecretLeaseDTO) => { + const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId); + if (!project) throw new BadRequestError({ message: "Project not found" }); + + const projectId = project.id; const { permission } = await permissionService.getProjectPermission( actor, actorId, @@ -57,7 +65,7 @@ export const dynamicSecretLeaseServiceFactory = ({ actorOrgId ); ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Edit, + ProjectPermissionActions.Create, subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) ); @@ -102,11 +110,15 @@ export const dynamicSecretLeaseServiceFactory = ({ actorOrgId, actorId, actor, - projectId, + projectSlug, path, environment, leaseId }: TRenewDynamicSecretLeaseDTO) => { + const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId); + if (!project) throw new BadRequestError({ message: "Project not found" }); + + const projectId = project.id; const { permission } = await permissionService.getProjectPermission( actor, actorId, @@ -125,12 +137,7 @@ export const dynamicSecretLeaseServiceFactory = ({ const dynamicSecretLease = await dynamicSecretLeaseDAL.findById(leaseId); if (!dynamicSecretLease) throw new BadRequestError({ message: "Dynamic secret lease not found" }); - const dynamicSecretCfg = await dynamicSecretDAL.findOne({ - id: dynamicSecretLease.dynamicSecretId, - folderId: folder.id - }); - if (!dynamicSecretCfg) throw new BadRequestError({ message: "Dynamic secret not found" }); - + const dynamicSecretCfg = dynamicSecretLease.dynamicSecret; const selectedProvider = dynamicSecretProviders[dynamicSecretCfg.type as DynamicSecretProviders]; const decryptedStoredInput = JSON.parse( infisicalSymmetricDecrypt({ @@ -168,12 +175,16 @@ export const dynamicSecretLeaseServiceFactory = ({ leaseId, environment, path, - projectId, + projectSlug, actor, actorId, actorOrgId, actorAuthMethod }: TDeleteDynamicSecretLeaseDTO) => { + const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId); + if (!project) throw new BadRequestError({ message: "Project not found" }); + + const projectId = project.id; const { permission } = await permissionService.getProjectPermission( actor, actorId, @@ -182,7 +193,7 @@ export const dynamicSecretLeaseServiceFactory = ({ actorOrgId ); ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Edit, + ProjectPermissionActions.Delete, subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) ); @@ -192,12 +203,7 @@ export const dynamicSecretLeaseServiceFactory = ({ const dynamicSecretLease = await dynamicSecretLeaseDAL.findById(leaseId); if (!dynamicSecretLease) throw new BadRequestError({ message: "Dynamic secret lease not found" }); - const dynamicSecretCfg = await dynamicSecretDAL.findOne({ - id: dynamicSecretLease.dynamicSecretId, - folderId: folder.id - }); - if (!dynamicSecretCfg) throw new BadRequestError({ message: "Dynamic secret not found" }); - + const dynamicSecretCfg = dynamicSecretLease.dynamicSecret; const selectedProvider = dynamicSecretProviders[dynamicSecretCfg.type as DynamicSecretProviders]; const decryptedStoredInput = JSON.parse( infisicalSymmetricDecrypt({ @@ -220,11 +226,15 @@ export const dynamicSecretLeaseServiceFactory = ({ slug, actor, actorId, - projectId, + projectSlug, actorOrgId, environment, actorAuthMethod }: TListDynamicSecretLeasesDTO) => { + const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId); + if (!project) throw new BadRequestError({ message: "Project not found" }); + + const projectId = project.id; const { permission } = await permissionService.getProjectPermission( actor, actorId, @@ -233,7 +243,7 @@ export const dynamicSecretLeaseServiceFactory = ({ actorOrgId ); ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Edit, + ProjectPermissionActions.Read, subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) ); @@ -247,10 +257,46 @@ export const dynamicSecretLeaseServiceFactory = ({ return dynamicSecretLeases; }; + const getLeaseDetails = async ({ + projectSlug, + actorOrgId, + path, + environment, + actor, + actorId, + leaseId, + actorAuthMethod + }: TDetailsDynamicSecretLeaseDTO) => { + const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId); + if (!project) throw new BadRequestError({ message: "Project not found" }); + + const projectId = project.id; + const { permission } = await permissionService.getProjectPermission( + actor, + actorId, + projectId, + actorAuthMethod, + actorOrgId + ); + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Read, + subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) + ); + + const folder = await folderDAL.findBySecretPath(projectId, environment, path); + if (!folder) throw new BadRequestError({ message: "Folder not found" }); + + const dynamicSecretLease = await dynamicSecretLeaseDAL.findById(leaseId); + if (!dynamicSecretLease) throw new BadRequestError({ message: "Dynamic secret lease not found" }); + + return dynamicSecretLease; + }; + return { create, listLeases, revokeLease, - renewLease + renewLease, + getLeaseDetails }; }; diff --git a/backend/src/services/dynamic-secret-lease/dynamic-secret-lease-types.ts b/backend/src/services/dynamic-secret-lease/dynamic-secret-lease-types.ts index 4326e0a76..6f1a17d78 100644 --- a/backend/src/services/dynamic-secret-lease/dynamic-secret-lease-types.ts +++ b/backend/src/services/dynamic-secret-lease/dynamic-secret-lease-types.ts @@ -9,23 +9,34 @@ export type TCreateDynamicSecretLeaseDTO = { path: string; environment: string; ttl?: string; -} & TProjectPermission; + projectSlug: string; +} & Omit; + +export type TDetailsDynamicSecretLeaseDTO = { + leaseId: string; + path: string; + environment: string; + projectSlug: string; +} & Omit; export type TListDynamicSecretLeasesDTO = { slug: string; path: string; environment: string; -} & TProjectPermission; + projectSlug: string; +} & Omit; export type TDeleteDynamicSecretLeaseDTO = { leaseId: string; path: string; environment: string; -} & TProjectPermission; + projectSlug: string; +} & Omit; export type TRenewDynamicSecretLeaseDTO = { leaseId: string; path: string; environment: string; ttl?: string; -} & TProjectPermission; + projectSlug: string; +} & Omit; diff --git a/backend/src/services/dynamic-secret/dynamic-secret-service.ts b/backend/src/services/dynamic-secret/dynamic-secret-service.ts index 38ac4c0a7..ffa9925f9 100644 --- a/backend/src/services/dynamic-secret/dynamic-secret-service.ts +++ b/backend/src/services/dynamic-secret/dynamic-secret-service.ts @@ -8,6 +8,7 @@ import { BadRequestError } from "@app/lib/errors"; import { TDynamicSecretLeaseDALFactory } from "../dynamic-secret-lease/dynamic-secret-lease-dal"; import { TDynamicSecretLeaseQueueServiceFactory } from "../dynamic-secret-lease/dynamic-secret-lease-queue"; +import { TProjectDALFactory } from "../project/project-dal"; import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal"; import { TDynamicSecretDALFactory } from "./dynamic-secret-dal"; import { @@ -26,6 +27,7 @@ type TDynamicSecretServiceFactoryDep = { dynamicSecretProviders: Record; dynamicSecretQueueService: Pick; folderDAL: Pick; + projectDAL: Pick; permissionService: Pick; }; @@ -37,7 +39,8 @@ export const dynamicSecretServiceFactory = ({ folderDAL, dynamicSecretProviders, permissionService, - dynamicSecretQueueService + dynamicSecretQueueService, + projectDAL }: TDynamicSecretServiceFactoryDep) => { const create = async ({ path, @@ -47,11 +50,15 @@ export const dynamicSecretServiceFactory = ({ maxTTL, provider, environment, - projectId, + projectSlug, actorOrgId, defaultTTL, actorAuthMethod }: TCreateDynamicSecretDTO) => { + const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId); + if (!project) throw new BadRequestError({ message: "Project not found" }); + + const projectId = project.id; const { permission } = await permissionService.getProjectPermission( actor, actorId, @@ -96,7 +103,7 @@ export const dynamicSecretServiceFactory = ({ defaultTTL, inputs, environment, - projectId, + projectSlug, path, actor, actorId, @@ -104,6 +111,11 @@ export const dynamicSecretServiceFactory = ({ actorOrgId, actorAuthMethod }: TUpdateDynamicSecretDTO) => { + const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId); + if (!project) throw new BadRequestError({ message: "Project not found" }); + + const projectId = project.id; + const { permission } = await permissionService.getProjectPermission( actor, actorId, @@ -161,11 +173,16 @@ export const dynamicSecretServiceFactory = ({ actorOrgId, actorId, actor, - projectId, + projectSlug, slug, path, environment }: TDeleteDynamicSecretDTO) => { + const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId); + if (!project) throw new BadRequestError({ message: "Project not found" }); + + const projectId = project.id; + const { permission } = await permissionService.getProjectPermission( actor, actorId, @@ -201,7 +218,7 @@ export const dynamicSecretServiceFactory = ({ const getDetails = async ({ slug, - projectId, + projectSlug, path, environment, actorAuthMethod, @@ -209,6 +226,10 @@ export const dynamicSecretServiceFactory = ({ actorId, actor }: TDetailsDynamicSecretDTO) => { + const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId); + if (!project) throw new BadRequestError({ message: "Project not found" }); + + const projectId = project.id; const { permission } = await permissionService.getProjectPermission( actor, actorId, @@ -244,10 +265,14 @@ export const dynamicSecretServiceFactory = ({ actorOrgId, actorId, actor, - projectId, + projectSlug, path, environment }: TListDynamicSecretsDTO) => { + const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId); + if (!project) throw new BadRequestError({ message: "Project not found" }); + + const projectId = project.id; const { permission } = await permissionService.getProjectPermission( actor, actorId, diff --git a/backend/src/services/dynamic-secret/dynamic-secret-types.ts b/backend/src/services/dynamic-secret/dynamic-secret-types.ts index 1af9d293e..d5b3baca9 100644 --- a/backend/src/services/dynamic-secret/dynamic-secret-types.ts +++ b/backend/src/services/dynamic-secret/dynamic-secret-types.ts @@ -18,7 +18,8 @@ export type TCreateDynamicSecretDTO = { path: string; environment: string; slug: string; -} & TProjectPermission; + projectSlug: string; +} & Omit; export type TUpdateDynamicSecretDTO = { slug: string; @@ -28,21 +29,25 @@ export type TUpdateDynamicSecretDTO = { path: string; environment: string; inputs?: TProvider["inputs"]; -} & TProjectPermission; + projectSlug: string; +} & Omit; export type TDeleteDynamicSecretDTO = { slug: string; path: string; environment: string; -} & TProjectPermission; + projectSlug: string; +} & Omit; export type TDetailsDynamicSecretDTO = { slug: string; path: string; environment: string; -} & TProjectPermission; + projectSlug: string; +} & Omit; export type TListDynamicSecretsDTO = { path: string; environment: string; -} & TProjectPermission; + projectSlug: string; +} & Omit; diff --git a/backend/src/services/dynamic-secret/providers/sql-database.ts b/backend/src/services/dynamic-secret/providers/sql-database.ts index 5425f64b6..7576e4f56 100644 --- a/backend/src/services/dynamic-secret/providers/sql-database.ts +++ b/backend/src/services/dynamic-secret/providers/sql-database.ts @@ -13,7 +13,7 @@ import { DynamicSecretSqlDBSchema, TDynamicProviderFns } from "./models"; const EXTERNAL_REQUEST_TIMEOUT = 10 * 1000; const generatePassword = (size?: number) => { - const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%^&*()_+-=[]{}|;,./<>"; + const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~!*'$#"; return customAlphabet(charset, 20)(size); }; @@ -62,7 +62,7 @@ export const SqlDatabaseProvider = (): TDynamicProviderFns => { await db.raw(creationStatement.toString()); await db.destroy(); - return { entityId: username, data: { username, password } }; + return { entityId: username, data: { DB_USERNAME: username, DB_PASSWORD: password } }; }; const revoke = async (inputs: unknown, entityId: string) => { diff --git a/frontend/src/hooks/api/dynamicSecret/mutation.ts b/frontend/src/hooks/api/dynamicSecret/mutation.ts index 0c317a2eb..11021554d 100644 --- a/frontend/src/hooks/api/dynamicSecret/mutation.ts +++ b/frontend/src/hooks/api/dynamicSecret/mutation.ts @@ -21,8 +21,8 @@ export const useCreateDynamicSecret = () => { ); return data.dynamicSecret; }, - onSuccess: (_, { path, environment, projectId }) => { - queryClient.invalidateQueries(dynamicSecretKeys.list({ path, projectId, environment })); + onSuccess: (_, { path, environment, projectSlug }) => { + queryClient.invalidateQueries(dynamicSecretKeys.list({ path, projectSlug, environment })); } }); }; @@ -38,8 +38,8 @@ export const useUpdateDynamicSecret = () => { ); return data.dynamicSecret; }, - onSuccess: (_, { path, environment, projectId }) => { - queryClient.invalidateQueries(dynamicSecretKeys.list({ path, projectId, environment })); + onSuccess: (_, { path, environment, projectSlug }) => { + queryClient.invalidateQueries(dynamicSecretKeys.list({ path, projectSlug, environment })); } }); }; @@ -55,8 +55,8 @@ export const useDeleteDynamicSecret = () => { ); return data.dynamicSecret; }, - onSuccess: (_, { path, environment, projectId }) => { - queryClient.invalidateQueries(dynamicSecretKeys.list({ path, projectId, environment })); + onSuccess: (_, { path, environment, projectSlug }) => { + queryClient.invalidateQueries(dynamicSecretKeys.list({ path, projectSlug, environment })); } }); }; diff --git a/frontend/src/hooks/api/dynamicSecret/queries.ts b/frontend/src/hooks/api/dynamicSecret/queries.ts index 84099d7d9..8c40f19a4 100644 --- a/frontend/src/hooks/api/dynamicSecret/queries.ts +++ b/frontend/src/hooks/api/dynamicSecret/queries.ts @@ -6,25 +6,25 @@ import { TDetailsDynamicSecretDTO, TDynamicSecret, TListDynamicSecretDTO } from export const dynamicSecretKeys = { list: ({ - projectId, + projectSlug, environment, path - }: Pick) => - [{ projectId, environment, path }, "dynamic-secrets"] as const, - details: ({ path, environment, projectId, slug }: TDetailsDynamicSecretDTO) => - [{ projectId, path, environment, slug }, "dynamic-secret-details"] as const + }: Pick) => + [{ projectSlug, environment, path }, "dynamic-secrets"] as const, + details: ({ path, environment, projectSlug, slug }: TDetailsDynamicSecretDTO) => + [{ projectSlug, path, environment, slug }, "dynamic-secret-details"] as const }; -export const useGetDynamicSecrets = ({ projectId, environment, path }: TListDynamicSecretDTO) => { +export const useGetDynamicSecrets = ({ projectSlug, environment, path }: TListDynamicSecretDTO) => { return useQuery({ - queryKey: dynamicSecretKeys.list({ path, environment, projectId }), - enabled: Boolean(projectId && environment && path), + queryKey: dynamicSecretKeys.list({ path, environment, projectSlug }), + enabled: Boolean(projectSlug && environment && path), queryFn: async () => { const { data } = await apiRequest.get<{ dynamicSecrets: TDynamicSecret[] }>( "/api/v1/dynamic-secrets", { params: { - projectId, + projectSlug, environment, path } @@ -37,20 +37,20 @@ export const useGetDynamicSecrets = ({ projectId, environment, path }: TListDyna }; export const useGetDynamicSecretDetails = ({ - projectId, + projectSlug, environment, path, slug }: TDetailsDynamicSecretDTO) => { return useQuery({ - queryKey: dynamicSecretKeys.details({ path, environment, projectId, slug }), - enabled: Boolean(projectId && environment && path && slug), + queryKey: dynamicSecretKeys.details({ path, environment, projectSlug, slug }), + enabled: Boolean(projectSlug && environment && path && slug), queryFn: async () => { const { data } = await apiRequest.get<{ dynamicSecret: TDynamicSecret & { inputs: unknown }; }>(`/api/v1/dynamic-secrets/${slug}`, { params: { - projectId, + projectSlug, environment, path } diff --git a/frontend/src/hooks/api/dynamicSecret/types.ts b/frontend/src/hooks/api/dynamicSecret/types.ts index 821b61cc4..a2fe5e10a 100644 --- a/frontend/src/hooks/api/dynamicSecret/types.ts +++ b/frontend/src/hooks/api/dynamicSecret/types.ts @@ -40,7 +40,7 @@ export type TDynamicSecretProvider = { }; export type TCreateDynamicSecretDTO = { - projectId: string; + projectSlug: string; provider: TDynamicSecretProvider; defaultTTL: string; maxTTL?: string; @@ -51,7 +51,7 @@ export type TCreateDynamicSecretDTO = { export type TUpdateDynamicSecretDTO = { slug: string; - projectId: string; + projectSlug: string; path: string; environment: string; data: { @@ -63,20 +63,20 @@ export type TUpdateDynamicSecretDTO = { }; export type TListDynamicSecretDTO = { - projectId: string; + projectSlug: string; path: string; environment: string; }; export type TDeleteDynamicSecretDTO = { - projectId: string; + projectSlug: string; path: string; environment: string; slug: string; }; export type TDetailsDynamicSecretDTO = { - projectId: string; + projectSlug: string; path: string; environment: string; slug: string; diff --git a/frontend/src/hooks/api/dynamicSecretLease/mutation.ts b/frontend/src/hooks/api/dynamicSecretLease/mutation.ts index c24e3ed31..679f73910 100644 --- a/frontend/src/hooks/api/dynamicSecretLease/mutation.ts +++ b/frontend/src/hooks/api/dynamicSecretLease/mutation.ts @@ -25,9 +25,9 @@ export const useCreateDynamicSecretLease = () => { ); return data; }, - onSuccess: (_, { path, environment, projectId, slug }) => { + onSuccess: (_, { path, environment, projectSlug, slug }) => { queryClient.invalidateQueries( - dynamicSecretLeaseKeys.list({ path, projectId, environment, slug }) + dynamicSecretLeaseKeys.list({ path, projectSlug, environment, slug }) ); } }); @@ -44,9 +44,9 @@ export const useRenewDynamicSecretLease = () => { ); return data.lease; }, - onSuccess: (_, { path, environment, projectId, slug }) => { + onSuccess: (_, { path, environment, projectSlug, slug }) => { queryClient.invalidateQueries( - dynamicSecretLeaseKeys.list({ path, projectId, environment, slug }) + dynamicSecretLeaseKeys.list({ path, projectSlug, environment, slug }) ); } }); @@ -63,9 +63,9 @@ export const useRevokeDynamicSecretLease = () => { ); return data.lease; }, - onSuccess: (_, { path, environment, projectId, slug }) => { + onSuccess: (_, { path, environment, projectSlug, slug }) => { queryClient.invalidateQueries( - dynamicSecretLeaseKeys.list({ path, projectId, environment, slug }) + dynamicSecretLeaseKeys.list({ path, projectSlug, environment, slug }) ); } }); diff --git a/frontend/src/hooks/api/dynamicSecretLease/queries.ts b/frontend/src/hooks/api/dynamicSecretLease/queries.ts index 0de9620c7..a9dd46a64 100644 --- a/frontend/src/hooks/api/dynamicSecretLease/queries.ts +++ b/frontend/src/hooks/api/dynamicSecretLease/queries.ts @@ -5,26 +5,26 @@ import { apiRequest } from "@app/config/request"; import { TDynamicSecretLease, TListDynamicSecretLeaseDTO } from "./types"; export const dynamicSecretLeaseKeys = { - list: ({ projectId, environment, path, slug }: TListDynamicSecretLeaseDTO) => - [{ projectId, environment, path, slug }, "dynamic-secret-leases"] as const + list: ({ projectSlug, environment, path, slug }: TListDynamicSecretLeaseDTO) => + [{ projectSlug, environment, path, slug }, "dynamic-secret-leases"] as const }; export const useGetDynamicSecretLeases = ({ - projectId, + projectSlug, environment, path, slug, enabled = true }: TListDynamicSecretLeaseDTO) => { return useQuery({ - queryKey: dynamicSecretLeaseKeys.list({ path, environment, projectId, slug }), - enabled: Boolean(projectId && environment && path && slug && enabled), + queryKey: dynamicSecretLeaseKeys.list({ path, environment, projectSlug, slug }), + enabled: Boolean(projectSlug && environment && path && slug && enabled), queryFn: async () => { const { data } = await apiRequest.get<{ leases: TDynamicSecretLease[] }>( - `/api/v1/dynamic-secrets/leases/${slug}`, + `/api/v1/dynamic-secrets/${slug}/leases`, { params: { - projectId, + projectSlug, environment, path } diff --git a/frontend/src/hooks/api/dynamicSecretLease/types.ts b/frontend/src/hooks/api/dynamicSecretLease/types.ts index b888970c2..5fe126bd8 100644 --- a/frontend/src/hooks/api/dynamicSecretLease/types.ts +++ b/frontend/src/hooks/api/dynamicSecretLease/types.ts @@ -15,7 +15,7 @@ export type TDynamicSecretLease = { export type TCreateDynamicSecretLeaseDTO = { slug: string; - projectId: string; + projectSlug: string; ttl?: string; path: string; environment: string; @@ -25,14 +25,14 @@ export type TRenewDynamicSecretLeaseDTO = { leaseId: string; slug: string; ttl?: string; - projectId: string; + projectSlug: string; path: string; environment: string; }; export type TListDynamicSecretLeaseDTO = { slug: string; - projectId: string; + projectSlug: string; path: string; environment: string; enabled?: boolean; @@ -41,7 +41,7 @@ export type TListDynamicSecretLeaseDTO = { export type TRevokeDynamicSecretLeaseDTO = { leaseId: string; slug: string; - projectId: string; + projectSlug: string; path: string; environment: string; }; diff --git a/frontend/src/views/SecretMainPage/SecretMainPage.tsx b/frontend/src/views/SecretMainPage/SecretMainPage.tsx index 6d82b160d..a697c8975 100644 --- a/frontend/src/views/SecretMainPage/SecretMainPage.tsx +++ b/frontend/src/views/SecretMainPage/SecretMainPage.tsx @@ -69,6 +69,7 @@ export const SecretMainPage = () => { // env slug const environment = router.query.env as string; const workspaceId = currentWorkspace?.id || ""; + const projectSlug = currentWorkspace?.slug || ""; const secretPath = (router.query.secretPath as string) || "/"; const canReadSecret = permission.can( ProjectPermissionActions.Read, @@ -139,7 +140,7 @@ export const SecretMainPage = () => { }); const { data: dynamicSecrets, isLoading: isDynamicSecretLoading } = useGetDynamicSecrets({ - projectId: workspaceId, + projectSlug, environment, path: secretPath }); @@ -258,6 +259,7 @@ export const SecretMainPage = () => { importedSecrets={importedSecrets} environment={environment} workspaceId={workspaceId} + projectSlug={projectSlug} secretPath={secretPath} isVisible={isVisible} filter={filter} @@ -316,7 +318,7 @@ export const SecretMainPage = () => { diff --git a/frontend/src/views/SecretMainPage/components/ActionBar/ActionBar.tsx b/frontend/src/views/SecretMainPage/components/ActionBar/ActionBar.tsx index d42fe8a07..ee3475ea4 100644 --- a/frontend/src/views/SecretMainPage/components/ActionBar/ActionBar.tsx +++ b/frontend/src/views/SecretMainPage/components/ActionBar/ActionBar.tsx @@ -62,7 +62,9 @@ type Props = { // swtich the secrets type as it gets decrypted after api call importedSecrets?: Array & { secrets: DecryptedSecret[] }>; environment: string; + // @depreciated will be moving all these details to zustand workspaceId: string; + projectSlug: string; secretPath?: string; filter: Filter; tags?: WsTag[]; @@ -81,6 +83,7 @@ export const ActionBar = ({ importedSecrets = [], environment, workspaceId, + projectSlug, secretPath = "/", filter, tags = [], @@ -443,7 +446,7 @@ export const ActionBar = ({ handlePopUpToggle("addDynamicSecret", isOpen)} - workspaceId={workspaceId} + projectSlug={projectSlug} environment={environment} secretPath={secretPath} /> diff --git a/frontend/src/views/SecretMainPage/components/ActionBar/CreateDynamicSecretForm/CreateDynamicSecretForm.tsx b/frontend/src/views/SecretMainPage/components/ActionBar/CreateDynamicSecretForm/CreateDynamicSecretForm.tsx index 8f2ab811d..4d2815c1d 100644 --- a/frontend/src/views/SecretMainPage/components/ActionBar/CreateDynamicSecretForm/CreateDynamicSecretForm.tsx +++ b/frontend/src/views/SecretMainPage/components/ActionBar/CreateDynamicSecretForm/CreateDynamicSecretForm.tsx @@ -11,7 +11,7 @@ import { SqlDatabaseInputForm } from "./SqlDatabaseInputForm"; type Props = { isOpen?: boolean; onToggle: (isOpen: boolean) => void; - workspaceId: string; + projectSlug:string; environment: string; secretPath: string; }; @@ -24,7 +24,7 @@ enum WizardSteps { export const CreateDynamicSecretForm = ({ isOpen, onToggle, - workspaceId, + projectSlug, environment, secretPath }: Props) => { @@ -92,7 +92,7 @@ export const CreateDynamicSecretForm = ({ diff --git a/frontend/src/views/SecretMainPage/components/ActionBar/CreateDynamicSecretForm/SqlDatabaseInputForm.tsx b/frontend/src/views/SecretMainPage/components/ActionBar/CreateDynamicSecretForm/SqlDatabaseInputForm.tsx index 5eb6086d3..c908ff4bf 100644 --- a/frontend/src/views/SecretMainPage/components/ActionBar/CreateDynamicSecretForm/SqlDatabaseInputForm.tsx +++ b/frontend/src/views/SecretMainPage/components/ActionBar/CreateDynamicSecretForm/SqlDatabaseInputForm.tsx @@ -58,7 +58,7 @@ type Props = { onCompleted: () => void; onCancel: () => void; secretPath: string; - projectId: string; + projectSlug: string; environment: string; }; @@ -67,7 +67,7 @@ export const SqlDatabaseInputForm = ({ onCancel, environment, secretPath, - projectId + projectSlug }: Props) => { const { control, @@ -89,7 +89,7 @@ export const SqlDatabaseInputForm = ({ slug, path: secretPath, defaultTTL, - projectId, + projectSlug, environment }); onCompleted(); diff --git a/frontend/src/views/SecretMainPage/components/DynamicSecretListView/CreateDynamicSecretLease.tsx b/frontend/src/views/SecretMainPage/components/DynamicSecretListView/CreateDynamicSecretLease.tsx index 4dc7e1592..e3f211ddd 100644 --- a/frontend/src/views/SecretMainPage/components/DynamicSecretListView/CreateDynamicSecretLease.tsx +++ b/frontend/src/views/SecretMainPage/components/DynamicSecretListView/CreateDynamicSecretLease.tsx @@ -13,20 +13,6 @@ import { useTimedReset } from "@app/hooks"; import { useCreateDynamicSecretLease } from "@app/hooks/api"; import { DynamicSecretProviders } from "@app/hooks/api/dynamicSecret/types"; -const formSchema = z.object({ - ttl: z.string().refine((val) => ms(val) > 0, "TTL must be a positive number") -}); -type TForm = z.infer; - -type Props = { - onClose: () => void; - slug: string; - provider: DynamicSecretProviders; - projectId: string; - environment: string; - secretPath: string; -}; - const OutputDisplay = ({ value, label, @@ -68,14 +54,14 @@ const OutputDisplay = ({ }; const renderOutputForm = (provider: DynamicSecretProviders, data: unknown) => { - const { username, password } = data as { username: string; password: string }; + const { DB_PASSWORD, DB_USERNAME } = data as { DB_USERNAME: string; DB_PASSWORD: string }; if (provider === DynamicSecretProviders.SqlDatabase) { return (
- +
@@ -84,9 +70,23 @@ const renderOutputForm = (provider: DynamicSecretProviders, data: unknown) => { return null; }; +const formSchema = z.object({ + ttl: z.string().refine((val) => ms(val) > 0, "TTL must be a positive number") +}); +type TForm = z.infer; + +type Props = { + onClose: () => void; + slug: string; + provider: DynamicSecretProviders; + projectSlug: string; + environment: string; + secretPath: string; +}; + export const CreateDynamicSecretLease = ({ onClose, - projectId, + projectSlug, slug, provider, secretPath, @@ -107,11 +107,11 @@ export const CreateDynamicSecretLease = ({ const createDynamicSecretLease = useCreateDynamicSecretLease(); const handleDynamicSecretLeaseCreate = async ({ ttl }: TForm) => { - if(createDynamicSecretLease.isLoading) return; + if (createDynamicSecretLease.isLoading) return; try { await createDynamicSecretLease.mutateAsync({ environment, - projectId, + projectSlug, path: secretPath, ttl, slug diff --git a/frontend/src/views/SecretMainPage/components/DynamicSecretListView/DynamicSecretLease.tsx b/frontend/src/views/SecretMainPage/components/DynamicSecretListView/DynamicSecretLease.tsx index bb989946d..4fc476a93 100644 --- a/frontend/src/views/SecretMainPage/components/DynamicSecretListView/DynamicSecretLease.tsx +++ b/frontend/src/views/SecretMainPage/components/DynamicSecretListView/DynamicSecretLease.tsx @@ -28,7 +28,7 @@ import { RenewDynamicSecretLease } from "./RenewDynamicSecretLease"; type Props = { slug: string; - projectId: string; + projectSlug: string; environment: string; secretPath: string; onClickNewLease: () => void; @@ -36,7 +36,7 @@ type Props = { }; export const DynamicSecretLease = ({ - projectId, + projectSlug, slug, environment, secretPath, @@ -48,7 +48,7 @@ export const DynamicSecretLease = ({ "renewSecret" ] as const); const { data: leases, isLoading: isLeaseLoading } = useGetDynamicSecretLeases({ - projectId, + projectSlug, environment, path: secretPath, slug @@ -62,7 +62,7 @@ export const DynamicSecretLease = ({ const { leaseId } = popUp.deleteSecret.data as { leaseId: string }; await deleteDynamicSecretLease.mutateAsync({ environment, - projectId, + projectSlug, path: secretPath, slug, leaseId @@ -193,7 +193,7 @@ export const DynamicSecretLease = ({ handlePopUpClose("renewSecret")} - projectId={projectId} + projectSlug={projectSlug} leaseId={(popUp.renewSecret?.data as { leaseId: string })?.leaseId} slug={slug} secretPath={secretPath} diff --git a/frontend/src/views/SecretMainPage/components/DynamicSecretListView/DynamicSecretListView.tsx b/frontend/src/views/SecretMainPage/components/DynamicSecretListView/DynamicSecretListView.tsx index 29663ced7..0cd039925 100644 --- a/frontend/src/views/SecretMainPage/components/DynamicSecretListView/DynamicSecretListView.tsx +++ b/frontend/src/views/SecretMainPage/components/DynamicSecretListView/DynamicSecretListView.tsx @@ -40,7 +40,7 @@ const formatProviderName = (type: DynamicSecretProviders) => { type Props = { dynamicSecrets: TDynamicSecret[]; environment: string; - workspaceId: string; + projectSlug: string; secretPath?: string; sortDir: SortDir; }; @@ -48,7 +48,7 @@ type Props = { export const DynamicSecretListView = ({ dynamicSecrets = [], environment, - workspaceId, + projectSlug, secretPath = "/", sortDir = SortDir.ASC }: Props) => { @@ -67,7 +67,7 @@ export const DynamicSecretListView = ({ const { slug } = popUp.deleteDynamicSecret.data as TDynamicSecret; await deleteDynamicSecret.mutateAsync({ environment, - projectId: workspaceId, + projectSlug, path: secretPath, slug }); @@ -206,7 +206,7 @@ export const DynamicSecretListView = ({ handlePopUpOpen("createDynamicSecretLease", secret)} onClose={() => handlePopUpClose("dynamicSecretLeases")} - projectId={workspaceId} + projectSlug={projectSlug} key={secret.id} slug={secret.slug} secretPath={secretPath} @@ -226,7 +226,7 @@ export const DynamicSecretListView = ({ (popUp.createDynamicSecretLease?.data as { type: DynamicSecretProviders })?.type } onClose={() => handlePopUpClose("createDynamicSecretLease")} - projectId={workspaceId} + projectSlug={projectSlug} slug={(popUp.createDynamicSecretLease?.data as { slug: string })?.slug} secretPath={secretPath} environment={environment} @@ -240,7 +240,7 @@ export const DynamicSecretListView = ({ handlePopUpClose("updateDynamicSecret")} - projectId={workspaceId} + projectSlug={projectSlug} slug={(popUp.updateDynamicSecret?.data as TDynamicSecret)?.slug} secretPath={secretPath} environment={environment} diff --git a/frontend/src/views/SecretMainPage/components/DynamicSecretListView/EditDynamicSecretForm/EditDynamicSecretForm.tsx b/frontend/src/views/SecretMainPage/components/DynamicSecretListView/EditDynamicSecretForm/EditDynamicSecretForm.tsx index fb5c3694c..7f22acfb6 100644 --- a/frontend/src/views/SecretMainPage/components/DynamicSecretListView/EditDynamicSecretForm/EditDynamicSecretForm.tsx +++ b/frontend/src/views/SecretMainPage/components/DynamicSecretListView/EditDynamicSecretForm/EditDynamicSecretForm.tsx @@ -9,7 +9,7 @@ import { EditDynamicSecretSqlProviderForm } from "./EditDynamicSecretSqlProvider type Props = { onClose: () => void; slug: string; - projectId: string; + projectSlug: string; environment: string; secretPath: string; }; @@ -17,13 +17,13 @@ type Props = { export const EditDynamicSecretForm = ({ slug, environment, - projectId, + projectSlug, onClose, secretPath }: Props) => { const { data: dynamicSecretDetails, isLoading: isDynamicSecretLoading } = useGetDynamicSecretDetails({ - projectId, + projectSlug, environment, slug, path: secretPath @@ -49,7 +49,7 @@ export const EditDynamicSecretForm = ({ > void; dynamicSecret: TDynamicSecret & { inputs: unknown }; secretPath: string; - projectId: string; environment: string; + projectSlug: string; }; export const EditDynamicSecretSqlProviderForm = ({ @@ -70,7 +70,7 @@ export const EditDynamicSecretSqlProviderForm = ({ dynamicSecret, environment, secretPath, - projectId + projectSlug }: Props) => { const { control, @@ -97,7 +97,7 @@ export const EditDynamicSecretSqlProviderForm = ({ await updateDynamicSecret.mutateAsync({ slug: dynamicSecret.slug, path: secretPath, - projectId, + projectSlug, environment, data: { maxTTL: maxTTL || undefined, diff --git a/frontend/src/views/SecretMainPage/components/DynamicSecretListView/RenewDynamicSecretLease.tsx b/frontend/src/views/SecretMainPage/components/DynamicSecretListView/RenewDynamicSecretLease.tsx index e7e7065a2..73c121127 100644 --- a/frontend/src/views/SecretMainPage/components/DynamicSecretListView/RenewDynamicSecretLease.tsx +++ b/frontend/src/views/SecretMainPage/components/DynamicSecretListView/RenewDynamicSecretLease.tsx @@ -25,14 +25,14 @@ type Props = { onClose: () => void; leaseId: string; slug: string; - projectId: string; + projectSlug: string; environment: string; secretPath: string; }; export const RenewDynamicSecretLease = ({ onClose, - projectId, + projectSlug, slug, leaseId, secretPath, @@ -57,7 +57,7 @@ export const RenewDynamicSecretLease = ({ try { await renewDynamicSecretLease.mutateAsync({ environment, - projectId, + projectSlug, path: secretPath, ttl, slug,