2026-06-22 15:36:56 +08:00
|
|
|
const CACHE = 'v2';
|
2026-06-22 14:59:24 +08:00
|
|
|
const LOGIN = '/login';
|
|
|
|
|
const EXPIRE_MS = 3 * 60 * 60 * 1000;
|
2026-06-21 23:28:31 +08:00
|
|
|
|
|
|
|
|
self.addEventListener('install', () => self.skipWaiting());
|
|
|
|
|
self.addEventListener('activate', e => e.waitUntil(self.clients.claim()));
|
|
|
|
|
|
|
|
|
|
self.addEventListener('fetch', e => {
|
|
|
|
|
const req = e.request;
|
2026-06-22 14:59:24 +08:00
|
|
|
const url = new URL(req.url);
|
|
|
|
|
|
2026-06-22 15:55:09 +08:00
|
|
|
// 登录页、静态资源不拦截
|
2026-06-22 14:59:24 +08:00
|
|
|
if (url.pathname === '/login' || url.pathname.startsWith('/_next/') ||
|
|
|
|
|
url.pathname.endsWith('.js') || url.pathname.endsWith('.css') ||
|
|
|
|
|
url.pathname.endsWith('.ico') || url.pathname.endsWith('.woff2')) {
|
2026-06-21 23:28:31 +08:00
|
|
|
e.respondWith(fetch(req));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
e.respondWith((async () => {
|
|
|
|
|
const token = self.__auth_token;
|
2026-06-22 13:01:37 +08:00
|
|
|
const tokenTime = self.__auth_time || 0;
|
2026-06-22 15:55:09 +08:00
|
|
|
const isApi = url.pathname.startsWith('/api/');
|
2026-06-22 13:01:37 +08:00
|
|
|
|
2026-06-22 15:55:09 +08:00
|
|
|
// 无 token 且不是 API 请求 → 跳转登录
|
2026-06-22 13:01:37 +08:00
|
|
|
if (!token || (Date.now() - tokenTime > EXPIRE_MS)) {
|
2026-06-22 15:55:09 +08:00
|
|
|
if (!isApi) {
|
|
|
|
|
self.__auth_token = null;
|
|
|
|
|
self.__auth_time = 0;
|
|
|
|
|
return Response.redirect(LOGIN, 302);
|
|
|
|
|
}
|
|
|
|
|
// API 请求无 token,直接发(让 API 自己返回 401)
|
|
|
|
|
return fetch(req);
|
2026-06-21 23:28:31 +08:00
|
|
|
}
|
|
|
|
|
|
2026-06-22 15:55:09 +08:00
|
|
|
// 添加认证头
|
2026-06-21 23:28:31 +08:00
|
|
|
const headers = new Headers(req.headers);
|
2026-06-22 14:59:24 +08:00
|
|
|
headers.set('X-Auth-User', token);
|
2026-06-21 23:28:31 +08:00
|
|
|
const res = await fetch(new Request(req, { headers }));
|
|
|
|
|
|
2026-06-22 15:55:09 +08:00
|
|
|
// 非 API 请求 401 → 跳转登录
|
|
|
|
|
if (res.status === 401 && !isApi) {
|
2026-06-22 13:01:37 +08:00
|
|
|
self.__auth_token = null;
|
|
|
|
|
self.__auth_time = 0;
|
2026-06-21 23:28:31 +08:00
|
|
|
return Response.redirect(LOGIN, 302);
|
|
|
|
|
}
|
2026-06-22 14:59:24 +08:00
|
|
|
|
2026-06-21 23:28:31 +08:00
|
|
|
return res;
|
|
|
|
|
})());
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
self.addEventListener('message', e => {
|
|
|
|
|
if (e.data && e.data.type === 'SET_TOKEN') {
|
|
|
|
|
self.__auth_token = e.data.token;
|
2026-06-22 13:01:37 +08:00
|
|
|
self.__auth_time = Date.now();
|
2026-06-21 23:28:31 +08:00
|
|
|
}
|
|
|
|
|
if (e.data && e.data.type === 'CLEAR_TOKEN') {
|
|
|
|
|
self.__auth_token = null;
|
2026-06-22 13:01:37 +08:00
|
|
|
self.__auth_time = 0;
|
2026-06-21 23:28:31 +08:00
|
|
|
}
|
|
|
|
|
});
|