diff --git a/backend/src/controllers/v1/secretImportController.ts b/backend/src/controllers/v1/secretImportController.ts index 08f4929ff..76b4945bd 100644 --- a/backend/src/controllers/v1/secretImportController.ts +++ b/backend/src/controllers/v1/secretImportController.ts @@ -1,31 +1,49 @@ import { Request, Response } from "express"; -import { validateMembership } from "../../helpers"; -import { Folder, SecretImport } from "../../models"; +import { isValidScope, validateMembership } from "../../helpers"; +import { ServiceTokenData } from "../../models"; +import Folder from "../../models/folder"; +import SecretImport from "../../models/secretImports"; import { getAllImportedSecrets } from "../../services/SecretImportService"; -import { BadRequestError, ResourceNotFoundError } from "../../utils/errors"; +import { getFolderWithPathFromId } from "../../services/FolderService"; +import { BadRequestError, ResourceNotFoundError,UnauthorizedRequestError } from "../../utils/errors"; import { ADMIN, MEMBER } from "../../variables"; import { EEAuditLogService } from "../../ee/services"; import { EventType } from "../../ee/models"; -import { getFolderPath } from "../../services/FolderService"; export const createSecretImport = async (req: Request, res: Response) => { const { workspaceId, environment, folderId, secretImport } = req.body; + + const folders = await Folder.findOne({ + workspace: workspaceId, + environment + }).lean(); + + if (!folders && folderId !== "root") { + throw ResourceNotFoundError({ + message: "Failed to find folder" + }); + } + + let secretPath = "/"; + if (folders) { + const { folderPath } = getFolderWithPathFromId(folders.nodes, folderId); + secretPath = folderPath; + } + if (req.authData.authPayload instanceof ServiceTokenData) { + // root check + const isValidScopeAccess = isValidScope(req.authData.authPayload, environment, secretPath); + if (!isValidScopeAccess) { + throw UnauthorizedRequestError({ message: "Folder Permission Denied" }); + } + } + const importSecDoc = await SecretImport.findOne({ workspace: workspaceId, environment, folderId }); - const folders = await Folder.findOne({ - workspace: workspaceId, - environment, - }).lean(); - - if (!folders) throw ResourceNotFoundError({ - message: "Failed to find folder" - }); - - const importToSecretPath = await getFolderPath(folders, folderId); + const importToSecretPath = folders?getFolderWithPathFromId(folders.nodes, folderId).folderPath:"/"; if (!importSecDoc) { const doc = new SecretImport({ @@ -99,11 +117,34 @@ export const updateSecretImport = async (req: Request, res: Response) => { throw BadRequestError({ message: "Import not found" }); } - await validateMembership({ - userId: req.user._id.toString(), - workspaceId: importSecDoc.workspace, - acceptedRoles: [ADMIN, MEMBER] - }); + if (!(req.authData.authPayload instanceof ServiceTokenData)) { + await validateMembership({ + userId: req.user._id.toString(), + workspaceId: importSecDoc.workspace, + acceptedRoles: [ADMIN, MEMBER] + }); + } else { + // check for service token validity + const folders = await Folder.findOne({ + workspace: importSecDoc.workspace, + environment: importSecDoc.environment + }).lean(); + + let secretPath = "/"; + if (folders) { + const { folderPath } = getFolderWithPathFromId(folders.nodes, importSecDoc.folderId); + secretPath = folderPath; + } + + const isValidScopeAccess = isValidScope( + req.authData.authPayload, + importSecDoc.environment, + secretPath + ); + if (!isValidScopeAccess) { + throw UnauthorizedRequestError({ message: "Folder Permission Denied" }); + } + } const orderBefore = importSecDoc.imports; importSecDoc.imports = secretImports; @@ -119,7 +160,7 @@ export const updateSecretImport = async (req: Request, res: Response) => { message: "Failed to find folder" }); - const importToSecretPath = await getFolderPath(folders, importSecDoc.folderId); + const importToSecretPath = folders?getFolderWithPathFromId(folders.nodes, importSecDoc.folderId).folderPath:"/"; await EEAuditLogService.createAuditLog( req.authData, @@ -149,11 +190,34 @@ export const deleteSecretImport = async (req: Request, res: Response) => { throw BadRequestError({ message: "Import not found" }); } - await validateMembership({ - userId: req.user._id.toString(), - workspaceId: importSecDoc.workspace, - acceptedRoles: [ADMIN, MEMBER] - }); + if (!(req.authData.authPayload instanceof ServiceTokenData)) { + await validateMembership({ + userId: req.user._id.toString(), + workspaceId: importSecDoc.workspace, + acceptedRoles: [ADMIN, MEMBER] + }); + } else { + // check for service token validity + const folders = await Folder.findOne({ + workspace: importSecDoc.workspace, + environment: importSecDoc.environment + }).lean(); + + let secretPath = "/"; + if (folders) { + const { folderPath } = getFolderWithPathFromId(folders.nodes, importSecDoc.folderId); + secretPath = folderPath; + } + + const isValidScopeAccess = isValidScope( + req.authData.authPayload, + importSecDoc.environment, + secretPath + ); + if (!isValidScopeAccess) { + throw UnauthorizedRequestError({ message: "Folder Permission Denied" }); + } + } importSecDoc.imports = importSecDoc.imports.filter( ({ environment, secretPath }) => !(environment === secretImportEnv && secretPath === secretImportPath) @@ -169,7 +233,7 @@ export const deleteSecretImport = async (req: Request, res: Response) => { message: "Failed to find folder" }); - const importToSecretPath = await getFolderPath(folders, importSecDoc.folderId); + const importToSecretPath = folders?getFolderWithPathFromId(folders.nodes, importSecDoc.folderId).folderPath:"/"; await EEAuditLogService.createAuditLog( req.authData, @@ -204,6 +268,29 @@ export const getSecretImports = async (req: Request, res: Response) => { return res.status(200).json({ secretImport: {} }); } + if (req.authData.authPayload instanceof ServiceTokenData) { + // check for service token validity + const folders = await Folder.findOne({ + workspace: importSecDoc.workspace, + environment: importSecDoc.environment + }).lean(); + + let secretPath = "/"; + if (folders) { + const { folderPath } = getFolderWithPathFromId(folders.nodes, importSecDoc.folderId); + secretPath = folderPath; + } + + const isValidScopeAccess = isValidScope( + req.authData.authPayload, + importSecDoc.environment, + secretPath + ); + if (!isValidScopeAccess) { + throw UnauthorizedRequestError({ message: "Folder Permission Denied" }); + } + } + return res.status(200).json({ secretImport: importSecDoc }); }; @@ -223,6 +310,29 @@ export const getAllSecretsFromImport = async (req: Request, res: Response) => { return res.status(200).json({ secrets: [] }); } + if (req.authData.authPayload instanceof ServiceTokenData) { + // check for service token validity + const folders = await Folder.findOne({ + workspace: importSecDoc.workspace, + environment: importSecDoc.environment + }).lean(); + + let secretPath = "/"; + if (folders) { + const { folderPath } = getFolderWithPathFromId(folders.nodes, importSecDoc.folderId); + secretPath = folderPath; + } + + const isValidScopeAccess = isValidScope( + req.authData.authPayload, + importSecDoc.environment, + secretPath + ); + if (!isValidScopeAccess) { + throw UnauthorizedRequestError({ message: "Folder Permission Denied" }); + } + } + await EEAuditLogService.createAuditLog( req.authData, { diff --git a/backend/src/controllers/v1/secretsFolderController.ts b/backend/src/controllers/v1/secretsFolderController.ts index 334df6d4f..46d4c3c1f 100644 --- a/backend/src/controllers/v1/secretsFolderController.ts +++ b/backend/src/controllers/v1/secretsFolderController.ts @@ -1,41 +1,49 @@ import { Request, Response } from "express"; -import { Secret } from "../../models"; import { Types } from "mongoose"; +import { EventType, FolderVersion } from "../../ee/models"; +import { EEAuditLogService, EESecretService } from "../../ee/services"; +import { validateMembership } from "../../helpers/membership"; +import { isValidScope } from "../../helpers/secrets"; +import { Secret, ServiceTokenData } from "../../models"; import Folder from "../../models/folder"; -import { BadRequestError } from "../../utils/errors"; import { appendFolder, deleteFolderById, generateFolderId, getAllFolderIds, getFolderByPath, - getFolderPath, + getFolderWithPathFromId, getParentFromFolderId, - searchByFolderId, - searchByFolderIdWithDir, - validateFolderName, + validateFolderName } from "../../services/FolderService"; +import { BadRequestError, UnauthorizedRequestError } from "../../utils/errors"; import { ADMIN, MEMBER } from "../../variables"; -import { validateMembership } from "../../helpers/membership"; -import { EventType, FolderVersion } from "../../ee/models"; -import { EEAuditLogService, EESecretService } from "../../ee/services"; // verify workspace id/environment export const createFolder = async (req: Request, res: Response) => { const { workspaceId, environment, folderName, parentFolderId } = req.body; if (!validateFolderName(folderName)) { throw BadRequestError({ - message: "Folder name cannot contain spaces. Only underscore and dashes", + message: "Folder name cannot contain spaces. Only underscore and dashes" }); } const folders = await Folder.findOne({ workspace: workspaceId, - environment, + environment }).lean(); + // space has no folders initialized if (!folders) { + if (req.authData.authPayload instanceof ServiceTokenData) { + // root check + const isValidScopeAccess = isValidScope(req.authData.authPayload, environment, "/"); + if (!isValidScopeAccess) { + throw UnauthorizedRequestError({ message: "Folder Permission Denied" }); + } + } + const id = generateFolderId(); const folder = new Folder({ workspace: workspaceId, @@ -44,19 +52,19 @@ export const createFolder = async (req: Request, res: Response) => { id: "root", name: "root", version: 1, - children: [{ id, name: folderName, children: [], version: 1 }], - }, + children: [{ id, name: folderName, children: [], version: 1 }] + } }); await folder.save(); const folderVersion = new FolderVersion({ workspace: workspaceId, environment, - nodes: folder.nodes, + nodes: folder.nodes }); await folderVersion.save(); await EESecretService.takeSecretSnapshot({ workspaceId, - environment, + environment }); await EEAuditLogService.createAuditLog( @@ -81,23 +89,40 @@ export const createFolder = async (req: Request, res: Response) => { const folder = appendFolder(folders.nodes, { folderName, parentFolderId }); await Folder.findByIdAndUpdate(folders._id, folders); - - const parentFolder = searchByFolderId(folders.nodes, parentFolderId); + const { folder: parentFolder, folderPath: parentFolderPath } = getFolderWithPathFromId( + folders.nodes, + parentFolderId || "root" + ); + + if (req.authData.authPayload instanceof ServiceTokenData) { + // root check + const isValidScopeAccess = isValidScope( + req.authData.authPayload, + environment, + parentFolderPath + ); + if (!isValidScopeAccess) { + throw UnauthorizedRequestError({ message: "Folder Permission Denied" }); + } + } + + await Folder.findByIdAndUpdate(folders._id, folders); + const folderVersion = new FolderVersion({ workspace: workspaceId, environment, - nodes: parentFolder, + nodes: parentFolder }); await folderVersion.save(); await EESecretService.takeSecretSnapshot({ workspaceId, environment, - folderId: parentFolderId, + folderId: parentFolderId }); - const folderPath = await getFolderPath(folders, folder.id); + const {folderPath} = getFolderWithPathFromId(folders.nodes, folder.id); await EEAuditLogService.createAuditLog( req.authData, @@ -121,18 +146,25 @@ export const createFolder = async (req: Request, res: Response) => { export const updateFolderById = async (req: Request, res: Response) => { const { folderId } = req.params; const { name, workspaceId, environment } = req.body; + if (!validateFolderName(name)) { + throw BadRequestError({ + message: "Folder name cannot contain spaces. Only underscore and dashes" + }); + } const folders = await Folder.findOne({ workspace: workspaceId, environment }); if (!folders) { throw BadRequestError({ message: "The folder doesn't exist" }); } - - // check that user is a member of the workspace - await validateMembership({ - userId: req.user._id.toString(), - workspaceId, - acceptedRoles: [ADMIN, MEMBER], - }); + + if (!(req.authData.authPayload instanceof ServiceTokenData)) { + // check that user is a member of the workspace + await validateMembership({ + userId: req.user._id.toString(), + workspaceId, + acceptedRoles: [ADMIN, MEMBER] + }); + } const parentFolder = getParentFromFolderId(folders.nodes, folderId); if (!parentFolder) { @@ -144,6 +176,15 @@ export const updateFolderById = async (req: Request, res: Response) => { throw BadRequestError({ message: "The folder doesn't exist" }); } + if (req.authData.authPayload instanceof ServiceTokenData) { + const { folderPath: secretPath } = getFolderWithPathFromId(folders.nodes, parentFolder.id); + // root check + const isValidScopeAccess = isValidScope(req.authData.authPayload, environment, secretPath); + if (!isValidScopeAccess) { + throw UnauthorizedRequestError({ message: "Folder Permission Denied" }); + } + } + const oldFolderName = folder.name; parentFolder.version += 1; folder.name = name; @@ -152,17 +193,17 @@ export const updateFolderById = async (req: Request, res: Response) => { const folderVersion = new FolderVersion({ workspace: workspaceId, environment, - nodes: parentFolder, + nodes: parentFolder }); await folderVersion.save(); await EESecretService.takeSecretSnapshot({ workspaceId, environment, - folderId: parentFolder.id, + folderId: parentFolder.id }); - const folderPath = await getFolderPath(folders, folder.id); + const {folderPath} = getFolderWithPathFromId(folders.nodes, folder.id); await EEAuditLogService.createAuditLog( req.authData, @@ -183,7 +224,7 @@ export const updateFolderById = async (req: Request, res: Response) => { return res.json({ message: "Successfully updated folder", - folder: { name: folder.name, id: folder.id }, + folder: { name: folder.name, id: folder.id } }); }; @@ -196,14 +237,16 @@ export const deleteFolder = async (req: Request, res: Response) => { throw BadRequestError({ message: "The folder doesn't exist" }); } - // check that user is a member of the workspace - await validateMembership({ - userId: req.user._id.toString(), - workspaceId, - acceptedRoles: [ADMIN, MEMBER], - }); + if (!(req.authData.authPayload instanceof ServiceTokenData)) { + // check that user is a member of the workspace + await validateMembership({ + userId: req.user._id.toString(), + workspaceId, + acceptedRoles: [ADMIN, MEMBER] + }); + } - const folderPath = await getFolderPath(folders, folderId); + const {folderPath} = getFolderWithPathFromId(folders.nodes, folderId); const delOp = deleteFolderById(folders.nodes, folderId); if (!delOp) { @@ -211,6 +254,14 @@ export const deleteFolder = async (req: Request, res: Response) => { } const { deletedNode: delFolder, parent: parentFolder } = delOp; + if (req.authData.authPayload instanceof ServiceTokenData) { + const { folderPath: secretPath } = getFolderWithPathFromId(folders.nodes, parentFolder.id); + const isValidScopeAccess = isValidScope(req.authData.authPayload, environment, secretPath); + if (!isValidScopeAccess) { + throw UnauthorizedRequestError({ message: "Folder Permission Denied" }); + } + } + parentFolder.version += 1; const delFolderIds = getAllFolderIds(delFolder); @@ -218,21 +269,21 @@ export const deleteFolder = async (req: Request, res: Response) => { const folderVersion = new FolderVersion({ workspace: workspaceId, environment, - nodes: parentFolder, + nodes: parentFolder }); await folderVersion.save(); if (delFolderIds.length) { await Secret.deleteMany({ folder: { $in: delFolderIds.map(({ id }) => id) }, workspace: workspaceId, - environment, + environment }); } await EESecretService.takeSecretSnapshot({ workspaceId, environment, - folderId: parentFolder.id, + folderId: parentFolder.id }); await EEAuditLogService.createAuditLog( @@ -256,13 +307,12 @@ export const deleteFolder = async (req: Request, res: Response) => { // TODO: validate workspace export const getFolders = async (req: Request, res: Response) => { - const { workspaceId, environment, parentFolderId, parentFolderPath } = - req.query as { - workspaceId: string; - environment: string; - parentFolderId?: string; - parentFolderPath?: string; - }; + const { workspaceId, environment, parentFolderId, parentFolderPath } = req.query as { + workspaceId: string; + environment: string; + parentFolderId?: string; + parentFolderPath?: string; + }; const folders = await Folder.findOne({ workspace: workspaceId, environment }); if (!folders) { @@ -270,16 +320,29 @@ export const getFolders = async (req: Request, res: Response) => { return; } - // check that user is a member of the workspace - await validateMembership({ - userId: req.user._id.toString(), - workspaceId, - acceptedRoles: [ADMIN, MEMBER], - }); + if (!(req.authData.authPayload instanceof ServiceTokenData)) { + // check that user is a member of the workspace + await validateMembership({ + userId: req.user._id.toString(), + workspaceId, + acceptedRoles: [ADMIN, MEMBER] + }); + } // if instead of parentFolderId given a path like /folder1/folder2 if (parentFolderPath) { + if (req.authData.authPayload instanceof ServiceTokenData) { + const isValidScopeAccess = isValidScope( + req.authData.authPayload, + environment, + parentFolderPath + ); + if (!isValidScopeAccess) { + throw UnauthorizedRequestError({ message: "Folder Permission Denied" }); + } + } const folder = getFolderByPath(folders.nodes, parentFolderPath); + if (!folder) { res.send({ folders: [], dir: [] }); return; @@ -287,27 +350,36 @@ export const getFolders = async (req: Request, res: Response) => { // dir is not needed at present as this is only used in overview section of secrets res.send({ folders: folder.children.map(({ id, name }) => ({ id, name })), - dir: [{ name: folder.name, id: folder.id }], + dir: [{ name: folder.name, id: folder.id }] }); } if (!parentFolderId) { + if (req.authData.authPayload instanceof ServiceTokenData) { + const isValidScopeAccess = isValidScope(req.authData.authPayload, environment, "/"); + if (!isValidScopeAccess) { + throw UnauthorizedRequestError({ message: "Folder Permission Denied" }); + } + } + const rootFolders = folders.nodes.children.map(({ id, name }) => ({ id, - name, + name })); res.send({ folders: rootFolders }); return; } - const folderBySearch = searchByFolderIdWithDir(folders.nodes, parentFolderId); - if (!folderBySearch) { - throw BadRequestError({ message: "The folder doesn't exist" }); + const { folder, folderPath, dir } = getFolderWithPathFromId(folders.nodes, parentFolderId); + if (req.authData.authPayload instanceof ServiceTokenData) { + const isValidScopeAccess = isValidScope(req.authData.authPayload, environment, folderPath); + if (!isValidScopeAccess) { + throw UnauthorizedRequestError({ message: "Folder Permission Denied" }); + } } - const { folder, dir } = folderBySearch; res.send({ folders: folder.children.map(({ id, name }) => ({ id, name })), - dir, + dir }); }; diff --git a/backend/src/routes/v1/secretImport.ts b/backend/src/routes/v1/secretImport.ts index 79ee8e238..21973f57e 100644 --- a/backend/src/routes/v1/secretImport.ts +++ b/backend/src/routes/v1/secretImport.ts @@ -1,14 +1,14 @@ import express from "express"; -const router = express.Router(); import { body, param, query } from "express-validator"; import { secretImportController } from "../../controllers/v1"; import { requireAuth, requireWorkspaceAuth, validateRequest } from "../../middleware"; import { ADMIN, AuthMode, MEMBER } from "../../variables"; +const router = express.Router(); router.post( "/", requireAuth({ - acceptedAuthModes: [AuthMode.JWT] + acceptedAuthModes: [AuthMode.JWT,AuthMode.SERVICE_TOKEN] }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], @@ -27,7 +27,7 @@ router.post( router.put( "/:id", requireAuth({ - acceptedAuthModes: [AuthMode.JWT] + acceptedAuthModes: [AuthMode.JWT,AuthMode.SERVICE_TOKEN] }), param("id").exists().isString().trim(), body("secretImports").exists().isArray(), @@ -40,7 +40,7 @@ router.put( router.delete( "/:id", requireAuth({ - acceptedAuthModes: [AuthMode.JWT] + acceptedAuthModes: [AuthMode.JWT,AuthMode.SERVICE_TOKEN] }), param("id").exists().isString().trim(), body("secretImportPath").isString().exists().trim(), @@ -52,7 +52,7 @@ router.delete( router.get( "/", requireAuth({ - acceptedAuthModes: [AuthMode.JWT] + acceptedAuthModes: [AuthMode.JWT,AuthMode.SERVICE_TOKEN] }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], @@ -68,7 +68,7 @@ router.get( router.get( "/secrets", requireAuth({ - acceptedAuthModes: [AuthMode.JWT] + acceptedAuthModes: [AuthMode.JWT,AuthMode.SERVICE_TOKEN] }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], diff --git a/backend/src/routes/v1/secretsFolder.ts b/backend/src/routes/v1/secretsFolder.ts index f7773367b..4580e50d3 100644 --- a/backend/src/routes/v1/secretsFolder.ts +++ b/backend/src/routes/v1/secretsFolder.ts @@ -1,27 +1,23 @@ import express from "express"; -const router = express.Router(); -import { - requireAuth, - requireWorkspaceAuth, - validateRequest, -} from "../../middleware"; import { body, param, query } from "express-validator"; import { createFolder, deleteFolder, getFolders, - updateFolderById, + updateFolderById } from "../../controllers/v1/secretsFolderController"; +import { requireAuth, requireWorkspaceAuth, validateRequest } from "../../middleware"; import { ADMIN, AuthMode, MEMBER } from "../../variables"; +const router = express.Router(); router.post( "/", requireAuth({ - acceptedAuthModes: [AuthMode.JWT], + acceptedAuthModes: [AuthMode.JWT,AuthMode.SERVICE_TOKEN] }), requireWorkspaceAuth({ acceptedRoles: [ADMIN, MEMBER], - locationWorkspaceId: "body", + locationWorkspaceId: "body" }), body("workspaceId").exists(), body("environment").exists(), @@ -34,7 +30,7 @@ router.post( router.patch( "/:folderId", requireAuth({ - acceptedAuthModes: [AuthMode.JWT], + acceptedAuthModes: [AuthMode.JWT,AuthMode.SERVICE_TOKEN] }), body("workspaceId").exists(), body("environment").exists(), @@ -46,7 +42,7 @@ router.patch( router.delete( "/:folderId", requireAuth({ - acceptedAuthModes: [AuthMode.JWT], + acceptedAuthModes: [AuthMode.JWT,AuthMode.SERVICE_TOKEN] }), body("workspaceId").exists(), body("environment").exists(), @@ -58,7 +54,7 @@ router.delete( router.get( "/", requireAuth({ - acceptedAuthModes: [AuthMode.JWT], + acceptedAuthModes: [AuthMode.JWT,AuthMode.SERVICE_TOKEN] }), query("workspaceId").exists().isString().trim(), query("environment").exists().isString().trim(), diff --git a/backend/src/services/FolderService.ts b/backend/src/services/FolderService.ts index 8e1c00750..81f169f4b 100644 --- a/backend/src/services/FolderService.ts +++ b/backend/src/services/FolderService.ts @@ -1,7 +1,7 @@ import { nanoid } from "nanoid"; import { Types } from "mongoose"; -import Folder, { TFolderRootSchema, TFolderSchema } from "../models/folder"; -import { ResourceNotFoundError } from "../utils/errors"; +import Folder, { TFolderSchema } from "../models/folder"; +import path from "path"; type TAppendFolderDTO = { folderName: string; @@ -59,7 +59,7 @@ const appendChild = (folders: TFolderSchema, folderName: string) => { id, name: folderName, children: [], - version: 1, + version: 1 }); return { id, name: folderName }; }; @@ -109,10 +109,7 @@ export const deleteFolderById = (folders: TFolderSchema, folderId: string) => { }; // bfs but return parent of the folderID -export const getParentFromFolderId = ( - folders: TFolderSchema, - folderId: string -) => { +export const getParentFromFolderId = (folders: TFolderSchema, folderId: string) => { const queue = [folders]; while (queue.length) { const folder = queue.pop() as TFolderSchema; @@ -141,10 +138,7 @@ export const getAllFolderIds = (folders: TFolderSchema) => { // We then record the number of childs of each root node // When we reach leaf node or when all childs of a root node are visited // We remove it from path recorded by using the total child record -export const searchByFolderIdWithDir = ( - folders: TFolderSchema, - folderId: string -) => { +export const searchByFolderIdWithDir = (folders: TFolderSchema, folderId: string) => { const stack = [folders]; const dir: Array<{ id: string; name: string }> = []; const hits: Record = {}; @@ -173,19 +167,19 @@ export const searchByFolderIdWithDir = ( return; }; -export const getFolderPath = ( - folders: TFolderRootSchema, - folderId: string - ) => { - const folderBySearch = searchByFolderIdWithDir(folders.nodes, folderId); - - if (!folderBySearch) throw ResourceNotFoundError({ - message: "Failed to find folder" - }); - - const folderPath = folderBySearch.dir.map((folder) => folder.name).join("/"); - return folderPath; +// used for get folder path from id +export const getFolderWithPathFromId = (folders: TFolderSchema, parentFolderId: string) => { + const search = searchByFolderIdWithDir(folders, parentFolderId); + if (!search) { + throw { message: "Folder permission denied" }; } + const { folder, dir } = search; + const folderPath = path.join( + "/", + ...dir.filter(({ name }) => name !== "root").map(({ name }) => name) + ); + return { folder, folderPath, dir }; +}; // to get folder of a path given // Like /frontend/folder#1 @@ -216,7 +210,7 @@ export const getFolderIdFromServiceToken = async ( ) => { const folders = await Folder.findOne({ workspace: workspaceId, - environment, + environment }); if (!folders) {