Skip to content

Commit b9a0908

Browse files
joshenlimalaister
andauthored
Refactor post calls from lib/common/fetch in auth pages to data/fetchers (supabase#36506)
* Deprecate use of getWithTimeout, refactor BuildingState and RestoringState to use RQ * Refactor profile-create-mutation to use data/fetchers, and edge-function-status-query to use fetch * Shift post from lib/common/fetch, refactor bucket-object-download-mutation * Address feedback * Minor fix * Refactor post calls from lib/common/fetch in auth pages to data/fetchers * Add missing POST users endpoint + small fix when deleting user via context menu * simplify handleFetchError * allow handleFetchError to accept unknown * non-breaking change --------- Co-authored-by: Alaister Young <[email protected]>
1 parent 88dca02 commit b9a0908

File tree

13 files changed

+121
-393
lines changed

13 files changed

+121
-393
lines changed

apps/studio/components/interfaces/Auth/Users/UsersV2.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,10 @@ export const UsersV2 = () => {
587587
visible={!!selectedUserToDelete}
588588
selectedUser={selectedUserToDelete}
589589
onClose={() => setSelectedUserToDelete(undefined)}
590-
onDeleteSuccess={() => setSelectedUserToDelete(undefined)}
590+
onDeleteSuccess={() => {
591+
if (selectedUserToDelete?.id === selectedUser) setSelectedUser(undefined)
592+
setSelectedUserToDelete(undefined)
593+
}}
591594
/>
592595
</>
593596
)

apps/studio/data/auth/auth-config-query.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { useQuery, useQueryClient, UseQueryOptions } from '@tanstack/react-query'
22
import type { components } from 'data/api'
33
import { get, handleError } from 'data/fetchers'
4+
import { IS_PLATFORM } from 'lib/constants'
45
import { useCallback } from 'react'
56
import type { ResponseError } from 'types'
67
import { authKeys } from './keys'
@@ -40,7 +41,7 @@ export const useAuthConfigQuery = <TData = ProjectAuthConfigData>(
4041
authKeys.authConfig(projectRef),
4142
({ signal }) => getProjectAuthConfig({ projectRef }, signal),
4243
{
43-
enabled: enabled && typeof projectRef !== 'undefined',
44+
enabled: enabled && IS_PLATFORM && typeof projectRef !== 'undefined',
4445
...options,
4546
}
4647
)

apps/studio/data/fetchers.ts

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,39 @@ async function handleFetchResponse<T>(response: Response): Promise<T | ResponseE
193193
}
194194
}
195195

