Skip to content

Commit 4f0d2f5

Browse files
committed
fix(secrets): reveal legacy values safely
1 parent ba193e3 commit 4f0d2f5

3 files changed

Lines changed: 47 additions & 3 deletions

File tree

apps/sim/app/workspace/[workspaceId]/settings/components/secrets/components/secrets-manager/secrets-manager.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1038,7 +1038,8 @@ export function SecretsManager() {
10381038
).map(([key, value]) => {
10391039
const cred = workspaceEnvKeyToCredential.get(key)
10401040
const canEditRow = canCreateWorkspaceSecret && cred?.role === 'admin'
1041-
const canRevealRow = cred?.role === 'admin' || Boolean(cred?.unredacted)
1041+
const canRevealRow =
1042+
isWorkspaceAdmin || cred?.role === 'admin' || Boolean(cred?.unredacted)
10421043
return (
10431044
<WorkspaceVariableRow
10441045
key={key}

apps/sim/hooks/queries/workspace.test.tsx

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ vi.mock('@/lib/api/client/request', () => ({
1717

1818
import { ApiClientError } from '@/lib/api/client/errors'
1919
import { createPinnedItemContract, deletePinnedItemContract } from '@/lib/api/contracts'
20-
import { useToggleWorkspacePin, workspaceKeys } from '@/hooks/queries/workspace'
20+
import {
21+
useToggleWorkspacePin,
22+
useWorkspacePermissionsQuery,
23+
workspaceKeys,
24+
} from '@/hooks/queries/workspace'
2125

2226
/** Trees rendered by a test, torn down in afterEach so observers do not leak across tests. */
2327
const mountedRoots: Root[] = []
@@ -92,6 +96,46 @@ beforeEach(() => {
9296
vi.clearAllMocks()
9397
})
9498

99+
describe('useWorkspacePermissionsQuery', () => {
100+
it('does not retain admin access while a different workspace loads', () => {
101+
const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } } })
102+
const container = document.createElement('div')
103+
const root = createRoot(container)
104+
mountedRoots.push(root)
105+
106+
queryClient.setQueryData(workspaceKeys.permissions('ws-a'), {
107+
users: [],
108+
total: 0,
109+
viewer: { userId: 'user-1', isAdmin: true, permissionType: 'admin' },
110+
})
111+
mockRequestJson.mockReturnValueOnce(new Promise<never>(() => {}))
112+
113+
function Probe({ workspaceId }: { workspaceId: string }) {
114+
const { data } = useWorkspacePermissionsQuery(workspaceId)
115+
return <span>{data ? (data.viewer?.isAdmin ? 'admin' : 'member') : 'loading'}</span>
116+
}
117+
118+
act(() => {
119+
root.render(
120+
<QueryClientProvider client={queryClient}>
121+
<Probe workspaceId='ws-a' />
122+
</QueryClientProvider>
123+
)
124+
})
125+
expect(container.textContent).toBe('admin')
126+
127+
act(() => {
128+
root.render(
129+
<QueryClientProvider client={queryClient}>
130+
<Probe workspaceId='ws-b' />
131+
</QueryClientProvider>
132+
)
133+
})
134+
135+
expect(container.textContent).toBe('loading')
136+
})
137+
})
138+
95139
describe('useToggleWorkspacePin', () => {
96140
it('pins by creating a row addressed to the workspace itself', async () => {
97141
mockRequestJson.mockResolvedValue({ pinnedItem: {} })

apps/sim/hooks/queries/workspace.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,6 @@ export function useWorkspacePermissionsQuery(workspaceId: string | null | undefi
336336
queryFn: ({ signal }) => fetchWorkspacePermissions(workspaceId as string, signal),
337337
enabled: Boolean(workspaceId),
338338
staleTime: WORKSPACE_PERMISSIONS_STALE_TIME,
339-
placeholderData: keepPreviousData,
340339
})
341340
}
342341

0 commit comments

Comments
 (0)