-
Notifications
You must be signed in to change notification settings - Fork 0
/
middleware.ts
102 lines (89 loc) · 2.69 KB
/
middleware.ts
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
import { jwtVerify } from "jose";
import { NextRequest, NextResponse } from "next/server";
import { getJWTSecretKey } from "./lib/auth";
import { HEADER_TOKEN_USERNAME } from "./middlewareHeaders";
const publicEndpoints = [
"/api/auth/login",
"/api/auth/register",
"/auth/login",
"/auth/register",
];
// if the user is logged in, kick 'em to /dashboard when user tries to access these endpoints
const kickWhenLoggedInEndpoints = [
"/api/auth/login",
"/api/auth/register",
"/auth/login",
"/auth/register",
];
function injectTokenPayload(req: NextRequest, username: string): NextResponse {
const headers = new Headers(req.headers);
headers.append(HEADER_TOKEN_USERNAME, username);
return NextResponse.next({ request: { headers } });
}
export default async function middleware(
req: NextRequest
): Promise<NextResponse> {
const isPublic =
publicEndpoints.find((ep) => req.nextUrl.pathname.startsWith(ep)) !=
undefined;
if (!isPublic) {
if (!req.cookies.has("token")) {
return NextResponse.redirect(
`${req.nextUrl.protocol}//${req.nextUrl.host}/auth/login`
);
}
const token = req.cookies.get("token")!;
let jwt;
try {
jwt = await jwtVerify(token.value, getJWTSecretKey());
} catch {
// invalid token! invalidate it
const response = NextResponse.redirect(
`${req.nextUrl.protocol}//${req.nextUrl.host}/auth/login`
);
response.cookies.delete("token");
return response;
}
// valid request yay!
return injectTokenPayload(req, jwt.payload["username"] as string);
} else {
const token = req.cookies.get("token");
let jwt;
if (token) {
try {
jwt = await jwtVerify(token.value, getJWTSecretKey());
} catch {
// invalid token! invalidate it
const response = NextResponse.next();
response.cookies.delete("token");
return response;
}
// valid token and public endpoint, check if we should kick em
const shouldKick =
kickWhenLoggedInEndpoints.find((ep) =>
req.nextUrl.pathname.startsWith(ep)
) != undefined;
if (shouldKick) {
return NextResponse.redirect(
`${req.nextUrl.protocol}//${req.nextUrl.host}/dashboard`
);
}
}
if (jwt) {
return injectTokenPayload(req, jwt.payload["username"] as string);
} else {
return NextResponse.next();
}
}
}
export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
*/
"/((?!_next/static|_next/image|favicon.ico).*)",
],
};