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.
+
+
+
+ );
+};