feat(infisical-pg): completed secret rollback

This commit is contained in:
Akhil Mohan
2024-01-27 12:38:23 +05:30
parent 784cdb4201
commit b5aa6c0000
57 changed files with 2017 additions and 453 deletions
@@ -19,7 +19,7 @@ import {
TUpdateFolderDTO
} from "./types";
const queryKeys = {
export const folderQueryKeys = {
getSecretFolders: ({ projectId, environment, path }: TGetProjectFoldersDTO) =>
["secret-folders", { projectId, environment, path }] as const
};
@@ -46,14 +46,14 @@ export const useGetProjectFolders = ({
TSecretFolder[],
unknown,
TSecretFolder[],
ReturnType<typeof queryKeys.getSecretFolders>
ReturnType<typeof folderQueryKeys.getSecretFolders>
>,
"queryKey" | "queryFn"
>;
}) =>
useQuery({
...options,
queryKey: queryKeys.getSecretFolders({ projectId, environment, path }),
queryKey: folderQueryKeys.getSecretFolders({ projectId, environment, path }),
enabled: Boolean(projectId) && Boolean(environment) && (options?.enabled ?? true),
queryFn: async () => fetchProjectFolders(projectId, environment, path)
});
@@ -65,7 +65,7 @@ export const useGetFoldersByEnv = ({
}: TGetFoldersByEnvDTO) => {
const folders = useQueries({
queries: environments.map((environment) => ({
queryKey: queryKeys.getSecretFolders({ projectId, environment, path }),
queryKey: folderQueryKeys.getSecretFolders({ projectId, environment, path }),
queryFn: async () => fetchProjectFolders(projectId, environment, path),
enabled: Boolean(projectId) && Boolean(environment)
}))
@@ -106,7 +106,9 @@ export const useCreateFolder = () => {
return data;
},
onSuccess: (_, { projectId, environment, path }) => {
queryClient.invalidateQueries(queryKeys.getSecretFolders({ projectId, environment, path }));
queryClient.invalidateQueries(
folderQueryKeys.getSecretFolders({ projectId, environment, path })
);
queryClient.invalidateQueries(
secretSnapshotKeys.list({ workspaceId: projectId, environment, directory: path })
);
@@ -131,7 +133,9 @@ export const useUpdateFolder = () => {
return data;
},
onSuccess: (_, { projectId, environment, path }) => {
queryClient.invalidateQueries(queryKeys.getSecretFolders({ projectId, environment, path }));
queryClient.invalidateQueries(
folderQueryKeys.getSecretFolders({ projectId, environment, path })
);
queryClient.invalidateQueries(
secretSnapshotKeys.list({ workspaceId: projectId, environment, directory: path })
);
@@ -157,7 +161,9 @@ export const useDeleteFolder = () => {
return data;
},
onSuccess: (_, { path = "/", projectId, environment }) => {
queryClient.invalidateQueries(queryKeys.getSecretFolders({ projectId, environment, path }));
queryClient.invalidateQueries(
folderQueryKeys.getSecretFolders({ projectId, environment, path })
);
queryClient.invalidateQueries(
secretSnapshotKeys.list({ workspaceId: projectId, environment, directory: path })
);
@@ -35,13 +35,13 @@ const fetchWorkspaceSnaphots = async ({
offset = 0
}: TGetSecretSnapshotsDTO & { offset: number }) => {
const res = await apiRequest.get<{ secretSnapshots: TSecretSnapshot[] }>(
`/api/v1/workspace/${workspaceId}/secret-snapshots`,
`/api/ee/v1/workspace/${workspaceId}/secret-snapshots`,
{
params: {
limit,
offset,
environment,
directory
path: directory
}
}
);
@@ -60,12 +60,12 @@ export const useGetWorkspaceSnapshotList = (dto: TGetSecretSnapshotsDTO & { isPa
const fetchSnapshotEncSecrets = async (snapshotId: string) => {
const res = await apiRequest.get<{ secretSnapshot: TSnapshotData }>(
`/api/v1/secret-snapshot/${snapshotId}`
`/api/ee/v1/secret-snapshot/${snapshotId}`
);
return res.data.secretSnapshot;
};
export const useGetSnapshotSecrets = ({ decryptFileKey, env, snapshotId }: TSnapshotDataProps) =>
export const useGetSnapshotSecrets = ({ decryptFileKey, snapshotId }: TSnapshotDataProps) =>
useQuery({
queryKey: secretSnapshotKeys.snapshotData(snapshotId),
enabled: Boolean(snapshotId && decryptFileKey),
@@ -82,45 +82,43 @@ export const useGetSnapshotSecrets = ({ decryptFileKey, env, snapshotId }: TSnap
const sharedSecrets: DecryptedSecret[] = [];
const personalSecrets: Record<string, { id: string; value: string }> = {};
data.secretVersions
.filter(({ environment }) => environment === env)
.forEach((encSecret) => {
const secretKey = decryptSymmetric({
ciphertext: encSecret.secretKeyCiphertext,
iv: encSecret.secretKeyIV,
tag: encSecret.secretKeyTag,
key
});
const secretValue = decryptSymmetric({
ciphertext: encSecret.secretValueCiphertext,
iv: encSecret.secretValueIV,
tag: encSecret.secretValueTag,
key
});
const secretComment = "";
const decryptedSecret = {
id: encSecret.secret,
env: encSecret.environment,
key: secretKey,
value: secretValue,
tags: encSecret.tags,
comment: secretComment,
createdAt: encSecret.createdAt,
updatedAt: encSecret.updatedAt,
type: "modified",
version: encSecret.version
};
if (encSecret.type === "personal") {
personalSecrets[decryptedSecret.key] = { id: encSecret.secret, value: secretValue };
} else {
sharedSecrets.push(decryptedSecret);
}
data.secretVersions.forEach((encSecret) => {
const secretKey = decryptSymmetric({
ciphertext: encSecret.secretKeyCiphertext,
iv: encSecret.secretKeyIV,
tag: encSecret.secretKeyTag,
key
});
const secretValue = decryptSymmetric({
ciphertext: encSecret.secretValueCiphertext,
iv: encSecret.secretValueIV,
tag: encSecret.secretValueTag,
key
});
const secretComment = "";
const decryptedSecret = {
id: encSecret.secretId,
env: data.environment.slug,
key: secretKey,
value: secretValue,
tags: encSecret.tags,
comment: secretComment,
createdAt: encSecret.createdAt,
updatedAt: encSecret.updatedAt,
type: "modified",
version: encSecret.version
};
if (encSecret.type === "personal") {
personalSecrets[decryptedSecret.key] = { id: encSecret.secretId, value: secretValue };
} else {
sharedSecrets.push(decryptedSecret);
}
});
sharedSecrets.forEach((val) => {
if (personalSecrets?.[val.key]) {
val.idOverride = personalSecrets[val.key].id;
@@ -130,7 +128,7 @@ export const useGetSnapshotSecrets = ({ decryptFileKey, env, snapshotId }: TSnap
});
return {
version: data.version,
id: data.id,
secrets: sharedSecrets,
createdAt: data.createdAt,
folders: data.folderVersion
@@ -144,11 +142,11 @@ const fetchWorkspaceSecretSnaphotCount = async (
directory = "/"
) => {
const res = await apiRequest.get<{ count: number }>(
`/api/v1/workspace/${workspaceId}/secret-snapshots/count`,
`/api/ee/v1/workspace/${workspaceId}/secret-snapshots/count`,
{
params: {
environment,
directory
path: directory
}
}
);
@@ -171,11 +169,8 @@ export const usePerformSecretRollback = () => {
const queryClient = useQueryClient();
return useMutation<{}, {}, TSecretRollbackDTO>({
mutationFn: async ({ workspaceId, ...dto }) => {
const { data } = await apiRequest.post(
`/api/v1/workspace/${workspaceId}/secret-snapshots/rollback`,
dto
);
mutationFn: async ({ snapshotId }) => {
const { data } = await apiRequest.post(`/api/ee/v1/secret-snapshot/${snapshotId}/rollback`);
return data;
},
onSuccess: (_, { workspaceId, environment, directory }) => {
@@ -183,6 +178,10 @@ export const usePerformSecretRollback = () => {
{ workspaceId, environment, secretPath: directory },
"secrets"
]);
queryClient.invalidateQueries([
"secret-folders",
{ projectId: workspaceId, environment, path: directory }
]);
queryClient.invalidateQueries(
secretSnapshotKeys.list({ workspaceId, environment, directory })
);
@@ -1,19 +1,20 @@
import { UserWsKeyPair } from "../keys/types";
import { EncryptedSecretVersion } from "../secrets/types";
import { WorkspaceEnv } from "../types";
export type TSecretSnapshot = {
id: string;
workspace: string;
version: number;
secretVersions: string[];
createdAt: string;
updatedAt: string;
__v: number;
};
export type TSnapshotData = Omit<TSecretSnapshot, "secretVersions"> & {
id: string;
secretVersions: EncryptedSecretVersion[];
folderVersion: Array<{ name: string; id: string }>;
environment: WorkspaceEnv;
};
export type TSnapshotDataProps = {
@@ -30,8 +31,8 @@ export type TGetSecretSnapshotsDTO = {
};
export type TSecretRollbackDTO = {
snapshotId: string;
workspaceId: string;
version: number;
environment: string;
directory?: string;
};
+2 -2
View File
@@ -46,12 +46,12 @@ export type DecryptedSecret = {
export type EncryptedSecretVersion = {
id: string;
secret: string;
secretId: string;
version: number;
workspace: string;
type: string;
environment: string;
isDeleted: boolean;
envId: string;
secretKeyCiphertext: string;
secretKeyIV: string;
secretKeyTag: string;
@@ -97,6 +97,7 @@ export const SnapshotView = ({
{}
);
const diffView: Array<TDiffView<DecryptedSecret>> = [];
console.log({ rollingSecrets, secrets });
rollingSecrets.forEach((rollSecret) => {
const { id } = rollSecret;
const doesExist = Boolean(secretGroupById?.[id]);
@@ -118,9 +119,9 @@ export const SnapshotView = ({
});
return diffView;
}, [secrets, rollingSecrets]);
console.log(secretDiffView);
const handleClickRollback = async () => {
if (!snapshotData?.version) {
if (!snapshotData?.id) {
createNotification({
text: "Failed to find secret version",
type: "success"
@@ -130,7 +131,7 @@ export const SnapshotView = ({
try {
await performRollback({
workspaceId,
version: snapshotData.version,
snapshotId: snapshotData.id,
environment,
directory: secretPath
});