diff --git a/apps/studio/components/layouts/EdgeFunctionsLayout/EdgeFunctionDetailsLayout.tsx b/apps/studio/components/layouts/EdgeFunctionsLayout/EdgeFunctionDetailsLayout.tsx
index 895917be4f9..394d0b66546 100644
--- a/apps/studio/components/layouts/EdgeFunctionsLayout/EdgeFunctionDetailsLayout.tsx
+++ b/apps/studio/components/layouts/EdgeFunctionsLayout/EdgeFunctionDetailsLayout.tsx
@@ -299,27 +299,25 @@ const EdgeFunctionDetailsLayout = ({
- {IS_PLATFORM && (
- <>
- {!!functionSlug && (
- }
- onClick={() => {
- setIsOpen(true)
- sendEvent({
- action: 'edge_function_test_side_panel_opened',
- groups: {
- project: ref ?? 'Unknown',
- organization: org?.slug ?? 'Unknown',
- },
- })
- }}
- >
- Test
-
- )}
- >
+ {!!functionSlug && (
+ }
+ onClick={() => {
+ setIsOpen(true)
+ if (IS_PLATFORM) {
+ sendEvent({
+ action: 'edge_function_test_side_panel_opened',
+ groups: {
+ project: ref ?? 'Unknown',
+ organization: org?.slug ?? 'Unknown',
+ },
+ })
+ }
+ }}
+ >
+ Test
+
)}
diff --git a/apps/studio/lib/api/edgeFunctions.test.ts b/apps/studio/lib/api/edgeFunctions.test.ts
index 06887983411..54e0af1f63e 100644
--- a/apps/studio/lib/api/edgeFunctions.test.ts
+++ b/apps/studio/lib/api/edgeFunctions.test.ts
@@ -1,4 +1,5 @@
-import { expect, describe, it } from 'vitest'
+import { describe, expect, it } from 'vitest'
+
import { isValidEdgeFunctionURL } from './edgeFunctions'
describe('isValidEdgeFunctionURL', () => {
@@ -9,7 +10,16 @@ describe('isValidEdgeFunctionURL', () => {
'https://projectref.supabase.red/functions/v3/hello-world',
]
- const invalidEdgeFunctionUrls = [
+ const validLocalEdgeFunctionsUrls = [
+ 'https://projectref.notsupabase.com/functions/v1/test',
+ 'https://notsupabase.com/functions/v1/test',
+ 'http://localhost:54321/functions/v1/test-2',
+ 'http://kong:8000/functions/v1/hello-world',
+ 'https://127.0.0.1:54321/functions/v1/test-3',
+ 'https://127.0.0.1:54321/functions/v1/test-5',
+ ]
+
+ const invalidPlatformEdgeFunctionUrls = [
'https://notsupabase.com/functions/v1/test',
'https://projectref.notsupabase.com/functions/v1/test',
'https://localhost?https://aaaa.supabase.co/functions/v1/xxx',
@@ -17,15 +27,41 @@ describe('isValidEdgeFunctionURL', () => {
'http://localhost:3000/?https://aaaa.supabase.co/functions/v1/xxx',
]
- it('should match valid edge function URLs', () => {
+ const invalidEdgeFunctionUrls = [
+ 'https://localhost?https://aaaa.supabase.co/functions/v1/xxx',
+ 'https://localhost:3000/?https://aaaa.supabase.co/functions/v1/xxx',
+ 'http://localhost:3000/?https://aaaa.supabase.co/functions/v1/xxx',
+ ]
+
+ it('should match valid edge function URLs on platform', () => {
for (const url of validEdgeFunctionUrls) {
- expect(isValidEdgeFunctionURL(url), `Expected ${url} to be valid`).toBe(true)
+ expect(isValidEdgeFunctionURL(url, true), `Expected ${url} to be valid`).toBe(true)
}
})
- it('should not match invalid edge function URLs', () => {
+ it('should not match local URLs on platform', () => {
+ for (const url of validLocalEdgeFunctionsUrls) {
+ expect(isValidEdgeFunctionURL(url, true), `Expected ${url} to be invalid on platform`).toBe(
+ false
+ )
+ }
+ })
+
+ it('should match valid local edge function URLs off platform', () => {
+ for (const url of validLocalEdgeFunctionsUrls) {
+ expect(isValidEdgeFunctionURL(url, false), `Expected ${url} to be valid`).toBe(true)
+ }
+ })
+
+ it('should not match invalid edge function URLs on platform', () => {
+ for (const url of invalidPlatformEdgeFunctionUrls) {
+ expect(isValidEdgeFunctionURL(url, true), `Expected ${url} to be invalid`).toBe(false)
+ }
+ })
+
+ it('should not match invalid edge function URLs off platform', () => {
for (const url of invalidEdgeFunctionUrls) {
- expect(isValidEdgeFunctionURL(url), `Expected ${url} to be invalid`).toBe(false)
+ expect(isValidEdgeFunctionURL(url, false), `Expected ${url} to be invalid`).toBe(false)
}
})
})
diff --git a/apps/studio/lib/api/edgeFunctions.ts b/apps/studio/lib/api/edgeFunctions.ts
index a62fadc91ea..15b0138328a 100644
--- a/apps/studio/lib/api/edgeFunctions.ts
+++ b/apps/studio/lib/api/edgeFunctions.ts
@@ -1,12 +1,20 @@
const NIMBUS_PROD_PROJECTS_URL = process.env.NIMBUS_PROD_PROJECTS_URL
-export const isValidEdgeFunctionURL = (url: string) => {
+export const isValidEdgeFunctionURL = (url: string, isPlatform: boolean) => {
if (NIMBUS_PROD_PROJECTS_URL !== undefined) {
const apexDomain = NIMBUS_PROD_PROJECTS_URL.replace('https://*.', '').replace(/\./g, '\\.')
const nimbusRegex = new RegExp('^https://[a-z]*\\.' + apexDomain + '/functions/v[0-9]{1}/.*$')
return nimbusRegex.test(url)
}
+ if (!isPlatform) {
+ const regexValidLocalEdgeFunctionURL = new RegExp(
+ '^https?://[^\\s/?#]+/functions/v[0-9]{1}/.*$'
+ )
+
+ return regexValidLocalEdgeFunctionURL.test(url)
+ }
+
const regexValidEdgeFunctionURL = new RegExp(
'^https://[a-z]*.supabase.(red|co)/functions/v[0-9]{1}/.*$'
)
diff --git a/apps/studio/pages/api/edge-functions/test.ts b/apps/studio/pages/api/edge-functions/test.ts
index 044dfe70cdb..442d4f1be4f 100644
--- a/apps/studio/pages/api/edge-functions/test.ts
+++ b/apps/studio/pages/api/edge-functions/test.ts
@@ -1,3 +1,4 @@
+import { IS_PLATFORM } from 'common'
import { isValidEdgeFunctionURL } from 'lib/api/edgeFunctions'
import { NextApiRequest, NextApiResponse } from 'next'
@@ -20,9 +21,12 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
async function handlePost(req: NextApiRequest, res: NextApiResponse) {
try {
- const { url, method, body: requestBody, headers: customHeaders } = req.body
+ const { url: requestUrl, method, body: requestBody, headers: customHeaders } = req.body
+ const url = IS_PLATFORM
+ ? requestUrl
+ : requestUrl.replace(process.env.SUPABASE_PUBLIC_URL, process.env.SUPABASE_URL)
- const validEdgeFnUrl = isValidEdgeFunctionURL(url)
+ const validEdgeFnUrl = isValidEdgeFunctionURL(url, IS_PLATFORM)
if (!validEdgeFnUrl) {
return res.status(400).json({