/** * 共享安全事件日志模块 (M14) * * 替代 5 个 hook 中各自实现的 logSecurityEvent 函数。 * 统一日志格式、脱敏策略和文件写入逻辑。 */ const fs = require('fs'); const path = require('path'); const { safeAppendJsonl } = require('./safe-append.js'); const CLAUDE_ROOT = require('./root.js'); const DEBUG_DIR = path.join(CLAUDE_ROOT, 'debug'); // 脱敏函数(优先使用 sanitize.js) const _sanitize = (() => { try { return require('../../scripts/sanitize.js').sanitize; } catch { return (text) => (text || '').replace(/[A-Za-z0-9+/]{32,}/g, '[REDACTED]'); } })(); /** * 写入安全事件日志 * @param {string} decision - 决策类型 (deny/ask/allow/auto-fix/hook-tamper 等) * @param {string} hook - hook 名称 * @param {string} reason - 原因描述 * @param {string} [detail] - 详细信息(会被脱敏和截断) */ function logSecurityEvent(decision, hook, reason, detail) { try { if (!fs.existsSync(DEBUG_DIR)) fs.mkdirSync(DEBUG_DIR, { recursive: true }); const dateStr = new Date().toISOString().slice(0, 10); const logFile = path.join(DEBUG_DIR, `security-${dateStr}.jsonl`); const entry = { ts: new Date().toISOString(), decision, hook, reason, detail: _sanitize((detail || '').slice(0, 200)), }; safeAppendJsonl(logFile, entry); } catch {} } module.exports = { logSecurityEvent, _sanitize };