diff --git a/package.json b/package.json index 7be7f9b..8374e30 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "dotenv": "^16.4.5", "eslint": "^8.57.0", "fastify": "^4.26.2", + "prettier": "^3.3.3", "tslib": "^2.6.2", "typescript": "^5.4.5" }, @@ -52,6 +53,7 @@ "domhandler": "^5.0.3", "domutils": "^3.1.0", "htmlparser2": "^9.1.0", - "meriyah": "^4.4.2" + "meriyah": "^4.4.2", + "parse-domain": "^8.0.2" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bb98d14..d2801e2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,6 +34,9 @@ importers: meriyah: specifier: ^4.4.2 version: 4.4.2 + parse-domain: + specifier: ^8.0.2 + version: 8.0.2 devDependencies: "@fastify/static": specifier: ^7.0.3 @@ -86,6 +89,9 @@ importers: fastify: specifier: ^4.26.2 version: 4.26.2 + prettier: + specifier: ^3.3.3 + version: 3.3.3 tslib: specifier: ^2.6.2 version: 2.6.2 @@ -1464,6 +1470,13 @@ packages: } engines: { node: ">=12" } + clone-regexp@3.0.0: + resolution: + { + integrity: sha512-ujdnoq2Kxb8s3ItNBtnYeXdm07FcU0u8ARAT1lQ2YdMwQC+cdiXX8KoqMVuglztILivceTtp4ivqGSmEmhBUJw==, + } + engines: { node: ">=12" } + color-convert@1.9.3: resolution: { @@ -1576,6 +1589,13 @@ packages: } engines: { node: ">= 0.6" } + convert-hrtime@5.0.0: + resolution: + { + integrity: sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==, + } + engines: { node: ">=12" } + cookie-signature@1.0.6: resolution: { @@ -1616,6 +1636,13 @@ packages: } engines: { node: ">= 8" } + data-uri-to-buffer@4.0.1: + resolution: + { + integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==, + } + engines: { node: ">= 12" } + dayjs@1.11.6: resolution: { @@ -2136,6 +2163,13 @@ packages: } engines: { node: ">=0.8.0" } + fetch-blob@3.2.0: + resolution: + { + integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==, + } + engines: { node: ^12.20 || >= 14.13 } + file-entry-cache@6.0.1: resolution: { @@ -2238,6 +2272,13 @@ packages: } engines: { node: ">= 6" } + formdata-polyfill@4.0.10: + resolution: + { + integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==, + } + engines: { node: ">=12.20.0" } + forwarded@0.2.0: resolution: { @@ -2292,6 +2333,13 @@ packages: integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==, } + function-timeout@0.1.1: + resolution: + { + integrity: sha512-0NVVC0TaP7dSTvn1yMiy6d6Q8gifzbvQafO46RtLG/kHJUBNd+pVRGOBoK44wNBvtSPUJRfdVvkFdD3p0xvyZg==, + } + engines: { node: ">=14.16" } + get-caller-file@2.0.5: resolution: { @@ -2575,6 +2623,13 @@ packages: } engines: { node: ">=10.13.0" } + ip-regex@5.0.0: + resolution: + { + integrity: sha512-fOCG6lhoKKakwv+C6KdsOnGvgXnmgfmp0myi3bcNwj3qfwPAxRKWEuFhvEFF7ceYIz6+1jRZ+yguLFAmUNPEfw==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } + ip@1.1.9: resolution: { @@ -2637,6 +2692,13 @@ packages: } engines: { node: ">=0.10.0" } + is-ip@5.0.1: + resolution: + { + integrity: sha512-FCsGHdlrOnZQcp0+XT5a+pYowf33itBalCl+7ovNXC/7o5BhIpG14M3OrpPPdBSIQJCm+0M5+9mO7S9VVTTCFw==, + } + engines: { node: ">=14.16" } + is-module@1.0.0: resolution: { @@ -2664,6 +2726,13 @@ packages: } engines: { node: ">=10" } + is-regexp@3.1.0: + resolution: + { + integrity: sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA==, + } + engines: { node: ">=12" } + is-stream@2.0.1: resolution: { @@ -3054,6 +3123,20 @@ packages: integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==, } + node-domexception@1.0.0: + resolution: + { + integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==, + } + engines: { node: ">=10.5.0" } + + node-fetch@3.3.2: + resolution: + { + integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } + node-forge@1.3.1: resolution: { @@ -3212,6 +3295,13 @@ packages: } engines: { node: ">=6" } + parse-domain@8.0.2: + resolution: + { + integrity: sha512-maw80QgO2LaQ/ZlnxMxx4TvU2hB6Ao+ZsM2EI8jGRqtybvSasKGc9VbgIiEXr7tH4ASCHx05VYwy50ajoMcIcg==, + } + hasBin: true + parseurl@1.3.3: resolution: { @@ -3318,6 +3408,14 @@ packages: } engines: { node: ">= 0.8.0" } + prettier@3.3.3: + resolution: + { + integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==, + } + engines: { node: ">=14" } + hasBin: true + process-nextick-args@2.0.1: resolution: { @@ -3889,6 +3987,13 @@ packages: } engines: { node: ">=8" } + super-regex@0.2.0: + resolution: + { + integrity: sha512-WZzIx3rC1CvbMDloLsVw0lkZVKJWbrkJ0k1ghKFmcnPrW1+jWbgTkTEWVtD9lMdmI4jZEz40+naBxl1dCUhXXw==, + } + engines: { node: ">=14.16" } + supports-color@5.5.0: resolution: { @@ -3969,6 +4074,13 @@ packages: integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==, } + time-span@5.1.0: + resolution: + { + integrity: sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==, + } + engines: { node: ">=12" } + to-regex-range@5.0.1: resolution: { @@ -4138,6 +4250,13 @@ packages: integrity: sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==, } + web-streams-polyfill@3.3.3: + resolution: + { + integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==, + } + engines: { node: ">= 8" } + webpack-bundle-analyzer@4.10.2: resolution: { @@ -5370,6 +5489,10 @@ snapshots: strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + clone-regexp@3.0.0: + dependencies: + is-regexp: 3.1.0 + color-convert@1.9.3: dependencies: color-name: 1.1.3 @@ -5431,6 +5554,8 @@ snapshots: content-type@1.0.5: {} + convert-hrtime@5.0.0: {} + cookie-signature@1.0.6: {} cookie@0.4.2: {} @@ -5450,6 +5575,8 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + data-uri-to-buffer@4.0.1: {} + dayjs@1.11.6: {} debounce@1.2.1: {} @@ -5793,6 +5920,11 @@ snapshots: dependencies: websocket-driver: 0.7.4 + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + file-entry-cache@6.0.1: dependencies: flat-cache: 3.2.0 @@ -5870,6 +6002,10 @@ snapshots: combined-stream: 1.0.8 mime-types: 2.1.35 + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + forwarded@0.2.0: {} fresh@0.5.2: {} @@ -5895,6 +6031,8 @@ snapshots: function-bind@1.1.2: {} + function-timeout@0.1.1: {} + get-caller-file@2.0.5: {} get-intrinsic@1.2.4: @@ -6064,6 +6202,8 @@ snapshots: interpret@3.1.1: {} + ip-regex@5.0.0: {} + ip@1.1.9: {} ipaddr.js@1.9.1: {} @@ -6088,6 +6228,11 @@ snapshots: dependencies: is-extglob: 2.1.1 + is-ip@5.0.1: + dependencies: + ip-regex: 5.0.0 + super-regex: 0.2.0 + is-module@1.0.0: {} is-number@7.0.0: {} @@ -6096,6 +6241,8 @@ snapshots: is-plain-obj@3.0.0: {} + is-regexp@3.1.0: {} + is-stream@2.0.1: {} is-wsl@2.2.0: @@ -6270,6 +6417,14 @@ snapshots: neo-async@2.6.2: {} + node-domexception@1.0.0: {} + + node-fetch@3.3.2: + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + node-forge@1.3.1: {} node-releases@2.0.14: {} @@ -6350,6 +6505,11 @@ snapshots: dependencies: callsites: 3.1.0 + parse-domain@8.0.2: + dependencies: + is-ip: 5.0.1 + node-fetch: 3.3.2 + parseurl@1.3.3: {} path-browserify@1.0.1: {} @@ -6402,6 +6562,8 @@ snapshots: prelude-ls@1.2.1: {} + prettier@3.3.3: {} + process-nextick-args@2.0.1: {} process-warning@3.0.0: {} @@ -6795,6 +6957,12 @@ snapshots: strip-json-comments@3.1.1: {} + super-regex@0.2.0: + dependencies: + clone-regexp: 3.0.0 + function-timeout: 0.1.1 + time-span: 5.1.0 + supports-color@5.5.0: dependencies: has-flag: 3.0.0 @@ -6835,6 +7003,10 @@ snapshots: thunky@1.1.0: {} + time-span@5.1.0: + dependencies: + convert-hrtime: 5.0.0 + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -6903,6 +7075,8 @@ snapshots: dependencies: minimalistic-assert: 1.0.1 + web-streams-polyfill@3.3.3: {} + webpack-bundle-analyzer@4.10.2: dependencies: "@discoveryjs/json-ext": 0.5.7 diff --git a/src/shared/index.ts b/src/shared/index.ts index 6b53ce7..90b9b42 100644 --- a/src/shared/index.ts +++ b/src/shared/index.ts @@ -6,6 +6,7 @@ import { rewriteHeaders } from "./rewriters/headers"; import { rewriteWorkers } from "./rewriters/worker"; import { isScramjetFile } from "./rewriters/html"; import { BareClient } from "@mercuryworkshop/bare-mux"; +import { parseDomain } from "parse-domain"; if (!self.$scramjet) { //@ts-expect-error really dumb workaround @@ -14,6 +15,7 @@ if (!self.$scramjet) { self.$scramjet.shared = { util: { isScramjetFile, + parseDomain, BareClient, }, url: { diff --git a/src/types.d.ts b/src/types.d.ts index 306a6b9..3b32a78 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -7,6 +7,7 @@ import { rewriteWorkers } from "./shared/rewriters/worker"; import { isScramjetFile } from "./shared/rewriters/html"; import type { Codec } from "./codecs"; import { BareClient } from "@mercuryworkshop/bare-mux"; +import { parseDomain } from "parse-domain"; declare global { interface Window { @@ -27,6 +28,7 @@ declare global { util: { BareClient: typeof BareClient; isScramjetFile: typeof isScramjetFile; + parseDomain: typeof parseDomain; }; }; config: { diff --git a/src/worker/index.ts b/src/worker/index.ts index 670f443..10bb0c2 100644 --- a/src/worker/index.ts +++ b/src/worker/index.ts @@ -1,5 +1,7 @@ import { BareResponseFetch } from "@mercuryworkshop/bare-mux"; import IDBMap from "@webreflection/idb-map"; +import { ParseResultType } from "parse-domain"; +import { parse } from "path"; declare global { interface Window { @@ -33,6 +35,7 @@ self.ScramjetServiceWorker = class ScramjetServiceWorker { rewriteCss, rewriteWorkers, } = self.$scramjet.shared.rewrite; + const { parseDomain } = self.$scramjet.shared.util; if (urlParam.has("url")) { return Response.redirect( @@ -69,23 +72,45 @@ self.ScramjetServiceWorker = class ScramjetServiceWorker { let [key, value] = cookieParsed.shift(); value = value.replace('"', ""); - const hostArg = cookieParsed.find( - (x) => x[0].toLowerCase() === "domain" - ); - cookieParsed = cookieParsed.filter( - (x) => x[0].toLowerCase() !== "domain" - ); + const hostArg = cookieParsed.find((x) => x[0] === "Domain"); + cookieParsed = cookieParsed.filter((x) => x[0] !== "Domain"); let host = hostArg ? hostArg[1] : undefined; + if (url.protocol === "http" && cookieParsed.includes(["Secure"])) + continue; + if ( + cookieParsed.includes(["SameSite", "None"]) && + !cookieParsed.includes(["Secure"]) + ) + continue; + if (host && host !== url.host) { if (host.startsWith(".")) host = host.slice(1); + const urlDomain = parseDomain(url.hostname); + + if (urlDomain.type === ParseResultType.Listed) { + const { subDomains: _, domain, topLevelDomains } = urlDomain; + if (!host.endsWith([domain, ...topLevelDomains].join("."))) + continue; + } else { + continue; + } + const realCookieStore = new IDBMap(host, { durability: "relaxed", prefix: "Cookies", }); - realCookieStore.set(key, { value: value, args: cookieParsed }); + realCookieStore.set(key, { + value: value, + args: cookieParsed, + subdomain: true, + }); } else { - cookieStore.set(key, { value: value, args: cookieParsed }); + cookieStore.set(key, { + value: value, + args: cookieParsed, + subdomain: false, + }); } }