Skip to content
Merged
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
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@
},
"scripts": {
"lint": "eslint",
"build": "./scripts/build.js"
"build": "node ./scripts/build.js"
}
}
}
25 changes: 22 additions & 3 deletions platform_spec/chromium/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,19 @@
"alarms",
"storage",
"webNavigation",
"tabs"
"tabs",
"declarativeNetRequestWithHostAccess"
],
"host_permissions": [
"<all_urls>"
],
"options_ui": {
"page": "html/options.html",
"open_in_tab": true
},
"background": {
"service_worker": "background.js"
"service_worker": "background.js",
"type": "module"
},
"action": {
"default_popup": "html/popup.html"
Expand All @@ -46,11 +51,25 @@
"html/before-navigate.html",
"html/blocked.html",
"html/crowd-bypassed.html",
"html/tracker-bypass.html",
"html/options.html",
"icon/48.png",
"injection_script.js",
"bypasses/*",
"helpers/*"],
"matches": ["<all_urls>"]
}]
}],

"declarative_net_request": {
"rule_resources": [{
"id": "ipLoggerRuleset",
"enabled": true,
"path": "ip_logger_blocker.json"
},
{
"id": "trackerRuleset",
"enabled": false,
"path": "tracker_bypass.json"
}]
}
}
31 changes: 26 additions & 5 deletions platform_spec/firefox/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,26 @@
"browser_specific_settings": {
"gecko": {
"id": "[email protected]",
"strict_min_version": "109.0"
"strict_min_version": "113.0"
}
},
"permissions": [
"alarms",
"storage",
"webNavigation",
"tabs"
"tabs",
"declarativeNetRequestWithHostAccess"
],
"host_permissions": [
"<all_urls>"
],
"options_ui": {
"page": "html/options.html",
"open_in_tab": true
},
"background": {
"scripts": ["background.js"]
"scripts": ["background.js"],
"type": "module"
},
"action": {
"default_popup": "html/popup.html"
Expand All @@ -51,11 +56,27 @@
"html/before-navigate.html",
"html/blocked.html",
"html/crowd-bypassed.html",
"html/tracker-bypass.html",
"html/options.html",
"icon/48.png",
"injection_script.js",
"bypasses/*",
"helpers/*"],
"helpers/*",
"rules.json"
],
"matches": ["<all_urls>"]
}]
}],
"declarative_net_request": {
"rule_resources": [{
"id": "ipLoggerRuleset",
"enabled": true,
"path": "ip_logger_blocker.json"
},
{
"id": "trackerRuleset",
"enabled": false,
"path": "tracker_bypass.json"
}]

}
}
40 changes: 19 additions & 21 deletions scripts/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,9 @@ import fs from 'fs-extra';
import ejs from 'ejs';
import process from 'process';
import path from 'path';
import {
copyArray,
changeCwdtoRoot,
getNumberOfCommits,
} from './build_js/utils.js';
import * as utils from './build_js/utils.js';

changeCwdtoRoot();
utils.changeCwdtoRoot();
let working_directory = process.cwd();
const distribution = `${working_directory}/build/dist`;
let [browser, version] = process.argv.slice(2);
Expand Down Expand Up @@ -48,16 +44,12 @@ fs.mkdirSync(browserDir);
// Copy privacy.md and src except js
let src = ['./src', './docs/PRIVACY.md'];
let exceptions = ['./src/js/', 'version.txt'];
await copyArray(src, browserDir, exceptions);
await utils.copyArray(src, browserDir, exceptions);

//copy js
src = ['./src/js'];
exceptions = [
'injection_script-original.js',
'injection_script.js',
'rules.json',
];
await copyArray(src, browserDir, exceptions);
exceptions = ['injection_script-original.js', 'injection_script.js'];
await utils.copyArray(src, browserDir, exceptions);

