Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 41 additions & 3 deletions src/app/service/service_worker/gm_api/gm_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -807,14 +807,43 @@ export default class GMApi {
const msg = `Refused to connect to "${details.url}": URL is blacklisted`;
throw throwErrorFn(msg);
}
let hasOriginPermission = false;
let originPattern = "";
if (!url.origin || url.origin === "null" || !url.protocol || !url.protocol.startsWith("http")) {
hasOriginPermission = true; // TBC
} else {
originPattern = `${url.origin}/*`;
try {
hasOriginPermission = await chrome.permissions.contains({ origins: [originPattern] });
} catch (e) {
console.warn(e);
}
}
const extensionSiteAccessOrigins = hasOriginPermission ? undefined : [originPattern];
const confirmExtensionSiteAccess = (): ConfirmParam => {
const metadata: { [key: string]: string } = {};
metadata[i18next.t("script_name")] = i18nName(request.script);
metadata[i18next.t("request_domain")] = url.hostname;
metadata[i18next.t("request_url")] = details.url;
throwErrorFn = null; // 确保 GC 可以释放 conn
return {
permission: "extension-site-access",
permissionValue: originPattern,
title: i18next.t("extension_site_access_title"),
metadata,
describe: i18next.t("extension_site_access_description"),
permissionContent: i18next.t("extension_site_access_content"),
extensionSiteAccessOrigins,
} as ConfirmParam;
};
const connectMatched = getConnectMatched(request.script.metadata.connect, url, sender);
if (connectMatched === ConnectMatch.ALL) {
// SC: 有 @connect * 就不询问
return true;
return hasOriginPermission ? true : confirmExtensionSiteAccess();
} else {
// 如果 @connect 有匹配到就放行
if (connectMatched > 0) {
return true;
return hasOriginPermission ? true : confirmExtensionSiteAccess();
}
// @connect 没有匹配,但有列明 @connect 的话,则自动拒绝
if (request.script.metadata.connect?.find((e) => !!e)) {
Expand All @@ -825,7 +854,7 @@ export default class GMApi {
wildcard: true,
});
if (ret && ret.allow) {
return true;
return hasOriginPermission ? true : confirmExtensionSiteAccess();
}
const msg = `Refused to connect to "${details.url}": This domain is not a part of the @connect list`;
throw throwErrorFn(msg);
Expand All @@ -839,6 +868,14 @@ export default class GMApi {

throwErrorFn = null; // 确保 GC 可以释放 conn

const ret = await GMApiInstance.permissionVerify.queryPermission(request, {
permission: "cors",
permissionValue: url.hostname,
wildcard: true,
});
if (ret?.allow && !hasOriginPermission) {
return confirmExtensionSiteAccess();
}
return {
permission: "cors",
permissionValue: url.hostname,
Expand All @@ -847,6 +884,7 @@ export default class GMApi {
describe: i18next.t("confirm_operation_description"),
wildcard: true,
permissionContent: i18next.t("domain"),
extensionSiteAccessOrigins,
} as ConfirmParam;
},
alias: ["GM.xmlHttpRequest"],
Expand Down
2 changes: 2 additions & 0 deletions src/app/service/service_worker/permission_verify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ export interface ConfirmParam {
wildcard?: boolean;
// 权限内容
permissionContent?: string;
// 需要在确认页面通过用户手势请求的扩展站点访问权限
extensionSiteAccessOrigins?: string[];
}

export interface UserConfirm {
Expand Down
3 changes: 3 additions & 0 deletions src/locales/de-DE/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,9 @@
"enabled_background_scripts": "Aktivierte und laufende Hintergrundskripte",
"script_accessing_cross_origin_resource": "Skript versucht auf Cross-Origin-Ressourcen zuzugreifen",
"confirm_operation_description": "Bitte bestätigen Sie, ob Sie dem Skript erlauben, diese Operation durchzuführen. Das Skript kann auch ein @connect-Tag hinzufügen, um diese Option zu überspringen",
"extension_site_access_title": "ScriptCat benötigt Website-Zugriff",
"extension_site_access_description": "Gewähren Sie dem Browser Website-Zugriff auf diesen Ursprung, damit ScriptCat die Anfrage ausführen kann. Dadurch wird die Website-Zugriffseinstellung der Erweiterung geändert.",
"extension_site_access_content": "Website",
"domain": "Domain",
"script_name": "Skriptname",
"request_domain": "Anfrage-Domain",
Expand Down
3 changes: 3 additions & 0 deletions src/locales/en-US/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,9 @@
"enabled_background_scripts": "Enabled and Running Background Scripts",
"script_accessing_cross_origin_resource": "Script is attempting to access a cross-origin resource",
"confirm_operation_description": "Please confirm if you allow the script to perform this operation. The script can also add the @connect tag to bypass this option.",
"extension_site_access_title": "ScriptCat needs site access",
"extension_site_access_description": "Grant browser site access to this origin so ScriptCat can perform the request. This changes the extension's site access setting.",
"extension_site_access_content": "Site",
"domain": "Domain",
"script_name": "Script Name",
"request_domain": "Request Domain",
Expand Down
3 changes: 3 additions & 0 deletions src/locales/ja-JP/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,9 @@
"enabled_background_scripts": "有効および実行中のバックグラウンドスクリプト",
"script_accessing_cross_origin_resource": "スクリプトがクロスドメインリソースにアクセスしようとしています",
"confirm_operation_description": "スクリプトがこの操作を実行することを許可するかどうか確認してください。スクリプトは@connectタグを追加してこのオプションをスキップすることもできます",
"extension_site_access_title": "ScriptCat にサイトアクセス権限が必要です",
"extension_site_access_description": "ScriptCat がこのリクエストを実行できるように、このオリジンへのブラウザーのサイトアクセス権限を許可してください。これは拡張機能のサイトアクセス設定を変更します。",
"extension_site_access_content": "サイト",
"domain": "ドメイン",
"script_name": "スクリプト名",
"request_domain": "リクエストドメイン",
Expand Down
3 changes: 3 additions & 0 deletions src/locales/ru-RU/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,9 @@
"enabled_background_scripts": "Включенные и работающие фоновые скрипты",
"script_accessing_cross_origin_resource": "Скрипт пытается получить доступ к кросс-доменному ресурсу",
"confirm_operation_description": "Пожалуйста, подтвердите, разрешаете ли вы скрипту выполнить эту операцию. Скрипт также может добавить тег @connect, чтобы пропустить эту опцию",
"extension_site_access_title": "ScriptCat требуется доступ к сайту",
"extension_site_access_description": "Разрешите браузеру доступ к сайту для этого источника, чтобы ScriptCat мог выполнить запрос. Это изменит настройку доступа к сайтам для расширения.",
"extension_site_access_content": "Сайт",
"domain": "Домен",
"script_name": "Название скрипта",
"request_domain": "Запрашиваемый домен",
Expand Down
3 changes: 3 additions & 0 deletions src/locales/vi-VN/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,9 @@
"enabled_background_scripts": "Script nền đã bật và đang chạy",
"script_accessing_cross_origin_resource": "Script đang cố gắng truy cập tài nguyên cross-origin",
"confirm_operation_description": "Vui lòng xác nhận xem bạn có cho phép script thực hiện thao tác này không. Script cũng có thể thêm thẻ @connect để bỏ qua tùy chọn này.",
"extension_site_access_title": "ScriptCat cần quyền truy cập trang web",
"extension_site_access_description": "Cấp quyền truy cập trang web của trình duyệt cho nguồn này để ScriptCat có thể thực hiện yêu cầu. Thao tác này thay đổi cài đặt truy cập trang web của tiện ích.",
"extension_site_access_content": "Trang web",
"domain": "Miền",
"script_name": "Tên script",
"request_domain": "Miền yêu cầu",
Expand Down
3 changes: 3 additions & 0 deletions src/locales/zh-CN/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,9 @@
"enabled_background_scripts": "开启和运行的后台脚本",
"script_accessing_cross_origin_resource": "脚本正在试图访问跨域资源",
"confirm_operation_description": "请您确认是否允许脚本进行此操作,脚本也可增加@connect标签跳过此选项",
"extension_site_access_title": "ScriptCat 需要站点访问权限",
"extension_site_access_description": "请授予浏览器对此来源的站点访问权限,让 ScriptCat 可以完成本次请求。这会修改扩展的站点访问设置。",
"extension_site_access_content": "站点",
"domain": "域名",
"script_name": "脚本名称",
"request_domain": "请求域名",
Expand Down
3 changes: 3 additions & 0 deletions src/locales/zh-TW/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,9 @@
"enabled_background_scripts": "開啟和執行的背景腳本",
"script_accessing_cross_origin_resource": "腳本正在嘗試存取跨網域資源",
"confirm_operation_description": "請您確認是否允許腳本進行此操作,腳本也可增加@connect標籤跳過此選項",
"extension_site_access_title": "ScriptCat 需要網站存取權限",
"extension_site_access_description": "請授予瀏覽器對此來源的網站存取權限,讓 ScriptCat 可以完成本次請求。這會修改擴充功能的網站存取設定。",
"extension_site_access_content": "網站",
"domain": "網域",
"script_name": "腳本名稱",
"request_domain": "請求網域",
Expand Down
158 changes: 93 additions & 65 deletions src/pages/confirm/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,27 @@
.catch((e: any) => {
Message.error(e.message || t("get_confirm_error"));
});
}, []);

Check warning on line 42 in src/pages/confirm/App.tsx

View workflow job for this annotation

GitHub Actions / Run tests

React Hook useEffect has missing dependencies: 't' and 'uuid'. Either include them or remove the dependency array

const handleConfirm = (allow: boolean, type: number) => {
return async () => {
if (!uuid) return;
try {
if (allow && confirm?.extensionSiteAccessOrigins?.length) {
const granted = await chrome.permissions.request({
origins: confirm.extensionSiteAccessOrigins,
});
if (!granted) {
await permissionClient
.confirm(uuid, {
allow: false,
type,
})
.catch(() => {});
window.close();
return;
}
}
Comment on lines +48 to +62
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only 1

await permissionClient.confirm(uuid, {
allow,
type,
Expand All @@ -60,6 +75,7 @@
};

const metadata = useMemo(() => (confirm && confirm.metadata && Object.keys(confirm.metadata)) || [], [confirm]);
const isExtensionSiteAccessConfirm = confirm?.permission === "extension-site-access";

return (
<div className="tw-h-full">
Expand All @@ -71,73 +87,85 @@
</span>
))}
<span className="tw-text-xl tw-font-500">{confirm?.describe}</span>
<div>
<Button type="primary" onClick={handleConfirm(false, 1)}>
{`${t("ignore")} (${second})`}
</Button>
</div>
<div>
<Space>
<Button onClick={handleConfirm(true, 1)} status="success">
{t("allow_once")}
</Button>
<Button onClick={handleConfirm(true, 3)} status="success">
{t("temporary_allow", {
permissionContent: confirm?.permissionContent,
})}
</Button>
{likeNum > 2 && (
<Button onClick={handleConfirm(true, 2)} status="success">
{t("temporary_allow_all", {
permissionContent: confirm?.permissionContent,
})}
{isExtensionSiteAccessConfirm ? (
<>
<div>
<Button type="primary" onClick={handleConfirm(true, 1)}>
{t("request_permission")}
</Button>
)}
<Button onClick={handleConfirm(true, 5)} status="success">
{t("permanent_allow", {
permissionContent: confirm?.permissionContent,
})}
</Button>
{likeNum > 2 && (
<Button onClick={handleConfirm(true, 4)} status="success">
{t("permanent_allow_all", {
permissionContent: confirm?.permissionContent,
})}
</div>
</>
) : (
<>
<div>
<Button type="primary" onClick={handleConfirm(false, 1)}>
{`${t("ignore")} (${second})`}
</Button>
)}
</Space>
</div>
<div>
<Space>
<Button onClick={handleConfirm(false, 1)} status="danger">
{t("deny_once")}
</Button>
<Button onClick={handleConfirm(false, 3)} status="danger">
{t("temporary_deny", {
permissionContent: confirm?.permissionContent,
})}
</Button>
{likeNum > 2 && (
<Button onClick={handleConfirm(false, 2)} status="danger">
{t("temporary_deny_all", {
permissionContent: confirm?.permissionContent,
})}
</Button>
)}
<Button onClick={handleConfirm(false, 5)} status="danger">
{t("permanent_deny", {
permissionContent: confirm?.permissionContent,
})}
</Button>
{likeNum > 2 && (
<Button onClick={handleConfirm(false, 4)} status="danger">
{t("permanent_deny_all", {
permissionContent: confirm?.permissionContent,
})}
</Button>
)}
</Space>
</div>
</div>
<div>
<Space>
<Button onClick={handleConfirm(true, 1)} status="success">
{t("allow_once")}
</Button>
<Button onClick={handleConfirm(true, 3)} status="success">
{t("temporary_allow", {
permissionContent: confirm?.permissionContent,
})}
</Button>
{likeNum > 2 && (
<Button onClick={handleConfirm(true, 2)} status="success">
{t("temporary_allow_all", {
permissionContent: confirm?.permissionContent,
})}
</Button>
)}
<Button onClick={handleConfirm(true, 5)} status="success">
{t("permanent_allow", {
permissionContent: confirm?.permissionContent,
})}
</Button>
{likeNum > 2 && (
<Button onClick={handleConfirm(true, 4)} status="success">
{t("permanent_allow_all", {
permissionContent: confirm?.permissionContent,
})}
</Button>
)}
</Space>
</div>
<div>
<Space>
<Button onClick={handleConfirm(false, 1)} status="danger">
{t("deny_once")}
</Button>
<Button onClick={handleConfirm(false, 3)} status="danger">
{t("temporary_deny", {
permissionContent: confirm?.permissionContent,
})}
</Button>
{likeNum > 2 && (
<Button onClick={handleConfirm(false, 2)} status="danger">
{t("temporary_deny_all", {
permissionContent: confirm?.permissionContent,
})}
</Button>
)}
<Button onClick={handleConfirm(false, 5)} status="danger">
{t("permanent_deny", {
permissionContent: confirm?.permissionContent,
})}
</Button>
{likeNum > 2 && (
<Button onClick={handleConfirm(false, 4)} status="danger">
{t("permanent_deny_all", {
permissionContent: confirm?.permissionContent,
})}
</Button>
)}
</Space>
</div>
</>
)}
</Space>
</div>
);
Expand Down
Loading