Files
live-hub-py/web/extension/huya-exchange-helper/relay.js
T
yml2213 4518b726ac feat(huya): 浏览器兑换三目标直达并收窄扩展注入范围
- 操作列改为「直播间 / 精英宝典 / 电竞宝典」三个直达按钮,点哪个就按哪个目标写入登录态并打开,去掉弹窗内选择
- 新增 services/huya_exchange_targets.py 统一三个目标地址,接口支持可选 body {"target": "..."}(不传=精英宝典)
- 扩展内容脚本从 <all_urls> 收窄到后台站点白名单,service worker 校验 sender.tab.url,拒绝其它来源的注入
- 注入改为 Cookie 写完后回执(ok/written/failed/error),前端按回执提示成功或失败,不再静默
- 扩展图标兜底改用 world:'MAIN' 读取;一个 Cookie 都没写成功时不打开目标页
- 兑换材料签发写审计 huya:exchange:kit(含账号与目标)
- 控制台脚本增加 huya.com 域校验与 Secure,与扩展路径保持一致
- 修复兑换记录轮询的跨账号串扰与卸载后 setState;兑换请求加 epoch 防止过期结果覆盖弹窗
- 新增 tests/test_huya_browser_exchange.py(13 项)并同步 docs/HUYA_BROWSER_EXCHANGE.md
2026-09-11 10:31:46 +08:00

59 lines
2.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 内容脚本:只注入后台管理系统页面(站点白名单见 manifest.content_scripts.matches)。
// 职责:① 标记扩展可用;② 把后台页面派发的兑换材料转发给 service worker;
// ③ 把写入结果回执给页面(修复"注入失败但界面仍提示成功")。
// 安全边界:不再注入 <all_urls>,页面侧只能通过固定事件名提交材料;
// service worker 仍会二次校验消息来源站点,Cookie 只写入 .huya.com 域。
// document_start 阶段可能拿到非 HTML 文档(XML/图片等)而没有 documentElement,
// 这里判空,避免异常连带杀死后面的监听注册(会导致自动注入永久失效)。
if (document.documentElement) {
document.documentElement.dataset.huyaExchangeHelper = '1';
}
function dispatchResult(payload) {
try {
window.dispatchEvent(
new CustomEvent('huya-exchange-result', { detail: JSON.stringify(payload) })
);
} catch (e) { /* 页面已卸载等场景忽略 */ }
}
window.addEventListener('huya-exchange-kit', (event) => {
// 后台页面用页面脚本派发的 CustomEvent,isTrusted 恒为 false,
// 所以这里不能校验 isTrusted;拦截点是 manifest 站点白名单 + service worker 的来源校验。
const detail = event.detail;
if (typeof detail !== 'string') return;
let kit;
try {
kit = JSON.parse(detail);
} catch (e) {
return; // 忽略非法消息
}
if (!kit || !kit.target_url || !Array.isArray(kit.cookies)) return;
const requestId = typeof kit.request_id === 'string' ? kit.request_id : '';
try {
chrome.runtime.sendMessage({ type: 'inject', kit }, (response) => {
const lastError = chrome.runtime.lastError ? chrome.runtime.lastError.message : '';
if (lastError) {
dispatchResult({ request_id: requestId, ok: false, written: 0, failed: 0, error: lastError });
return;
}
const result = response || {};
dispatchResult({
request_id: requestId,
ok: Boolean(result.ok),
written: Number(result.written) || 0,
failed: Number(result.failed) || 0,
error: typeof result.error === 'string' ? result.error : '',
});
});
} catch (e) {
dispatchResult({
request_id: requestId,
ok: false,
written: 0,
failed: 0,
error: '扩展上下文失效,请在扩展管理页重新加载扩展',
});
}
}, true);