feat: 按域名授权、iframe 多帧填充、自动提交限流修正,并补齐工程规范与文档
安全与权限: - 站点访问权限改为 optional_host_permissions,保存配置时逐域名授权;移除 host_permissions 与 tabs,安装提示不再出现全站数据访问与浏览记录 - 主口令不再写入 storage.session,改用 IndexedDB 中不可导出的 CryptoKey 句柄恢复解锁,锁定即丢弃 - content script 注入范围只注册已授权域名,并随权限变化即时收敛 自动登录: - 支持 iframe 内的登录表单:脚本注入所有帧,逐帧按自身地址匹配配置 - 手动填充改为逐帧探测,定向发送到真正含密码框的帧 - 限流修正:只在真正触发提交后计数;判定登录成功后立即清零;达到上限时页面给出可见提示;重置判断只看启用中的配置 - SPA 重试改为 DOM 变更门控 + 退避,并单独监听已发现的 Shadow Root 工程化与文档: - 引入 ESLint(扁平配置)与 Prettier,CI 增加 lint 与 format:check - 信息类日志改为 debugLog(默认静默,chrome.storage.local.debugLog 开关) - 测试 123 → 128 用例(新增权限、iframe、限流相关用例) - README / PRIVACY / CHANGELOG 同步
This commit is contained in:
@@ -18,9 +18,10 @@ Chrome Manifest V3 扩展。所有凭据只保存在本机,不上传任何服
|
||||
- 自动填充用户名与密码,可选择是否自动点击登录
|
||||
- 三级降级探测字段:显式选择器 → 关键词启发式(`name` / `id` / `placeholder` / `autocomplete`)→ 全量兜底
|
||||
- 支持 Shadow DOM 穿透(组件库封装的登录框也能识别)
|
||||
- 针对 SPA 的延迟重试:表单晚于脚本渲染时,最长 30 秒内持续重试
|
||||
- 支持 iframe 内的登录表单(如 SSO 内嵌登录页):脚本注入所有帧,各帧按自己的地址匹配配置;iframe 内命中多个环境时不弹浮窗(避免被裁切),改用当前激活环境
|
||||
- 针对 SPA 的延迟重试:表单晚于脚本渲染时,最长 30 秒内持续重试。重试按 DOM 变更门控并逐步退避,且会监听已发现的 Shadow Root,因此既不会在大页面空转,也不会漏掉组件内部后渲染的登录框
|
||||
- 检测到验证码(reCAPTCHA / hCaptcha / 滑块 / 图形码)时只填充、不自动提交,并提示手动完成
|
||||
- 同一域名连续登录失败 3 次后暂停自动提交,5 分钟后自动恢复
|
||||
- 同一域名连续**自动提交** 3 次后暂停自动提交(仍填充),5 分钟后自动恢复;检测到登录成功(登录框消失或已离开匹配地址)会立即清零计数,达到上限时页面上会给出提示
|
||||
- 手动填充:在当前页面按需注入并填充,无需预先打开对应页面
|
||||
|
||||
**安全与数据**
|
||||
@@ -52,7 +53,9 @@ Chrome Manifest V3 扩展。所有凭据只保存在本机,不上传任何服
|
||||
- **口令不落盘**:Service Worker 空闲被回收后,靠 IndexedDB 中的密钥句柄恢复解锁,无需重新输入口令,同时避免了口令被读取
|
||||
- **句柄不可导出**:`crypto.subtle.exportKey()` 对句柄会失败,拿到句柄只能"使用"不能"抄走"
|
||||
- **锁定即失效**:手动锁定或自动锁定会删除会话明文与密钥句柄
|
||||
- **注入范围 = 已配置域名**:通过 `chrome.scripting.registerContentScripts` 动态注册,锁定时自动清空
|
||||
- **默认零站点权限**:不声明 `host_permissions`,站点访问权走 `optional_host_permissions`,安装时**不申请**任何网站访问权限
|
||||
- **按域名授权**:保存配置时才询问一次"允许访问该网站";拒绝也只是该域名不自动填充,**手动填充始终可用**(靠 `activeTab`)
|
||||
- **注入范围 = 已授权域名**:通过 `chrome.scripting.registerContentScripts` 动态注册,只注册已授权的站点,锁定时自动清空
|
||||
|
||||
## 技术栈
|
||||
|
||||
@@ -101,6 +104,10 @@ npm install
|
||||
| 命令 | 说明 |
|
||||
| --- | --- |
|
||||
| `npm run typecheck` | 仅类型检查(`tsc --noEmit`) |
|
||||
| `npm run lint` | ESLint 检查(未使用变量、常见错误) |
|
||||
| `npm run lint:fix` | ESLint 自动修复 |
|
||||
| `npm run format` | Prettier 格式化 `src` / `scripts` / `tests` |
|
||||
| `npm run format:check` | 仅检查格式(CI 使用) |
|
||||
| `npm run build` | 开发构建,带 sourcemap,输出到 `dist/` |
|
||||
| `npm run build:release` | 发布构建,压缩、无 sourcemap |
|
||||
| `npm run watch` | 监听源码变更自动重建 |
|
||||
@@ -109,6 +116,19 @@ npm install
|
||||
| `npm run package` | 发布构建 + 打出 `release/auto-login-v<版本>.zip` |
|
||||
| `npm run release -- patch` | 版本递增 + 同步版本号 + 构建打包(见下文) |
|
||||
|
||||
> 格式化范围暂定为源码与测试(`src` / `scripts` / `tests`),未包含 `popup.html`、`popup.css` 与 `_locales`,以免产生上千行的纯空白 diff;需要时可自行扩展 `package.json` 里的 globs。
|
||||
|
||||
### 调试日志
|
||||
|
||||
信息类日志(填充过程、注入范围、解锁恢复等)**默认静默**,避免刷满网页控制台与 Service Worker 控制台。需要排查问题时,在扩展的 Service Worker 控制台执行一次:
|
||||
|
||||
```js
|
||||
chrome.storage.local.set({ debugLog: true }); // 打开
|
||||
chrome.storage.local.remove("debugLog"); // 关闭
|
||||
```
|
||||
|
||||
打开后各项日志会以 `[AutoLogin]` 前缀输出。异常类告警(如注册 content script 失败、填充超时诊断)不受该开关影响,始终输出。
|
||||
|
||||
`dist/` 不纳入版本控制,克隆后必须先执行 `npm run build` 才能加载扩展。
|
||||
|
||||
### 本地加载
|
||||
@@ -126,10 +146,11 @@ npm test
|
||||
|
||||
- `tests/crypto-store.test.js` 保险库加解密、解锁 / 锁定、密钥句柄解锁
|
||||
- `tests/key-store.test.js` 密钥句柄的存取与降级行为
|
||||
- `tests/permissions.test.js` 可选主机权限的授权状态判断与申请
|
||||
- `tests/env-store.test.js` 环境与配置 CRUD
|
||||
- `tests/utils.test.js` URL 匹配、HTML 转义、match pattern 转换
|
||||
- `tests/utils.test.js` URL 匹配、HTML 转义、match pattern 转换、调试日志开关
|
||||
- `tests/detect-captcha.test.js` 验证码识别
|
||||
- `tests/content-fill.test.js` 表单探测与填充引擎(jsdom 真实 DOM)
|
||||
- `tests/content-fill.test.js` 表单探测与填充引擎(jsdom 真实 DOM,含 Shadow DOM、多环境浮窗、失败次数限制、SPA 重试)
|
||||
|
||||
## 构建与发布
|
||||
|
||||
@@ -161,12 +182,17 @@ git tag v1.0.1 && git push && git push --tags
|
||||
| 权限 | 用途 |
|
||||
| --- | --- |
|
||||
| `storage` | 保存域名配置(密文存 `local`)与解锁期间的会话数据 |
|
||||
| `tabs` | 读取当前标签页地址与标题,用于「填入当前域名」和匹配判断 |
|
||||
| `scripting` | 按需注入填充脚本;注入范围由用户配置的域名动态限定 |
|
||||
| `activeTab` | 用户点击扩展时临时访问当前标签页 |
|
||||
| `activeTab` | 你点击扩展图标时临时访问当前标签页,用于「在当前页面填充」与「填入当前域名」 |
|
||||
| `scripting` | 按需注入填充脚本;注入范围仅限你已授权的域名 |
|
||||
| `sidePanel` | 提供侧边栏界面 |
|
||||
| `bookmarks` | 从浏览器书签批量导入域名 |
|
||||
| `host_permissions: <all_urls>` | 在用户配置过的任意域名上执行填充(实际注入范围由配置动态限定,未配置的站点不会注入) |
|
||||
| `bookmarks` | 从浏览器书签批量导入域名(仅在你点击「从书签导入」时读取) |
|
||||
| `optional_host_permissions: *://*/*` | **仅为"可申请"声明,安装时不授予**。你在保存某个域名配置时会被询问一次是否允许访问该网站;未授权的站点不会注入任何脚本 |
|
||||
|
||||
> 注入粒度是"已授权域名下的所有帧"(`allFrames`):iframe 里的登录表单也能被填充,因此同一域名下嵌的第三方 iframe 也会执行脚本;但每个帧都会用自己的地址去匹配配置,不匹配的帧不做任何操作。
|
||||
|
||||
> 未声明 `host_permissions`,也未声明 `tabs`,因此安装提示中不会出现"读取和更改您在所有网站上的数据"或"读取您的浏览记录"。
|
||||
>
|
||||
> 撤销授权:在 `chrome://extensions` 的扩展详情页中移除对应站点权限即可,扩展会立即同步注销注入范围(该域名退化为只能手动填充)。
|
||||
|
||||
## 隐私
|
||||
|
||||
|
||||
Reference in New Issue
Block a user