diff --git a/src/api/routers/credentials.ts b/src/api/routers/credentials.ts index 6bc96c5a..6d3c6355 100644 --- a/src/api/routers/credentials.ts +++ b/src/api/routers/credentials.ts @@ -7,12 +7,11 @@ import { decryptCredential } from '../../db/crypto.js'; import { createCredential, deleteCredential, - listAllCredentials, listOrgCredentials, updateCredential, } from '../../db/repositories/credentialsRepository.js'; import { credentials } from '../../db/schema/index.js'; -import { protectedProcedure, router, superAdminProcedure } from '../trpc.js'; +import { protectedProcedure, router } from '../trpc.js'; function maskValue(value: string): string { if (value.length <= 4) return '****'; @@ -28,14 +27,6 @@ export const credentialsRouter = router({ })); }), - listAll: superAdminProcedure.query(async () => { - const rows = await listAllCredentials(); - return rows.map((row) => ({ - ...row, - value: maskValue(row.value), - })); - }), - create: protectedProcedure .input( z.object({ diff --git a/src/db/repositories/credentialsRepository.ts b/src/db/repositories/credentialsRepository.ts index f0e235c0..56e1c5ef 100644 --- a/src/db/repositories/credentialsRepository.ts +++ b/src/db/repositories/credentialsRepository.ts @@ -1,45 +1,7 @@ import { and, eq } from 'drizzle-orm'; import { getDb } from '../client.js'; import { decryptCredential, encryptCredential } from '../crypto.js'; -import { - credentials, - integrationCredentials, - organizations, - projectIntegrations, -} from '../schema/index.js'; - -// ============================================================================ -// Global credential management (superadmin only) -// ============================================================================ - -/** - * List all credentials across all organizations. - * Joins with organizations to include org name. - */ -export async function listAllCredentials(): Promise< - (typeof credentials.$inferSelect & { orgName: string })[] -> { - const db = getDb(); - const rows = await db - .select({ - id: credentials.id, - orgId: credentials.orgId, - orgName: organizations.name, - name: credentials.name, - envVarKey: credentials.envVarKey, - value: credentials.value, - isDefault: credentials.isDefault, - createdAt: credentials.createdAt, - updatedAt: credentials.updatedAt, - }) - .from(credentials) - .innerJoin(organizations, eq(credentials.orgId, organizations.id)); - - return rows.map((row) => ({ - ...row, - value: decryptCredential(row.value, row.orgId), - })); -} +import { credentials, integrationCredentials, projectIntegrations } from '../schema/index.js'; // ============================================================================ // Integration credential resolution diff --git a/web/src/components/layout/sidebar.tsx b/web/src/components/layout/sidebar.tsx index 51b9f612..7f13b8da 100644 --- a/web/src/components/layout/sidebar.tsx +++ b/web/src/components/layout/sidebar.tsx @@ -29,7 +29,6 @@ const globalNav = [ { to: '/global/defaults' as const, label: 'Cascade Defaults', icon: SlidersHorizontal }, { to: '/global/definitions' as const, label: 'Agent Definitions', icon: BookOpen }, { to: '/global/organizations' as const, label: 'Organizations', icon: Building }, - { to: '/global/credentials' as const, label: 'Global Credentials', icon: KeyRound }, ]; const settingsNav = [ diff --git a/web/src/components/settings/credential-form-dialog.tsx b/web/src/components/settings/credential-form-dialog.tsx index 3248e0be..6b4d8f8b 100644 --- a/web/src/components/settings/credential-form-dialog.tsx +++ b/web/src/components/settings/credential-form-dialog.tsx @@ -33,7 +33,6 @@ export function CredentialFormDialog({ const invalidate = () => { queryClient.invalidateQueries({ queryKey: trpc.credentials.list.queryOptions().queryKey }); - queryClient.invalidateQueries({ queryKey: trpc.credentials.listAll.queryOptions().queryKey }); }; const createMutation = useMutation({ diff --git a/web/src/components/settings/credentials-table.tsx b/web/src/components/settings/credentials-table.tsx index 428f59a7..b88a7703 100644 --- a/web/src/components/settings/credentials-table.tsx +++ b/web/src/components/settings/credentials-table.tsx @@ -26,20 +26,13 @@ import { CredentialFormDialog } from './credential-form-dialog.js'; interface Credential { id: number; orgId: string; - orgName?: string; name: string; envVarKey: string; value: string; isDefault: boolean; } -export function CredentialsTable({ - credentials, - showOrg = false, -}: { - credentials: Credential[]; - showOrg?: boolean; -}) { +export function CredentialsTable({ credentials }: { credentials: Credential[] }) { const queryClient = useQueryClient(); const [deleteId, setDeleteId] = useState(null); const [editCredential, setEditCredential] = useState(null); @@ -48,7 +41,6 @@ export function CredentialsTable({ mutationFn: (id: number) => trpcClient.credentials.delete.mutate({ id }), onSuccess: () => { queryClient.invalidateQueries({ queryKey: trpc.credentials.list.queryOptions().queryKey }); - queryClient.invalidateQueries({ queryKey: trpc.credentials.listAll.queryOptions().queryKey }); setDeleteId(null); }, }); @@ -59,7 +51,6 @@ export function CredentialsTable({ - {showOrg && Organization} Name Env Var Key Value @@ -70,26 +61,13 @@ export function CredentialsTable({ {credentials.length === 0 && ( - + No credentials yet )} {credentials.map((cred) => ( - {showOrg && ( - -
- {cred.orgName} - - {cred.orgId} - -
-
- )} {cred.name} {cred.envVarKey} diff --git a/web/src/routes/global/credentials.tsx b/web/src/routes/global/credentials.tsx deleted file mode 100644 index 12b4da0c..00000000 --- a/web/src/routes/global/credentials.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { CredentialsTable } from '@/components/settings/credentials-table.js'; -import { trpc } from '@/lib/trpc.js'; -import { useQuery } from '@tanstack/react-query'; -import { createRoute } from '@tanstack/react-router'; -import { rootRoute } from '../__root.js'; - -function GlobalCredentialsPage() { - const credentialsQuery = useQuery(trpc.credentials.listAll.queryOptions()); - - return ( -
-
-

Global Credentials

- {credentialsQuery.data && ( - - {credentialsQuery.data.length} credentials - - )} -
- - {credentialsQuery.isLoading && ( -
Loading credentials...
- )} - - {credentialsQuery.isError && ( -
- Failed to load credentials: {credentialsQuery.error.message} -
- )} - - {credentialsQuery.data && ( - - )} -
- ); -} - -export const globalCredentialsRoute = createRoute({ - getParentRoute: () => rootRoute, - path: '/global/credentials', - component: GlobalCredentialsPage, -}); diff --git a/web/src/routes/route-tree.ts b/web/src/routes/route-tree.ts index 9c80de3d..1e4b2492 100644 --- a/web/src/routes/route-tree.ts +++ b/web/src/routes/route-tree.ts @@ -1,6 +1,5 @@ import { rootRoute } from './__root.js'; import { globalAgentConfigsRoute } from './global/agent-configs.js'; -import { globalCredentialsRoute } from './global/credentials.js'; import { globalDefaultsRoute } from './global/defaults.js'; import { globalDefinitionsRoute } from './global/definitions.js'; import { globalOrganizationsRoute } from './global/organizations.js'; @@ -31,7 +30,6 @@ export const routeTree = rootRoute.addChildren([ globalDefinitionsRoute, globalWebhookLogsRoute, globalOrganizationsRoute, - globalCredentialsRoute, globalRunsRoute, workItemRunsRoute, prRunsRoute,