diff --git a/backend/src/services/secret-blind-index/secret-blind-index-dal.ts b/backend/src/services/secret-blind-index/secret-blind-index-dal.ts index 8fa60cde7..825dea3a7 100644 --- a/backend/src/services/secret-blind-index/secret-blind-index-dal.ts +++ b/backend/src/services/secret-blind-index/secret-blind-index-dal.ts @@ -30,7 +30,6 @@ export const secretBlindIndexDALFactory = (db: TDbClient) => { .leftJoin(TableName.SecretFolder, `${TableName.SecretFolder}.id`, `${TableName.Secret}.folderId`) .leftJoin(TableName.Environment, `${TableName.Environment}.id`, `${TableName.SecretFolder}.envId`) .where({ projectId }) - .whereNull("secretBlindIndex") .select(selectAllTableCols(TableName.Secret)) .select( db.ref("slug").withSchema(TableName.Environment).as("environment"), @@ -49,7 +48,6 @@ export const secretBlindIndexDALFactory = (db: TDbClient) => { .leftJoin(TableName.Environment, `${TableName.Environment}.id`, `${TableName.SecretFolder}.envId`) .where({ projectId }) .whereIn(`${TableName.Secret}.id`, secretIds) - .whereNull("secretBlindIndex") .select(selectAllTableCols(TableName.Secret)) .select( db.ref("slug").withSchema(TableName.Environment).as("environment"), diff --git a/frontend/src/views/Settings/ProjectSettingsPage/components/ProjectGeneralTab/ProjectGeneralTab.tsx b/frontend/src/views/Settings/ProjectSettingsPage/components/ProjectGeneralTab/ProjectGeneralTab.tsx index 511dff93e..bdbd41c1c 100644 --- a/frontend/src/views/Settings/ProjectSettingsPage/components/ProjectGeneralTab/ProjectGeneralTab.tsx +++ b/frontend/src/views/Settings/ProjectSettingsPage/components/ProjectGeneralTab/ProjectGeneralTab.tsx @@ -5,6 +5,7 @@ import { E2EESection } from "../E2EESection"; import { EnvironmentSection } from "../EnvironmentSection"; import { PointInTimeVersionLimitSection } from "../PointInTimeVersionLimitSection"; import { ProjectNameChangeSection } from "../ProjectNameChangeSection"; +import { RebuildSecretIndicesSection } from "../RebuildSecretIndicesSection/RebuildSecretIndicesSection"; import { SecretTagsSection } from "../SecretTagsSection"; export const ProjectGeneralTab = () => { @@ -17,6 +18,7 @@ export const ProjectGeneralTab = () => { + ); diff --git a/frontend/src/views/Settings/ProjectSettingsPage/components/RebuildSecretIndicesSection/RebuildSecretIndicesSection.tsx b/frontend/src/views/Settings/ProjectSettingsPage/components/RebuildSecretIndicesSection/RebuildSecretIndicesSection.tsx new file mode 100644 index 000000000..23c495074 --- /dev/null +++ b/frontend/src/views/Settings/ProjectSettingsPage/components/RebuildSecretIndicesSection/RebuildSecretIndicesSection.tsx @@ -0,0 +1,93 @@ +import { createNotification } from "@app/components/notifications"; +import { + decryptAssymmetric, + decryptSymmetric +} from "@app/components/utilities/cryptography/crypto"; +import { Button } from "@app/components/v2"; +import { useProjectPermission, useWorkspace } from "@app/context"; +import { useToggle } from "@app/hooks"; +import { useGetUserWsKey, useNameWorkspaceSecrets } from "@app/hooks/api"; +import { ProjectMembershipRole } from "@app/hooks/api/roles/types"; +import { fetchWorkspaceSecrets } from "@app/hooks/api/workspace/queries"; + +export const RebuildSecretIndicesSection = () => { + const { currentWorkspace } = useWorkspace(); + const { membership } = useProjectPermission(); + const nameWorkspaceSecrets = useNameWorkspaceSecrets(); + + const [isIndexing, setIsIndexing] = useToggle(); + const { data: decryptFileKey } = useGetUserWsKey(currentWorkspace?.id!); + + if (!currentWorkspace) return null; + + const onRebuildIndices = async () => { + if (!currentWorkspace?.id) return; + setIsIndexing.on(); + try { + const encryptedSecrets = await fetchWorkspaceSecrets(currentWorkspace.id); + + if (!currentWorkspace || !decryptFileKey) { + return; + } + + const key = decryptAssymmetric({ + ciphertext: decryptFileKey.encryptedKey, + nonce: decryptFileKey.nonce, + publicKey: decryptFileKey.sender.publicKey, + privateKey: localStorage.getItem("PRIVATE_KEY") as string + }); + + const secretsToUpdate = encryptedSecrets.map((encryptedSecret) => { + const secretName = decryptSymmetric({ + ciphertext: encryptedSecret.secretKeyCiphertext, + iv: encryptedSecret.secretKeyIV, + tag: encryptedSecret.secretKeyTag, + key + }); + + return { + secretName, + secretId: encryptedSecret.id + }; + }); + await nameWorkspaceSecrets.mutateAsync({ + workspaceId: currentWorkspace.id, + secretsToUpdate + }); + + createNotification({ + text: "Successfully rebuilt secret indices", + type: "success" + }); + } catch (err) { + console.log(err); + } finally { + setIsIndexing.off(); + } + }; + + const isAdmin = membership.roles.includes(ProjectMembershipRole.Admin); + + if (!isAdmin) { + return null; + } + + return ( +
+
+

Rebuild Secret Indices

+
+

+ This will rebuild indices of all secrets in the project. +

+ +
+ ); +};