import { PermissionAction } from '@supabase/shared-types/out/constants' import { useParams } from 'common' import { AlertCircle, ChevronDown, Globe, Lock } from 'lucide-react' import { useState } from 'react' import { Badge, Button, Card, CardContent, CardDescription, CardHeader, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, Tooltip, TooltipContent, TooltipTrigger, } from 'ui' import { PageSection, PageSectionAside, PageSectionContent, PageSectionMeta, PageSectionSummary, PageSectionTitle, } from 'ui-patterns' import { ShimmeringLoader } from 'ui-patterns/ShimmeringLoader' import AddRestrictionModal from './AddRestrictionModal' import AllowAllModal from './AllowAllModal' import DisallowAllModal from './DisallowAllModal' import RemoveRestrictionModal from './RemoveRestrictionModal' import { ButtonTooltip } from '@/components/ui/ButtonTooltip' import { DocsButton } from '@/components/ui/DocsButton' import { useNetworkRestrictionsQuery } from '@/data/network-restrictions/network-restrictions-query' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' import { DOCS_URL } from '@/lib/constants' interface AccessButtonProps { disabled: boolean onClick: (value: boolean) => void } const AllowAllAccessButton = ({ disabled, onClick }: AccessButtonProps) => ( {disabled && ( You need additional permissions to update network restrictions )} ) const DisallowAllAccessButton = ({ disabled, onClick }: AccessButtonProps) => ( onClick(true)} tooltip={{ content: { side: 'bottom', text: disabled ? 'You need additional permissions to update network restrictions' : undefined, }, }} > Restrict all access ) export const NetworkRestrictions = () => { const { ref } = useParams() const { data: project } = useSelectedProjectQuery() const [isAddingAddress, setIsAddingAddress] = useState() const [isAllowingAll, setIsAllowingAll] = useState(false) const [isDisallowingAll, setIsDisallowingAll] = useState(false) const [selectedRestrictionToRemove, setSelectedRestrictionToRemove] = useState() const { data, isPending: isLoading } = useNetworkRestrictionsQuery({ projectRef: ref }) const { can: canUpdateNetworkRestrictions } = useAsyncCheckPermissions( PermissionAction.UPDATE, 'projects', { resource: { project_id: project?.id, }, } ) const hasAccessToRestrictions = data?.entitlement === 'allowed' const ipv4Restrictions = data?.config?.dbAllowedCidrs ?? [] // @ts-ignore [Joshen] API typing issue const ipv6Restrictions = data?.config?.dbAllowedCidrsV6 ?? [] const restrictedIps = ipv4Restrictions.concat(ipv6Restrictions) const restrictionStatus = data?.status ?? '' const hasApplyError = restrictionStatus === 'stored' const isUninitialized = restrictedIps.length === 0 && restrictionStatus.length === 0 const isAllowedAll = restrictedIps.includes('0.0.0.0/0') && restrictedIps.includes('::/0') const isDisallowedAll = restrictedIps.length === 0 if (!hasAccessToRestrictions) return null return ( <> Network restrictions {!canUpdateNetworkRestrictions ? ( Add restriction ) : ( setIsAddingAddress('IPv4')} >

Add IPv4 restriction

setIsAddingAddress('IPv6')} >

Add IPv6 restriction

)}
{isLoading ? (
) : hasApplyError ? (

Your network restrictions were not applied correctly

Please try to add your network restrictions again

) : ( {isUninitialized || isAllowedAll ? (

Your database can be accessed by all IP addresses

You may start limiting access to your database by adding a network restriction.

) : isDisallowedAll ? (

Your database cannot be accessed externally

All external IP addresses have been disallowed from accessing your project's database.

Note: Restrictions only apply to your database, and not to Briven services

) : ( <>

Only the following IP addresses have access to your database.

You may remove all of them to allow all IP addresses to have access to your database.

Note: Restrictions only apply to your database, and not to Briven services

{restrictedIps.map((ip) => { return (
{ipv4Restrictions.includes(ip) ? 'IPv4' : 'IPv6'}

{ip}

) })}
)}
)}
setIsAllowingAll(false)} /> setIsDisallowingAll(false)} /> setIsAddingAddress(undefined)} /> setSelectedRestrictionToRemove(undefined)} /> ) }