diff --git a/apps/studio/components/interfaces/Settings/Database/JITAccess.tsx b/apps/studio/components/interfaces/Settings/Database/JITAccess.tsx index 205ff820a1a..5100d771be2 100644 --- a/apps/studio/components/interfaces/Settings/Database/JITAccess.tsx +++ b/apps/studio/components/interfaces/Settings/Database/JITAccess.tsx @@ -7,6 +7,7 @@ import { DOCS_URL } from 'lib/constants' import { EllipsisVertical, Pencil, Trash2, UserPlus } from 'lucide-react' import Link from 'next/link' import { useMemo, useState } from 'react' +import { toast } from 'sonner' import { AlertDialog, AlertDialogAction, @@ -352,7 +353,6 @@ const MOCK_USERS: JITUserRule[] = [ ]), MOCK_MEMBERS ), - createRuleFromMember('rule-5', 'member-5', createEmptyGrants(), MOCK_MEMBERS), ] function RoleRuleEditor({ @@ -575,6 +575,7 @@ export const JITAccess = () => { const [draft, setDraft] = useState(() => createDraft()) const [showInlineValidation, setShowInlineValidation] = useState(false) const [userPendingDelete, setUserPendingDelete] = useState(null) + const [showEnableJitDialog, setShowEnableJitDialog] = useState(false) const membersWithRules = useMemo(() => new Set(users.map((user) => user.memberId)), [users]) const availableMembersForAdd = useMemo( @@ -589,6 +590,10 @@ export const JITAccess = () => { () => draft.grants.filter((grant) => grant.enabled).length, [draft.grants] ) + const activeRuleCount = useMemo( + () => users.filter((user) => user.status.active > 0).length, + [users] + ) const inlineValidation = useMemo( () => ({ member: !draft.memberId @@ -605,6 +610,35 @@ export const JITAccess = () => { setSheetOpen(false) } + const closeEnableJitDialog = () => { + setShowEnableJitDialog(false) + } + + const handleConfirmEnableJit = () => { + setEnabled(true) + closeEnableJitDialog() + } + + const handleJitToggleChange = (checked: boolean) => { + if (checked && !enabled && activeRuleCount > 0) { + setShowEnableJitDialog(true) + return + } + + if (!checked && enabled) { + setEnabled(false) + toast.success( + activeRuleCount > 0 + ? `JIT access disabled. ${activeRuleCount} configured user${activeRuleCount === 1 ? '' : 's' + } can no longer request temporary database access.` + : 'JIT access disabled.' + ) + return + } + + setEnabled(checked) + } + const openAddUserSheet = () => { setSheetMode('add') setEditingUserId(null) @@ -694,7 +728,7 @@ export const JITAccess = () => { setEnabled(checked)} + onCheckedChange={handleJitToggleChange} disabled={isPostgresVersionOutdated} /> @@ -707,10 +741,10 @@ export const JITAccess = () => { - {!enabled && !users?.length && isPostgresVersionOutdated && ( + {!enabled && isPostgresVersionOutdated && ( { !open && closeSheet()}> @@ -972,7 +1007,8 @@ export const JITAccess = () => { Remove the JIT access rule for {deleteUserDisplayName}?

- This only removes the rule from the list. The project member will not be deleted from the project. + This only removes the rule from the list. The project member will not be deleted + from the project.

@@ -985,6 +1021,33 @@ export const JITAccess = () => { + + !open && closeEnableJitDialog()} + > + + + JIT access will activate existing rules + +
+

+ Enabling JIT will immediately activate {activeRuleCount} existing user rule + {activeRuleCount === 1 ? '' : 's'}, allowing{' '} + {activeRuleCount === 1 ? 'that user' : 'those users'} to request temporary + database access. +

+
+
+
+ + Cancel + + Enable JIT access + + +
+
)