-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmiddleware.ts
More file actions
90 lines (77 loc) · 2.71 KB
/
middleware.ts
File metadata and controls
90 lines (77 loc) · 2.71 KB
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
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
// Add atob for base64 decoding
function isJwtExpired(token: string): boolean {
try {
const payload = token.split('.')[1]
const decoded = JSON.parse(Buffer.from(payload, 'base64').toString('utf-8'))
if (!decoded.exp) return false
// exp is in seconds since epoch
return Date.now() >= decoded.exp * 1000
} catch {
// If token is malformed, treat as expired
return true
}
}
function isTokenExpiredAfter24Hours(token: string): boolean {
try {
const payload = token.split('.')[1]
const decoded = JSON.parse(Buffer.from(payload, 'base64').toString('utf-8'))
if (!decoded.iat) return false // iat = issued at time
// Check if 24 hours (86400000 milliseconds) have passed since token was issued
const tokenIssuedAt = decoded.iat * 1000 // Convert to milliseconds
const twentyFourHoursInMs = 24 * 60 * 60 * 1000
return Date.now() >= tokenIssuedAt + twentyFourHoursInMs
} catch {
// If token is malformed, treat as expired
return true
}
}
export function middleware(request: NextRequest) {
const token = request.cookies.get('auth-token')?.value
// List of public routes
const publicPaths = [
'/login',
'/register',
'/email-confirmation',
'/not-found',
'/',
'events',
'venues',
'/events/check-attendance/insipector',
'/events/check-attendance/scan'
]
const isPublic = publicPaths.some(path => request.nextUrl.pathname.startsWith(path))
// Check for missing or expired token
if (!isPublic && (!token || isJwtExpired(token))) {
const loginUrl = new URL('/login', request.url)
loginUrl.searchParams.set('redirect', request.nextUrl.pathname)
// Set a cookie flag to indicate token expiration for client-side logout
const response = NextResponse.redirect(loginUrl)
response.cookies.set('token-expired', 'true', {
path: '/',
sameSite: 'lax',
maxAge: 60 // 1 minute, just enough for the redirect
})
return response
}
// Check for 24-hour expiration
if (!isPublic && token && isTokenExpiredAfter24Hours(token)) {
const loginUrl = new URL('/login', request.url)
loginUrl.searchParams.set('redirect', request.nextUrl.pathname)
// Set a cookie flag to indicate 24-hour expiration for client-side logout
const response = NextResponse.redirect(loginUrl)
response.cookies.set('token-expired-24h', 'true', {
path: '/',
sameSite: 'lax',
maxAge: 60 // 1 minute, just enough for the redirect
})
return response
}
return NextResponse.next()
}
export const config = {
matcher: [
'/((?!login|register|email-confirmation|not-found).*)',
],
}