import { PermissionAction } from '@supabase/shared-types/out/constants' import { noop } from 'lodash' import { Edit, MoreVertical, Trash } from 'lucide-react' import { Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, TableCell, TableRow, Tooltip, TooltipContent, TooltipTrigger, } from 'ui' import { generatePolicyUpdateSQL } from './PolicyTableRow.utils' import type { Policy } from './PolicyTableRow.utils' import { SIDEBAR_KEYS } from '@/components/layouts/ProjectLayout/LayoutSidebar/LayoutSidebarProvider' import { DropdownMenuItemTooltip } from '@/components/ui/DropdownMenuItemTooltip' import { useAuthConfigQuery } from '@/data/auth/auth-config-query' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' import { useAiAssistantStateSnapshot } from '@/state/ai-assistant-state' import { useSidebarManagerSnapshot } from '@/state/sidebar-manager-state' interface PolicyRowProps { policy: Policy onSelectEditPolicy: (policy: Policy) => void onSelectDeletePolicy: (policy: Policy) => void isLocked?: boolean } export const PolicyRow = ({ policy, isLocked: isLockedDefault = false, onSelectEditPolicy = noop, onSelectDeletePolicy = noop, }: PolicyRowProps) => { const aiSnap = useAiAssistantStateSnapshot() const { openSidebar } = useSidebarManagerSnapshot() const { can: canUpdatePolicies } = useAsyncCheckPermissions( PermissionAction.TENANT_SQL_ADMIN_WRITE, 'policies' ) const { data: project } = useSelectedProjectQuery() const { data: authConfig } = useAuthConfigQuery({ projectRef: project?.ref }) // override islocked for Realtime messages table const isLocked = policy.schema === 'realtime' && policy.table === 'messages' ? false : isLockedDefault // TODO(km): Simple check for roles that allow authenticated access. // In the future, we'll use splinter to return proper warnings for policies that allow anonymous user access. const appliesToAnonymousUsers = authConfig?.EXTERNAL_ANONYMOUS_USERS_ENABLED && (policy.roles.includes('authenticated') || policy.roles.includes('public')) const displayedRoles = (() => { const rolesWithAnonymous = appliesToAnonymousUsers ? [...policy.roles, 'anonymous sign-ins'] : policy.roles return rolesWithAnonymous })() return (
{policy.command}
{displayedRoles.slice(0, 2).map((role, i) => ( {role} {i < Math.min(displayedRoles.length, 2) - 1 ? ', ' : ' '} ))}
{displayedRoles.length > 2 && (
+ {displayedRoles.length - 2} more
{displayedRoles.slice(2).map((role, i, arr) => ( <> {role} {i < arr.length - 1 && ', '} ))}
)}
{!isLocked && (