From 1e857c04b72890d981221971a1a3cb055391db8c Mon Sep 17 00:00:00 2001 From: Victor Santos Date: Tue, 4 Nov 2025 14:40:33 -0300 Subject: [PATCH 01/12] feat: add segment click handling in SecretInput and InfisicalSecretInput components --- .../InfisicalSecretInput.tsx | 37 ++++++++ .../components/v2/SecretInput/SecretInput.tsx | 94 +++++++++++++++++-- .../SecretDashboardPage.tsx | 21 ++++- .../SecretDashboardPage/route.tsx | 3 +- 4 files changed, 143 insertions(+), 12 deletions(-) diff --git a/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx b/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx index 9c4dc0b83..07d07dd4d 100644 --- a/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx +++ b/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx @@ -3,6 +3,7 @@ import { faFolder, faKey, faLayerGroup, faSearch } from "@fortawesome/free-solid import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import * as Popover from "@radix-ui/react-popover"; +import { ROUTE_PATHS } from "@app/const/routes"; import { useProject } from "@app/context"; import { useDebounce, useToggle } from "@app/hooks"; import { useGetProjectFolders, useGetProjectSecrets } from "@app/hooks/api"; @@ -307,6 +308,41 @@ export const InfisicalSecretInput = forwardRef( } }, []); + const handleClickSegment = useCallback( + (segment: string, allSegments: string[]) => { + // Single segment: search in current environment and path + if (allSegments.length === 1) { + const currentEnv = propEnvironment || ""; + const currentPath = propSecretPath || "/"; + const encodedPath = encodeURIComponent(currentPath); + const url = ROUTE_PATHS.SecretManager.SecretDashboardPage.path + .replace("$projectId", projectId) + .replace("$envSlug", currentEnv); + window.open( + `${url}?secretPath=${encodedPath}&search=${encodeURIComponent(segment)}&filterBy=secret`, + "_blank", + "noopener,noreferrer" + ); + return; + } + + // Multiple segments: first is env, last is secret, middle are folders + const environmentSlug = allSegments[0]; + const secretName = allSegments[allSegments.length - 1]; + const folderPath = allSegments.length > 2 ? `/${allSegments.slice(1, -1).join("/")}` : "/"; + const encodedPath = encodeURIComponent(folderPath); + const url = ROUTE_PATHS.SecretManager.SecretDashboardPage.path + .replace("$projectId", projectId) + .replace("$envSlug", environmentSlug); + window.open( + `${url}?secretPath=${encodedPath}&search=${encodeURIComponent(secretName)}&filterBy=secret`, + "_blank", + "noopener,noreferrer" + ); + }, + [projectId, propEnvironment, propSecretPath] + ); + return ( @@ -329,6 +365,7 @@ export const InfisicalSecretInput = forwardRef( }} onChange={(e) => onChange?.(e.target.value)} containerClassName={containerClassName} + onClickSegment={handleClickSegment} /> void, + hoveredPart?: string, + isCmdOrCtrlPressed?: boolean, + onClickSegment?: (segment: string, allSegments: string[]) => void ) => { if (isLoadingValue) return HIDDEN_SECRET_VALUE; if (isErrorLoadingValue) @@ -27,10 +31,51 @@ const syntaxHighlight = ( const isInterpolationSyntax = el.startsWith("${") && el.endsWith("}"); if (isInterpolationSyntax) { skipNext = true; + const part = el; + const innerContent = el.slice(2, -1); // Remove ${ and } + const parts = innerContent.split("."); + return ( - + ${ - {el.slice(2, -1)} + {parts.map((segment, segmentIndex) => { + const segmentKey = `${part}-segment-${segmentIndex}`; + const isHovered = hoveredPart === segmentKey; + const shouldShowHoverStyle = isHovered && isCmdOrCtrlPressed; + + return ( + + onHoverPart?.(segmentKey)} + onMouseLeave={() => onHoverPart?.("")} + onClick={(e) => { + if (isCmdOrCtrlPressed) { + e.preventDefault(); + e.stopPropagation(); + onClickSegment?.(segment, parts); + } + }} + onKeyDown={(e) => { + if (isCmdOrCtrlPressed && (e.key === "Enter" || e.key === " ")) { + e.preventDefault(); + e.stopPropagation(); + onClickSegment?.(segment, parts); + } + }} + > + {segment} + + {segmentIndex < parts.length - 1 && ( + . + )} + + ); + })} } ); @@ -60,6 +105,7 @@ type Props = TextareaHTMLAttributes & { canEditButNotView?: boolean; isLoadingValue?: boolean; isErrorLoadingValue?: boolean; + onClickSegment?: (segment: string, allSegments: string[]) => void; }; const commonClassName = "font-mono text-sm caret-white border-none outline-hidden w-full break-all"; @@ -79,11 +125,36 @@ export const SecretInput = forwardRef( canEditButNotView, isLoadingValue, isErrorLoadingValue, + onClickSegment, ...props }, ref ) => { const [isSecretFocused, setIsSecretFocused] = useToggle(); + const [hoveredPart, setHoveredPart] = useState(); + const [isCmdOrCtrlPressed, setIsCmdOrCtrlPressed] = useState(false); + + useEffect(() => { + const handleKeyDown = (e: KeyboardEvent) => { + if (e.metaKey || e.ctrlKey) { + setIsCmdOrCtrlPressed(true); + } + }; + + const handleKeyUp = (e: KeyboardEvent) => { + if (!e.metaKey && !e.ctrlKey) { + setIsCmdOrCtrlPressed(false); + } + }; + + window.addEventListener("keydown", handleKeyDown); + window.addEventListener("keyup", handleKeyUp); + + return () => { + window.removeEventListener("keydown", handleKeyDown); + window.removeEventListener("keyup", handleKeyUp); + }; + }, []); return (
( style={{ maxHeight: `${21 * 7}px` }} >
-
+          
             
               
                 {syntaxHighlight(
@@ -99,7 +170,13 @@ export const SecretInput = forwardRef(
                   isVisible || (isSecretFocused && !valueAlwaysHidden),
                   isImport,
                   isLoadingValue,
-                  isErrorLoadingValue
+                  isErrorLoadingValue,
+                  (part) => {
+                    setHoveredPart(part);
+                  },
+                  hoveredPart,
+                  isCmdOrCtrlPressed,
+                  onClickSegment
                 )}
               
             
@@ -128,6 +205,9 @@ export const SecretInput = forwardRef(
               onBlur?.(evt);
               setIsSecretFocused.off();
             }}
+            onMouseLeave={() => {
+              setHoveredPart(undefined);
+            }}
             value={value || ""}
             {...props}
             readOnly={isReadOnly || isLoadingValue || isErrorLoadingValue}
diff --git a/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx b/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx
index a2ee814f8..74ad462e4 100644
--- a/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx
+++ b/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx
@@ -534,7 +534,7 @@ const Page = () => {
   }, [secretPath]);
 
   useEffect(() => {
-    if (!routerQueryParams.search && !routerQueryParams.tags) return;
+    if (!routerQueryParams.search && !routerQueryParams.tags && !routerQueryParams.filterBy) return;
 
     const queryTags = routerQueryParams.tags
       ? (routerQueryParams.tags as string).split(",").filter((tag) => Boolean(tag.trim()))
@@ -544,21 +544,34 @@ const Page = () => {
       updatedTags[tag] = true;
     });
 
+    const filterBy = routerQueryParams.filterBy
+      ? (routerQueryParams.filterBy as string).split(",").filter(Boolean)
+      : [];
+
+    const includeFilter: Record = {
+      [RowType.Folder]: filterBy.includes("folder"),
+      [RowType.Import]: filterBy.includes("import"),
+      [RowType.DynamicSecret]: filterBy.includes("dynamic"),
+      [RowType.Secret]: filterBy.includes("secret"),
+      [RowType.SecretRotation]: filterBy.includes("rotation")
+    };
+
     setFilter((prev) => ({
       ...prev,
       ...defaultFilterState,
       searchFilter: (routerQueryParams.search as string) ?? "",
-      tags: updatedTags
+      tags: updatedTags,
+      include: includeFilter
     }));
     setDebouncedSearchFilter(routerQueryParams.search as string);
     // this is a temp workaround until we fully transition state to query params,
     navigate({
       search: (state) => {
-        const { search, tags: qTags, ...query } = state;
+        const { search, tags: qTags, filterBy: qFilterBy, ...query } = state;
         return query;
       }
     });
-  }, [routerQueryParams.search, routerQueryParams.tags]);
+  }, [routerQueryParams.search, routerQueryParams.tags, routerQueryParams.filterBy]);
 
   const selectedSecrets = useSelectedSecrets();
   const selectedSecretActions = useSelectedSecretActions();
