From 0ff6cc67c7cafee9736216196876e7ac589d6f80 Mon Sep 17 00:00:00 2001 From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com> Date: Sun, 16 Nov 2025 01:39:07 +0900 Subject: [PATCH 1/5] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=20`@connect=20*`=20?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E7=94=9F=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/service/service_worker/gm_api/gm_api.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/service/service_worker/gm_api/gm_api.ts b/src/app/service/service_worker/gm_api/gm_api.ts index 4e279a862..dfd1bde07 100644 --- a/src/app/service/service_worker/gm_api/gm_api.ts +++ b/src/app/service/service_worker/gm_api/gm_api.ts @@ -45,7 +45,7 @@ import { headerModifierMap, headersReceivedMap } from "./gm_xhr"; import { BgGMXhr } from "@App/pkg/utils/xhr/bg_gm_xhr"; const askUnlistedConnect = false; -const askConnectStar = true; +const askConnectStar = false; let generatedUniqueMarkerIDs = ""; let generatedUniqueMarkerIDWhen = ""; From c57465e83cf5bfe280e802e76386b60cf6df1aa4 Mon Sep 17 00:00:00 2001 From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com> Date: Sun, 16 Nov 2025 02:00:46 +0900 Subject: [PATCH 2/5] Update gm_api.ts --- .../service/service_worker/gm_api/gm_api.ts | 47 ++++++++++++------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/src/app/service/service_worker/gm_api/gm_api.ts b/src/app/service/service_worker/gm_api/gm_api.ts index dfd1bde07..fa5e1f8e7 100644 --- a/src/app/service/service_worker/gm_api/gm_api.ts +++ b/src/app/service/service_worker/gm_api/gm_api.ts @@ -45,7 +45,7 @@ import { headerModifierMap, headersReceivedMap } from "./gm_xhr"; import { BgGMXhr } from "@App/pkg/utils/xhr/bg_gm_xhr"; const askUnlistedConnect = false; -const askConnectStar = false; +const askConnectStar = true; // 如果只有 "*", 而脚本要求连接自己以外的网域,则需要询问 let generatedUniqueMarkerIDs = ""; let generatedUniqueMarkerIDWhen = ""; @@ -144,33 +144,48 @@ export enum ConnectMatch { SELF = 3, } +export enum SelfMatch { + NONE = 0, + SELF = 1, + SUB = 2, +} + export const getConnectMatched = ( metadataConnect: string[] | undefined, reqURL: URL, sender: IGetSender ): ConnectMatch => { if (metadataConnect?.length) { + const checkSelfDomainMatching = () => { + const senderURL = sender.getSender()?.url; + if (senderURL) { + let senderURLObject; + try { + senderURLObject = new URL(senderURL); + } catch { + // ignore + } + if (senderURLObject) { + if (reqURL.hostname === senderURLObject.hostname) return SelfMatch.SELF; // 自身 + if (`.${reqURL.hostname}`.endsWith(`.${senderURLObject.hostname}`)) return SelfMatch.SUB; // 子域 + } + } + return SelfMatch.NONE; + }; + let withWildCard = false; for (let i = 0, l = metadataConnect.length; i < l; i += 1) { const lowerMetaConnect = metadataConnect[i].toLowerCase(); if (lowerMetaConnect === "self") { - const senderURL = sender.getSender()?.url; - if (senderURL) { - let senderURLObject; - try { - senderURLObject = new URL(senderURL); - } catch { - // ignore - } - if (senderURLObject) { - if (reqURL.hostname === senderURLObject.hostname) return ConnectMatch.SELF; - } - } + if (checkSelfDomainMatching()) return ConnectMatch.SELF; // 包含子域 } else if (lowerMetaConnect === "*") { - return ConnectMatch.ALL; + if (checkSelfDomainMatching()) return ConnectMatch.SELF; // 包含子域 + withWildCard = true; } else if (`.${reqURL.hostname}`.endsWith(`.${lowerMetaConnect}`)) { return ConnectMatch.DOMAIN; } } + // 有 * 但不是自身网域 又不是列明网域 则询问 + if (withWildCard) return ConnectMatch.ALL; } return ConnectMatch.NONE; }; @@ -280,7 +295,7 @@ export default class GMApi { url.host = detail.domain || ""; url.hostname = detail.domain || ""; } - if (getConnectMatched(request.script.metadata.connect, url, sender) === 0) { + if (getConnectMatched(request.script.metadata.connect, url, sender) === ConnectMatch.NONE) { throw new Error("hostname must be in the definition of connect"); } const metadata: { [key: string]: string } = {}; @@ -682,7 +697,7 @@ export default class GMApi { return false; } const connectMatched = getConnectMatched(request.script.metadata.connect, url, sender); - if (connectMatched === 1) { + if (connectMatched === ConnectMatch.ALL) { if (!askConnectStar) { return true; } From b2f026bb3d9afe53a78a678f0f1808040a0416dc Mon Sep 17 00:00:00 2001 From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com> Date: Sun, 16 Nov 2025 02:26:36 +0900 Subject: [PATCH 3/5] =?UTF-8?q?=E8=B7=9F=E9=9A=A8TM?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/service_worker/gm_api/gm_api.test.ts | 2 +- src/app/service/service_worker/gm_api/gm_api.ts | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/app/service/service_worker/gm_api/gm_api.test.ts b/src/app/service/service_worker/gm_api/gm_api.test.ts index efc9bdb76..07ca21674 100644 --- a/src/app/service/service_worker/gm_api/gm_api.test.ts +++ b/src/app/service/service_worker/gm_api/gm_api.test.ts @@ -41,7 +41,7 @@ describe.concurrent("isConnectMatched", () => { it.concurrent('metadata 包含 "self" 且 sender.url 与 reqURL 主机相同时回传 true', () => { const req = new URL("https://app.example.com/dashboard"); const sender = makeSender("https://app.example.com/some-page"); - expect(getConnectMatched(["self"], req, sender)).toBe(ConnectMatch.SELF); + expect(getConnectMatched(["self"], req, sender)).toBe(ConnectMatch.EXACT); }); it.concurrent('metadata 包含 "self" 但 sender.url 与 reqURL 主机不同时回传 false(若无其他规则命中)', () => { diff --git a/src/app/service/service_worker/gm_api/gm_api.ts b/src/app/service/service_worker/gm_api/gm_api.ts index fa5e1f8e7..aceda8754 100644 --- a/src/app/service/service_worker/gm_api/gm_api.ts +++ b/src/app/service/service_worker/gm_api/gm_api.ts @@ -141,12 +141,12 @@ export enum ConnectMatch { NONE = 0, ALL = 1, DOMAIN = 2, - SELF = 3, + EXACT = 3, } export enum SelfMatch { NONE = 0, - SELF = 1, + EXACT = 1, SUB = 2, } @@ -166,7 +166,7 @@ export const getConnectMatched = ( // ignore } if (senderURLObject) { - if (reqURL.hostname === senderURLObject.hostname) return SelfMatch.SELF; // 自身 + if (reqURL.hostname === senderURLObject.hostname) return SelfMatch.EXACT; // 自身 if (`.${reqURL.hostname}`.endsWith(`.${senderURLObject.hostname}`)) return SelfMatch.SUB; // 子域 } } @@ -176,12 +176,12 @@ export const getConnectMatched = ( for (let i = 0, l = metadataConnect.length; i < l; i += 1) { const lowerMetaConnect = metadataConnect[i].toLowerCase(); if (lowerMetaConnect === "self") { - if (checkSelfDomainMatching()) return ConnectMatch.SELF; // 包含子域 + if (checkSelfDomainMatching() > 0) return ConnectMatch.DOMAIN; // 完全匹配或其子域 } else if (lowerMetaConnect === "*") { - if (checkSelfDomainMatching()) return ConnectMatch.SELF; // 包含子域 - withWildCard = true; + if (checkSelfDomainMatching() === SelfMatch.EXACT) return ConnectMatch.EXACT; // 完全匹配 + withWildCard = true; // 检查其他 @connect } else if (`.${reqURL.hostname}`.endsWith(`.${lowerMetaConnect}`)) { - return ConnectMatch.DOMAIN; + return ConnectMatch.DOMAIN; // 完全匹配或其子域 } } // 有 * 但不是自身网域 又不是列明网域 则询问 From 8f2bf46025c3f6ca56ae17890dd540b4aabd5689 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E4=B8=80=E4=B9=8B?= Date: Sun, 16 Nov 2025 12:27:26 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8D=95=E5=85=83?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/service/service_worker/gm_api/gm_api.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/app/service/service_worker/gm_api/gm_api.ts b/src/app/service/service_worker/gm_api/gm_api.ts index aceda8754..7118e1621 100644 --- a/src/app/service/service_worker/gm_api/gm_api.ts +++ b/src/app/service/service_worker/gm_api/gm_api.ts @@ -138,10 +138,10 @@ export const checkHasUnsafeHeaders = (key: string) => { }; export enum ConnectMatch { - NONE = 0, - ALL = 1, - DOMAIN = 2, - EXACT = 3, + NONE = 0, // 没有匹配 + ALL = 1, // 遇到 "*" 通配符 + DOMAIN = 2, // 匹配子域 + EXACT = 3, // 完全匹配 } export enum SelfMatch { @@ -176,7 +176,12 @@ export const getConnectMatched = ( for (let i = 0, l = metadataConnect.length; i < l; i += 1) { const lowerMetaConnect = metadataConnect[i].toLowerCase(); if (lowerMetaConnect === "self") { - if (checkSelfDomainMatching() > 0) return ConnectMatch.DOMAIN; // 完全匹配或其子域 + switch (checkSelfDomainMatching()) { + case SelfMatch.EXACT: + return ConnectMatch.EXACT; // 完全匹配 + case SelfMatch.SUB: + return ConnectMatch.DOMAIN; // 完全匹配或其子域 + } } else if (lowerMetaConnect === "*") { if (checkSelfDomainMatching() === SelfMatch.EXACT) return ConnectMatch.EXACT; // 完全匹配 withWildCard = true; // 检查其他 @connect From 321d1d869ac85239828db5fbd7b74a9c6282d630 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E4=B8=80=E4=B9=8B?= Date: Sun, 16 Nov 2025 12:28:28 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8D=95=E5=85=83?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/service/service_worker/gm_api/gm_api.test.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/app/service/service_worker/gm_api/gm_api.test.ts b/src/app/service/service_worker/gm_api/gm_api.test.ts index 07ca21674..3a7e823ad 100644 --- a/src/app/service/service_worker/gm_api/gm_api.test.ts +++ b/src/app/service/service_worker/gm_api/gm_api.test.ts @@ -42,6 +42,10 @@ describe.concurrent("isConnectMatched", () => { const req = new URL("https://app.example.com/dashboard"); const sender = makeSender("https://app.example.com/some-page"); expect(getConnectMatched(["self"], req, sender)).toBe(ConnectMatch.EXACT); + + const req2 = new URL("https://app.example.com/dashboard"); + const sender2 = makeSender("https://example.com/some-page"); + expect(getConnectMatched(["self"], req2, sender2)).toBe(ConnectMatch.DOMAIN); }); it.concurrent('metadata 包含 "self" 但 sender.url 与 reqURL 主机不同时回传 false(若无其他规则命中)', () => {