apiAuthenticate.ts52 lines · main
| 1 | import type { JwtPayload } from '@supabase/supabase-js' |
| 2 | import type { NextApiRequest, NextApiResponse } from 'next' |
| 3 | |
| 4 | import { getUserClaims } from '@/lib/gotrue' |
| 5 | import 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 | */ |
| 17 | export 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 | */ |
| 37 | export 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 | } |