fix: harden auth middleware against transient db errors

This commit is contained in:
Your Name
2026-07-02 12:16:12 +08:00
parent c27bf04a71
commit 201cc5fb7a
3 changed files with 135 additions and 33 deletions
+48 -23
View File
@@ -689,7 +689,14 @@ async function attachUserSession(req, _res, next) {
if (!userAuth) return next();
const token = userToken(req);
req.userToken = token;
req.userSession = token ? await userAuth.verify(token) : null;
try {
req.userSession = token ? await userAuth.verify(token) : null;
req.userSessionError = null;
} catch (err) {
req.userSession = null;
req.userSessionError = err;
console.error('[Auth] session verify failed:', err instanceof Error ? err.message : err);
}
next();
}
@@ -700,18 +707,27 @@ app.use(attachUserSession);
app.get('/auth/status', async (req, res) => {
await userAuthReady;
if (userAuth) {
const me = await userAuth.getMe(userToken(req));
if (!me) return res.json({ authenticated: false, mode: 'user' });
const row = await userAuth.getUserById(me.id);
const capabilityState = await userAuth.resolveUserCapabilities(row);
return res.json({
authenticated: true,
user: me,
mode: 'user',
capabilities: capabilityState.capabilities,
grantedSkills: capabilityState.grantedSkills ?? [],
unrestricted: capabilityState.unrestricted,
});
try {
const me = await userAuth.getMe(userToken(req));
if (!me) return res.json({ authenticated: false, mode: 'user' });
const row = await userAuth.getUserById(me.id);
const capabilityState = await userAuth.resolveUserCapabilities(row);
return res.json({
authenticated: true,
user: me,
mode: 'user',
capabilities: capabilityState.capabilities,
grantedSkills: capabilityState.grantedSkills ?? [],
unrestricted: capabilityState.unrestricted,
});
} catch (err) {
console.error('[Auth] status failed:', err instanceof Error ? err.message : err);
return res.status(503).json({
authenticated: false,
mode: 'unavailable',
message: '用户认证服务不可用,请稍后重试',
});
}
}
if (isDatabaseConfigured()) {
return res.status(503).json({
@@ -1742,18 +1758,27 @@ api.use(async (req, res, next) => {
const plazaPublic = isPlazaPublicRead(req.path, req.method);
if (userAuth && tkmindProxy) {
if (req.userSession) {
if (req.userSessionError) {
if (plazaPublic) return next();
return res.status(503).json({ message: '用户认证服务不可用,请稍后重试' });
}
try {
if (req.userSession) {
const me = await userAuth.getMe(req.userToken);
if (me) req.currentUser = me;
}
if (plazaPublic) return next();
if (!req.userSession) {
return res.status(401).json({ message: '未授权,请重新登录' });
}
const me = await userAuth.getMe(req.userToken);
if (me) req.currentUser = me;
if (!me) return res.status(401).json({ message: '登录已过期' });
req.currentUser = me;
return next();
} catch (err) {
console.error('[Auth] API auth failed:', err instanceof Error ? err.message : err);
return res.status(503).json({ message: '用户认证服务不可用,请稍后重试' });
}
if (plazaPublic) return next();
if (!req.userSession) {
return res.status(401).json({ message: '未授权,请重新登录' });
}
const me = await userAuth.getMe(req.userToken);
if (!me) return res.status(401).json({ message: '登录已过期' });
req.currentUser = me;
return next();
}
if (legacyAuth?.verify(legacySessionToken(req))) return next();