// sync_token 验证 — 使用与 EternalAI 共享的 SYNC_SECRET 验证 JWT
// sync_token 由 EternalAI 签发（HS256），包含 { roleId, adminId, jti, type:'sync' }，5 分钟过期

const jwt = require('jsonwebtoken');

const SYNC_SECRET = process.env.SYNC_SECRET;

if (!SYNC_SECRET) {
  if (process.env.NODE_ENV === 'production') {
    throw new Error(
      'SYNC_SECRET 环境变量未设置。请从 EternalAI 数据库获取 SYNC_SECRET 并配置到 .env 文件中。\n' +
      '获取方式：在 EternalAI 服务器执行\n' +
      '  psql -d eternalai -c \'SELECT value FROM "SystemConfig" WHERE key=\'\'SYNC_SECRET\'\'\'\''
    );
  }
  console.warn('[安全警告] SYNC_SECRET 未设置，sync_token 验证将无法工作。请在 .env 中配置与 EternalAI 一致的 SYNC_SECRET。');
}

// P2 修复：jti 重放保护 — 内存缓存已使用的 jti，5 分钟 TTL
const usedJtis = new Map();
const JTI_TTL_MS = 5 * 60 * 1000;

function cleanupExpiredJtis() {
  const now = Date.now();
  for (const [jti, ts] of usedJtis) {
    if (now - ts > JTI_TTL_MS) {
      usedJtis.delete(jti);
    }
  }
}

// 验证 sync_token，返回 payload 或 null
function verifySyncToken(token) {
  if (!SYNC_SECRET) {
    return null;
  }
  try {
    // P3 修复：显式指定算法，防止 alg 混淆攻击
    const decoded = jwt.verify(token, SYNC_SECRET, { algorithms: ['HS256'] });
    if (decoded.type !== 'sync') return null;

    // P2 修复：jti 重放保护
    if (decoded.jti) {
      cleanupExpiredJtis();
      if (usedJtis.has(decoded.jti)) {
        console.warn('[安全警告] sync_token 重放被拒绝, jti:', decoded.jti);
        return null;
      }
      usedJtis.set(decoded.jti, Date.now());
    }

    return decoded;
  } catch {
    return null;
  }
}

module.exports = { verifySyncToken };
