File size: 4,237 Bytes
b4297ca
 
 
 
fdaf912
 
b4297ca
 
 
 
 
fdaf912
b4297ca
d5e0a0f
b4297ca
 
 
 
 
fdaf912
b4297ca
 
 
 
 
fdaf912
 
 
 
 
 
 
b4297ca
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fdaf912
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b4297ca
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0702eb8
 
fdaf912
0702eb8
 
b4297ca
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
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).+)']
// };