let bypasses = {};
for (const i of fs.readdirSync(`${working_directory}/src/bypasses`)) {
Expand Down Expand Up @@ -87,25 +79,26 @@ fs.writeFileSync(outputPath, result);
if (browser === 'all') {
const chromiumDir = `${working_directory}/build/FastForward.chromium`;
fs.mkdirSync(chromiumDir);
await copyArray([browserDir], chromiumDir);
await utils.copyArray([browserDir], chromiumDir);
}

/*Compile*/
/*version*/
let packageVersion = '';
if (version === 'ver') {
packageVersion = fs.readFileSync('version.txt', 'utf-8').trim();
} else if (version === 'nover') {
const lastCommit = getNumberOfCommits();
const lastCommit = utils.getNumberOfCommits();
packageVersion = `0.${lastCommit}`;
}

async function buildExtension(browser) {
const targetBrowser = browser === 'firefox' ? 'firefox-desktop' : 'chromium';
const browserDir = `${working_directory}/build/FastForward.${browser}`;
const manfistFile = `${working_directory}/platform_spec/${browser}/manifest.json`;
await copyArray([manfistFile], browserDir);
const browserOutDir = `${working_directory}/build/FastForward.${browser}`;
const browserSrcDir = `${working_directory}/platform_spec/${browser}`;
const manfistFile = `${browserSrcDir}/manifest.json`;
await utils.copyArray([manfistFile], browserOutDir);
fs.writeFileSync(
`${browserDir}/manifest.json`,
`${browserOutDir}/manifest.json`,
JSON.stringify(
Object.assign(JSON.parse(fs.readFileSync(manfistFile, 'utf8')), {
version: packageVersion,
Expand All @@ -114,10 +107,15 @@ async function buildExtension(browser) {
4 //pretty print
)
);
await utils.convertRulesToDNRRulesets(
`${browserOutDir}/rules.json`,
`${browserOutDir}/ip_logger_blocker.json`,
`${browserOutDir}/tracker_bypass.json`
);

await webExt.cmd.build(
{
sourceDir: browserDir,
sourceDir: browserOutDir,
artifactsDir: `${distribution}`,
overwriteDest: true,
browser: targetBrowser,
Expand Down
16 changes: 14 additions & 2 deletions scripts/build_js/injection_script_template.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,20 @@ const bypasses = [/- bypasses -/];
const script_src = new URL(document.currentScript.src);
const ext_base_URL = script_src.searchParams.get('ext_base_URL');

if (location.host in bypasses) {
const bypass_url = bypasses[location.host];
function matchingBypass(bypasses) {
for (const [key] of Object.entries(bypasses)) {
if (key.charAt(0) === '/' && key.charAt(key.length - 1) === '/') {
let pattern = new RegExp(key.substring(1, key.length - 1));
return pattern.test(location.href) ? key : null;
} else if (key === location.host) {
return key;
}
return null;
}
}

if (matchingBypass(bypasses)) {
const bypass_url = bypasses[matchingBypass(bypasses)];

import(ext_base_URL.concat(bypass_url)).then(({ default: bypass }) => {
import(ext_base_URL.concat('helpers/dom.js')).then(
Expand Down
59 changes: 59 additions & 0 deletions scripts/build_js/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,62 @@ export function getNumberOfCommits() {
console.error(error);
}
}

/**
* Converts a rules.json with trackers and ip_loggers file into two
* separate declarativeNetRequest rulesets and writes the resulting JSONs to file.
*
* @async
* @function convertRulesToDeclarativeNetRequest
* @param {string} rulesFilePath - The path to the input JSON file containing the rules to be converted.
* @param {string} ipLoggerOutputFile - The path to the output file where the ip logger rules will be written.
* @param {string} trackerOutputFile - The path to the output file where the tracker rules will be written.
*
* @returns {Promise<void>}
*/
export async function convertRulesToDNRRulesets(
rulesFilePath,
ipLoggerOutputFile,
trackerOutputFile
) {
const rules = JSON.parse(await fs.readFile(rulesFilePath));
const domainRegex = /:\/\/\*?\.?([^/]+)/;
const ip_loggerRules = rules.ip_logger.map((urlPattern, index) => {
const domainMatch = urlPattern.match(domainRegex);
if (!domainMatch) console.error('Unable to parse domain for', urlPattern);
return {
id: index + 1,
priority: 1,
action: {
type: 'redirect',
redirect: { extensionPath: '/html/blocked.html' },
},
condition: {
urlFilter: `||${domainMatch[1]}`,
resourceTypes: ['main_frame'],
},
};
});

const trackerRules = rules.tracker.map((urlPattern, index) => {
const domainMatch = urlPattern.match(domainRegex);
if (!domainMatch) console.error('Unable to parse domain for', urlPattern);
return {
id: index + 1,
priority: 1,
action: {
type: 'redirect',
redirect: {
regexSubstitution: `https://fastforward.team/bypassed?type=tracker&url=\\0`,
},
},
condition: {
regexFilter: '^https?://' + domainMatch[1] + '.*',
resourceTypes: ['main_frame'],
},
};
});

await fs.writeFile(ipLoggerOutputFile, JSON.stringify(ip_loggerRules));
await fs.writeFile(trackerOutputFile, JSON.stringify(trackerRules));
}
8 changes: 7 additions & 1 deletion src/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"message": "Take me to destinations after % second(s)."
},
"optionsTrackerBypass": {
"message": "Bypass trackers (such as bit.ly and t.co) using Apimon.de."
"message": "Bypass trackers (such as bit.ly and goo.gl) using Unshorten.me."
},
"optionsInstantNavigationTrackers": {
"message": "Instantly take me to destinations of trackers."
Expand Down Expand Up @@ -145,6 +145,12 @@
},
"crowdBypassTempDisabled":{
"message":"Crowd bypass has been temporarily disabled"
},
"trackerBypass": {
"message": "Bypassing tracker..."
},
"trackerBypassedError": {
"message": "Oops! Something went wrong. Redirecting to the original link..."
}

}
Loading