@@ -3,6 +3,7 @@ import { runMigrationsFromContent } from '../../database/migrate.ts'
33import { VERSION } from '../../version.ts'
44import { embeddedMigrations } from '../../database/migrations-embedded.ts'
55import { parseSchemaComment } from '../schemaComment.ts'
6+ import { authenticateWithSupabase } from '../managementAuth.ts'
67import postgres from 'postgres'
78
89// Get management API base URL from environment variable (for testing against localhost/staging)
@@ -12,95 +13,6 @@ const MGMT_API_BASE = MGMT_API_BASE_RAW.match(/^https?:\/\//)
1213 ? MGMT_API_BASE_RAW
1314 : `https://${ MGMT_API_BASE_RAW } `
1415
15- // Returns true if the projectRef passed is a non-branch project, false otherwise
16- async function canAccessProject ( projectRef : string , accessToken : string ) : Promise < boolean > {
17- const url = `${ MGMT_API_BASE } /v1/projects/${ projectRef } `
18- const response = await fetch ( url , {
19- method : 'GET' ,
20- headers : {
21- Authorization : `Bearer ${ accessToken } ` ,
22- 'Content-Type' : 'application/json' ,
23- } ,
24- } )
25- return response . ok
26- }
27-
28- // Returns all projects refs
29- async function getAllProjects ( accessToken : string ) : Promise < string [ ] > {
30- const url = `${ MGMT_API_BASE } /v1/projects`
31- const response = await fetch ( url , {
32- method : 'GET' ,
33- headers : {
34- Authorization : `Bearer ${ accessToken } ` ,
35- 'Content-Type' : 'application/json' ,
36- } ,
37- } )
38- if ( response . ok ) {
39- const projects = ( await response . json ( ) ) as Array < { ref ?: string } >
40- return Array . isArray ( projects )
41- ? projects
42- . map ( ( project ) => project . ref )
43- . filter ( ( projectRef ) : projectRef is string => Boolean ( projectRef ) )
44- : [ ]
45- } else {
46- return [ ]
47- }
48- }
49-
50- // Returns all branch project refs of a give projectRef
51- async function getAllBranches ( projectRef : string , accessToken : string ) : Promise < string [ ] > {
52- const url = `${ MGMT_API_BASE } /v1/projects/${ projectRef } /branches`
53- const response = await fetch ( url , {
54- method : 'GET' ,
55- headers : {
56- Authorization : `Bearer ${ accessToken } ` ,
57- 'Content-Type' : 'application/json' ,
58- } ,
59- } )
60- if ( response . ok ) {
61- const branches = ( await response . json ( ) ) as Array < { project_ref ?: string } >
62- return Array . isArray ( branches )
63- ? branches
64- . map ( ( branch ) => branch . project_ref )
65- . filter ( ( projectRef ) : projectRef is string => Boolean ( projectRef ) )
66- : [ ]
67- } else {
68- return [ ]
69- }
70- }
71-
72- // Authenticates with Supabase management API. Returns null if the accessToken has
73- // access to the projectRef project, other returns an error string
74- async function authenticateWithSupabase (
75- projectRef : string ,
76- accessToken : string | null
77- ) : Promise < string | null > {
78- if ( ! accessToken ) {
79- return 'Unauthorized: Invalid credentials'
80- }
81-
82- // First we check if the token can return the project directly
83- // If it does then the token is valid for this project and
84- // we authenticate the request
85- const tokenCanAccesProject = await canAccessProject ( projectRef , accessToken )
86- if ( tokenCanAccesProject ) {
87- return null
88- }
89-
90- // If the token does not return a project then projectRef could be a branch
91- // project, in which case we enumerate branch projects of all projects
92- const allProjectRefs = await getAllProjects ( accessToken )
93- for ( const ref of allProjectRefs ) {
94- const branches = await getAllBranches ( ref , accessToken )
95- if ( branches . includes ( projectRef ) ) {
96- return null
97- }
98- }
99-
100- // It's not even a branch project
101- return 'Unauthorized: Invalid credentials'
102- }
103-
10416// Helper to delete edge function via Management API
10517async function deleteEdgeFunction (
10618 projectRef : string ,
@@ -163,7 +75,7 @@ Deno.serve(async (req) => {
16375
16476 const accessToken = authHeader . substring ( 7 ) // Remove 'Bearer '
16577
166- const supabaseAuthError = await authenticateWithSupabase ( projectRef , accessToken )
78+ const supabaseAuthError = await authenticateWithSupabase ( MGMT_API_BASE , projectRef , accessToken )
16779 if ( supabaseAuthError ) {
16880 return new Response ( 'Unauthorized' , { status : 401 } )
16981 }
0 commit comments