Spaces:
Build error
Build error
import { User } from "next-auth"; | |
import { NextRequest, NextResponse } from "next/server"; | |
import { createClient } from "@supabase/supabase-js" | |
type session = {} | User; | |
export const middleware = async (request: NextRequest) => { | |
const { pathname, origin } = request.nextUrl; | |
const signinPage = new URL('/sign-in', origin); | |
// Add callbackUrl params to the signinPage URL | |
signinPage.searchParams.set('callbackUrl', pathname); | |
const unauthorizedPage = new URL('/unauthorized', origin); | |
// Retrieve the session token from the request cookies | |
const session = request.cookies.get('next-auth.session-token') || request.cookies.get('__Secure-next-auth.session-token'); | |
if (session) { | |
// console.log('session:', session); | |
// Check the database for the session token | |
const supabaseAuth = createClient( | |
process.env.SUPABASE_URL ?? '', | |
process.env.SUPABASE_SERVICE_ROLE_KEY ?? '', | |
{ db: { schema: 'next_auth' } }, | |
); | |
const supabase = createClient( | |
process.env.SUPABASE_URL ?? '', | |
process.env.SUPABASE_SERVICE_ROLE_KEY ?? '', | |
{ db: { schema: 'public' } }, | |
); | |
const { data, error } = await supabaseAuth | |
.from('sessions') | |
.select('userId, expires') | |
.eq('sessionToken', session?.value) | |
.single(); | |
// console.log('data:', data); | |
// Check if the session is expired or not | |
const now = new Date().getTime(); | |
const expires = new Date(data?.expires).getTime(); | |
const sessionExpired = expires > now ? true : false; | |
// Redirect to the sign-in page if the session is expired and not on the sign-in page | |
if (pathname != "/sign-in" && !sessionExpired) { | |
return NextResponse.redirect(signinPage.href, { status: 302 }); | |
} | |
if (error) { | |
// Redirect to the sign-in page if there is an error fetching the session from the database | |
console.error('Error fetching session from database:', error.message); | |
return NextResponse.redirect(signinPage.href, { status: 302 }); | |
} | |
// Check if the user is an admin for specific routes | |
const adminPaths = ['/admin', '/admin/*', '/api/admin/*']; | |
// Dont match /api/admin/is-admin | |
const allowedAdminPaths = ['/api/admin/is-admin']; | |
// Match the pathname to the admin paths but not the allowed admin paths | |
const isAdminRoute = adminPaths.some((path) => new RegExp(path).test(pathname)) && !allowedAdminPaths.some((path) => new RegExp(path).test(pathname)); | |
if (isAdminRoute) { | |
const { data: adminData, error: adminError } = await supabase | |
.from('admins') | |
.select('id') | |
.eq('id', data?.userId) | |
.single(); | |
// Redirect to the unauthorized page if the user is not an admin | |
if (adminError || !adminData) { | |
console.error('User is not an admin or error fetching admin data:', adminError?.message); | |
return NextResponse.redirect(unauthorizedPage.href, { status: 302 }); | |
} | |
} | |
} | |
else { | |
// Redirect to the sign-in page if there is no session token | |
// console.error('No session token found'); | |
return NextResponse.redirect(signinPage.href, { status: 302 }); | |
} | |
// Continue to the next middleware | |
return NextResponse.next(); | |
} | |
export const config = { | |
matcher: ['/((?!api/auth|_next/static|_next/image|favicon.ico|favicon-16x16.png|apple-touch-icon.png|about|sign-in|api/status|privacy-policy|terms-of-service|sitemap.xml|robots.txt).+)'] | |
} | |
// Default middleware for NextAuth checking for JWT session not database session | |
// export { default } from "next-auth/middleware" | |
// export const config = { | |
// matcher: ["/chat", "/search", "/query"] | |
// } | |
// // Ensure auth is required for all except the following paths | |
// export const config = { | |
// matcher: ['/((?!api/auth|_next/static|_next/image|favicon.ico|favicon-16x16.png|apple-touch-icon.png|about|sign-in|api/status|privacy-policy|terms-of-service|sitemap.xml|robots.txt).+)'] | |
// }; |