feat(infisical-pg): completed root folder level secret, secret import and folder

This commit is contained in:
Akhil Mohan
2024-01-27 12:38:23 +05:30
parent 8a6ab7f2f6
commit 0e1191f2ea
70 changed files with 3105 additions and 278 deletions
+2 -1
View File
@@ -14,6 +14,7 @@ import {
TGetUserProjectPermissionDTO,
TOrgRole,
TPermission,
TProjectPermission,
TProjectRole
} from "./types";
@@ -50,7 +51,7 @@ const getProjectRoles = async (projectId: string) => {
}>(`/api/ee/v1/workspace/${projectId}/roles`);
return data.data.roles.map(({ permissions, ...el }) => ({
...el,
permissions: unpackRules(permissions as PackRule<TPermission>[])
permissions: unpackRules(permissions as PackRule<TProjectPermission>[])
}));
};
+3 -3
View File
@@ -10,7 +10,7 @@ export type TProjectRole = {
createdAt: string;
updatedAt: string;
description?: string;
permissions: TPermission[];
permissions: TProjectPermission[];
};
export type TOrgRole = {
@@ -67,13 +67,13 @@ export type TCreateProjectRoleDTO = {
name: string;
description?: string;
slug: string;
permissions: TPermission[];
permissions: TProjectPermission[];
};
export type TUpdateProjectRoleDTO = {
projectId: string;
id: string;
} & Partial<Omit<TCreateOrgRoleDTO, "orgId">>;
} & Partial<Omit<TCreateProjectRoleDTO, "orgId">>;
export type TDeleteProjectRoleDTO = {
projectId: string;
@@ -20,25 +20,25 @@ import {
} from "./types";
const queryKeys = {
getSecretFolders: ({ workspaceId, environment, directory }: TGetProjectFoldersDTO) =>
["secret-folders", { workspaceId, environment, directory }] as const
getSecretFolders: ({ projectId, environment, path }: TGetProjectFoldersDTO) =>
["secret-folders", { projectId, environment, path }] as const
};
const fetchProjectFolders = async (workspaceId: string, environment: string, directory = "/") => {
const fetchProjectFolders = async (projectId: string, environment: string, path = "/") => {
const { data } = await apiRequest.get<{ folders: TSecretFolder[] }>("/api/v1/folders", {
params: {
workspaceId,
projectId,
environment,
directory
path
}
});
return data.folders;
};
export const useGetProjectFolders = ({
workspaceId,
projectId,
environment,
directory = "/",
path = "/",
options = {}
}: TGetProjectFoldersDTO & {
options?: Omit<
@@ -53,21 +53,21 @@ export const useGetProjectFolders = ({
}) =>
useQuery({
...options,
queryKey: queryKeys.getSecretFolders({ workspaceId, environment, directory }),
enabled: Boolean(workspaceId) && Boolean(environment) && (options?.enabled ?? true),
queryFn: async () => fetchProjectFolders(workspaceId, environment, directory)
queryKey: queryKeys.getSecretFolders({ projectId, environment, path }),
enabled: Boolean(projectId) && Boolean(environment) && (options?.enabled ?? true),
queryFn: async () => fetchProjectFolders(projectId, environment, path)
});
export const useGetFoldersByEnv = ({
directory = "/",
workspaceId,
path = "/",
projectId,
environments
}: TGetFoldersByEnvDTO) => {
const folders = useQueries({
queries: environments.map((environment) => ({
queryKey: queryKeys.getSecretFolders({ workspaceId, environment, directory }),
queryFn: async () => fetchProjectFolders(workspaceId, environment, directory),
enabled: Boolean(workspaceId) && Boolean(environment)
queryKey: queryKeys.getSecretFolders({ projectId, environment, path }),
queryFn: async () => fetchProjectFolders(projectId, environment, path),
enabled: Boolean(projectId) && Boolean(environment)
}))
});
@@ -105,15 +105,13 @@ export const useCreateFolder = () => {
const { data } = await apiRequest.post("/api/v1/folders", dto);
return data;
},
onSuccess: (_, { workspaceId, environment, directory }) => {
onSuccess: (_, { projectId, environment, path }) => {
queryClient.invalidateQueries(queryKeys.getSecretFolders({ projectId, environment, path }));
queryClient.invalidateQueries(
queryKeys.getSecretFolders({ workspaceId, environment, directory })
secretSnapshotKeys.list({ workspaceId: projectId, environment, directory: path })
);
queryClient.invalidateQueries(
secretSnapshotKeys.list({ workspaceId, environment, directory })
);
queryClient.invalidateQueries(
secretSnapshotKeys.count({ workspaceId, environment, directory })
secretSnapshotKeys.count({ workspaceId: projectId, environment, directory: path })
);
}
});
@@ -123,24 +121,22 @@ export const useUpdateFolder = () => {
const queryClient = useQueryClient();
return useMutation<{}, {}, TUpdateFolderDTO>({
mutationFn: async ({ directory = "/", folderName, name, environment, workspaceId }) => {
const { data } = await apiRequest.patch(`/api/v1/folders/${folderName}`, {
mutationFn: async ({ path = "/", folderId, name, environment, projectId }) => {
const { data } = await apiRequest.patch(`/api/v1/folders/${folderId}`, {
name,
environment,
workspaceId,
directory
projectId,
path
});
return data;
},
onSuccess: (_, { workspaceId, environment, directory }) => {
onSuccess: (_, { projectId, environment, path }) => {
queryClient.invalidateQueries(queryKeys.getSecretFolders({ projectId, environment, path }));
queryClient.invalidateQueries(
queryKeys.getSecretFolders({ workspaceId, environment, directory })
secretSnapshotKeys.list({ workspaceId: projectId, environment, directory: path })
);
queryClient.invalidateQueries(
secretSnapshotKeys.list({ workspaceId, environment, directory })
);
queryClient.invalidateQueries(
secretSnapshotKeys.count({ workspaceId, environment, directory })
secretSnapshotKeys.count({ workspaceId: projectId, environment, directory: path })
);
}
});
@@ -150,25 +146,23 @@ export const useDeleteFolder = () => {
const queryClient = useQueryClient();
return useMutation<{}, {}, TDeleteFolderDTO>({
mutationFn: async ({ directory = "/", folderName, environment, workspaceId }) => {
const { data } = await apiRequest.delete(`/api/v1/folders/${folderName}`, {
mutationFn: async ({ path = "/", folderId, environment, projectId }) => {
const { data } = await apiRequest.delete(`/api/v1/folders/${folderId}`, {
data: {
environment,
workspaceId,
directory
projectId,
path
}
});
return data;
},
onSuccess: (_, { directory = "/", workspaceId, environment }) => {
onSuccess: (_, { path = "/", projectId, environment }) => {
queryClient.invalidateQueries(queryKeys.getSecretFolders({ projectId, environment, path }));
queryClient.invalidateQueries(
queryKeys.getSecretFolders({ workspaceId, environment, directory })
secretSnapshotKeys.list({ workspaceId: projectId, environment, directory: path })
);
queryClient.invalidateQueries(
secretSnapshotKeys.list({ workspaceId, environment, directory })
);
queryClient.invalidateQueries(
secretSnapshotKeys.count({ workspaceId, environment, directory })
secretSnapshotKeys.count({ workspaceId: projectId, environment, directory: path })
);
}
});
+13 -13
View File
@@ -4,35 +4,35 @@ export type TSecretFolder = {
};
export type TGetProjectFoldersDTO = {
workspaceId: string;
projectId: string;
environment: string;
directory?: string;
path?: string;
};
export type TGetFoldersByEnvDTO = {
environments: string[];
workspaceId: string;
directory?: string;
projectId: string;
path?: string;
};
export type TCreateFolderDTO = {
workspaceId: string;
projectId: string;
environment: string;
folderName: string;
directory?: string;
name: string;
path?: string;
};
export type TUpdateFolderDTO = {
workspaceId: string;
projectId: string;
environment: string;
name: string;
folderName: string;
directory?: string;
folderId: string;
path?: string;
};
export type TDeleteFolderDTO = {
workspaceId: string;
projectId: string;
environment: string;
folderName: string;
directory?: string;
folderId: string;
path?: string;
};
@@ -9,21 +9,21 @@ export const useCreateSecretImport = () => {
const queryClient = useQueryClient();
return useMutation<{}, {}, TCreateSecretImportDTO>({
mutationFn: async ({ secretImport, environment, workspaceId, directory }) => {
mutationFn: async ({ import: secretImport, environment, projectId, path }) => {
const { data } = await apiRequest.post("/api/v1/secret-imports", {
secretImport,
import: secretImport,
environment,
workspaceId,
directory
projectId,
path
});
return data;
},
onSuccess: (_, { workspaceId, environment, directory }) => {
onSuccess: (_, { environment, projectId, path }) => {
queryClient.invalidateQueries(
secretImportKeys.getProjectSecretImports({ workspaceId, environment, directory })
secretImportKeys.getProjectSecretImports({ projectId, environment, path })
);
queryClient.invalidateQueries(
secretImportKeys.getSecretImportSecrets({ workspaceId, environment, directory })
secretImportKeys.getSecretImportSecrets({ projectId, environment, path })
);
}
});
@@ -33,21 +33,21 @@ export const useUpdateSecretImport = () => {
const queryClient = useQueryClient();
return useMutation<{}, {}, TUpdateSecretImportDTO>({
mutationFn: async ({ environment, workspaceId, directory, secretImports, id }) => {
const { data } = await apiRequest.put(`/api/v1/secret-imports/${id}`, {
secretImports,
mutationFn: async ({ environment, import: secretImports, projectId, path, id }) => {
const { data } = await apiRequest.patch(`/api/v1/secret-imports/${id}`, {
import: secretImports,
environment,
workspaceId,
directory
path,
projectId
});
return data;
},
onSuccess: (_, { workspaceId, environment, directory }) => {
onSuccess: (_, { environment, projectId, path }) => {
queryClient.invalidateQueries(
secretImportKeys.getProjectSecretImports({ workspaceId, environment, directory })
secretImportKeys.getProjectSecretImports({ projectId, path, environment })
);
queryClient.invalidateQueries(
secretImportKeys.getSecretImportSecrets({ workspaceId, environment, directory })
secretImportKeys.getSecretImportSecrets({ environment, path, projectId })
);
}
});
@@ -57,21 +57,22 @@ export const useDeleteSecretImport = () => {
const queryClient = useQueryClient();
return useMutation<{}, {}, TDeleteSecretImportDTO>({
mutationFn: async ({ id, secretImportEnv, secretImportPath }) => {
mutationFn: async ({ id, projectId, path, environment }) => {
const { data } = await apiRequest.delete(`/api/v1/secret-imports/${id}`, {
data: {
secretImportPath,
secretImportEnv
projectId,
path,
environment
}
});
return data;
},
onSuccess: (_, { workspaceId, environment, directory }) => {
onSuccess: (_, { projectId, environment, path }) => {
queryClient.invalidateQueries(
secretImportKeys.getProjectSecretImports({ workspaceId, environment, directory })
secretImportKeys.getProjectSecretImports({ projectId, environment, path })
);
queryClient.invalidateQueries(
secretImportKeys.getSecretImportSecrets({ workspaceId, environment, directory })
secretImportKeys.getSecretImportSecrets({ projectId, environment, path })
);
}
});
@@ -7,44 +7,44 @@ import {
} from "@app/components/utilities/cryptography/crypto";
import { apiRequest } from "@app/config/request";
import { TGetImportedSecrets, TGetSecretImports, TImportedSecrets, TSecretImports } from "./types";
import { TGetImportedSecrets, TGetSecretImports, TImportedSecrets, TSecretImport } from "./types";
export const secretImportKeys = {
getProjectSecretImports: ({ environment, workspaceId, directory }: TGetSecretImports) =>
[{ workspaceId, directory, environment }, "secrets-imports"] as const,
getProjectSecretImports: ({ environment, projectId, path }: TGetSecretImports) =>
[{ projectId, path, environment }, "secrets-imports"] as const,
getSecretImportSecrets: ({
workspaceId,
environment,
directory
projectId,
path
}: Omit<TGetImportedSecrets, "decryptFileKey">) =>
[{ workspaceId, environment, directory }, "secrets-import-sec"] as const
[{ environment, path, projectId }, "secrets-import-sec"] as const
};
const fetchSecretImport = async ({ workspaceId, environment, directory }: TGetSecretImports) => {
const { data } = await apiRequest.get<{ secretImport: TSecretImports }>(
const fetchSecretImport = async ({ projectId, environment, path = "/" }: TGetSecretImports) => {
const { data } = await apiRequest.get<{ secretImports: TSecretImport[] }>(
"/api/v1/secret-imports",
{
params: {
workspaceId,
projectId,
environment,
directory
path
}
}
);
return data.secretImport;
return data.secretImports;
};
export const useGetSecretImports = ({
workspaceId,
environment,
directory = "/",
path = "/",
projectId,
options = {}
}: TGetSecretImports & {
options?: Omit<
UseQueryOptions<
TSecretImports,
TSecretImport[],
unknown,
TSecretImports,
TSecretImport[],
ReturnType<typeof secretImportKeys.getProjectSecretImports>
>,
"queryKey" | "queryFn"
@@ -52,9 +52,9 @@ export const useGetSecretImports = ({
}) =>
useQuery({
...options,
queryKey: secretImportKeys.getProjectSecretImports({ workspaceId, environment, directory }),
enabled: Boolean(workspaceId) && Boolean(environment) && (options?.enabled ?? true),
queryFn: () => fetchSecretImport({ workspaceId, environment, directory })
queryKey: secretImportKeys.getProjectSecretImports({ environment, projectId, path }),
enabled: Boolean(projectId) && Boolean(environment) && (options?.enabled ?? true),
queryFn: () => fetchSecretImport({ path, projectId, environment })
});
const fetchImportedSecrets = async (
@@ -76,10 +76,10 @@ const fetchImportedSecrets = async (
};
export const useGetImportedSecrets = ({
workspaceId,
environment,
decryptFileKey,
directory,
path,
projectId,
options = {}
}: TGetImportedSecrets & {
options?: Omit<
@@ -94,16 +94,16 @@ export const useGetImportedSecrets = ({
}) =>
useQuery({
enabled:
Boolean(workspaceId) &&
Boolean(projectId) &&
Boolean(environment) &&
Boolean(decryptFileKey) &&
(options?.enabled ?? true),
queryKey: secretImportKeys.getSecretImportSecrets({
workspaceId,
environment,
directory
path,
projectId
}),
queryFn: () => fetchImportedSecrets(workspaceId, environment, directory),
queryFn: () => fetchImportedSecrets(projectId, environment, path),
select: useCallback(
(data: TImportedSecrets[]) => {
const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY") as string;
+23 -20
View File
@@ -1,12 +1,16 @@
import { UserWsKeyPair } from "../keys/types";
import { EncryptedSecret } from "../secrets/types";
export type TSecretImports = {
export type TSecretImport = {
id: string;
workspaceId: string;
environment: string;
folderId: string;
imports: Array<{ environment: string; secretPath: string }>;
importPath: string;
importEnv: {
name: string;
slug: string;
id: string;
};
position: string;
createdAt: string;
updatedAt: string;
};
@@ -19,44 +23,43 @@ export type TImportedSecrets = {
};
export type TGetSecretImports = {
workspaceId: string;
projectId: string;
environment: string;
directory?: string;
path?: string;
};
export type TGetImportedSecrets = {
workspaceId: string;
projectId: string;
environment: string;
directory?: string;
path?: string;
decryptFileKey: UserWsKeyPair;
};
export type TCreateSecretImportDTO = {
workspaceId: string;
projectId: string;
environment: string;
directory?: string;
secretImport: {
path?: string;
import: {
environment: string;
secretPath: string;
path: string;
};
};
export type TUpdateSecretImportDTO = {
id: string;
workspaceId: string;
projectId: string;
environment: string;
directory?: string;
secretImports: Array<{
path?: string;
import: Partial<{
environment: string;
secretPath: string;
path: string;
position: number;
}>;
};
export type TDeleteSecretImportDTO = {
id: string;
workspaceId: string;
projectId: string;
environment: string;
directory?: string;
secretImportPath: string;
secretImportEnv: string;
path?: string;
};
+1 -1
View File
@@ -12,7 +12,7 @@ export type {
} from "./secretApprovalRequest/types";
export { ApprovalStatus, CommitType } from "./secretApprovalRequest/types";
export type { TSecretFolder } from "./secretFolders/types";
export type { TImportedSecrets, TSecretImports } from "./secretImports/types";
export type { TImportedSecrets, TSecretImport } from "./secretImports/types";
export type {
TGetSecretRotationProviders,
TProviderTemplate,