From 37de37d8ad0478ca6509ff24ba1d5a54c9f05dd1 Mon Sep 17 00:00:00 2001 From: Bharat Kathi Date: Fri, 26 Jun 2026 00:36:56 -0700 Subject: [PATCH] feat: list all accounts/applications regardless of access Stop filtering ListAccounts/ListApplications by access groups so anyone can see what already exists (prevents accidental name collisions when creating new entries). Detail/CRUD endpoints stay gated. Each list item carries a can_access bool computed server-side. The UI renders locked cards as non-clickable with a lock icon + muted styling instead of the arrow-out affordance. --- vault/api/account.go | 16 +++++++++---- vault/api/app_secret.go | 16 +++++++++---- web/src/lib/vault.ts | 2 ++ web/src/pages/AccountsPage.tsx | 39 +++++++++++++++++++++++++------- web/src/pages/AppSecretsPage.tsx | 39 +++++++++++++++++++++++++------- 5 files changed, 86 insertions(+), 26 deletions(-) diff --git a/vault/api/account.go b/vault/api/account.go index b328dd5..a6f9410 100644 --- a/vault/api/account.go +++ b/vault/api/account.go @@ -18,6 +18,11 @@ type accountRequest struct { AccessGroupNames []string `json:"access_group_names"` } +type accountListItem struct { + service.AccountWithSecretCount + CanAccess bool `json:"can_access"` +} + func ListAccounts(c *gin.Context) { Require(c, RequestTokenExists(c)) accounts, err := service.GetAllAccounts() @@ -29,13 +34,14 @@ func ListAccounts(c *gin.Context) { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } - authorized := make([]service.AccountWithSecretCount, 0, len(accounts)) + response := make([]accountListItem, 0, len(accounts)) for _, account := range accounts { - if RequestTokenCanAccessAccount(c, account.Account) { - authorized = append(authorized, account) - } + response = append(response, accountListItem{ + AccountWithSecretCount: account, + CanAccess: RequestTokenCanAccessAccount(c, account.Account), + }) } - c.JSON(http.StatusOK, authorized) + c.JSON(http.StatusOK, response) } func GetAccount(c *gin.Context) { diff --git a/vault/api/app_secret.go b/vault/api/app_secret.go index 0b5ecf8..7200c57 100644 --- a/vault/api/app_secret.go +++ b/vault/api/app_secret.go @@ -20,6 +20,11 @@ type appSecretRequest struct { Value string `json:"value"` } +type applicationListItem struct { + service.ApplicationWithSecretCount + CanAccess bool `json:"can_access"` +} + func ListApplications(c *gin.Context) { Require(c, RequestTokenExists(c)) applications, err := service.GetAllApplications() @@ -27,13 +32,14 @@ func ListApplications(c *gin.Context) { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } - authorized := make([]service.ApplicationWithSecretCount, 0, len(applications)) + response := make([]applicationListItem, 0, len(applications)) for _, application := range applications { - if RequestTokenCanAccessApplication(c, application.Application) { - authorized = append(authorized, application) - } + response = append(response, applicationListItem{ + ApplicationWithSecretCount: application, + CanAccess: RequestTokenCanAccessApplication(c, application.Application), + }) } - c.JSON(http.StatusOK, authorized) + c.JSON(http.StatusOK, response) } func GetApplication(c *gin.Context) { diff --git a/web/src/lib/vault.ts b/web/src/lib/vault.ts index dbe2951..c794304 100644 --- a/web/src/lib/vault.ts +++ b/web/src/lib/vault.ts @@ -106,10 +106,12 @@ export type AppSecretApplicationWithSecrets = AppSecretApplication & { export type AccountListItem = Account & { secret_count: number + can_access: boolean } export type AppSecretApplicationListItem = AppSecretApplication & { secret_count: number + can_access: boolean } export type AccountInput = { diff --git a/web/src/pages/AccountsPage.tsx b/web/src/pages/AccountsPage.tsx index beedfa9..4fd663f 100644 --- a/web/src/pages/AccountsPage.tsx +++ b/web/src/pages/AccountsPage.tsx @@ -1,5 +1,5 @@ import { useQuery } from "@tanstack/react-query" -import { ArrowUpRight, Clock3, KeyRound, Plus, Search } from "lucide-react" +import { ArrowUpRight, Clock3, KeyRound, Lock, Plus, Search } from "lucide-react" import { useMemo, useState } from "react" import { Link } from "react-router-dom" @@ -10,6 +10,7 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Input } from "@/components/ui/input" import { Skeleton } from "@/components/ui/skeleton" import { listAccounts } from "@/lib/vault" +import { cn } from "@/lib/utils" function formatDate(value: string) { return new Date(value).toLocaleDateString(undefined, { @@ -86,14 +87,26 @@ export default function AccountsPage() { ) : (
- {filteredAccounts.map((account) => ( - - + {filteredAccounts.map((account) => { + const card = ( + {account.name} - - + + {account.can_access ? : } @@ -122,8 +135,18 @@ export default function AccountsPage() {
- - ))} + ) + + return account.can_access ? ( + + {card} + + ) : ( +
+ {card} +
+ ) + })} )} diff --git a/web/src/pages/AppSecretsPage.tsx b/web/src/pages/AppSecretsPage.tsx index 11d5dc1..fff1abd 100644 --- a/web/src/pages/AppSecretsPage.tsx +++ b/web/src/pages/AppSecretsPage.tsx @@ -1,5 +1,5 @@ import { useQuery } from "@tanstack/react-query" -import { ArrowUpRight, Clock3, CodeXml, Plus, Search } from "lucide-react" +import { ArrowUpRight, Clock3, CodeXml, Lock, Plus, Search } from "lucide-react" import { useMemo, useState } from "react" import { Link } from "react-router-dom" @@ -10,6 +10,7 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Input } from "@/components/ui/input" import { Skeleton } from "@/components/ui/skeleton" import { listAppSecretApplications, type AppSecretApplicationListItem } from "@/lib/vault" +import { cn } from "@/lib/utils" function formatDate(value: string) { return new Date(value).toLocaleDateString(undefined, { @@ -91,16 +92,28 @@ export default function AppSecretsPage() { ) : (
- {filteredApplications.map((application) => ( - - + {filteredApplications.map((application) => { + const card = ( + {application.name} - - + + {application.can_access ? : } @@ -128,8 +141,18 @@ export default function AppSecretsPage() {
- - ))} + ) + + return application.can_access ? ( + + {card} + + ) : ( +
+ {card} +
+ ) + })} )}