Compare commits

...

11 commits
1.1.4 ... main

Author SHA1 Message Date
Cooper
20c7342dc0 1.2.0 2024-08-19 19:14:52 +00:00
TPN
cd2ecdb6b6
Merge pull request #2 from ztpn/main 2024-08-19 18:45:42 +01:00
TPN
e6756d25f8 Update cookies whitelist and permission req page 2024-08-19 17:29:37 +01:00
TPN
fa1e42eab1 Fix response header modification 2024-08-15 19:24:45 +01:00
TPN
af263c1f70 Update regex 2024-08-15 18:37:14 +01:00
TPN
0a55847ce0 Update packages 2024-08-15 15:43:10 +01:00
TPN
4c724ff9c9 Enforce new whitelists 2024-08-15 15:34:19 +01:00
TPN
1f214dddb3 Update whitelists 2024-08-15 15:33:51 +01:00
Captain Jack Sparrow
9f146d2032
Update README.md 2024-04-26 22:17:45 -04:00
Cooper Ransom
8a9b689a92 Fix an issue 2024-04-25 17:05:58 -04:00
Cooper Ransom
e1b943bdc1 Sudo-extension now 2024-04-25 16:49:46 -04:00
16 changed files with 5555 additions and 4421 deletions

View file

@ -1 +1 @@
Please visit the [main document at primary repository](https://github.com/movie-web/movie-web/blob/dev/.github/CODE_OF_CONDUCT.md). Please visit the [main document at primary repository](https://github.com/sussy-code/smov/blob/dev/.github/CODE_OF_CONDUCT.md).

View file

@ -1 +1 @@
Please visit the [main document at primary repository](https://github.com/movie-web/movie-web/blob/dev/.github/CONTRIBUTING.md). Please visit the [main document at primary repository](https://github.com/sussy-code/smov/blob/dev/.github/CONTRIBUTING.md).

6
.github/SECURITY.md vendored
View file

@ -2,9 +2,9 @@
## Supported Versions ## Supported Versions
The latest version of movie-web is the only version that is supported, as it is the only version that is being actively developed. The latest version of sudo-flix is the only version that is supported, as it is the only version that is being actively developed.
## Reporting a Vulnerability ## Reporting a Vulnerability
You can contact the movie-web maintainers to report a vulnerability: You can contact the sudo-flix maintainers to report a vulnerability:
- Report the vulnerability in the [movie-web Discord server](https://movie-web.github.io/links/discord) - Report the vulnerability in the [Discord server](https://discord.gg/g742e7Mu2W)

View file

@ -1,6 +1,6 @@
This pull request resolves #XXX This pull request resolves #XXX
- [ ] I have read and agreed to the [code of conduct](https://github.com/movie-web/movie-web/blob/dev/.github/CODE_OF_CONDUCT.md). - [ ] I have read and agreed to the [code of conduct](https://github.com/sussy-code/smov/blob/dev/.github/CODE_OF_CONDUCT.md).
- [ ] I have read and complied with the [contributing guidelines](https://github.com/movie-web/movie-web/blob/dev/.github/CONTRIBUTING.md). - [ ] I have read and complied with the [contributing guidelines](https://github.com/sussy-code/smov/blob/dev/.github/CONTRIBUTING.md).
- [ ] What I'm implementing was assigned to me and is an [approved issue](https://github.com/movie-web/movie-web/issues?q=is%3Aopen+is%3Aissue+label%3Aapproved). For reference, please take a look at our [GitHub projects](https://github.com/movie-web/movie-web/projects). - [ ] What I'm implementing was assigned to me and is an [approved issue](https://github.com/sussy-code/smov/issues?q=is%3Aopen+is%3Aissue+label%3Aapproved). For reference, please take a look at our [GitHub projects](https://github.com/sussy-code/smov/projects).
- [ ] I have tested all of my changes. - [ ] I have tested all of my changes.

View file

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2023 movie-web Copyright (c) 2023 sudo-flix
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,6 +1,6 @@
# extension # extension
Enhance your movie-web experience with just one click Enhance your experience with just one click
## Running for development ## Running for development

View file

@ -4,7 +4,7 @@
"optional_host_permissions": [ "\u003Call_urls>" ], "optional_host_permissions": [ "\u003Call_urls>" ],
"permissions": [ "storage", "declarativeNetRequest", "activeTab", "cookies" ], "permissions": [ "storage", "declarativeNetRequest", "activeTab", "cookies" ],
"update_url": "https://clients2.google.com/service/update2/crx", "update_url": "https://clients2.google.com/service/update2/crx",
"version": "1.1.4", "version": "1.2.0",
"web_accessible_resources": [ { "web_accessible_resources": [ {
"matches": [ "\u003Call_urls>" ], "matches": [ "\u003Call_urls>" ],
"resources": [ "assets/active.png", "assets/inactive.png" ] "resources": [ "assets/active.png", "assets/inactive.png" ]

View file

@ -1,9 +1,9 @@
{ {
"name": "@movie-web/extension", "name": "@movie-web/extension",
"displayName": "movie-web extension", "displayName": "sudo-flix extension",
"version": "1.1.4", "version": "1.2.0",
"description": "Enhance your movie-web experience with just one click", "description": "Enhance your streaming experience with just one click",
"author": "movie-web", "author": "sudo-flix",
"scripts": { "scripts": {
"dev": "plasmo dev", "dev": "plasmo dev",
"build": "plasmo build", "build": "plasmo build",
@ -16,28 +16,28 @@
"preinstall": "npx -y only-allow pnpm" "preinstall": "npx -y only-allow pnpm"
}, },
"dependencies": { "dependencies": {
"@plasmohq/messaging": "^0.6.1", "@plasmohq/messaging": "^0.6.2",
"@plasmohq/storage": "^1.9.0", "@plasmohq/storage": "^1.11.0",
"plasmo": "0.84.0", "plasmo": "0.84.0",
"react": "18.2.0", "react": "18.2.0",
"react-dom": "18.2.0" "react-dom": "18.2.0"
}, },
"devDependencies": { "devDependencies": {
"@types/chrome": "0.0.251", "@types/chrome": "0.0.251",
"@types/firefox-webext-browser": "^120.0.0", "@types/firefox-webext-browser": "^120.0.4",
"@types/node": "20.9.0", "@types/node": "20.9.0",
"@types/react": "18.2.37", "@types/react": "18.2.37",
"@types/react-dom": "18.2.15", "@types/react-dom": "18.2.15",
"@typescript-eslint/eslint-plugin": "^6.15.0", "@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.15.0", "@typescript-eslint/parser": "^6.21.0",
"eslint": "^8.56.0", "eslint": "^8.57.0",
"eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb": "^19.0.4",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-import-resolver-typescript": "^3.6.1", "eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "^2.29.1", "eslint-plugin-import": "^2.29.1",
"eslint-plugin-prettier": "^5.1.1", "eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-react": "^7.33.2", "eslint-plugin-react": "^7.35.0",
"eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-hooks": "^4.6.2",
"prettier": "3.0.3", "prettier": "3.0.3",
"typescript": "5.2.2" "typescript": "5.2.2"
}, },

File diff suppressed because it is too large Load diff

View file

@ -5,7 +5,7 @@ import type { BaseResponse } from '~types/response';
import { removeDynamicRules, setDynamicRules } from '~utils/declarativeNetRequest'; import { removeDynamicRules, setDynamicRules } from '~utils/declarativeNetRequest';
import { isFirefox } from '~utils/extension'; import { isFirefox } from '~utils/extension';
import { makeFullUrl } from '~utils/fetcher'; import { makeFullUrl } from '~utils/fetcher';
import { assertDomainWhitelist } from '~utils/storage'; import { assertDomainWhitelist, canAccessCookies } from '~utils/storage';
const MAKE_REQUEST_DYNAMIC_RULE = 23498; const MAKE_REQUEST_DYNAMIC_RULE = 23498;
@ -60,6 +60,12 @@ const handler: PlasmoMessaging.MessageHandler<Request, Response<any>> = async (r
ruleId: MAKE_REQUEST_DYNAMIC_RULE, ruleId: MAKE_REQUEST_DYNAMIC_RULE,
targetDomains: [new URL(url).hostname], targetDomains: [new URL(url).hostname],
requestHeaders: req.body.headers, requestHeaders: req.body.headers,
// set Access-Control-Allow-Credentials if the reqested host has access to cookies
responseHeaders: {
...(canAccessCookies(new URL(url).hostname) && {
'Access-Control-Allow-Credentials': 'true',
}),
},
}); });
const response = await fetch(url, { const response = await fetch(url, {
@ -84,7 +90,10 @@ const handler: PlasmoMessaging.MessageHandler<Request, Response<any>> = async (r
statusCode: response.status, statusCode: response.status,
headers: { headers: {
...Object.fromEntries(response.headers.entries()), ...Object.fromEntries(response.headers.entries()),
'Set-Cookie': cookies.map((cookie) => `${cookie.name}=${cookie.value}`).join(', '), // include cookies if allowed for the reqested host
...(canAccessCookies(new URL(url).hostname) && {
'Set-Cookie': cookies.map((cookie) => `${cookie.name}=${cookie.value}`).join(', '),
}),
}, },
body, body,
finalUrl: response.url, finalUrl: response.url,

View file

@ -3,7 +3,7 @@ import type { PlasmoMessaging } from '@plasmohq/messaging';
import type { BaseRequest } from '~types/request'; import type { BaseRequest } from '~types/request';
import type { BaseResponse } from '~types/response'; import type { BaseResponse } from '~types/response';
import { setDynamicRules } from '~utils/declarativeNetRequest'; import { setDynamicRules } from '~utils/declarativeNetRequest';
import { assertDomainWhitelist } from '~utils/storage'; import { assertDomainWhitelist, modifiableResponseHeaders } from '~utils/storage';
interface Request extends BaseRequest { interface Request extends BaseRequest {
ruleId: number; ruleId: number;
@ -18,6 +18,17 @@ const handler: PlasmoMessaging.MessageHandler<Request, BaseResponse> = async (re
if (!req.sender?.tab?.url) throw new Error('No tab URL found in the request.'); if (!req.sender?.tab?.url) throw new Error('No tab URL found in the request.');
if (!req.body) throw new Error('No request body found in the request.'); if (!req.body) throw new Error('No request body found in the request.');
// restrict what response headers can be modified
req.body.responseHeaders = Object.keys(req.body.responseHeaders ?? {})
.filter((key) => modifiableResponseHeaders.includes(key.toLowerCase()))
.reduce(
(obj, key) => {
obj[key] = (req.body?.responseHeaders ?? {})[key];
return obj;
},
{} as Record<string, string>,
);
await assertDomainWhitelist(req.sender.tab.url); await assertDomainWhitelist(req.sender.tab.url);
await setDynamicRules(req.body); await setDynamicRules(req.body);
res.send({ res.send({

View file

@ -8,7 +8,7 @@ export function BottomLabel() {
<h3 className="bottom-label"> <h3 className="bottom-label">
{version} {version}
<div className="dot" /> <div className="dot" />
movie-web sudo-flix
</h3> </h3>
); );
} }

View file

@ -8,7 +8,7 @@ export function DisabledScreen() {
<Icon name="warningCircle" /> <Icon name="warningCircle" />
</div> </div>
<p> <p>
The <strong>movie-web extension</strong> can not be used on this page The <strong>sudo-flix extension</strong> can not be used on this page
</p> </p>
</div> </div>
); );

View file

@ -32,7 +32,7 @@ export default function PermissionRequest() {
We need some <br /> browser permissions We need some <br /> browser permissions
</h1> </h1>
<p className="text-color paragraph"> <p className="text-color paragraph">
We don&apos;t like it either, but the movie-web extension needs quite a few permissions to function. Listed We don&apos;t like it either, but the sudo-flix extension needs quite a few permissions to function. Listed
below is an explanation for all permissions we need. below is an explanation for all permissions we need.
</p> </p>
@ -41,7 +41,7 @@ export default function PermissionRequest() {
purple purple
icon={<Icon name="github" />} icon={<Icon name="github" />}
right={ right={
<Button type="secondary" href="https://github.com/movie-web/extension"> <Button type="secondary" href="https://github.com/sussy-code/browser-ext">
Read source code Read source code
</Button> </Button>
} }
@ -66,7 +66,7 @@ export default function PermissionRequest() {
<h3>Network Requests</h3> <h3>Network Requests</h3>
<p className="text-color paragraph"> <p className="text-color paragraph">
This permission allows the extension to instruct the browser how to request data from sites. In more This permission allows the extension to instruct the browser how to request data from sites. In more
technical terms, this allows movie-web to modify HTTP headers that it wouldn&apos;t normally be allowed technical terms, this allows sudo-flix to modify HTTP headers that it wouldn&apos;t normally be allowed
to. to.
</p> </p>
<p className="text-color paragraph"> <p className="text-color paragraph">
@ -76,7 +76,8 @@ export default function PermissionRequest() {
<Card icon={<Icon name="cookie" />}> <Card icon={<Icon name="cookie" />}>
<h3>Read and write cookies</h3> <h3>Read and write cookies</h3>
<p className="text-color paragraph"> <p className="text-color paragraph">
Some sources use cookies for authentication. We need to be able to read and set those cookies. Some sources use cookies for authentication. We need to be able to read and set those cookies. The
extension will only be able to accees the cookies for a few sites we scrape.
</p> </p>
<p className="text-color paragraph"> <p className="text-color paragraph">
You won&apos;t be prompted for this permission, it&apos;s included in Read & change data from all sites. You won&apos;t be prompted for this permission, it&apos;s included in Read & change data from all sites.

View file

@ -1,4 +1,5 @@
import { isChrome } from './extension'; import { isChrome } from './extension';
import { modifiableResponseHeaders } from './storage';
interface DynamicRule { interface DynamicRule {
ruleId: number; ruleId: number;
@ -56,11 +57,6 @@ export const setDynamicRules = async (body: DynamicRule) => {
operation: chrome.declarativeNetRequest.HeaderOperation.SET, operation: chrome.declarativeNetRequest.HeaderOperation.SET,
value: '*', value: '*',
}, },
{
header: 'Access-Control-Allow-Credentials',
operation: chrome.declarativeNetRequest.HeaderOperation.SET,
value: 'true',
},
...mapHeadersToDeclarativeNetRequestHeaders( ...mapHeadersToDeclarativeNetRequestHeaders(
body.responseHeaders ?? {}, body.responseHeaders ?? {},
chrome.declarativeNetRequest.HeaderOperation.SET, chrome.declarativeNetRequest.HeaderOperation.SET,
@ -104,11 +100,6 @@ export const setDynamicRules = async (body: DynamicRule) => {
operation: 'set', operation: 'set',
value: '*', value: '*',
}, },
{
header: 'Access-Control-Allow-Credentials',
operation: 'set',
value: 'true',
},
...mapHeadersToDeclarativeNetRequestHeaders(body.responseHeaders ?? {}, 'set'), ...mapHeadersToDeclarativeNetRequestHeaders(body.responseHeaders ?? {}, 'set'),
], ],
}, },

View file

@ -3,16 +3,32 @@ import { useStorage } from '@plasmohq/storage/hook';
import { makeUrlIntoDomain } from '~utils/domains'; import { makeUrlIntoDomain } from '~utils/domains';
export const DEFAULT_DOMAIN_WHITELIST = [ export const DEFAULT_DOMAIN_WHITELIST = [];
'mw.lonelil.ru',
'watch.qtchaos.de', export const modifiableResponseHeaders = [
'bmov.app', 'access-control-allow-origin',
'bmov.vercel.app', 'access-control-allow-methods',
'stream.thehairy.me', 'access-control-allow-headers',
'scootydooter.vercel.app', 'content-security-policy',
'movie-web-me.vercel.app', 'content-security-policy-report-only',
'content-disposition',
]; ];
const hostsWithCookiesAccess: RegExp[] = [
/^(?:.*\.)?ee3\.me$/,
/^(?:.*\.)?rips\.cc$/,
/^(?:.*\.)?m4ufree\.(?:tv|to|pw)$/,
/^(?:.*\.)?goojara\.to$/,
/^(?:.*\.)?levidia\.ch$/,
/^(?:.*\.)?wootly\.ch$/,
/^(?:.*\.)?multimovies\.(?:sbs|online|cloud)$/,
];
export function canAccessCookies(host: string): boolean {
if (hostsWithCookiesAccess.some((regex) => regex.test(host))) return true;
return false;
}
export const storage = new Storage(); export const storage = new Storage();
const getDomainWhiteList = async () => { const getDomainWhiteList = async () => {