-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmiddleware.js
72 lines (62 loc) · 2.14 KB
/
middleware.js
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
import { jwtVerify } from "jose";
import { NextResponse } from "next/server";
/**
* Middleware to handle JWT verification and route protection.
*
*
* @async
* @function middleware
* @param {Request} req - The incoming HTTP request object.
* @returns {Promise<NextResponse>} - Proceeds to the next middleware or redirects to login.
*/
export async function middleware(req) {
console.log("Intercepted path:", req.nextUrl.pathname);
const url = req.nextUrl;
// Exclude static files (served directly from the public folder)
if (
url.pathname.startsWith("/_next") || // Built assets
url.pathname.match(/\.(png|jpg|jpeg|gif|svg|ico|webp)$/) || // Image files
url.pathname.startsWith("/public/") // Allow serving static files from the public directory
) {
return NextResponse.next();
}
// Retrieve the token from cookies
const token = req.cookies.get("token");
if (!token) {
// Redirect to login if the token is missing
const redirectUrl = new URL("/login", req.url);
redirectUrl.searchParams.set("redirectTo", url.pathname);
return NextResponse.redirect(redirectUrl);
}
try {
// Verify the token using jose
const secret = new TextEncoder().encode(process.env.JWT_SECRET);
const { payload } = await jwtVerify(token.value, secret);
// Attach user data to headers
const newHeaders = new Headers(req.headers);
newHeaders.set("x-user", JSON.stringify(payload));
// Proceed to the next middleware or route handler
return NextResponse.next({
request: {
headers: newHeaders,
},
});
} catch (error) {
console.error("JWT Verification Error:", error.message);
// Redirect to login for invalid tokens
const redirectUrl = new URL("/login", req.url);
redirectUrl.searchParams.set("redirectTo", req.nextUrl.pathname);
return NextResponse.redirect(redirectUrl);
}
}
/**
* Specifies which routes the middleware applies to.
*
*
* @constant
* @type {Object}
* @property {Array<string>} matcher - Array of route patterns requiring authentication.
*/
export const config = {
matcher: ["/favourites", "/shoppingList"], // Add routes requiring authentication
};