apiAuthenticate.ts52 lines · main
1import type { JwtPayload } from '@supabase/supabase-js'
2import type { NextApiRequest, NextApiResponse } from 'next'
3
4import { getUserClaims } from '@/lib/gotrue'
5import type { ResponseError } from '@/types'
6
7/**
8 * Use this method on api routes to check if user is authenticated and having required permissions.
9 * This method can only be used from the server side.
10 * Member permission is mandatory whenever orgSlug/projectRef query param exists
11 * @param {NextApiRequest} req
12 * @param {NextApiResponse} _res
13 *
14 * @returns {Object<user, error, description>}
15 * user null, with error and description if not authenticated or not enough permissions
16 */
17export async function apiAuthenticate(
18 req: NextApiRequest,
19 _res: NextApiResponse
20): Promise<JwtPayload | { error: ResponseError }> {
21 try {
22 const claims = await fetchUserClaims(req)
23 if (!claims) {
24 return { error: new Error('The user does not exist') }
25 }
26
27 return claims
28 } catch (error) {
29 return { error: error as ResponseError }
30 }
31}
32
33/**
34 * @returns
35 * user with only id prop or detail object. It depends on requireUserDetail config
36 */
37export async function fetchUserClaims(req: NextApiRequest): Promise<JwtPayload> {
38 const token = req.headers.authorization?.replace(/bearer /i, '')
39 if (!token) {
40 throw new Error('missing access token')
41 }
42 const { claims, error } = await getUserClaims(token)
43 if (error) {
44 throw error
45 }
46
47 if (!claims) {
48 throw new Error('The user does not exist')
49 }
50
51 return claims
52}