✨ Add @site-access opt-in scripts to the popup - #1597
Conversation
|
我感觉这个设计不对,再思考一下,而且match相关的属性已经挺多了 如果我没有理解错的话,用户主要想解决的问题应该是: 脚本没有匹配某个网站,用户可以快速便捷的将这个网站加入脚本match,从UI/UX上去解决(现在已经可以在脚本设置中添加) |
UserScript 一直没有这个 opt-in 设计。我觉得是有价值啦
这个就是我反对的不合理性。用户在讨论中也明白我的意思。只是他想要的是用户自行决定(因为他的脚本都是 all sites ),而我这个是要作者加进去的 老实说他根本不是指 「脚本没有匹配某个网站」 @CodFrm |
|
按 PickInvariant 从“原始 URL 规则”和 现在的逻辑是:有
目前执行层的 condition 会阻止真正脚本主体运行,所以这不等同于直接越权执行;但注册层作为一道独立边界并没有实现 PR 描述里的“收窄”,而且和执行层语义不一致。 建议把这个 seam 收紧:opt-in 且没有有效 |
# Conflicts: # src/app/service/service_worker/popup.ts # src/app/service/service_worker/runtime.ts # src/app/service/service_worker/script.ts # src/app/service/service_worker/utils.test.ts # src/locales/de-DE/common.json # src/locales/en-US/common.json # src/locales/ja-JP/common.json # src/locales/ko-KR/common.json # src/locales/pt-BR/common.json # src/locales/ru-RU/common.json # src/locales/tr-TR/common.json # src/locales/vi-VN/common.json # src/locales/zh-CN/common.json # src/locales/zh-TW/common.json # src/pages/options/routes/ScriptEditor/tabs/SettingsPane.tsx # src/pages/popup/App.test.tsx # src/pages/popup/App.tsx # src/pages/popup/preload.ts # src/pages/popup/usePopupData.test.ts # src/pages/popup/usePopupData.ts
Checklist / 检查清单
背景
脚本作者需要声明“默认不在所有站点运行,但允许用户明确选择站点”的脚本。
现有
@match、@include、@exclude规则适合描述脚本的原始匹配范围,但不能表达用户主动选择的 opt-in 站点,也不能安全地把 opt-in 规则直接混入原始匹配规则。因此,本次增加独立的
@site-accessopt-in 规则:其中:
opt-in表示脚本需要额外的站点访问许可;+开头的规则表示作者声明的初始 / 默认站点;@site-access +<pattern>元数据。本次改动
@site-access opt-in以及@site-access +<pattern>默认站点。+*://<host>/*时显示移除许可操作。@early-start和@unwrap脚本都在执行边界检查原始 URL 规则与 site-access 规则的交集。chrome.userScripts.update/register。实现考虑
1. 不修改原始
@match/@include/@exclude语义opt-in 站点许可不会覆盖脚本原始 URL 规则。
脚本是否执行必须同时满足:
@match/@include/@exclude规则允许当前 URL;@site-access的作者默认规则或用户自定义规则允许当前 URL;这样可以避免把用户的 opt-in 设置误认为脚本作者扩大了脚本原始匹配范围。
2. 在浏览器注册和执行载荷两侧同时限制访问范围
仅在页面加载请求中检查 site-access 不足以保护以下路径:
@early-start脚本可能在页面请求之前执行;@unwrap脚本可能直接执行注册载荷;因此实现同时处理:
chrome.userScripts注册范围;@early-start预注入载荷;@unwrap直接执行载荷;被拒绝的页面不会执行脚本,也不会暴露可直接调用的完整脚本函数。
3. 用户规则使用 additive custom metablock
用户通过 Popup 加入当前站点时,实际保存的是:
作者声明的
@site-access内容不会被覆盖,用户规则可以单独编辑、删除或重置。Popup 的“移除当前站点”操作只删除它自己生成的精确 host 规则。更宽泛的规则需要在设置页面中明确编辑,避免删除操作显示成功但脚本仍因其他规则继续运行。
4. Popup reload 必须等待注册完成
加入或移除站点会触发脚本注册信息更新。
消息队列原有的普通 publish 是异步通知,不等待订阅者完成,因此 Popup 如果立即 reload,可能使用旧的注册规则。现在 Popup RPC 会等待当前 Service Worker 中的异步 install handler 完成,确认注册更新结束后才 reload 当前标签页。
5. 保持 issue 范围清晰
本 PR 实现的是作者控制的
@site-access opt-in设计。原始
@match/@include不匹配当前页面的脚本仍不会因为本功能自动出现在 Popup 中。面向所有未匹配脚本的发现、展示和双向管理属于更广泛的后续范围,本 PR 不改变现有脚本匹配边界。已知限制
1. 不会自动发现原始规则完全不匹配的脚本
如果脚本的原始
@match/@include规则完全不匹配当前页面,即使作者声明了@site-access opt-in,该脚本也不会被本 PR 自动加入 Popup 的候选列表。2. Popup 只处理精确 host 许可
Popup 的快捷移除操作只处理
+*://<host>/*形式的用户规则。以下规则不会通过 Popup 的快捷按钮删除:
这些规则需要在脚本设置页面中编辑或删除。
3. 作者默认站点不能通过“移除用户许可”关闭
如果作者默认规则已经允许当前站点,用户删除自己的同站点规则不会阻止脚本运行。因此这种情况下 Popup 不显示误导性的移除许可操作。
建议审查重点
@site-access opt-in是否始终与原始 URL 规则取交集;@early-start、@unwrap执行载荷是否都执行 site-access 检查;chrome.userScripts.update/register完成;关联
Related to #1590
验证
pnpm exec vitest run --no-coverage --reporter=dot --reporter.summary=false:303 个文件,3,285 个测试通过pnpm typecheck:通过pnpm build:通过;仅保留现有 Rspack asset-size 和 Monaco 警告