# 更新日志 本文件记录本项目的所有重要变更。 格式参考 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/), 版本号遵循 [语义化版本](https://semver.org/lang/zh-CN/)。 ## [Unreleased] ### Added - iframe 支持:脚本注入所有帧(`allFrames`),可填充内嵌在 iframe 中的登录表单(如 SSO 登录页) - 构建管线:引入 esbuild 负责打包与压缩,`tsc` 只做类型检查(`scripts/build.mjs`) - 构建自检:校验 `manifest.json` / `popup.html` 引用的文件是否存在、版本号是否一致 - 打包与发布脚本:`npm run package` 产出 zip,`npm run release -- ` 递增版本并同步 `manifest.json` / `package.json` / `updates.xml` - CI:`.gitea/workflows/release.yml`,推送 `v*` 标签时自动测试、打包并上传产物 - 密钥句柄存储模块 `src/key-store.ts`:以不可导出的 `CryptoKey` 句柄替代明文口令,实现 Service Worker 重启后自动解锁 - `utils.toMatchPatterns()`:把域名配置转成合法的 Chrome match pattern - 按域名的动态脚本注入:只向用户配置过的域名注册 content script - 测试:新增 `tests/key-store.test.js`、`tests/content-fill.test.js`(jsdom 真实 DOM)、`tests/permissions.test.js`,测试总数 54 → 114 - 文档:`README.md`、`PRIVACY.md`、`CHANGELOG.md`、`LICENSE` - 代码规范:ESLint(扁平配置)+ Prettier,提供 `npm run lint` / `format` 脚本,CI 中执行检查 - 调试日志开关:`chrome.storage.local.debugLog`(`utils.initDebugLog` / `debugLog`),默认静默 ### Changed - `popup.ts`(1479 行)拆分为 `src/popup/` 下 15 个模块,模块间通过 `PopupCtx` 上下文互相调用,消除网状耦合 - `manifest.json` 移除静态 `content_scripts`(原为 `` 无条件注入所有页面) - **站点访问权限改为按域名授权**:移除 `host_permissions: `,改用 `optional_host_permissions`,在保存配置时逐域名询问;未授权域名不再自动填充,但手动填充仍可用 - 移除 `tabs` 权限(改用 `activeTab`),安装提示不再包含"读取您的浏览记录" - 配置列表新增「未授权」标记,点击即可重新申请站点访问权限 - 别名兜底改为优先取当前标签页标题(`activeTab` 即可读),并修正未声明 `tabs` 时 `tabs.query({url})` 过滤被忽略导致可能取到无关标题的问题 - 信息类日志改为按需输出(默认静默),仅保留异常告警常驻输出;新增 `chrome.storage.local.debugLog` 开关 - 多环境浮窗的移除逻辑收敛为 `closeEnvPicker()`,去掉几处"表达式语句"写法 ### Performance - SPA 重试改为"DOM 变更门控 + 退避"策略:页面自上次扫描后无任何变更时跳过该轮全量 DOM 扫描,重试间隔从固定 500ms 改为 300ms → 3s 逐步退避。大页面(数万节点)在 30 秒窗口内的全量扫描次数从最多 60 次降到个位数 - 扫描中发现的 Shadow Root 会被单独监听(body 上的 MutationObserver 感知不到 Shadow DOM 内部变化),在降低扫描频次的同时避免漏填组件内部后渲染的登录框 - 手动填充改为"探测已注入标记 → `chrome.scripting.executeScript` 按需注入",并逐帧探测、定向发消息到"真正有密码框"的帧 - 多环境选择浮窗只在顶层帧渲染;子帧(iframe)内命中多个环境时改用当前激活环境的配置,避免浮窗被 iframe 裁切 - `dist/` 不再纳入版本控制,改为构建产物;克隆后需执行 `npm run build` - 类型检查与产物生成分离:`tsconfig.json` 设置 `noEmit` ### Security - **按最小权限运行**:不再持有"访问所有网站"的永久权限,站点访问权改为用户逐域名授予;配合已移除的 `tabs` 权限,安装提示中不再出现全站数据访问与浏览记录条目 - **移除明文口令存储**:不再把主口令写入 `chrome.storage.session`,改为在 IndexedDB 保存不可导出的密钥句柄;旧版本残留的 `__autoPwd` 在升级后会被自动迁移为句柄并立即删除 - 锁定(手动或 10 分钟无操作)时一并删除密钥句柄,解锁状态不再"自动复活" - 脚本注入范围由"所有网站"收敛为"用户配置过的域名",锁定时自动清空 - 未配置的站点不再执行任何扩展脚本,同时消除了原先在所有页面常驻的 `MutationObserver` ### Fixed - 尝试次数只在**真正触发提交后**才累加:此前命中域名但页面没有登录框也会消耗配额,导致"登录成功后在站内浏览几个页面,自动提交就被暂停" - 登录成功后计数不再累积:新增提交结果观察(登录框消失或已离开匹配地址 → 判定成功 → 清零),修正了纯域名配置下"连续 3 次成功登录后停止自动提交"的问题 - 达到上限时给出**页面可见提示**(此前只有一条默认静默的调试日志,用户只看到"填了但不提交") - 计数重置判断只看启用中的配置,被禁用的配置不再阻止重置 - 命中配置但整页始终没有登录框时清掉旧的尝试计数 - `tests/detect-captcha.test.js` 缺少 `chrome.runtime.sendMessage` mock,导致加载 `content.js` 时抛出未处理的 Promise 拒绝,测试结果不干净 ## [1.0.0] - 2026-09-14 ### Added - 首个可用版本 - 域名自动填充与自动提交,支持通配符与路径匹配 - 多环境(个人 / 测试 / 生产)管理与多环境命中弹窗选择 - 登录表单字段三级降级探测,支持 Shadow DOM 穿透与 SPA 延迟重试 - 验证码检测(reCAPTCHA / hCaptcha / 滑块 / 图形码),命中时只填充不提交 - 同一域名连续失败 3 次后暂停自动提交,5 分钟后恢复 - 保险库加密:PBKDF2-SHA256(20 万次迭代)+ AES-GCM-256,自动锁定 - 配置导入导出(兼容 v1 / v2 / v3 格式,支持文件口令加密) - 从浏览器书签批量导入域名 - 口令强度评估与暴力破解耗时估算 - 中英双语界面,侧边栏形态