forked from lobehub/lobe-chat
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmiddleware.ts
146 lines (119 loc) · 4.15 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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server';
import { NextRequest, NextResponse } from 'next/server';
import { UAParser } from 'ua-parser-js';
import urlJoin from 'url-join';
import { authEnv } from '@/config/auth';
import { LOBE_THEME_APPEARANCE } from '@/const/theme';
import NextAuthEdge from '@/libs/next-auth/edge';
import { parseBrowserLanguage } from '@/utils/locale';
import { RouteVariants } from '@/utils/server/routeVariants';
import { OAUTH_AUTHORIZED } from './const/auth';
export const config = {
matcher: [
// include any files in the api or trpc folders that might have an extension
'/(api|trpc|webapi)(.*)',
// include the /
'/',
'/discover',
'/discover(.*)',
'/chat',
'/chat(.*)',
'/changelog(.*)',
'/settings(.*)',
'/files',
'/files(.*)',
'/repos(.*)',
'/profile(.*)',
'/me',
'/me(.*)',
'/login(.*)',
'/signup(.*)',
'/next-auth/error',
// ↓ cloud ↓
],
};
const parseDefaultThemeFromTime = (request: NextRequest) => {
// 获取经度信息,Next.js 会自动解析 geo 信息到请求对象中
const longitude = 'geo' in request && (request.geo as any)?.longitude;
if (typeof longitude === 'number') {
// 计算时区偏移(每15度经度对应1小时)
// 东经为正,西经为负
const offsetHours = Math.round(longitude / 15);
// 计算当地时间
const localHour = (new Date().getUTCHours() + offsetHours + 24) % 24;
console.log(`[theme] localHour: ${localHour}`);
// 6点到18点之间返回 light 主题
return localHour >= 6 && localHour < 18 ? 'light' : 'dark';
}
return 'light';
};
const defaultMiddleware = (request: NextRequest) => {
// 1. 从 cookie 中读取用户偏好
const theme =
request.cookies.get(LOBE_THEME_APPEARANCE)?.value || parseDefaultThemeFromTime(request);
// if it's a new user, there's no cookie
// So we need to use the fallback language parsed by accept-language
const locale = parseBrowserLanguage(request.headers);
// const locale =
// request.cookies.get(LOBE_LOCALE_COOKIE)?.value ||
// browserLanguage;
const ua = request.headers.get('user-agent');
const device = new UAParser(ua || '').getDevice();
// 2. 创建规范化的偏好值
const route = RouteVariants.serializeVariants({
isMobile: device.type === 'mobile',
locale,
theme,
});
const url = new URL(request.url);
if (['/api', '/trpc', '/webapi'].some((path) => url.pathname.startsWith(path)))
return NextResponse.next();
// 处理 URL 重写
// 构建新路径: /${route}${originalPathname}
// 只对 GET 请求进行 URL 重写,确保其他类型的请求(包括 OPTIONS)不受影响
const nextPathname = `/${urlJoin(route, url.pathname)}`;
console.log(`[rewrite] ${url.pathname} -> ${nextPathname}`);
url.pathname = nextPathname;
return NextResponse.rewrite(url);
};
const publicRoute = ['/', '/discover'];
// Initialize an Edge compatible NextAuth middleware
const nextAuthMiddleware = NextAuthEdge.auth((req) => {
const response = defaultMiddleware(req);
// skip the '/' route
if (publicRoute.some((url) => req.nextUrl.pathname.startsWith(url))) return response;
// Just check if session exists
const session = req.auth;
// Check if next-auth throws errors
// refs: https://github.com/lobehub/lobe-chat/pull/1323
const isLoggedIn = !!session?.expires;
// Remove & amend OAuth authorized header
response.headers.delete(OAUTH_AUTHORIZED);
if (isLoggedIn) {
response.headers.set(OAUTH_AUTHORIZED, 'true');
}
return response;
});
const isProtectedRoute = createRouteMatcher([
'/settings(.*)',
'/files(.*)',
'/onboard(.*)',
// ↓ cloud ↓
]);
const clerkAuthMiddleware = clerkMiddleware(
async (auth, req) => {
if (isProtectedRoute(req)) await auth.protect();
return defaultMiddleware(req);
},
{
// https://github.com/lobehub/lobe-chat/pull/3084
clockSkewInMs: 60 * 60 * 1000,
signInUrl: '/login',
signUpUrl: '/signup',
},
);
export default authEnv.NEXT_PUBLIC_ENABLE_CLERK_AUTH
? clerkAuthMiddleware
: authEnv.NEXT_PUBLIC_ENABLE_NEXT_AUTH
? nextAuthMiddleware
: defaultMiddleware;