diff --git a/backend/src/lib/api-docs/constants.ts b/backend/src/lib/api-docs/constants.ts index 188af00b7..e635d93da 100644 --- a/backend/src/lib/api-docs/constants.ts +++ b/backend/src/lib/api-docs/constants.ts @@ -515,6 +515,9 @@ export const FOLDERS = { path: "The path to list folders from.", directory: "The directory to list folders from. (Deprecated in favor of path)" }, + GET_BY_ID: { + folderId: "The id of the folder to get details." + }, CREATE: { workspaceId: "The ID of the project to create the folder in.", environment: "The slug of the environment to create the folder in.", diff --git a/backend/src/server/routes/v1/secret-folder-router.ts b/backend/src/server/routes/v1/secret-folder-router.ts index 1a1747f64..276bb36ef 100644 --- a/backend/src/server/routes/v1/secret-folder-router.ts +++ b/backend/src/server/routes/v1/secret-folder-router.ts @@ -292,4 +292,39 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) => return { folders }; } }); + + server.route({ + method: "GET", + url: "/:id", + config: { + rateLimit: readLimit + }, + schema: { + description: "Get folder by id", + security: [ + { + bearerAuth: [] + } + ], + params: z.object({ + id: z.string().trim().describe(FOLDERS.GET_BY_ID.folderId) + }), + response: { + 200: z.object({ + folder: SecretFoldersSchema + }) + } + }, + onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]), + handler: async (req) => { + const folder = await server.services.folder.getFolderById({ + actorId: req.permission.id, + actor: req.permission.type, + actorAuthMethod: req.permission.authMethod, + actorOrgId: req.permission.orgId, + id: req.params.id + }); + return { folder }; + } + }); }; diff --git a/backend/src/services/secret-folder/secret-folder-dal.ts b/backend/src/services/secret-folder/secret-folder-dal.ts index 283f60c7c..1803f8977 100644 --- a/backend/src/services/secret-folder/secret-folder-dal.ts +++ b/backend/src/services/secret-folder/secret-folder-dal.ts @@ -322,7 +322,7 @@ export const secretFolderDALFactory = (db: TDbClient) => { .first(); if (folder) { const { envId, envName, envSlug, ...el } = folder; - return { ...el, environment: { envId, envName, envSlug } }; + return { ...el, environment: { envId, envName, envSlug }, envId }; } } catch (error) { throw new DatabaseError({ error, name: "Find by id" }); diff --git a/backend/src/services/secret-folder/secret-folder-service.ts b/backend/src/services/secret-folder/secret-folder-service.ts index 97258c006..9d6c29454 100644 --- a/backend/src/services/secret-folder/secret-folder-service.ts +++ b/backend/src/services/secret-folder/secret-folder-service.ts @@ -6,7 +6,7 @@ import { TSecretFoldersInsert } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { TSecretSnapshotServiceFactory } from "@app/ee/services/secret-snapshot/secret-snapshot-service"; -import { BadRequestError } from "@app/lib/errors"; +import { BadRequestError, NotFoundError } from "@app/lib/errors"; import { TProjectDALFactory } from "../project/project-dal"; import { TProjectEnvDALFactory } from "../project-env/project-env-dal"; @@ -14,6 +14,7 @@ import { TSecretFolderDALFactory } from "./secret-folder-dal"; import { TCreateFolderDTO, TDeleteFolderDTO, + TGetFolderByIdDTO, TGetFolderDTO, TUpdateFolderDTO, TUpdateManyFoldersDTO @@ -368,11 +369,22 @@ export const secretFolderServiceFactory = ({ return folders; }; + const getFolderById = async ({ actor, actorId, actorOrgId, actorAuthMethod, id }: TGetFolderByIdDTO) => { + const folder = await folderDAL.findById(id); + if (!folder) throw new NotFoundError({ message: "folder not found" }); + // folder list is allowed to be read by anyone + // permission to check does user has access + await permissionService.getProjectPermission(actor, actorId, folder.projectId, actorAuthMethod, actorOrgId); + + return folder; + }; + return { createFolder, updateFolder, updateManyFolders, deleteFolder, - getFolders + getFolders, + getFolderById }; }; diff --git a/backend/src/services/secret-folder/secret-folder-types.ts b/backend/src/services/secret-folder/secret-folder-types.ts index c01d5f7b8..5c80b9582 100644 --- a/backend/src/services/secret-folder/secret-folder-types.ts +++ b/backend/src/services/secret-folder/secret-folder-types.ts @@ -37,3 +37,7 @@ export type TGetFolderDTO = { environment: string; path: string; } & TProjectPermission; + +export type TGetFolderByIdDTO = { + id: string; +} & Omit; diff --git a/docs/api-reference/endpoints/folders/get-by-id.mdx b/docs/api-reference/endpoints/folders/get-by-id.mdx new file mode 100644 index 000000000..db3c4d0cc --- /dev/null +++ b/docs/api-reference/endpoints/folders/get-by-id.mdx @@ -0,0 +1,4 @@ +--- +title: "Get by ID" +openapi: "GET /api/v1/folders/{id}" +--- diff --git a/docs/mint.json b/docs/mint.json index 9cbc22666..176f93e1c 100644 --- a/docs/mint.json +++ b/docs/mint.json @@ -576,6 +576,7 @@ "group": "Folders", "pages": [ "api-reference/endpoints/folders/list", + "api-reference/endpoints/folders/get-by-id", "api-reference/endpoints/folders/create", "api-reference/endpoints/folders/update", "api-reference/endpoints/folders/delete"