-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmiddleware.ts
118 lines (99 loc) · 3.47 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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import {NextRequest, NextResponse} from 'next/server';
import {JwtPayload} from 'jsonwebtoken';
import {verifyJwtToken} from './lib/server/auth';
import {getAuthTokenServer} from '@/utils/getAuthTokenServer';
import createMiddleware from 'next-intl/middleware';
import {routing} from './i18n/routing';
const locales = ['en-US', 'pt-BR'];
const defaultLocale = 'en-US';
interface JWTAccessToken extends JwtPayload {
id: number,
email: string,
givenName: string,
surName: string,
role: string,
languageId: string,
jti: string,
expiresIn: number,
}
// TODO: These routes will need to be updated.
const excludedPaths = ['/email', '/favicon.ico', '/_next', '/api', '/login', '/signup'];
const handleI18nRouting = createMiddleware(routing);
async function getLocaleFromJWT(): Promise<string | null> {
try {
const token = await getAuthTokenServer();
if (!token) {
return null;
}
const user = await verifyJwtToken(token);
const { languageId } = user as JWTAccessToken;
if (languageId && locales.includes(languageId)) {
return languageId;
}
return null;
} catch (error) {
console.error('Error parsing JWT:', error);
return null;
}
}
async function getLocale(request: NextRequest) {
try {
// First try and get locale from JWT
const userLocale = await getLocaleFromJWT();
if (userLocale) return userLocale;
//Fall back to Accept-Language header
const acceptLanguage = request.headers.get('Accept-Language');
if (acceptLanguage) {
const browserLocale = acceptLanguage
.split(',')[0]
.split('-')[0]
.toLowerCase();
if (locales.includes(browserLocale)) {
return browserLocale
}
}
//Otherwise, use Default locale
return defaultLocale;
} catch (error) {
console.log('Error detecting locale:', error);
return defaultLocale;
}
}
export async function middleware(request: NextRequest) {
const response = NextResponse.next();
const { pathname } = request.nextUrl;
const accessToken = request.cookies.get('dmspt');
const refreshToken = request.cookies.get('dmspr');
/* TODO: might want to add a 'redirect' query param to url to redirect user after
login to the original page they were trying to get to.*/
/* Check for tokens for paths that are not excluded from authentication
and are not signup or login */
const isExcludedPath = excludedPaths.some(path => pathname.includes(path));
if (!isExcludedPath) {
if (!accessToken && !refreshToken) {
return NextResponse.redirect(new URL('/login', request.url));
}
}
const pathnameIsMissingLocale = locales.every(
(locale) => !pathname.startsWith(`/${locale}`) && pathname !== `/${locale}`
);
if (pathnameIsMissingLocale) {
const locale = await getLocale(request);
const newUrl = new URL(`/${locale}${pathname}`, request.url);
if (request.nextUrl.search) {
newUrl.search = request.nextUrl.search; // Only assign if it's valid
}
return NextResponse.redirect(newUrl);
}
const i18nResponse = handleI18nRouting(request);
if (i18nResponse) return i18nResponse;
// Add url info to custom header. Need this for just the /dmps landing page
if (request.nextUrl.pathname.startsWith('/en-US/dmps')) {
response.headers.set('x-url', request.nextUrl.href);
}
return response;
}
export const config = {
// Don't run middleware for api endpoints, static files, anything in our pubic folder or _next files
matcher: ['/((?!api|_next|static|.*\\..*).*)',]
};