From d0edaefc1a4b7cc881e4d76d085bea396b099229 Mon Sep 17 00:00:00 2001 From: Vaibhav <117663341+7ttp@users.noreply.github.com> Date: Wed, 20 May 2026 05:11:21 +0530 Subject: [PATCH] fix: edgefn shotcuts (#46057) ## TL;DR fixes few edge cases in edgefn shrortcuts ## ref: - closes https://github.com/supabase/supabase/issues/46056 ## Summary by CodeRabbit * **Improvements** * Edge function shortcuts now enforce permission requirements. Shortcuts for viewing function details are only available to users with read access, and shortcuts for creating new functions require create permissions. * Creating new edge functions is now restricted to active projects. Users must have the appropriate permissions and an active project to use the creation shortcut. [![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46057?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) --- .../Functions/useFunctionsDetailShortcuts.ts | 25 +++++++++++++------ .../Functions/useFunctionsListShortcuts.ts | 3 +++ .../EdgeFunctionDetailsLayout.tsx | 1 + .../pages/project/[ref]/functions/index.tsx | 3 +++ 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/apps/studio/components/interfaces/Functions/useFunctionsDetailShortcuts.ts b/apps/studio/components/interfaces/Functions/useFunctionsDetailShortcuts.ts index e7d3cb64d50..94b04112754 100644 --- a/apps/studio/components/interfaces/Functions/useFunctionsDetailShortcuts.ts +++ b/apps/studio/components/interfaces/Functions/useFunctionsDetailShortcuts.ts @@ -6,6 +6,7 @@ import { useShortcut } from '@/state/shortcuts/useShortcut' interface UseFunctionsDetailShortcutsParams { projectRef: string | undefined functionSlug: string | undefined + canReadFunctions: boolean isPlatform: boolean onOpenTest: () => void onOpenDownload: () => void @@ -24,6 +25,7 @@ interface UseFunctionsDetailShortcutsParams { export function useFunctionsDetailShortcuts({ projectRef, functionSlug, + canReadFunctions, isPlatform, onOpenTest, onOpenDownload, @@ -32,33 +34,40 @@ export function useFunctionsDetailShortcuts({ const router = useRouter() const ready = Boolean(projectRef && functionSlug) + const shortcutsEnabled = ready && canReadFunctions const base = `/project/${projectRef}/functions/${functionSlug}` useShortcut(SHORTCUT_IDS.NAV_FUNCTION_DETAIL_OVERVIEW, () => router.push(base), { - enabled: ready && isPlatform, + enabled: shortcutsEnabled && isPlatform, }) useShortcut( SHORTCUT_IDS.NAV_FUNCTION_DETAIL_INVOCATIONS, () => router.push(`${base}/invocations`), - { enabled: ready && isPlatform } + { enabled: shortcutsEnabled && isPlatform } ) useShortcut(SHORTCUT_IDS.NAV_FUNCTION_DETAIL_LOGS, () => router.push(`${base}/logs`), { - enabled: ready && isPlatform, + enabled: shortcutsEnabled && isPlatform, }) useShortcut(SHORTCUT_IDS.NAV_FUNCTION_DETAIL_CODE, () => router.push(`${base}/code`), { - enabled: ready, + enabled: shortcutsEnabled, }) useShortcut(SHORTCUT_IDS.NAV_FUNCTION_DETAIL_SETTINGS, () => router.push(`${base}/details`), { - enabled: ready, + enabled: shortcutsEnabled, }) - useShortcut(SHORTCUT_IDS.FUNCTION_DETAIL_OPEN_TEST, onOpenTest, { enabled: ready }) + useShortcut(SHORTCUT_IDS.FUNCTION_DETAIL_OPEN_TEST, onOpenTest, { + enabled: shortcutsEnabled, + }) - useShortcut(SHORTCUT_IDS.FUNCTION_DETAIL_OPEN_DOWNLOAD, onOpenDownload, { enabled: ready }) + useShortcut(SHORTCUT_IDS.FUNCTION_DETAIL_OPEN_DOWNLOAD, onOpenDownload, { + enabled: shortcutsEnabled, + }) - useShortcut(SHORTCUT_IDS.FUNCTION_DETAIL_COPY_URL, onCopyUrl, { enabled: ready }) + useShortcut(SHORTCUT_IDS.FUNCTION_DETAIL_COPY_URL, onCopyUrl, { + enabled: shortcutsEnabled, + }) } diff --git a/apps/studio/components/interfaces/Functions/useFunctionsListShortcuts.ts b/apps/studio/components/interfaces/Functions/useFunctionsListShortcuts.ts index 10c3b3bc762..a50f13608cb 100644 --- a/apps/studio/components/interfaces/Functions/useFunctionsListShortcuts.ts +++ b/apps/studio/components/interfaces/Functions/useFunctionsListShortcuts.ts @@ -11,6 +11,7 @@ interface UseFunctionsListShortcutsParams { setSearch: Dispatch> | ((value: string) => void) sort: EdgeFunctionsSort setSort: (value: EdgeFunctionsSort) => void + canCreateNew: boolean onCreateNew: () => void onRefresh: () => void } @@ -20,6 +21,7 @@ export function useFunctionsListShortcuts({ setSearch, sort, setSort, + canCreateNew, onCreateNew, onRefresh, }: UseFunctionsListShortcutsParams) { @@ -33,6 +35,7 @@ export function useFunctionsListShortcuts({ ) useShortcut(SHORTCUT_IDS.LIST_PAGE_NEW_ITEM, onCreateNew, { + enabled: canCreateNew, label: 'Deploy a new function', }) diff --git a/apps/studio/components/layouts/EdgeFunctionsLayout/EdgeFunctionDetailsLayout.tsx b/apps/studio/components/layouts/EdgeFunctionsLayout/EdgeFunctionDetailsLayout.tsx index 7021b098a52..d5850dd9455 100644 --- a/apps/studio/components/layouts/EdgeFunctionsLayout/EdgeFunctionDetailsLayout.tsx +++ b/apps/studio/components/layouts/EdgeFunctionsLayout/EdgeFunctionDetailsLayout.tsx @@ -263,6 +263,7 @@ const EdgeFunctionDetailsLayout = ({ useFunctionsDetailShortcuts({ projectRef: ref, functionSlug, + canReadFunctions, isPlatform: IS_PLATFORM, onOpenTest: openTestSheet, onOpenDownload: () => setIsDownloadOpen((prev) => !prev), diff --git a/apps/studio/pages/project/[ref]/functions/index.tsx b/apps/studio/pages/project/[ref]/functions/index.tsx index f62d9ab6215..9d474c96578 100644 --- a/apps/studio/pages/project/[ref]/functions/index.tsx +++ b/apps/studio/pages/project/[ref]/functions/index.tsx @@ -39,6 +39,7 @@ import AlertError from '@/components/ui/AlertError' import { DocsButton } from '@/components/ui/DocsButton' import { ShortcutTooltip } from '@/components/ui/ShortcutTooltip' import { useEdgeFunctionsQuery } from '@/data/edge-functions/edge-functions-query' +import { useIsProjectActive } from '@/hooks/misc/useSelectedProject' import { DOCS_URL, IS_PLATFORM } from '@/lib/constants' import { onSearchInputEscape } from '@/lib/keyboard' import { SHORTCUT_IDS } from '@/state/shortcuts/registry' @@ -48,6 +49,7 @@ const EdgeFunctionsPage: NextPageWithLayout = () => { const router = useRouter() const { ref } = useParams() const showLastHourStats = useFlag('edgeFunctionsRequestMetrics') + const isProjectActive = useIsProjectActive() const searchInputRef = useRef(null) @@ -72,6 +74,7 @@ const EdgeFunctionsPage: NextPageWithLayout = () => { setSearch, sort, setSort: setSortQueryParam, + canCreateNew: isProjectActive, onCreateNew: () => router.push(`/project/${ref}/functions/new`), onRefresh: () => { refetch()