diff --git a/frontend/src/pages/secret-manager/SecretDashboardPage/route.tsx b/frontend/src/pages/secret-manager/SecretDashboardPage/route.tsx
index 0700b3322..da48a04f0 100644
--- a/frontend/src/pages/secret-manager/SecretDashboardPage/route.tsx
+++ b/frontend/src/pages/secret-manager/SecretDashboardPage/route.tsx
@@ -11,6 +11,7 @@ const SecretDashboardPageQueryParamsSchema = z.object({
   secretPath: z.string().catch("/"),
   search: z.string().catch(""),
   tags: z.string().catch(""),
+  filterBy: z.string().catch(""),
   connectionId: z.string().optional(),
   connectionName: z.string().optional()
 });
@@ -20,7 +21,7 @@ export const Route = createFileRoute(
   component: SecretDashboardPage,
   validateSearch: zodValidator(SecretDashboardPageQueryParamsSchema),
   search: {
-    middlewares: [stripSearchParams({ secretPath: "/", search: "", tags: "" })]
+    middlewares: [stripSearchParams({ secretPath: "/", search: "", tags: "", filterBy: "" })]
   },
   beforeLoad: ({ context, params, search }) => {
     const secretPathSegments = search.secretPath.split("/").filter(Boolean);

From 4d974db485458d96c8cdbc9e9ac358c3e322d38e Mon Sep 17 00:00:00 2001
From: Victor Santos 
Date: Tue, 4 Nov 2025 16:15:23 -0300
Subject: [PATCH 02/12] feat: enhance navigation and URL state management in
 SecretDashboardPage and input components

---
 .../InfisicalSecretInput.tsx                  | 62 +++++++++-------
 .../components/v2/SecretInput/SecretInput.tsx |  8 ++-
 .../SecretDashboardPage.tsx                   | 70 ++++++++++++++-----
 3 files changed, 96 insertions(+), 44 deletions(-)

diff --git a/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx b/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx
index 07d07dd4d..98f42923a 100644
--- a/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx
+++ b/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx
@@ -2,6 +2,7 @@ import { forwardRef, TextareaHTMLAttributes, useCallback, useMemo, useRef, useSt
 import { faFolder, faKey, faLayerGroup, faSearch } from "@fortawesome/free-solid-svg-icons";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import * as Popover from "@radix-ui/react-popover";
+import { useNavigate } from "@tanstack/react-router";
 
 import { ROUTE_PATHS } from "@app/const/routes";
 import { useProject } from "@app/context";
@@ -81,6 +82,7 @@ export const InfisicalSecretInput = forwardRef(
   ) => {
     const { currentProject } = useProject();
     const projectId = currentProject?.id || "";
+    const navigate = useNavigate({ from: ROUTE_PATHS.SecretManager.SecretDashboardPage.path });
 
     const [debouncedValue] = useDebounce(value, 100);
 
@@ -310,37 +312,49 @@ export const InfisicalSecretInput = forwardRef(
 
     const handleClickSegment = useCallback(
       (segment: string, allSegments: string[]) => {
-        // Single segment: search in current environment and path
         if (allSegments.length === 1) {
-          const currentEnv = propEnvironment || "";
-          const currentPath = propSecretPath || "/";
-          const encodedPath = encodeURIComponent(currentPath);
-          const url = ROUTE_PATHS.SecretManager.SecretDashboardPage.path
-            .replace("$projectId", projectId)
-            .replace("$envSlug", currentEnv);
-          window.open(
-            `${url}?secretPath=${encodedPath}&search=${encodeURIComponent(segment)}&filterBy=secret`,
-            "_blank",
-            "noopener,noreferrer"
-          );
+          navigate({
+            search: (prev) => ({
+              ...prev,
+              search: segment,
+              filterBy: "secret"
+            })
+          });
           return;
         }
 
-        // Multiple segments: first is env, last is secret, middle are folders
         const environmentSlug = allSegments[0];
         const secretName = allSegments[allSegments.length - 1];
-        const folderPath = allSegments.length > 2 ? `/${allSegments.slice(1, -1).join("/")}` : "/";
-        const encodedPath = encodeURIComponent(folderPath);
-        const url = ROUTE_PATHS.SecretManager.SecretDashboardPage.path
-          .replace("$projectId", projectId)
-          .replace("$envSlug", environmentSlug);
-        window.open(
-          `${url}?secretPath=${encodedPath}&search=${encodeURIComponent(secretName)}&filterBy=secret`,
-          "_blank",
-          "noopener,noreferrer"
-        );
+        let folderPath = "/";
+
+        if (allSegments.length > 2) {
+          const pathSegments = allSegments.slice(1, -1);
+          for (let i = 0; i < pathSegments.length; i += 1) {
+            const pathSegment = pathSegments[i];
+            folderPath += `${pathSegment}`;
+            if (pathSegment === segment) {
+              folderPath += "/";
+              break;
+            }
+            folderPath += "/";
+          }
+        }
+
+        navigate({
+          to: ROUTE_PATHS.SecretManager.SecretDashboardPage.path,
+          params: {
+            projectId,
+            envSlug: environmentSlug
+          },
+          search: (prev) => ({
+            ...prev,
+            secretPath: segment === environmentSlug ? "/" : folderPath,
+            search: segment === secretName ? secretName : prev.search,
+            filterBy: segment === secretName ? "secret" : prev.filterBy
+          })
+        });
       },
-      [projectId, propEnvironment, propSecretPath]
+      [navigate, projectId]
     );
 
     return (
diff --git a/frontend/src/components/v2/SecretInput/SecretInput.tsx b/frontend/src/components/v2/SecretInput/SecretInput.tsx
index ac5a4ff7c..758d1a225 100644
--- a/frontend/src/components/v2/SecretInput/SecretInput.tsx
+++ b/frontend/src/components/v2/SecretInput/SecretInput.tsx
@@ -53,10 +53,16 @@ const syntaxHighlight = (
                   } ${shouldShowHoverStyle ? "cursor-pointer underline decoration-yellow-400" : ""}`}
                   onMouseEnter={() => onHoverPart?.(segmentKey)}
                   onMouseLeave={() => onHoverPart?.("")}
-                  onClick={(e) => {
+                  onMouseDown={(e) => {
                     if (isCmdOrCtrlPressed) {
                       e.preventDefault();
                       e.stopPropagation();
+                    }
+                  }}
+                  onClick={(e) => {
+                    e.stopPropagation();
+                    if (isCmdOrCtrlPressed) {
+                      e.preventDefault();
                       onClickSegment?.(segment, parts);
                     }
                   }}
diff --git a/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx b/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx
index 74ad462e4..1bc06de4d 100644
--- a/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx
+++ b/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx
@@ -475,34 +475,73 @@ const Page = () => {
     );
 
   const handleTagToggle = useCallback(
-    (tagSlug: string) =>
+    (tagSlug: string) => {
       setFilter((state) => {
         const isTagPresent = Boolean(state.tags?.[tagSlug]);
         const newTagFilter = { ...state.tags };
         if (isTagPresent) delete newTagFilter[tagSlug];
         else newTagFilter[tagSlug] = true;
+
+        // Update URL to match filter state
+        const tagsList = Object.keys(newTagFilter).filter((tag) => newTagFilter[tag]);
+        navigate({
+          search: (prev) => ({
+            ...prev,
+            tags: tagsList.length > 0 ? tagsList.join(",") : ""
+          })
+        });
+
         return { ...state, tags: newTagFilter };
-      }),
-    []
+      });
+    },
+    [navigate]
   );
 
   const handleToggleRowType = useCallback(
-    (rowType: RowType) =>
+    (rowType: RowType) => {
       setFilter((state) => {
+        const newInclude = {
+          ...state.include,
+          [rowType]: !state.include[rowType]
+        };
+
+        // Update URL to match filter state
+        const filterByList: string[] = [];
+        if (newInclude[RowType.Folder]) filterByList.push("folder");
+        if (newInclude[RowType.Import]) filterByList.push("import");
+        if (newInclude[RowType.DynamicSecret]) filterByList.push("dynamic");
+        if (newInclude[RowType.Secret]) filterByList.push("secret");
+        if (newInclude[RowType.SecretRotation]) filterByList.push("rotation");
+
+        navigate({
+          search: (prev) => ({
+            ...prev,
+            filterBy: filterByList.length > 0 ? filterByList.join(",") : ""
+          })
+        });
+
         return {
           ...state,
-          include: {
-            ...state.include,
-            [rowType]: !state.include[rowType]
-          }
+          include: newInclude
         };
-      }),
-    []
+      });
+    },
+    [navigate]
   );
 
   const handleSearchChange = useCallback(
-    (searchFilter: string) => setFilter((state) => ({ ...state, searchFilter })),
-    []
+    (searchFilter: string) => {
+      setFilter((state) => ({ ...state, searchFilter }));
+
+      // Update URL to match filter state
+      navigate({
+        search: (prev) => ({
+          ...prev,
+          search: searchFilter || ""
+        })
+      });
+    },
+    [navigate]
   );
 
   const handleToggleVisibility = useCallback(() => setIsVisible((state) => !state), []);
@@ -564,13 +603,6 @@ const Page = () => {
       include: includeFilter
     }));
     setDebouncedSearchFilter(routerQueryParams.search as string);
-    // this is a temp workaround until we fully transition state to query params,
-    navigate({
-      search: (state) => {
-        const { search, tags: qTags, filterBy: qFilterBy, ...query } = state;
-        return query;
-      }
-    });
   }, [routerQueryParams.search, routerQueryParams.tags, routerQueryParams.filterBy]);
 
   const selectedSecrets = useSelectedSecrets();

From 659900a48420b07a578a2b974ad4295322161a5e Mon Sep 17 00:00:00 2001
From: Victor Santos 
Date: Tue, 4 Nov 2025 16:54:06 -0300
Subject: [PATCH 03/12] feat: add error notifications for invalid project ID
 and secret references in InfisicalSecretInput

---
 .../InfisicalSecretInput.tsx                  | 25 +++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx b/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx
index 98f42923a..c5c119896 100644
--- a/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx
+++ b/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx
@@ -4,6 +4,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import * as Popover from "@radix-ui/react-popover";
 import { useNavigate } from "@tanstack/react-router";
 
+import { createNotification } from "@app/components/notifications";
 import { ROUTE_PATHS } from "@app/const/routes";
 import { useProject } from "@app/context";
 import { useDebounce, useToggle } from "@app/hooks";
@@ -312,6 +313,22 @@ export const InfisicalSecretInput = forwardRef(
 
     const handleClickSegment = useCallback(
       (segment: string, allSegments: string[]) => {
+        if (!projectId) {
+          createNotification({
+            text: "Project ID is not set",
+            type: "error"
+          });
+          return;
+        }
+
+        if (allSegments.length === 0) {
+          createNotification({
+            text: "Invalid secret reference",
+            type: "error"
+          });
+          return;
+        }
+
         if (allSegments.length === 1) {
           navigate({
             search: (prev) => ({
@@ -330,6 +347,14 @@ export const InfisicalSecretInput = forwardRef(
         if (allSegments.length > 2) {
           const pathSegments = allSegments.slice(1, -1);
           for (let i = 0; i < pathSegments.length; i += 1) {
+            if (!pathSegments[i]) {
+              createNotification({
+                text: "Invalid secret reference",
+                type: "error"
+              });
+              return;
+            }
+
             const pathSegment = pathSegments[i];
             folderPath += `${pathSegment}`;
             if (pathSegment === segment) {

From 2b5021e19ef90efc6a12a41861a878d48252b403 Mon Sep 17 00:00:00 2001
From: Victor Santos 
Date: Tue, 4 Nov 2025 17:08:59 -0300
Subject: [PATCH 04/12] docs update

---
 docs/documentation/platform/secret-reference.mdx | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/docs/documentation/platform/secret-reference.mdx b/docs/documentation/platform/secret-reference.mdx
index 545ed6b3b..dfb3bf0ec 100644
--- a/docs/documentation/platform/secret-reference.mdx
+++ b/docs/documentation/platform/secret-reference.mdx
@@ -17,6 +17,10 @@ For example, if secret A references values from secrets B and C located in diffe
 
 This is an important security consideration when planning your secret access strategy, especially when working with cross-environment or cross-folder references.
 
+
+  You can hold the `Cmd` (Mac) or `Ctrl` (Windows/Linux) key and click the secret reference to be redirected to it. 
+
+
 ### Syntax
 
 When defining a secret reference, interpolation syntax is used to define references to secrets in other environments and [folders](./folder).

From 7b83481815ca5381c15d66dc9549ff30fad6aa9e Mon Sep 17 00:00:00 2001
From: Victor Santos 
Date: Wed, 5 Nov 2025 10:52:30 -0300
Subject: [PATCH 05/12] permission check

---
 .../InfisicalSecretInput.tsx                  | 55 ++++++++++++++++++-
 1 file changed, 54 insertions(+), 1 deletion(-)

diff --git a/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx b/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx
index c5c119896..39c56c281 100644
--- a/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx
+++ b/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx
@@ -6,9 +6,11 @@ import { useNavigate } from "@tanstack/react-router";
 
 import { createNotification } from "@app/components/notifications";
 import { ROUTE_PATHS } from "@app/const/routes";
-import { useProject } from "@app/context";
+import { useProject, useProjectPermission } from "@app/context";
+import { ProjectPermissionSecretActions } from "@app/context/ProjectPermissionContext/types";
 import { useDebounce, useToggle } from "@app/hooks";
 import { useGetProjectFolders, useGetProjectSecrets } from "@app/hooks/api";
+import { hasSecretReadValueOrDescribePermission } from "@app/lib/fn/permission";
 
 import { SecretInput } from "../SecretInput";
 
@@ -84,6 +86,7 @@ export const InfisicalSecretInput = forwardRef(
     const { currentProject } = useProject();
     const projectId = currentProject?.id || "";
     const navigate = useNavigate({ from: ROUTE_PATHS.SecretManager.SecretDashboardPage.path });
+    const { permission } = useProjectPermission();
 
     const [debouncedValue] = useDebounce(value, 100);
 
@@ -330,6 +333,30 @@ export const InfisicalSecretInput = forwardRef(
         }
 
         if (allSegments.length === 1) {
+          const canReadSecretValue = hasSecretReadValueOrDescribePermission(
+            permission,
+            ProjectPermissionSecretActions.ReadValue,
+            {
+              environment: propEnvironment ?? "",
+              secretPath: propSecretPath ?? "/",
+              secretName: segment,
+              secretTags: []
+            }
+          );
+
+          console.log("canReadSecretValue", canReadSecretValue);
+          console.log("propEnvironment", propEnvironment);
+          console.log("propSecretPath", propSecretPath);
+          console.log("segment", segment);
+
+          if (!canReadSecretValue) {
+            createNotification({
+              text: "You do not have permission to access this secret",
+              type: "error"
+            });
+            return;
+          }
+
           navigate({
             search: (prev) => ({
               ...prev,
@@ -365,6 +392,32 @@ export const InfisicalSecretInput = forwardRef(
           }
         }
 
+        const secretPath = segment === environmentSlug ? "/" : folderPath;
+
+        const canReadSecretValue = hasSecretReadValueOrDescribePermission(
+          permission,
+          ProjectPermissionSecretActions.ReadValue,
+          {
+            environment: environmentSlug,
+            secretPath,
+            secretName: secretName ?? "",
+            secretTags: []
+          }
+        );
+
+        console.log("canReadSecretValue", canReadSecretValue);
+        console.log("environmentSlug", environmentSlug);
+        console.log("secretPath", secretPath);
+        console.log("secretName", secretName);
+
+        if (!canReadSecretValue) {
+          createNotification({
+            text: "You do not have permission to access this secret",
+            type: "error"
+          });
+          return;
+        }
+
         navigate({
           to: ROUTE_PATHS.SecretManager.SecretDashboardPage.path,
           params: {

From 10aace268e7e7181e8063fd93ddeb2cd66d9f2c1 Mon Sep 17 00:00:00 2001
From: Victor Santos 
Date: Wed, 5 Nov 2025 11:24:02 -0300
Subject: [PATCH 06/12] refactor: remove console logs and enhance tooltip
 information in CreateSecretForm

---
 .../InfisicalSecretInput/InfisicalSecretInput.tsx   | 12 +-----------
 .../src/components/v2/SecretInput/SecretInput.tsx   |  6 ++++++
 .../CreateSecretForm/CreateSecretForm.tsx           | 13 +++++++++++++
 .../SecretDashboardPage/SecretDashboardPage.tsx     |  2 +-
 4 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx b/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx
index 39c56c281..3b6d68112 100644
--- a/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx
+++ b/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx
@@ -344,11 +344,6 @@ export const InfisicalSecretInput = forwardRef(
             }
           );
 
-          console.log("canReadSecretValue", canReadSecretValue);
-          console.log("propEnvironment", propEnvironment);
-          console.log("propSecretPath", propSecretPath);
-          console.log("segment", segment);
-
           if (!canReadSecretValue) {
             createNotification({
               text: "You do not have permission to access this secret",
@@ -405,11 +400,6 @@ export const InfisicalSecretInput = forwardRef(
           }
         );
 
-        console.log("canReadSecretValue", canReadSecretValue);
-        console.log("environmentSlug", environmentSlug);
-        console.log("secretPath", secretPath);
-        console.log("secretName", secretName);
-
         if (!canReadSecretValue) {
           createNotification({
             text: "You do not have permission to access this secret",
@@ -432,7 +422,7 @@ export const InfisicalSecretInput = forwardRef(
           })
         });
       },
-      [navigate, projectId]
+      [navigate, projectId, permission, propEnvironment, propSecretPath]
     );
 
     return (
diff --git a/frontend/src/components/v2/SecretInput/SecretInput.tsx b/frontend/src/components/v2/SecretInput/SecretInput.tsx
index 758d1a225..1745a84ec 100644
--- a/frontend/src/components/v2/SecretInput/SecretInput.tsx
+++ b/frontend/src/components/v2/SecretInput/SecretInput.tsx
@@ -153,12 +153,18 @@ export const SecretInput = forwardRef(
         }
       };
 
+      const handleBlur = () => {
+        setIsCmdOrCtrlPressed(false);
+      };
+
       window.addEventListener("keydown", handleKeyDown);
       window.addEventListener("keyup", handleKeyUp);
+      window.addEventListener("blur", handleBlur);
 
       return () => {
         window.removeEventListener("keydown", handleKeyDown);
         window.removeEventListener("keyup", handleKeyUp);
+        window.removeEventListener("blur", handleBlur);
       };
     }, []);
 
diff --git a/frontend/src/pages/secret-manager/OverviewPage/components/CreateSecretForm/CreateSecretForm.tsx b/frontend/src/pages/secret-manager/OverviewPage/components/CreateSecretForm/CreateSecretForm.tsx
index 977943330..3a7639cda 100644
--- a/frontend/src/pages/secret-manager/OverviewPage/components/CreateSecretForm/CreateSecretForm.tsx
+++ b/frontend/src/pages/secret-manager/OverviewPage/components/CreateSecretForm/CreateSecretForm.tsx
@@ -249,6 +249,19 @@ export const CreateSecretForm = ({ secretPath = "/", onClose }: Props) => {
         name="value"
         render={({ field }) => (
           
+                You can add references to other secrets using the format{" "}
+                
+                  ${"{"}secret_name{"}"}
+                
+                .
+                
+
You can go to the referenced secret by holding the Cmd (Mac) or{" "} + Ctrl (Windows/Linux) key and clicking on the secret name. +
+ } + tooltipClassName="max-w-md" label="Value" isError={Boolean(errors?.value)} errorText={errors?.value?.message} diff --git a/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx b/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx index 1bc06de4d..d525cea30 100644 --- a/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx +++ b/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx @@ -602,7 +602,7 @@ const Page = () => { tags: updatedTags, include: includeFilter })); - setDebouncedSearchFilter(routerQueryParams.search as string); + setDebouncedSearchFilter((routerQueryParams.search as string) ?? ""); }, [routerQueryParams.search, routerQueryParams.tags, routerQueryParams.filterBy]); const selectedSecrets = useSelectedSecrets(); From 46a4152c070ecc6df0378ddebc3f05ccc99787f0 Mon Sep 17 00:00:00 2001 From: Victor Santos Date: Wed, 5 Nov 2025 12:19:16 -0300 Subject: [PATCH 07/12] refactor: remove default filter state from SecretDashboardPage to streamline filter management --- .../secret-manager/SecretDashboardPage/SecretDashboardPage.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx b/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx index d525cea30..a16e6cd88 100644 --- a/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx +++ b/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx @@ -597,7 +597,6 @@ const Page = () => { setFilter((prev) => ({ ...prev, - ...defaultFilterState, searchFilter: (routerQueryParams.search as string) ?? "", tags: updatedTags, include: includeFilter From 782776e9dee2d07a4269c62e253576ce6767d935 Mon Sep 17 00:00:00 2001 From: Victor Santos Date: Fri, 7 Nov 2025 12:58:52 -0300 Subject: [PATCH 08/12] Enhance InfisicalSecretInput to use wildcard for environment and secret tags; update error message to reflect resource type. Improve tooltip in CreateSecretForm for secret references in both Overview and SecretDashboard pages. --- .../InfisicalSecretInput.tsx | 17 ++++++++++++----- .../CreateSecretForm/CreateSecretForm.tsx | 8 +++++--- .../CreateSecretForm/CreateSecretForm.tsx | 15 +++++++++++++++ 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx b/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx index 3b6d68112..82a652624 100644 --- a/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx +++ b/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx @@ -337,10 +337,10 @@ export const InfisicalSecretInput = forwardRef( permission, ProjectPermissionSecretActions.ReadValue, { - environment: propEnvironment ?? "", + environment: propEnvironment ?? "*", secretPath: propSecretPath ?? "/", secretName: segment, - secretTags: [] + secretTags: ["*"] } ); @@ -395,14 +395,21 @@ export const InfisicalSecretInput = forwardRef( { environment: environmentSlug, secretPath, - secretName: secretName ?? "", - secretTags: [] + secretName: secretName ?? "*", + secretTags: ["*"] } ); + let resourceName = "secret"; + if (segment === environmentSlug) { + resourceName = "environment"; + } else if (segment !== secretName && folderPath.includes(segment)) { + resourceName = "folder"; + } + if (!canReadSecretValue) { createNotification({ - text: "You do not have permission to access this secret", + text: `You do not have permission to access this ${resourceName}`, type: "error" }); return; diff --git a/frontend/src/pages/secret-manager/OverviewPage/components/CreateSecretForm/CreateSecretForm.tsx b/frontend/src/pages/secret-manager/OverviewPage/components/CreateSecretForm/CreateSecretForm.tsx index 3a7639cda..2ed31e50c 100644 --- a/frontend/src/pages/secret-manager/OverviewPage/components/CreateSecretForm/CreateSecretForm.tsx +++ b/frontend/src/pages/secret-manager/OverviewPage/components/CreateSecretForm/CreateSecretForm.tsx @@ -255,10 +255,12 @@ export const CreateSecretForm = ({ secretPath = "/", onClose }: Props) => { ${"{"}secret_name{"}"} - .
-
You can go to the referenced secret by holding the Cmd (Mac) or{" "} - Ctrl (Windows/Linux) key and clicking on the secret name. +
+ You can go to the referenced secret by holding the{" "} + Cmd (Mac) or{" "} + Ctrl (Windows/Linux) key + and clicking on the secret name.
} tooltipClassName="max-w-md" diff --git a/frontend/src/pages/secret-manager/SecretDashboardPage/components/CreateSecretForm/CreateSecretForm.tsx b/frontend/src/pages/secret-manager/SecretDashboardPage/components/CreateSecretForm/CreateSecretForm.tsx index 858fcde77..1a4884ddb 100644 --- a/frontend/src/pages/secret-manager/SecretDashboardPage/components/CreateSecretForm/CreateSecretForm.tsx +++ b/frontend/src/pages/secret-manager/SecretDashboardPage/components/CreateSecretForm/CreateSecretForm.tsx @@ -197,6 +197,21 @@ export const CreateSecretForm = ({ render={({ field }) => ( + You can add references to other secrets using the format{" "} + + ${"{"}secret_name{"}"} + +
+
+ You can go to the referenced secret by holding the{" "} + Cmd (Mac) or{" "} + Ctrl (Windows/Linux) key + and clicking on the secret name. + + } + tooltipClassName="max-w-md" isError={Boolean(errors?.value)} errorText={errors?.value?.message} > From 2083e9102f11b305608ef07aa3ad3218f2983593 Mon Sep 17 00:00:00 2001 From: Victor Santos Date: Mon, 10 Nov 2025 14:50:57 -0300 Subject: [PATCH 09/12] Refactor secret permission validation in InfisicalSecretInput and improve tooltip styling in CreateSecretForm components --- .../InfisicalSecretInput.tsx | 42 ++++++++---------- .../CreateSecretForm/CreateSecretForm.tsx | 8 ++-- .../SecretDashboardPage.tsx | 43 ++++++++++--------- .../CreateSecretForm/CreateSecretForm.tsx | 8 ++-- 4 files changed, 50 insertions(+), 51 deletions(-) diff --git a/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx b/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx index 82a652624..d1f2e1a62 100644 --- a/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx +++ b/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx @@ -389,30 +389,26 @@ export const InfisicalSecretInput = forwardRef( const secretPath = segment === environmentSlug ? "/" : folderPath; - const canReadSecretValue = hasSecretReadValueOrDescribePermission( - permission, - ProjectPermissionSecretActions.ReadValue, - { - environment: environmentSlug, - secretPath, - secretName: secretName ?? "*", - secretTags: ["*"] + // Only validate secret permission, users can always view environments and folders + if (segment === secretName) { + const canReadSecretValue = hasSecretReadValueOrDescribePermission( + permission, + ProjectPermissionSecretActions.ReadValue, + { + environment: environmentSlug, + secretPath, + secretName: secretName ?? "*", + secretTags: ["*"] + } + ); + + if (!canReadSecretValue) { + createNotification({ + text: "You do not have permission to access this secret", + type: "error" + }); + return; } - ); - - let resourceName = "secret"; - if (segment === environmentSlug) { - resourceName = "environment"; - } else if (segment !== secretName && folderPath.includes(segment)) { - resourceName = "folder"; - } - - if (!canReadSecretValue) { - createNotification({ - text: `You do not have permission to access this ${resourceName}`, - type: "error" - }); - return; } navigate({ diff --git a/frontend/src/pages/secret-manager/OverviewPage/components/CreateSecretForm/CreateSecretForm.tsx b/frontend/src/pages/secret-manager/OverviewPage/components/CreateSecretForm/CreateSecretForm.tsx index 2ed31e50c..a821a029d 100644 --- a/frontend/src/pages/secret-manager/OverviewPage/components/CreateSecretForm/CreateSecretForm.tsx +++ b/frontend/src/pages/secret-manager/OverviewPage/components/CreateSecretForm/CreateSecretForm.tsx @@ -252,15 +252,15 @@ export const CreateSecretForm = ({ secretPath = "/", onClose }: Props) => { tooltipText={
You can add references to other secrets using the format{" "} - + ${"{"}secret_name{"}"}

You can go to the referenced secret by holding the{" "} - Cmd (Mac) or{" "} - Ctrl (Windows/Linux) key - and clicking on the secret name. + Cmd (Mac) or{" "} + Ctrl{" "} + (Windows/Linux) key and clicking on the secret name.
} tooltipClassName="max-w-md" diff --git a/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx b/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx index a16e6cd88..53fc476ad 100644 --- a/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx +++ b/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx @@ -219,17 +219,19 @@ const Page = () => { ProjectPermissionSub.Commits ); + const defaultIncludeFilters = { + [RowType.Folder]: routerQueryParams.filterBy?.includes(RowType.Folder) || false, + [RowType.Import]: routerQueryParams.filterBy?.includes(RowType.Import) || false, + [RowType.DynamicSecret]: routerQueryParams.filterBy?.includes(RowType.DynamicSecret) || false, + [RowType.Secret]: routerQueryParams.filterBy?.includes(RowType.Secret) || false, + [RowType.SecretRotation]: routerQueryParams.filterBy?.includes(RowType.SecretRotation) || false + }; + const defaultFilterState = { tags: {}, searchFilter: (routerQueryParams.search as string) || "", // these should always be on by default for the UI, they will be disabled for the query below based off permissions - include: { - [RowType.Folder]: false, - [RowType.Import]: false, - [RowType.DynamicSecret]: false, - [RowType.Secret]: false, - [RowType.SecretRotation]: false - } + include: defaultIncludeFilters }; const [filter, setFilter] = useState(defaultFilterState); @@ -529,6 +531,19 @@ const Page = () => { [navigate] ); + const handleClearFilters = useCallback(() => { + setFilter(defaultFilterState); + setDebouncedSearchFilter(""); + navigate({ + search: (prev) => ({ + ...prev, + search: "", + tags: "", + filterBy: "" + }) + }); + }, [navigate]); + const handleSearchChange = useCallback( (searchFilter: string) => { setFilter((state) => ({ ...state, searchFilter })); @@ -882,19 +897,7 @@ const Page = () => { isPITEnabled={isPITEnabled} hasPathPolicies={hasPathPolicies} onRequestAccess={(params) => handlePopUpOpen("requestAccess", params)} - onClearFilters={() => - setFilter((prev) => ({ - ...prev, - tags: {}, - include: { - secret: false, - import: false, - dynamic: false, - rotation: false, - folder: false - } - })) - } + onClearFilters={handleClearFilters} />
You can add references to other secrets using the format{" "} - + ${"{"}secret_name{"}"}

You can go to the referenced secret by holding the{" "} - Cmd (Mac) or{" "} - Ctrl (Windows/Linux) key - and clicking on the secret name. + Cmd (Mac) or{" "} + Ctrl{" "} + (Windows/Linux) key and clicking on the secret name.
} tooltipClassName="max-w-md" From f16bc7df7e74cbc930bd24dbb8b1f5a1577b3498 Mon Sep 17 00:00:00 2001 From: Victor Santos Date: Mon, 10 Nov 2025 15:57:58 -0300 Subject: [PATCH 10/12] Refactor filter state management in SecretDashboardPage to improve clarity and maintainability. Introduced a new function to derive filter state from query parameters and streamlined filter reset logic. --- .../SecretDashboardPage.tsx | 107 ++++++++---------- 1 file changed, 48 insertions(+), 59 deletions(-) diff --git a/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx b/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx index 53fc476ad..203a3f6eb 100644 --- a/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx +++ b/frontend/src/pages/secret-manager/SecretDashboardPage/SecretDashboardPage.tsx @@ -219,24 +219,43 @@ const Page = () => { ProjectPermissionSub.Commits ); - const defaultIncludeFilters = { - [RowType.Folder]: routerQueryParams.filterBy?.includes(RowType.Folder) || false, - [RowType.Import]: routerQueryParams.filterBy?.includes(RowType.Import) || false, - [RowType.DynamicSecret]: routerQueryParams.filterBy?.includes(RowType.DynamicSecret) || false, - [RowType.Secret]: routerQueryParams.filterBy?.includes(RowType.Secret) || false, - [RowType.SecretRotation]: routerQueryParams.filterBy?.includes(RowType.SecretRotation) || false - }; + const getFilterStateFromQueryParams = useCallback(() => { + const filterByArray = routerQueryParams.filterBy + ? (routerQueryParams.filterBy as string).split(",").filter(Boolean) + : []; - const defaultFilterState = { - tags: {}, - searchFilter: (routerQueryParams.search as string) || "", - // these should always be on by default for the UI, they will be disabled for the query below based off permissions - include: defaultIncludeFilters - }; + const includeFilters = { + [RowType.Folder]: filterByArray.includes("folder") || false, + [RowType.Import]: filterByArray.includes("import") || false, + [RowType.DynamicSecret]: filterByArray.includes("dynamic") || false, + [RowType.Secret]: filterByArray.includes("secret") || false, + [RowType.SecretRotation]: filterByArray.includes("rotation") || false + }; + + const tags = routerQueryParams.tags + ? routerQueryParams.tags.split(",").reduce( + (acc, tag) => { + const trimmedTag = tag.trim(); + if (trimmedTag) { + acc[trimmedTag] = true; + } + return acc; + }, + {} as Record + ) + : {}; + + return { + tags, + searchFilter: (routerQueryParams.search as string) || "", + include: includeFilters + }; + }, [routerQueryParams.search, routerQueryParams.tags, routerQueryParams.filterBy]); + + const defaultFilterState = getFilterStateFromQueryParams(); const [filter, setFilter] = useState(defaultFilterState); const [debouncedSearchFilter, setDebouncedSearchFilter] = useDebounce(filter.searchFilter); - const [filterHistory, setFilterHistory] = useState>(new Map()); const createSecretPopUp = usePopUpState(PopUpNames.CreateSecretForm); const { togglePopUp } = usePopUpAction(); @@ -532,7 +551,17 @@ const Page = () => { ); const handleClearFilters = useCallback(() => { - setFilter(defaultFilterState); + setFilter({ + searchFilter: "", + tags: {}, + include: { + [RowType.Folder]: false, + [RowType.Import]: false, + [RowType.DynamicSecret]: false, + [RowType.Secret]: false, + [RowType.SecretRotation]: false + } + }); setDebouncedSearchFilter(""); navigate({ search: (prev) => ({ @@ -581,43 +610,10 @@ const Page = () => { }); useEffect(() => { - // restore filters for path if set - const restore = filterHistory.get(secretPath); - setFilter(restore ?? defaultFilterState); - setDebouncedSearchFilter(restore?.searchFilter ?? ""); - }, [secretPath]); - - useEffect(() => { - if (!routerQueryParams.search && !routerQueryParams.tags && !routerQueryParams.filterBy) return; - - const queryTags = routerQueryParams.tags - ? (routerQueryParams.tags as string).split(",").filter((tag) => Boolean(tag.trim())) - : []; - const updatedTags: Record = {}; - queryTags.forEach((tag) => { - updatedTags[tag] = true; - }); - - const filterBy = routerQueryParams.filterBy - ? (routerQueryParams.filterBy as string).split(",").filter(Boolean) - : []; - - const includeFilter: Record = { - [RowType.Folder]: filterBy.includes("folder"), - [RowType.Import]: filterBy.includes("import"), - [RowType.DynamicSecret]: filterBy.includes("dynamic"), - [RowType.Secret]: filterBy.includes("secret"), - [RowType.SecretRotation]: filterBy.includes("rotation") - }; - - setFilter((prev) => ({ - ...prev, - searchFilter: (routerQueryParams.search as string) ?? "", - tags: updatedTags, - include: includeFilter - })); - setDebouncedSearchFilter((routerQueryParams.search as string) ?? ""); - }, [routerQueryParams.search, routerQueryParams.tags, routerQueryParams.filterBy]); + const filterState = getFilterStateFromQueryParams(); + setFilter(filterState); + setDebouncedSearchFilter(filterState.searchFilter); + }, [getFilterStateFromQueryParams]); const selectedSecrets = useSelectedSecrets(); const selectedSecretActions = useSelectedSecretActions(); @@ -656,13 +652,6 @@ const Page = () => { } const handleResetFilter = () => { - // store for breadcrumb nav to restore previously used filters - setFilterHistory((prev) => { - const curr = new Map(prev); - curr.set(secretPath, filter); - return curr; - }); - setFilter(defaultFilterState); setDebouncedSearchFilter(""); }; From 7b91e7192cac2d05d710153929b8074eb2fa956a Mon Sep 17 00:00:00 2001 From: Victor Santos Date: Mon, 10 Nov 2025 16:43:06 -0300 Subject: [PATCH 11/12] Refactor secret path handling in InfisicalSecretInput to use folderPath directly, enhancing clarity in permission validation logic. --- .../v2/InfisicalSecretInput/InfisicalSecretInput.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx b/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx index d1f2e1a62..8da31d67d 100644 --- a/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx +++ b/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx @@ -387,8 +387,6 @@ export const InfisicalSecretInput = forwardRef( } } - const secretPath = segment === environmentSlug ? "/" : folderPath; - // Only validate secret permission, users can always view environments and folders if (segment === secretName) { const canReadSecretValue = hasSecretReadValueOrDescribePermission( @@ -396,8 +394,8 @@ export const InfisicalSecretInput = forwardRef( ProjectPermissionSecretActions.ReadValue, { environment: environmentSlug, - secretPath, - secretName: secretName ?? "*", + secretPath: folderPath, + secretName, secretTags: ["*"] } ); From 619846983d1b6071b19f3e0fb52628505cc0e7aa Mon Sep 17 00:00:00 2001 From: Victor Santos Date: Tue, 11 Nov 2025 09:23:23 -0300 Subject: [PATCH 12/12] Enhance filter state management in InfisicalSecretInput by adding a tags property to the search state, improving flexibility for future filtering options. --- .../v2/InfisicalSecretInput/InfisicalSecretInput.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx b/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx index 8da31d67d..a109004e1 100644 --- a/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx +++ b/frontend/src/components/v2/InfisicalSecretInput/InfisicalSecretInput.tsx @@ -356,7 +356,8 @@ export const InfisicalSecretInput = forwardRef( search: (prev) => ({ ...prev, search: segment, - filterBy: "secret" + filterBy: "secret", + tags: "" }) }); return; @@ -419,7 +420,8 @@ export const InfisicalSecretInput = forwardRef( ...prev, secretPath: segment === environmentSlug ? "/" : folderPath, search: segment === secretName ? secretName : prev.search, - filterBy: segment === secretName ? "secret" : prev.filterBy + filterBy: segment === secretName ? "secret" : prev.filterBy, + tags: "" }) }); },