Merge remote-tracking branch 'origin/main' into feat/add-version-limits

This commit is contained in:
Sheen Capadngan
2024-06-08 01:37:14 +08:00
126 changed files with 3741 additions and 729 deletions
@@ -169,6 +169,7 @@ const sqlFindSecretPathByFolderId = (db: Knex, projectId: string, folderIds: str
// this is for root condition
// if the given folder id is root folder id then intial path is set as / instead of /root
// if not root folder the path here will be /<folder name>
depth: 1,
path: db.raw(`CONCAT('/', (CASE WHEN "parentId" is NULL THEN '' ELSE ${TableName.SecretFolder}.name END))`),
child: db.raw("NULL::uuid"),
environmentSlug: `${TableName.Environment}.slug`
@@ -185,6 +186,7 @@ const sqlFindSecretPathByFolderId = (db: Knex, projectId: string, folderIds: str
.select({
// then we join join this folder name behind previous as we are going from child to parent
// the root folder check is used to avoid last / and also root name in folders
depth: db.raw("parent.depth + 1"),
path: db.raw(
`CONCAT( CASE
WHEN ${TableName.SecretFolder}."parentId" is NULL THEN ''
@@ -199,7 +201,7 @@ const sqlFindSecretPathByFolderId = (db: Knex, projectId: string, folderIds: str
);
})
.select("*")
.from<TSecretFolders & { child: string | null; path: string; environmentSlug: string }>("parent");
.from<TSecretFolders & { child: string | null; path: string; environmentSlug: string; depth: number }>("parent");
export type TSecretFolderDALFactory = ReturnType<typeof secretFolderDALFactory>;
// never change this. If u do write a migration for it
@@ -260,12 +262,23 @@ export const secretFolderDALFactory = (db: TDbClient) => {
try {
const folders = await sqlFindSecretPathByFolderId(tx || db, projectId, folderIds);
// travelling all the way from leaf node to root contains real path
const rootFolders = groupBy(
folders.filter(({ parentId }) => parentId === null),
(i) => i.child || i.id // root condition then child and parent will null
);
const actualFolders = groupBy(
folders.filter(({ depth }) => depth === 1),
(i) => i.id // root condition then child and parent will null
);
return folderIds.map((folderId) => rootFolders[folderId]?.[0]);
return folderIds.map((folderId) => {
if (!rootFolders[folderId]?.[0]) return;
const actualId = rootFolders[folderId][0].child || rootFolders[folderId][0].id;
const folder = actualFolders[actualId][0];
return { ...folder, path: rootFolders[folderId]?.[0].path };
});
} catch (error) {
throw new DatabaseError({ error, name: "Find by secret path" });
}
@@ -253,7 +253,7 @@ export const secretFolderServiceFactory = ({
const env = await projectEnvDAL.findOne({ projectId, slug: environment });
if (!env) throw new BadRequestError({ message: "Environment not found", name: "Update folder" });
const folder = await folderDAL
.findOne({ envId: env.id, id, parentId: parentFolder.id })
.findOne({ envId: env.id, id, parentId: parentFolder.id, isReserved: false })
// now folder api accepts id based change
// this is for cli backward compatiability and when cli removes this, we will remove this logic
.catch(() => folderDAL.findOne({ envId: env.id, name: id, parentId: parentFolder.id }));
@@ -276,7 +276,11 @@ export const secretFolderServiceFactory = ({
}
const newFolder = await folderDAL.transaction(async (tx) => {
const [doc] = await folderDAL.update({ envId: env.id, id: folder.id, parentId: parentFolder.id }, { name }, tx);
const [doc] = await folderDAL.update(
{ envId: env.id, id: folder.id, parentId: parentFolder.id, isReserved: false },
{ name },
tx
);
await folderVersionDAL.create(
{
name: doc.name,
@@ -324,7 +328,12 @@ export const secretFolderServiceFactory = ({
if (!parentFolder) throw new BadRequestError({ message: "Secret path not found" });
const [doc] = await folderDAL.delete(
{ envId: env.id, [uuidValidate(idOrName) ? "id" : "name"]: idOrName, parentId: parentFolder.id },
{
envId: env.id,
[uuidValidate(idOrName) ? "id" : "name"]: idOrName,
parentId: parentFolder.id,
isReserved: false
},
tx
);
if (!doc) throw new BadRequestError({ message: "Folder not found", name: "Delete folder" });
@@ -354,7 +363,7 @@ export const secretFolderServiceFactory = ({
const parentFolder = await folderDAL.findBySecretPath(projectId, environment, secretPath);
if (!parentFolder) return [];
const folders = await folderDAL.find({ envId: env.id, parentId: parentFolder.id });
const folders = await folderDAL.find({ envId: env.id, parentId: parentFolder.id, isReserved: false });
return folders;
};
@@ -1,5 +1,9 @@
import { TProjectPermission } from "@app/lib/types";
export enum ReservedFolders {
SecretReplication = "__reserve_replication_"
}
export type TCreateFolderDTO = {
environment: string;
path: string;
@@ -15,7 +15,7 @@ export const secretFolderVersionDALFactory = (db: TDbClient) => {
try {
const docs = await (tx || db)(TableName.SecretFolderVersion)
.join(TableName.SecretFolder, `${TableName.SecretFolderVersion}.folderId`, `${TableName.SecretFolder}.id`)
.where({ parentId: folderId })
.where({ parentId: folderId, isReserved: false })
.join<TSecretFolderVersions>(
(tx || db)(TableName.SecretFolderVersion)
.groupBy("envId", "folderId")