| import type { Request, Response, NextFunction } from 'express' |
| import { getIdentityFromRequest, issueIdentityCookie } from '../services/identityService.js' |
| import { logger } from '../utils/logger.js' |
| import { userRepo } from '../repositories/userRepository.js' |
|
|
| const RENEWAL_LOG_INTERVAL_MS = 5 * 60 * 1000 |
| const RENEWAL_MAP_MAX_SIZE = 10_000 |
| const renewalLogAt = new Map<string, number>() |
|
|
| |
| const RENEWAL_CLEANUP_INTERVAL_MS = 10 * 60 * 1000 |
| setInterval(() => { |
| const threshold = Date.now() - RENEWAL_LOG_INTERVAL_MS |
| for (const [userId, lastTime] of renewalLogAt) { |
| if (lastTime < threshold) renewalLogAt.delete(userId) |
| } |
| }, RENEWAL_CLEANUP_INTERVAL_MS).unref() |
|
|
| function shouldLogRenewal(userId: string): boolean { |
| const now = Date.now() |
| const last = renewalLogAt.get(userId) ?? 0 |
| if (now - last < RENEWAL_LOG_INTERVAL_MS) return false |
| |
| if (renewalLogAt.size >= RENEWAL_MAP_MAX_SIZE) { |
| const firstKey = renewalLogAt.keys().next().value |
| if (firstKey) renewalLogAt.delete(firstKey) |
| } |
| renewalLogAt.set(userId, now) |
| return true |
| } |
|
|
| |
| |
| |
| |
| export function identityHttpMiddleware(req: Request, res: Response, next: NextFunction): void { |
| const identity = getIdentityFromRequest(req) |
| if (identity) { |
| userRepo.touch(identity.userId) |
| req.identityUserId = identity.userId |
| const issued = issueIdentityCookie(req, res, identity.userId) |
| if (shouldLogRenewal(identity.userId)) { |
| logger.debug('客户端身份凭据已续期', { |
| userId: identity.userId, |
| method: req.method, |
| path: req.path, |
| expiresAt: issued.expiresAt, |
| }) |
| } |
| } |
| next() |
| } |
|
|