196+
async function handleFetchError(response: unknown): Promise<ResponseError> {
197+
let resJson: any = {}
198+
199+
if (response instanceof Error) {
200+
resJson = response
201+
}
202+
203+
if (response instanceof Response) {
204+
resJson = await response.json()
205+
}
206+
207+
const status = response instanceof Response ? response.status : undefined
208+
209+
const message =
210+
resJson.message ??
211+
resJson.msg ??
212+
resJson.error ??
213+
`An error has occurred: ${status ?? 'Unknown error'}`
214+
const retryAfter =
215+
response instanceof Response && response.headers.get('Retry-After')
216+
? parseInt(response.headers.get('Retry-After')!)
217+
: undefined
218+
219+
let error = new ResponseError(message, status, undefined, retryAfter)
220+
221+
// @ts-expect-error - [Alaister] many of our local api routes check `if (response.error)`.
222+
// This is a fix to keep those checks working without breaking changes.
223+
// In future we should check for `if (response instanceof ResponseError)` instead.
224+
error.error = error
225+
226+
return error
227+
}
228+
196229
/**
197230
* To be used only for dashboard API endpoints. Use `fetch` directly if calling a non dashboard API endpoint
198231
*
@@ -218,9 +251,9 @@ export async function fetchPost<T = any>(
218251
...otherOptions,
219252
signal: abortSignal,
220253
})
221-
if (!response.ok) return handleError(response)
254+
if (!response.ok) return handleFetchError(response)
222255
return handleFetchResponse(response)
223256
} catch (error) {
224-
return handleError(error)
257+
return handleFetchError(error)
225258
}
226259
}

apps/studio/lib/self-hosted.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1+
import { fetchPost } from 'data/fetchers'
12
import { constructHeaders } from 'lib/api/apiHelpers'
2-
import { post } from 'lib/common/fetch'
33
import { PG_META_URL } from 'lib/constants'
44
import type { ResponseError } from 'types'
55

66
export async function queryPgMetaSelfHosted(sql: string, headersInit?: { [prop: string]: any }) {
77
const headers = constructHeaders(headersInit ?? {})
8-
const response = await post(`${PG_META_URL}/query`, { query: sql }, { headers })
8+
const response = await fetchPost(`${PG_META_URL}/query`, { query: sql }, { headers })
99

1010
if (response.error) {
1111
return { error: response.error as ResponseError }

apps/studio/pages/api/platform/auth/[ref]/config.ts

Lines changed: 0 additions & 179 deletions
This file was deleted.

apps/studio/pages/api/platform/auth/[ref]/invite.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
import { createClient } from '@supabase/supabase-js'
12
import { NextApiRequest, NextApiResponse } from 'next'
2-
import apiWrapper from 'lib/api/apiWrapper'
3+
4+
import { fetchPost } from 'data/fetchers'
35
import { constructHeaders } from 'lib/api/apiHelpers'
4-
import { post } from 'lib/common/fetch'
6+
import apiWrapper from 'lib/api/apiWrapper'
7+
8+
const supabase = createClient(process.env.SUPABASE_URL!, process.env.SUPABASE_SERVICE_KEY!)
59

610
export default (req: NextApiRequest, res: NextApiResponse) => apiWrapper(req, res, handler)
711

@@ -25,6 +29,12 @@ const handlePost = async (req: NextApiRequest, res: NextApiResponse) => {
2529
})
2630
const url = `${process.env.SUPABASE_URL}/auth/v1/invite`
2731
const payload = { email: req.body.email }
28-
const response = await post(url, payload, { headers })
29-
return res.status(200).json(response)
32+
33+
const response = await fetchPost(url, payload, { headers })
34+
if (response.error) {
35+
const { code, message } = response.error
36+
return res.status(code).json({ message })
37+
} else {
38+
return res.status(200).json(response)
39+
}
3040
}

apps/studio/pages/api/platform/auth/[ref]/magiclink.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import { NextApiRequest, NextApiResponse } from 'next'
2-
import SqlString from 'sqlstring'
32

4-
import apiWrapper from 'lib/api/apiWrapper'
3+
import { fetchPost } from 'data/fetchers'
54
import { constructHeaders } from 'lib/api/apiHelpers'
6-
import { post } from 'lib/common/fetch'
7-
import { tryParseInt } from 'lib/helpers'
5+
import apiWrapper from 'lib/api/apiWrapper'
86

97
export default (req: NextApiRequest, res: NextApiResponse) => apiWrapper(req, res, handler)
108

@@ -28,6 +26,12 @@ const handlePost = async (req: NextApiRequest, res: NextApiResponse) => {
2826
})
2927
const url = `${process.env.SUPABASE_URL}/auth/v1/magiclink`
3028
const payload = { email: req.body.email }
31-
const response = await post(url, payload, { headers })
32-
return res.status(200).json(response)
29+
30+
const response = await fetchPost(url, payload, { headers })
31+
if (response.error) {
32+
const { code, message } = response.error
33+
return res.status(code).json({ message })
34+
} else {
35+
return res.status(200).json(response)
36+
}
3337
}

apps/studio/pages/api/platform/auth/[ref]/otp.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import { NextApiRequest, NextApiResponse } from 'next'
2-
import SqlString from 'sqlstring'
32

4-
import apiWrapper from 'lib/api/apiWrapper'
3+
import { fetchPost } from 'data/fetchers'
54
import { constructHeaders } from 'lib/api/apiHelpers'
6-
import { post } from 'lib/common/fetch'
7-
import { tryParseInt } from 'lib/helpers'
5+
import apiWrapper from 'lib/api/apiWrapper'
86

97
export default (req: NextApiRequest, res: NextApiResponse) => apiWrapper(req, res, handler)
108

@@ -28,6 +26,12 @@ const handlePost = async (req: NextApiRequest, res: NextApiResponse) => {
2826
})
2927
const url = `${process.env.SUPABASE_URL}/auth/v1/otp`
3028
const payload = { phone: req.body.phone }
31-
const response = await post(url, payload, { headers })
32-
return res.status(200).json(response)
29+
30+
const response = await fetchPost(url, payload, { headers })
31+
if (response.error) {
32+
const { code, message } = response.error
33+
return res.status(code).json({ message })
34+
} else {
35+
return res.status(200).json(response)
36+
}
3337
}

apps/studio/pages/api/platform/auth/[ref]/recover.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import { NextApiRequest, NextApiResponse } from 'next'
2-
import SqlString from 'sqlstring'
32

4-
import apiWrapper from 'lib/api/apiWrapper'
3+
import { fetchPost } from 'data/fetchers'
54
import { constructHeaders } from 'lib/api/apiHelpers'
6-
import { post } from 'lib/common/fetch'
7-
import { tryParseInt } from 'lib/helpers'
5+
import apiWrapper from 'lib/api/apiWrapper'
86

97
export default (req: NextApiRequest, res: NextApiResponse) => apiWrapper(req, res, handler)
108

@@ -28,6 +26,12 @@ const handlePost = async (req: NextApiRequest, res: NextApiResponse) => {
2826
})
2927
const url = `${process.env.SUPABASE_URL}/auth/v1/recover`
3028
const payload = { email: req.body.email }
31-
const response = await post(url, payload, { headers })
32-
return res.status(200).json(response)
29+
30+
const response = await fetchPost(url, payload, { headers })
31+
if (response.error) {
32+
const { code, message } = response.error
33+
return res.status(code).json({ message })
34+
} else {
35+
return res.status(200).json(response)
36+
}
3337
}

0 commit comments

Comments
 (0)