mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-10 21:29:20 +00:00
feat: refactored getPathfromId to folder service
This commit is contained in:
@@ -1,29 +1,14 @@
|
|||||||
import { Request, Response } from "express";
|
import { Request, Response } from "express";
|
||||||
import path from "path";
|
|
||||||
import { isValidScope, validateMembership } from "../../helpers";
|
import { isValidScope, validateMembership } from "../../helpers";
|
||||||
import { ServiceTokenData } from "../../models";
|
import { ServiceTokenData } from "../../models";
|
||||||
import Folder, { TFolderRootSchema } from "../../models/folder";
|
import Folder from "../../models/folder";
|
||||||
import SecretImport from "../../models/secretImports";
|
import SecretImport from "../../models/secretImports";
|
||||||
import { searchByFolderIdWithDir } from "../../services/FolderService";
|
|
||||||
import { getAllImportedSecrets } from "../../services/SecretImportService";
|
import { getAllImportedSecrets } from "../../services/SecretImportService";
|
||||||
|
import { getFolderWithPathFromId } from "../../services/FolderService";
|
||||||
import { BadRequestError, ResourceNotFoundError,UnauthorizedRequestError } from "../../utils/errors";
|
import { BadRequestError, ResourceNotFoundError,UnauthorizedRequestError } from "../../utils/errors";
|
||||||
import { ADMIN, MEMBER } from "../../variables";
|
import { ADMIN, MEMBER } from "../../variables";
|
||||||
import { EEAuditLogService } from "../../ee/services";
|
import { EEAuditLogService } from "../../ee/services";
|
||||||
import { EventType } from "../../ee/models";
|
import { EventType } from "../../ee/models";
|
||||||
import { getFolderPath } from "../../services/FolderService";
|
|
||||||
|
|
||||||
const getFolderWithPathFromId = (folders: TFolderRootSchema, parentFolderId: string) => {
|
|
||||||
const search = searchByFolderIdWithDir(folders.nodes, 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 };
|
|
||||||
};
|
|
||||||
|
|
||||||
export const createSecretImport = async (req: Request, res: Response) => {
|
export const createSecretImport = async (req: Request, res: Response) => {
|
||||||
const { workspaceId, environment, folderId, secretImport } = req.body;
|
const { workspaceId, environment, folderId, secretImport } = req.body;
|
||||||
@@ -34,12 +19,14 @@ export const createSecretImport = async (req: Request, res: Response) => {
|
|||||||
}).lean();
|
}).lean();
|
||||||
|
|
||||||
if (!folders && folderId !== "root") {
|
if (!folders && folderId !== "root") {
|
||||||
throw BadRequestError({ message: "Folder doesn't exist" });
|
throw ResourceNotFoundError({
|
||||||
|
message: "Failed to find folder"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let secretPath = "/";
|
let secretPath = "/";
|
||||||
if (folders) {
|
if (folders) {
|
||||||
const { folderPath } = getFolderWithPathFromId(folders, folderId);
|
const { folderPath } = getFolderWithPathFromId(folders.nodes, folderId);
|
||||||
secretPath = folderPath;
|
secretPath = folderPath;
|
||||||
}
|
}
|
||||||
if (req.authData.authPayload instanceof ServiceTokenData) {
|
if (req.authData.authPayload instanceof ServiceTokenData) {
|
||||||
@@ -56,16 +43,7 @@ export const createSecretImport = async (req: Request, res: Response) => {
|
|||||||
folderId
|
folderId
|
||||||
});
|
});
|
||||||
|
|
||||||
const folders = await Folder.findOne({
|
const importToSecretPath = folders?getFolderWithPathFromId(folders.nodes, folderId).folderPath:"/";
|
||||||
workspace: workspaceId,
|
|
||||||
environment,
|
|
||||||
}).lean();
|
|
||||||
|
|
||||||
if (!folders) throw ResourceNotFoundError({
|
|
||||||
message: "Failed to find folder"
|
|
||||||
});
|
|
||||||
|
|
||||||
const importToSecretPath = await getFolderPath(folders, folderId);
|
|
||||||
|
|
||||||
if (!importSecDoc) {
|
if (!importSecDoc) {
|
||||||
const doc = new SecretImport({
|
const doc = new SecretImport({
|
||||||
@@ -154,7 +132,7 @@ export const updateSecretImport = async (req: Request, res: Response) => {
|
|||||||
|
|
||||||
let secretPath = "/";
|
let secretPath = "/";
|
||||||
if (folders) {
|
if (folders) {
|
||||||
const { folderPath } = getFolderWithPathFromId(folders, importSecDoc.folderId);
|
const { folderPath } = getFolderWithPathFromId(folders.nodes, importSecDoc.folderId);
|
||||||
secretPath = folderPath;
|
secretPath = folderPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,7 +160,7 @@ export const updateSecretImport = async (req: Request, res: Response) => {
|
|||||||
message: "Failed to find folder"
|
message: "Failed to find folder"
|
||||||
});
|
});
|
||||||
|
|
||||||
const importToSecretPath = await getFolderPath(folders, importSecDoc.folderId);
|
const importToSecretPath = folders?getFolderWithPathFromId(folders.nodes, importSecDoc.folderId).folderPath:"/";
|
||||||
|
|
||||||
await EEAuditLogService.createAuditLog(
|
await EEAuditLogService.createAuditLog(
|
||||||
req.authData,
|
req.authData,
|
||||||
@@ -227,7 +205,7 @@ export const deleteSecretImport = async (req: Request, res: Response) => {
|
|||||||
|
|
||||||
let secretPath = "/";
|
let secretPath = "/";
|
||||||
if (folders) {
|
if (folders) {
|
||||||
const { folderPath } = getFolderWithPathFromId(folders, importSecDoc.folderId);
|
const { folderPath } = getFolderWithPathFromId(folders.nodes, importSecDoc.folderId);
|
||||||
secretPath = folderPath;
|
secretPath = folderPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,7 +233,7 @@ export const deleteSecretImport = async (req: Request, res: Response) => {
|
|||||||
message: "Failed to find folder"
|
message: "Failed to find folder"
|
||||||
});
|
});
|
||||||
|
|
||||||
const importToSecretPath = await getFolderPath(folders, importSecDoc.folderId);
|
const importToSecretPath = folders?getFolderWithPathFromId(folders.nodes, importSecDoc.folderId).folderPath:"/";
|
||||||
|
|
||||||
await EEAuditLogService.createAuditLog(
|
await EEAuditLogService.createAuditLog(
|
||||||
req.authData,
|
req.authData,
|
||||||
@@ -299,7 +277,7 @@ export const getSecretImports = async (req: Request, res: Response) => {
|
|||||||
|
|
||||||
let secretPath = "/";
|
let secretPath = "/";
|
||||||
if (folders) {
|
if (folders) {
|
||||||
const { folderPath } = getFolderWithPathFromId(folders, importSecDoc.folderId);
|
const { folderPath } = getFolderWithPathFromId(folders.nodes, importSecDoc.folderId);
|
||||||
secretPath = folderPath;
|
secretPath = folderPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,7 +319,7 @@ export const getAllSecretsFromImport = async (req: Request, res: Response) => {
|
|||||||
|
|
||||||
let secretPath = "/";
|
let secretPath = "/";
|
||||||
if (folders) {
|
if (folders) {
|
||||||
const { folderPath } = getFolderWithPathFromId(folders, importSecDoc.folderId);
|
const { folderPath } = getFolderWithPathFromId(folders.nodes, importSecDoc.folderId);
|
||||||
secretPath = folderPath;
|
secretPath = folderPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,39 +1,24 @@
|
|||||||
import { Request, Response } from "express";
|
import { Request, Response } from "express";
|
||||||
import { Types } from "mongoose";
|
import { Types } from "mongoose";
|
||||||
import path from "path";
|
|
||||||
import { EventType, FolderVersion } from "../../ee/models";
|
import { EventType, FolderVersion } from "../../ee/models";
|
||||||
import { EEAuditLogService, EESecretService } from "../../ee/services";
|
import { EEAuditLogService, EESecretService } from "../../ee/services";
|
||||||
import { validateMembership } from "../../helpers/membership";
|
import { validateMembership } from "../../helpers/membership";
|
||||||
import { isValidScope } from "../../helpers/secrets";
|
import { isValidScope } from "../../helpers/secrets";
|
||||||
import { Secret, ServiceTokenData } from "../../models";
|
import { Secret, ServiceTokenData } from "../../models";
|
||||||
import Folder, { TFolderRootSchema } from "../../models/folder";
|
import Folder from "../../models/folder";
|
||||||
import {
|
import {
|
||||||
appendFolder,
|
appendFolder,
|
||||||
deleteFolderById,
|
deleteFolderById,
|
||||||
generateFolderId,
|
generateFolderId,
|
||||||
getAllFolderIds,
|
getAllFolderIds,
|
||||||
getFolderByPath,
|
getFolderByPath,
|
||||||
getFolderPath,
|
getFolderWithPathFromId,
|
||||||
getParentFromFolderId,
|
getParentFromFolderId,
|
||||||
searchByFolderIdWithDir,
|
|
||||||
validateFolderName
|
validateFolderName
|
||||||
} from "../../services/FolderService";
|
} from "../../services/FolderService";
|
||||||
import { BadRequestError, UnauthorizedRequestError } from "../../utils/errors";
|
import { BadRequestError, UnauthorizedRequestError } from "../../utils/errors";
|
||||||
import { ADMIN, MEMBER } from "../../variables";
|
import { ADMIN, MEMBER } from "../../variables";
|
||||||
|
|
||||||
const getFolderWithPathFromId = (folders: TFolderRootSchema, parentFolderId: string) => {
|
|
||||||
const search = searchByFolderIdWithDir(folders.nodes, 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 };
|
|
||||||
};
|
|
||||||
|
|
||||||
// verify workspace id/environment
|
// verify workspace id/environment
|
||||||
export const createFolder = async (req: Request, res: Response) => {
|
export const createFolder = async (req: Request, res: Response) => {
|
||||||
const { workspaceId, environment, folderName, parentFolderId } = req.body;
|
const { workspaceId, environment, folderName, parentFolderId } = req.body;
|
||||||
@@ -106,7 +91,7 @@ export const createFolder = async (req: Request, res: Response) => {
|
|||||||
await Folder.findByIdAndUpdate(folders._id, folders);
|
await Folder.findByIdAndUpdate(folders._id, folders);
|
||||||
|
|
||||||
const { folder: parentFolder, folderPath: parentFolderPath } = getFolderWithPathFromId(
|
const { folder: parentFolder, folderPath: parentFolderPath } = getFolderWithPathFromId(
|
||||||
folders,
|
folders.nodes,
|
||||||
parentFolderId || "root"
|
parentFolderId || "root"
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -137,7 +122,7 @@ export const createFolder = async (req: Request, res: Response) => {
|
|||||||
folderId: parentFolderId
|
folderId: parentFolderId
|
||||||
});
|
});
|
||||||
|
|
||||||
const folderPath = await getFolderPath(folders, folder.id);
|
const {folderPath} = getFolderWithPathFromId(folders.nodes, folder.id);
|
||||||
|
|
||||||
await EEAuditLogService.createAuditLog(
|
await EEAuditLogService.createAuditLog(
|
||||||
req.authData,
|
req.authData,
|
||||||
@@ -192,7 +177,7 @@ export const updateFolderById = async (req: Request, res: Response) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (req.authData.authPayload instanceof ServiceTokenData) {
|
if (req.authData.authPayload instanceof ServiceTokenData) {
|
||||||
const { folderPath: secretPath } = getFolderWithPathFromId(folders, parentFolder.id);
|
const { folderPath: secretPath } = getFolderWithPathFromId(folders.nodes, parentFolder.id);
|
||||||
// root check
|
// root check
|
||||||
const isValidScopeAccess = isValidScope(req.authData.authPayload, environment, secretPath);
|
const isValidScopeAccess = isValidScope(req.authData.authPayload, environment, secretPath);
|
||||||
if (!isValidScopeAccess) {
|
if (!isValidScopeAccess) {
|
||||||
@@ -200,6 +185,7 @@ export const updateFolderById = async (req: Request, res: Response) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const oldFolderName = folder.name;
|
||||||
parentFolder.version += 1;
|
parentFolder.version += 1;
|
||||||
folder.name = name;
|
folder.name = name;
|
||||||
|
|
||||||
@@ -217,7 +203,7 @@ export const updateFolderById = async (req: Request, res: Response) => {
|
|||||||
folderId: parentFolder.id
|
folderId: parentFolder.id
|
||||||
});
|
});
|
||||||
|
|
||||||
const folderPath = await getFolderPath(folders, folder.id);
|
const {folderPath} = getFolderWithPathFromId(folders.nodes, folder.id);
|
||||||
|
|
||||||
await EEAuditLogService.createAuditLog(
|
await EEAuditLogService.createAuditLog(
|
||||||
req.authData,
|
req.authData,
|
||||||
@@ -260,7 +246,7 @@ export const deleteFolder = async (req: Request, res: Response) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const folderPath = await getFolderPath(folders, folderId);
|
const {folderPath} = getFolderWithPathFromId(folders.nodes, folderId);
|
||||||
|
|
||||||
const delOp = deleteFolderById(folders.nodes, folderId);
|
const delOp = deleteFolderById(folders.nodes, folderId);
|
||||||
if (!delOp) {
|
if (!delOp) {
|
||||||
@@ -269,7 +255,7 @@ export const deleteFolder = async (req: Request, res: Response) => {
|
|||||||
const { deletedNode: delFolder, parent: parentFolder } = delOp;
|
const { deletedNode: delFolder, parent: parentFolder } = delOp;
|
||||||
|
|
||||||
if (req.authData.authPayload instanceof ServiceTokenData) {
|
if (req.authData.authPayload instanceof ServiceTokenData) {
|
||||||
const { folderPath: secretPath } = getFolderWithPathFromId(folders, parentFolder.id);
|
const { folderPath: secretPath } = getFolderWithPathFromId(folders.nodes, parentFolder.id);
|
||||||
const isValidScopeAccess = isValidScope(req.authData.authPayload, environment, secretPath);
|
const isValidScopeAccess = isValidScope(req.authData.authPayload, environment, secretPath);
|
||||||
if (!isValidScopeAccess) {
|
if (!isValidScopeAccess) {
|
||||||
throw UnauthorizedRequestError({ message: "Folder Permission Denied" });
|
throw UnauthorizedRequestError({ message: "Folder Permission Denied" });
|
||||||
@@ -384,7 +370,7 @@ export const getFolders = async (req: Request, res: Response) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { folder, folderPath, dir } = getFolderWithPathFromId(folders, parentFolderId);
|
const { folder, folderPath, dir } = getFolderWithPathFromId(folders.nodes, parentFolderId);
|
||||||
if (req.authData.authPayload instanceof ServiceTokenData) {
|
if (req.authData.authPayload instanceof ServiceTokenData) {
|
||||||
const isValidScopeAccess = isValidScope(req.authData.authPayload, environment, folderPath);
|
const isValidScopeAccess = isValidScope(req.authData.authPayload, environment, folderPath);
|
||||||
if (!isValidScopeAccess) {
|
if (!isValidScopeAccess) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
import { Types } from "mongoose";
|
import { Types } from "mongoose";
|
||||||
import Folder, { TFolderRootSchema, TFolderSchema } from "../models/folder";
|
import Folder, { TFolderSchema } from "../models/folder";
|
||||||
import { ResourceNotFoundError } from "../utils/errors";
|
import path from "path";
|
||||||
|
|
||||||
type TAppendFolderDTO = {
|
type TAppendFolderDTO = {
|
||||||
folderName: string;
|
folderName: string;
|
||||||
@@ -59,7 +59,7 @@ const appendChild = (folders: TFolderSchema, folderName: string) => {
|
|||||||
id,
|
id,
|
||||||
name: folderName,
|
name: folderName,
|
||||||
children: [],
|
children: [],
|
||||||
version: 1,
|
version: 1
|
||||||
});
|
});
|
||||||
return { id, name: folderName };
|
return { id, name: folderName };
|
||||||
};
|
};
|
||||||
@@ -109,10 +109,7 @@ export const deleteFolderById = (folders: TFolderSchema, folderId: string) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// bfs but return parent of the folderID
|
// bfs but return parent of the folderID
|
||||||
export const getParentFromFolderId = (
|
export const getParentFromFolderId = (folders: TFolderSchema, folderId: string) => {
|
||||||
folders: TFolderSchema,
|
|
||||||
folderId: string
|
|
||||||
) => {
|
|
||||||
const queue = [folders];
|
const queue = [folders];
|
||||||
while (queue.length) {
|
while (queue.length) {
|
||||||
const folder = queue.pop() as TFolderSchema;
|
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
|
// 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
|
// 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
|
// We remove it from path recorded by using the total child record
|
||||||
export const searchByFolderIdWithDir = (
|
export const searchByFolderIdWithDir = (folders: TFolderSchema, folderId: string) => {
|
||||||
folders: TFolderSchema,
|
|
||||||
folderId: string
|
|
||||||
) => {
|
|
||||||
const stack = [folders];
|
const stack = [folders];
|
||||||
const dir: Array<{ id: string; name: string }> = [];
|
const dir: Array<{ id: string; name: string }> = [];
|
||||||
const hits: Record<string, number> = {};
|
const hits: Record<string, number> = {};
|
||||||
@@ -173,19 +167,19 @@ export const searchByFolderIdWithDir = (
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getFolderPath = (
|
// used for get folder path from id
|
||||||
folders: TFolderRootSchema,
|
export const getFolderWithPathFromId = (folders: TFolderSchema, parentFolderId: string) => {
|
||||||
folderId: string
|
const search = searchByFolderIdWithDir(folders, parentFolderId);
|
||||||
) => {
|
if (!search) {
|
||||||
const folderBySearch = searchByFolderIdWithDir(folders.nodes, folderId);
|
throw { message: "Folder permission denied" };
|
||||||
|
|
||||||
if (!folderBySearch) throw ResourceNotFoundError({
|
|
||||||
message: "Failed to find folder"
|
|
||||||
});
|
|
||||||
|
|
||||||
const folderPath = folderBySearch.dir.map((folder) => folder.name).join("/");
|
|
||||||
return folderPath;
|
|
||||||
}
|
}
|
||||||
|
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
|
// to get folder of a path given
|
||||||
// Like /frontend/folder#1
|
// Like /frontend/folder#1
|
||||||
@@ -216,7 +210,7 @@ export const getFolderIdFromServiceToken = async (
|
|||||||
) => {
|
) => {
|
||||||
const folders = await Folder.findOne({
|
const folders = await Folder.findOne({
|
||||||
workspace: workspaceId,
|
workspace: workspaceId,
|
||||||
environment,
|
environment
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!folders) {
|
if (!folders) {
|
||||||
|
|||||||
Reference in New Issue
Block a user