fix(auth): живая сессия на устройстве — рефреш на холодном старте, grace-окно ротации, без логаута при временных ошибках
- /api/auth/me при 401 делает одну попытку refresh (раньше refresh-retry был
отключён для всех /api/auth/* — холодный старт после 15 мин простоя = логаут)
- ротация: повтор старого refresh-токена в пределах RACE_TOLERANCE_MS (5 мин)
выдаёт новую пару от successor вместо deny; cookie больше не стираются при
stale-токенах (разлогинивались все вкладки устройства); reuse после окна —
revoke family как раньше (тесты обновлены)
- refreshSession различает 401/403/400 (сессия мертва) vs 429/5xx/сеть
(transient — нет logout, отложенный retry)
- единый рефреш: useAuth keep-alive и useOfflineSync переведены на refreshSession;
межвкладочная дедупликация через BroadcastChannel('auth-refresh')
- refreshLimiter: keyGenerator buildRateLimitKey (per-user, не общий IP-бакет офиса)
This commit is contained in:
@@ -188,7 +188,11 @@ export function registerAuthCoreRoutes(router: Router): void {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
clearAuthCookies(res);
|
||||
// clearCookies === false: неоднозначный отказ (гонка ротации, successor
|
||||
// не найден) — cookie не трогаем, у клиента может быть живая winner-cookie.
|
||||
if (result.clearCookies !== false) {
|
||||
clearAuthCookies(res);
|
||||
}
|
||||
res.status(401).json({ success: false, error: result.error });
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user