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:
+22
-6
@@ -28,7 +28,7 @@ const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const DIST = path.join(ROOT, "dist");
|
||||
|
||||
/** 全局脚本:必须独立成文件,iife 格式,彼此通过 globalThis 通信 */
|
||||
const GLOBAL_SCRIPTS = ["utils", "env-store", "crypto-store", "key-store"];
|
||||
const GLOBAL_SCRIPTS = ["utils", "permissions", "env-store", "crypto-store", "key-store"];
|
||||
/** 独立入口:各自成文件,不做跨文件打包 */
|
||||
const STANDALONE_SCRIPTS = ["background", "content"];
|
||||
/** 由 background 通过 chrome.scripting 按需注入的脚本(manifest 里不再静态声明) */
|
||||
@@ -73,7 +73,9 @@ async function verifyReferences() {
|
||||
const manifest = JSON.parse(await readFile(path.join(ROOT, "manifest.json"), "utf8"));
|
||||
const refs = new Set();
|
||||
|
||||
const add = (p) => { if (typeof p === "string") refs.add(p); };
|
||||
const add = (p) => {
|
||||
if (typeof p === "string") refs.add(p);
|
||||
};
|
||||
add(manifest.background?.service_worker);
|
||||
add(manifest.side_panel?.default_path);
|
||||
Object.values(manifest.icons || {}).forEach(add);
|
||||
@@ -101,7 +103,9 @@ async function checkVersionConsistency() {
|
||||
const manifest = JSON.parse(await readFile(path.join(ROOT, "manifest.json"), "utf8"));
|
||||
const pkg = JSON.parse(await readFile(path.join(ROOT, "package.json"), "utf8"));
|
||||
if (manifest.version !== pkg.version) {
|
||||
console.warn(`[build] 版本号不一致:manifest.json=${manifest.version} package.json=${pkg.version}(执行 npm run release 可同步)`);
|
||||
console.warn(
|
||||
`[build] 版本号不一致:manifest.json=${manifest.version} package.json=${pkg.version}(执行 npm run release 可同步)`,
|
||||
);
|
||||
}
|
||||
return manifest.version;
|
||||
}
|
||||
@@ -112,7 +116,13 @@ export async function buildAll({ release = false, watch = false } = {}) {
|
||||
|
||||
if (watch) {
|
||||
const contexts = await Promise.all(
|
||||
entryPoints().map((ep) => esbuild.context({ ...esbuildOptions({ release, format: ep.format, bundle: ep.bundle }), entryPoints: [ep.in], outfile: ep.out }))
|
||||
entryPoints().map((ep) =>
|
||||
esbuild.context({
|
||||
...esbuildOptions({ release, format: ep.format, bundle: ep.bundle }),
|
||||
entryPoints: [ep.in],
|
||||
outfile: ep.out,
|
||||
}),
|
||||
),
|
||||
);
|
||||
await Promise.all(contexts.map((c) => c.watch()));
|
||||
console.log(`[build] 监听中… v${version}(Ctrl+C 退出)`);
|
||||
@@ -121,11 +131,17 @@ export async function buildAll({ release = false, watch = false } = {}) {
|
||||
|
||||
await rm(DIST, { recursive: true, force: true }); // 清掉历史产物,避免残留旧文件被打进包
|
||||
for (const ep of entryPoints()) {
|
||||
await esbuild.build({ ...esbuildOptions({ release, format: ep.format, bundle: ep.bundle }), entryPoints: [ep.in], outfile: ep.out });
|
||||
await esbuild.build({
|
||||
...esbuildOptions({ release, format: ep.format, bundle: ep.bundle }),
|
||||
entryPoints: [ep.in],
|
||||
outfile: ep.out,
|
||||
});
|
||||
}
|
||||
|
||||
const refs = await verifyReferences();
|
||||
console.log(`[build] v${version} ${release ? "release" : "dev"} 构建完成:${entryPoints().length} 个入口,校验 ${refs.length} 处引用`);
|
||||
console.log(
|
||||
`[build] v${version} ${release ? "release" : "dev"} 构建完成:${entryPoints().length} 个入口,校验 ${refs.length} 处引用`,
|
||||
);
|
||||
return { version, refs };
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user