Refactor in scrub.js, reformat in the rest of the javascript
This commit is contained in:
@ -15,6 +15,7 @@ function control_host() {
|
||||
console.info("(config)Got i2p:", getFuncName());
|
||||
return getFromStorageControlHost();
|
||||
}
|
||||
|
||||
function control_port() {
|
||||
console.info("(config)Got i2p:", getFuncName());
|
||||
return getFromStorageControlPort();
|
||||
|
225
consoleinfo.js
225
consoleinfo.js
@ -1,46 +1,193 @@
|
||||
document.addEventListener("DOMContentLoaded", consoleStatus, false);
|
||||
/**
|
||||
* @fileoverview I2P Router Console Status Manager
|
||||
* Handles router console connectivity checking and UI updates
|
||||
*/
|
||||
|
||||
function consoleStatus() {
|
||||
let recv = fetch("http://127.0.0.1:7657/welcome");
|
||||
recv.then(routerConsoleSuccess, routerConsoleError);
|
||||
}
|
||||
// Constants
|
||||
const CONSOLE_CONFIG = {
|
||||
ROUTER_URL: "http://127.0.0.1:7657",
|
||||
WELCOME_PATH: "/welcome",
|
||||
FETCH_OPTIONS: {
|
||||
method: "GET",
|
||||
cache: "no-store",
|
||||
redirect: "follow",
|
||||
},
|
||||
};
|
||||
|
||||
function routerConsoleSuccess(myJson) {
|
||||
console.warn("(consoleinfo)", myJson);
|
||||
contentUpdateById("router-check", "consoleSuccessStatus");
|
||||
let routerness = document.querySelectorAll(".routerness");
|
||||
if (routerness !== null) {
|
||||
unhide(routerness);
|
||||
}
|
||||
}
|
||||
const UI_ELEMENTS = {
|
||||
ROUTER_STATUS: "router-check",
|
||||
ROUTER_CLASS: ".routerness",
|
||||
HIDDEN_CLASS: "hidden",
|
||||
};
|
||||
|
||||
function routerConsoleError(error) {
|
||||
console.error("(consoleinfo)", error);
|
||||
contentUpdateById("router-check", "consoleFailedStatus");
|
||||
let routerness = document.querySelectorAll(".routerness");
|
||||
if (routerness !== null) {
|
||||
hide(routerness);
|
||||
}
|
||||
}
|
||||
const MESSAGE_KEYS = {
|
||||
SUCCESS: "consoleSuccessStatus",
|
||||
FAILURE: "consoleFailedStatus",
|
||||
};
|
||||
|
||||
function hide(elementsToHide) {
|
||||
const elements = Array.isArray(elementsToHide)
|
||||
? elementsToHide
|
||||
: [elementsToHide];
|
||||
elements.forEach((element) => {
|
||||
console.log("(consoleinfo) hiding");
|
||||
el.classList.add("hidden");
|
||||
});
|
||||
}
|
||||
/**
|
||||
* UI Manager for handling element visibility
|
||||
*/
|
||||
class UIManager {
|
||||
/**
|
||||
* Toggle element visibility
|
||||
* @param {Element|NodeList} elements - Elements to modify
|
||||
* @param {boolean} show - Whether to show or hide
|
||||
*/
|
||||
static toggleVisibility(elements, show) {
|
||||
try {
|
||||
if (!elements) {
|
||||
throw new Error("Elements parameter is null or undefined");
|
||||
}
|
||||
|
||||
function unhide(elementsToShow) {
|
||||
const elements = Array.isArray(elementsToShow)
|
||||
? elementsToShow
|
||||
: [elementsToShow];
|
||||
elements.forEach((element) => {
|
||||
if (element.style) {
|
||||
console.log("(consoleinfo) unhiding");
|
||||
el.classList.remove("hidden");
|
||||
const elementArray =
|
||||
elements instanceof NodeList ? Array.from(elements) : [elements];
|
||||
|
||||
elementArray.forEach((element) => {
|
||||
if (element && element.style !== undefined && element.style !== null) {
|
||||
const action = show ? "remove" : "add";
|
||||
element.classList[action](UI_ELEMENTS.HIDDEN_CLASS);
|
||||
console.debug(`(consoleinfo) ${show ? "showing" : "hiding"} element`);
|
||||
} else {
|
||||
console.warn(
|
||||
"(consoleinfo) Invalid element encountered during visibility toggle"
|
||||
);
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Visibility toggle failed:", error);
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Update element content by ID
|
||||
* @param {string} elementId - Target element ID
|
||||
* @param {string} messageKey - i18n message key
|
||||
*/
|
||||
static updateContent(elementId, messageKey) {
|
||||
try {
|
||||
const element = document.getElementById(elementId);
|
||||
if (!element) {
|
||||
throw new Error(`Element not found : ${elementId}`);
|
||||
}
|
||||
element.textContent = chrome.i18n.getMessage(messageKey);
|
||||
} catch (error) {
|
||||
console.error("Content update failed:", error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get elements by selector
|
||||
* @param {string} selector - CSS selector
|
||||
* @return {?NodeList}
|
||||
*/
|
||||
static getElements(selector) {
|
||||
try {
|
||||
return document.querySelectorAll(selector);
|
||||
} catch (error) {
|
||||
console.error("Element selection failed:", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Router Console Manager
|
||||
*/
|
||||
class RouterConsoleManager {
|
||||
/**
|
||||
* Check router console connectivity
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
static async checkConsoleStatus() {
|
||||
console.info("(consoleinfo) Checking router console status");
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${CONSOLE_CONFIG.ROUTER_URL}${CONSOLE_CONFIG.WELCOME_PATH}`,
|
||||
CONSOLE_CONFIG.FETCH_OPTIONS
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Console response not OK : ${response.status}`);
|
||||
}
|
||||
|
||||
await this.handleConsoleSuccess(response);
|
||||
} catch (error) {
|
||||
await this.handleConsoleError(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle successful console connection
|
||||
* @param {Response} response - Fetch response
|
||||
*/
|
||||
static async handleConsoleSuccess(response) {
|
||||
console.info("(consoleinfo) Router console check successful");
|
||||
|
||||
try {
|
||||
UIManager.updateContent(UI_ELEMENTS.ROUTER_STATUS, MESSAGE_KEYS.SUCCESS);
|
||||
|
||||
const routerElements = UIManager.getElements(UI_ELEMENTS.ROUTER_CLASS);
|
||||
if (routerElements) {
|
||||
UIManager.toggleVisibility(routerElements, true);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Console success handling failed:", error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle console connection failure
|
||||
* @param {Error} error - Connection error
|
||||
*/
|
||||
static async handleConsoleError(error) {
|
||||
console.error("(consoleinfo) Router console check failed:", error);
|
||||
|
||||
try {
|
||||
UIManager.updateContent(UI_ELEMENTS.ROUTER_STATUS, MESSAGE_KEYS.FAILURE);
|
||||
|
||||
const routerElements = UIManager.getElements(UI_ELEMENTS.ROUTER_CLASS);
|
||||
if (routerElements) {
|
||||
UIManager.toggleVisibility(routerElements, false);
|
||||
}
|
||||
} catch (additionalError) {
|
||||
console.error("Console error handling failed:", additionalError);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize console monitoring
|
||||
*/
|
||||
static initialize() {
|
||||
try {
|
||||
this.checkConsoleStatus();
|
||||
console.info("(consoleinfo) Router console monitoring initialized");
|
||||
} catch (error) {
|
||||
console.error("Console initialization failed:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Event Listeners
|
||||
document.addEventListener(
|
||||
"DOMContentLoaded",
|
||||
() => {
|
||||
RouterConsoleManager.initialize();
|
||||
},
|
||||
{
|
||||
passive: true,
|
||||
capture: false,
|
||||
}
|
||||
);
|
||||
|
||||
// Export for testing
|
||||
if (typeof module !== "undefined" && module.exports) {
|
||||
module.exports = {
|
||||
RouterConsoleManager,
|
||||
UIManager,
|
||||
CONSOLE_CONFIG,
|
||||
UI_ELEMENTS,
|
||||
MESSAGE_KEYS,
|
||||
};
|
||||
}
|
||||
|
12
info.js
12
info.js
@ -29,7 +29,7 @@ const UI_ELEMENTS = {
|
||||
/**
|
||||
* Privacy Manager for handling browser privacy settings
|
||||
*/
|
||||
class PrivacyManager {
|
||||
class PrivacyManagerInfo {
|
||||
/**
|
||||
* Check WebRTC peer connection status
|
||||
*/
|
||||
@ -291,10 +291,10 @@ async function initialize() {
|
||||
try {
|
||||
// Initialize privacy settings
|
||||
await Promise.all([
|
||||
PrivacyManager.checkPeerConnection(),
|
||||
PrivacyManager.checkSnowflake(),
|
||||
PrivacyManager.checkHistory(),
|
||||
PrivacyManager.checkReferer(),
|
||||
PrivacyManagerInfo.checkPeerConnection(),
|
||||
PrivacyManagerInfo.checkSnowflake(),
|
||||
PrivacyManagerInfo.checkHistory(),
|
||||
PrivacyManagerInfo.checkReferer(),
|
||||
]);
|
||||
|
||||
// Initialize UI
|
||||
@ -323,7 +323,7 @@ if (browser?.windows) {
|
||||
// Export for testing
|
||||
if (typeof module !== "undefined" && module.exports) {
|
||||
module.exports = {
|
||||
PrivacyManager,
|
||||
PrivacyManager: PrivacyManagerInfo,
|
||||
TabManager,
|
||||
RouterManager,
|
||||
UIManager,
|
||||
|
@ -66,8 +66,6 @@
|
||||
"scripts": [
|
||||
"options/options.js",
|
||||
"config.js",
|
||||
"torrent/common.js",
|
||||
"torrent/background.js",
|
||||
"host.js",
|
||||
"privacy.js",
|
||||
"platform.js",
|
||||
|
146
platform.js
146
platform.js
@ -1,26 +1,132 @@
|
||||
var android = false;
|
||||
/**
|
||||
* @fileoverview I2P Platform Detection Manager
|
||||
* Handles platform detection and feature support for Firefox WebExtensions
|
||||
*/
|
||||
|
||||
var gettingInfo = browser.runtime.getPlatformInfo();
|
||||
gettingInfo.then((got) => {
|
||||
if (got.os == "android") {
|
||||
console.log("Running in Android detected");
|
||||
android = true;
|
||||
return true;
|
||||
} else {
|
||||
console.log("Running in Desktop detected");
|
||||
android = false;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
// Platform configuration constants
|
||||
const PLATFORM_CONFIG = {
|
||||
PLATFORMS: {
|
||||
ANDROID: "android",
|
||||
DESKTOP: "desktop",
|
||||
},
|
||||
FEATURES: {
|
||||
CLOSABLE: "closable",
|
||||
CONTAINER_TABS: "containerTabs",
|
||||
SIDEBAR: "sidebar",
|
||||
},
|
||||
};
|
||||
|
||||
function isDroid() {
|
||||
console.log("android?", android);
|
||||
if (android == undefined) {
|
||||
return false;
|
||||
/**
|
||||
* Platform Manager for handling platform-specific functionality
|
||||
*/
|
||||
class PlatformManager {
|
||||
constructor() {
|
||||
// Platform state
|
||||
this.platformState = {
|
||||
isAndroid: false,
|
||||
isInitialized: false,
|
||||
};
|
||||
|
||||
// Initialize platform detection
|
||||
this.initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize platform detection
|
||||
* @private
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
async initialize() {
|
||||
try {
|
||||
const platformInfo = await browser.runtime.getPlatformInfo();
|
||||
this.platformState.isAndroid =
|
||||
platformInfo.os === PLATFORM_CONFIG.PLATFORMS.ANDROID;
|
||||
this.platformState.isInitialized = true;
|
||||
|
||||
console.info(
|
||||
`(platform) Running in ${
|
||||
this.platformState.isAndroid ? "Android" : "Desktop"
|
||||
} detected`
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("Platform detection failed:", error);
|
||||
this.platformState.isAndroid = false;
|
||||
this.platformState.isInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if running on Android
|
||||
* @return {boolean}
|
||||
*/
|
||||
isAndroid() {
|
||||
if (!this.platformState.isInitialized) {
|
||||
console.warn("Platform detection not yet initialized");
|
||||
return false;
|
||||
}
|
||||
return this.platformState.isAndroid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if running on Desktop
|
||||
* @return {boolean}
|
||||
*/
|
||||
isDesktop() {
|
||||
return !this.isAndroid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if windows are closable
|
||||
* @return {boolean}
|
||||
*/
|
||||
isClosable() {
|
||||
return this.isDesktop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current platform state
|
||||
* @return {Object}
|
||||
*/
|
||||
getPlatformState() {
|
||||
return { ...this.platformState };
|
||||
}
|
||||
return android;
|
||||
}
|
||||
|
||||
function notClosable() {
|
||||
return false;
|
||||
// Create singleton instance
|
||||
const platformManager = new PlatformManager();
|
||||
|
||||
/**
|
||||
* Legacy API compatibility layer
|
||||
*/
|
||||
const PlatformAPI = {
|
||||
/**
|
||||
* Check if running on Android (legacy support)
|
||||
* @return {boolean}
|
||||
*/
|
||||
isDroid() {
|
||||
const isAndroid = platformManager.isAndroid();
|
||||
console.log("(platform) android?", isAndroid);
|
||||
return isAndroid;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if windows are not closable (legacy support)
|
||||
* @return {boolean}
|
||||
*/
|
||||
notClosable() {
|
||||
return !platformManager.isClosable();
|
||||
},
|
||||
};
|
||||
|
||||
// Export legacy API functions to window
|
||||
window.isDroid = PlatformAPI.isDroid;
|
||||
window.notClosable = PlatformAPI.notClosable;
|
||||
|
||||
// Export for testing
|
||||
if (typeof module !== "undefined" && module.exports) {
|
||||
module.exports = {
|
||||
platformManager,
|
||||
PLATFORM_CONFIG,
|
||||
PlatformAPI,
|
||||
};
|
||||
}
|
||||
|
853
privacy.js
853
privacy.js
@ -1,541 +1,364 @@
|
||||
var titlepref = chrome.i18n.getMessage("titlePreface");
|
||||
/**
|
||||
* @fileoverview I2P Privacy Manager
|
||||
* Handles Firefox privacy settings and data cleanup for I2P container tabs
|
||||
*/
|
||||
|
||||
function onSet(result) {
|
||||
if (result) {
|
||||
console.log("->: Value was updated");
|
||||
} else {
|
||||
console.log("-X: Value was not updated");
|
||||
}
|
||||
}
|
||||
|
||||
/* This disables queries to centralized databases of bad URLs to screen for
|
||||
risky sites in your browser */
|
||||
function disableHyperlinkAuditing() {
|
||||
var setting = browser.privacy.websites.hyperlinkAuditingEnabled.set({
|
||||
value: false,
|
||||
});
|
||||
console.log("Disabling hyperlink auditing/val=", {
|
||||
value: false,
|
||||
});
|
||||
setting.then(onSet);
|
||||
}
|
||||
|
||||
// UNINSTALL ONLY
|
||||
function enableHyperlinkAuditing() {
|
||||
var setting = browser.privacy.websites.hyperlinkAuditingEnabled.clear();
|
||||
console.log("Disabling hyperlink auditing/val=", {
|
||||
value: false,
|
||||
});
|
||||
setting.then(onSet);
|
||||
}
|
||||
|
||||
// This enables first-party isolation
|
||||
function enableFirstPartyIsolation() {
|
||||
var setting = browser.privacy.websites.firstPartyIsolate.set({
|
||||
value: true,
|
||||
});
|
||||
console.log("Enabling first party isolation/val=", {
|
||||
value: true,
|
||||
});
|
||||
setting.then(onSet);
|
||||
}
|
||||
|
||||
// UNINSTALL ONLY
|
||||
function disableFirstPartyIsolation() {
|
||||
var setting = browser.privacy.websites.firstPartyIsolate.clear();
|
||||
console.log("Enabling first party isolation/val=", {
|
||||
value: true,
|
||||
});
|
||||
setting.then(onSet);
|
||||
}
|
||||
|
||||
/* This rejects tracking cookies and third-party cookies but it
|
||||
LEAVES "Persistent" Cookies unmodified in favor of an option in the content
|
||||
interface for now */
|
||||
function disableEvilCookies() {
|
||||
var getting = browser.privacy.websites.cookieConfig.get({});
|
||||
getting.then((got) => {
|
||||
var setting = browser.privacy.websites.cookieConfig.set({
|
||||
value: {
|
||||
behavior: "reject_third_party",
|
||||
nonPersistentCookies: got.value.nonPersistentCookies,
|
||||
},
|
||||
});
|
||||
console.log("Setting cookie behavior/val=", {
|
||||
value: {
|
||||
behavior: "reject_third_party",
|
||||
nonPersistentCookies: got.value.nonPersistentCookies,
|
||||
},
|
||||
});
|
||||
setting.then(onSet);
|
||||
});
|
||||
}
|
||||
|
||||
function enableEvilCookies() {
|
||||
var getting = browser.privacy.websites.cookieConfig.clear();
|
||||
}
|
||||
|
||||
// Make sure that they're gone
|
||||
/*function disableBadCookies(){
|
||||
var setting = browser.privacy.websites.thirdPartyCookiesAllowed.set({
|
||||
value: false
|
||||
});
|
||||
console.log("Disabling third party cookies/val=", {
|
||||
value: false
|
||||
})
|
||||
setting.then(onSet);
|
||||
}*/
|
||||
|
||||
// this disables the use of referrer headers
|
||||
function disableReferrers() {
|
||||
var setting = browser.privacy.websites.referrersEnabled.set({
|
||||
value: false,
|
||||
});
|
||||
console.log("Disabling referrer headers/val=", {
|
||||
value: false,
|
||||
});
|
||||
setting.then(onSet);
|
||||
}
|
||||
|
||||
// UNINSATALL ONLY
|
||||
function enableReferrers() {
|
||||
var setting = browser.privacy.websites.referrersEnabled.clear();
|
||||
console.log("Disabling referrer headers/val=", {
|
||||
value: false,
|
||||
});
|
||||
setting.then(onSet);
|
||||
}
|
||||
|
||||
// enable fingerprinting resistent features(letterboxing and stuff)
|
||||
function enableResistFingerprinting() {
|
||||
var setting = browser.privacy.websites.resistFingerprinting.set({
|
||||
value: true,
|
||||
});
|
||||
console.log("Enabling resist fingerprinting/val=", {
|
||||
value: true,
|
||||
});
|
||||
setting.then(onSet);
|
||||
}
|
||||
|
||||
// UNINSTALL ONLY
|
||||
function disableResistFingerprinting() {
|
||||
var setting = browser.privacy.websites.resistFingerprinting.clear();
|
||||
console.log("Enabling resist fingerprinting/val=", {
|
||||
value: false,
|
||||
});
|
||||
setting.then(onSet);
|
||||
}
|
||||
|
||||
// This is essentially a blocklist of clearnet web-sites known to do bad tracking
|
||||
function enableTrackingProtection() {
|
||||
var setting = browser.privacy.websites.trackingProtectionMode.set({
|
||||
value: "always",
|
||||
});
|
||||
console.log("Enabling tracking protection/val=", {
|
||||
value: "always",
|
||||
});
|
||||
setting.then(onSet);
|
||||
}
|
||||
|
||||
// UNINSTALL ONLY
|
||||
function disableTrackingProtection() {
|
||||
var setting = browser.privacy.websites.trackingProtectionMode.clear();
|
||||
console.log("Enabling tracking protection/val=", {
|
||||
value: "always",
|
||||
});
|
||||
setting.then(onSet);
|
||||
}
|
||||
|
||||
/* This disables protected content, which is a form of digital restrictions
|
||||
management dependent on identifying information */
|
||||
function disableDigitalRestrictionsManagement() {
|
||||
var gettingInfo = browser.runtime.getPlatformInfo();
|
||||
gettingInfo.then((got) => {
|
||||
if (got.os == "win") {
|
||||
var setting = browser.privacy.websites.protectedContentEnabled.set({
|
||||
value: false,
|
||||
});
|
||||
console.log(
|
||||
"Setting Protected Content(Digital Restrictions Management) false/val=",
|
||||
{
|
||||
value: false,
|
||||
}
|
||||
);
|
||||
setting.then(onSet);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// UNINSTALL ONLY
|
||||
function disableDigitalRestrictionsManagement() {
|
||||
var gettingInfo = browser.runtime.getPlatformInfo();
|
||||
gettingInfo.then((got) => {
|
||||
if (got.os == "win") {
|
||||
var setting = browser.privacy.websites.protectedContentEnabled.clear();
|
||||
console.log(
|
||||
"Setting Protected Content(Digital Restrictions Management) false/val=",
|
||||
{
|
||||
value: true,
|
||||
}
|
||||
);
|
||||
setting.then(onSet);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function unsetAllPrivacy() {
|
||||
enableHyperlinkAuditing();
|
||||
disableFirstPartyIsolation();
|
||||
enableEvilCookies();
|
||||
enableReferrers();
|
||||
disableTrackingProtection();
|
||||
disableResistFingerprinting();
|
||||
enableDigitalRestrictionsManagement();
|
||||
UnsetPeerConnection();
|
||||
EnableSavePasswords();
|
||||
}
|
||||
|
||||
browser.management.onUninstalled.addListener((info) => {
|
||||
function gotSelf(selfinfo) {
|
||||
if (info.name == selfinfo.name) {
|
||||
unsetAllPrivacy();
|
||||
}
|
||||
}
|
||||
var gettingSelf = browser.management.getSelf();
|
||||
gettingSelf.then(gotSelf);
|
||||
});
|
||||
|
||||
function setAllPrivacy() {
|
||||
disableHyperlinkAuditing();
|
||||
enableFirstPartyIsolation();
|
||||
disableEvilCookies();
|
||||
//disableReferrers();
|
||||
enableTrackingProtection();
|
||||
enableResistFingerprinting();
|
||||
disableDigitalRestrictionsManagement();
|
||||
}
|
||||
|
||||
setAllPrivacy();
|
||||
|
||||
function ResetPeerConnection() {
|
||||
function reset(snowflake) {
|
||||
var webrtc = true;
|
||||
console.log("No snowflake plugin found, pre-disabled WebRTC");
|
||||
var rtc = browser.privacy.network.peerConnectionEnabled.set({
|
||||
value: webrtc,
|
||||
});
|
||||
rtc.then(AssurePeerConnection);
|
||||
}
|
||||
|
||||
function snowflake(snowflake) {
|
||||
console.log("snowflake plugin found, leaving WebRTC alone", snowflake);
|
||||
AssurePeerConnection();
|
||||
}
|
||||
var snowflakeInfo = browser.management.get(
|
||||
"{b11bea1f-a888-4332-8d8a-cec2be7d24b9}" // string
|
||||
);
|
||||
snowflakeInfo.then(snowflake, reset);
|
||||
}
|
||||
|
||||
function AssurePeerConnection() {
|
||||
function assure(webrtc) {
|
||||
browser.privacy.network.peerConnectionEnabled.set({
|
||||
value: true,
|
||||
});
|
||||
chrome.privacy.network.webRTCIPHandlingPolicy.set({
|
||||
value: "disable_non_proxied_udp",
|
||||
});
|
||||
}
|
||||
let rtc = browser.privacy.network.peerConnectionEnabled.get({});
|
||||
rtc.then(assure);
|
||||
}
|
||||
|
||||
// UNINSTALL ONLY
|
||||
function UnsetPeerConnection() {
|
||||
function assure(webrtc) {
|
||||
browser.privacy.network.peerConnectionEnabled.set({
|
||||
value: true,
|
||||
});
|
||||
chrome.privacy.network.webRTCIPHandlingPolicy.set({
|
||||
value: "default",
|
||||
});
|
||||
}
|
||||
let rtc = browser.privacy.network.peerConnectionEnabled.get({});
|
||||
rtc.then(assure);
|
||||
}
|
||||
|
||||
var gettingInfo = browser.runtime.getPlatformInfo();
|
||||
gettingInfo.then((got) => {
|
||||
if (got.os == "android") {
|
||||
browser.tabs.onCreated.addListener(ResetPeerConnection);
|
||||
} else {
|
||||
browser.windows.onCreated.addListener(ResetPeerConnection);
|
||||
}
|
||||
});
|
||||
//AssurePeerConnection();
|
||||
|
||||
function ResetDisableSavePasswords() {
|
||||
browser.privacy.services.passwordSavingEnabled.set({
|
||||
value: false,
|
||||
});
|
||||
console.log("Re-disabled saved passwords");
|
||||
}
|
||||
|
||||
function EnableSavePasswords() {
|
||||
browser.privacy.services.passwordSavingEnabled.clear();
|
||||
console.log("Enabled saved passwords");
|
||||
}
|
||||
|
||||
//ResetDisableSavePasswords()
|
||||
|
||||
var defaultSettings = {
|
||||
since: "forever",
|
||||
dataTypes: ["downloads", "passwords", "formData", "localStorage", "history"],
|
||||
const PRIVACY_CONFIG = {
|
||||
TITLE_PREFACE: chrome.i18n.getMessage("titlePreface"),
|
||||
SNOWFLAKE_ID: "{b11bea1f-a888-4332-8d8a-cec2be7d24b9}",
|
||||
WINDOWS: {
|
||||
OS: "win",
|
||||
},
|
||||
BROWSING_DATA: {
|
||||
SINCE: "forever",
|
||||
TYPES: ["downloads", "passwords", "formData", "localStorage", "history"],
|
||||
},
|
||||
};
|
||||
|
||||
function onError(therror) {
|
||||
console.error(therror);
|
||||
/**
|
||||
* Privacy Manager for handling browser privacy settings
|
||||
*/
|
||||
class PrivacyManager {
|
||||
/**
|
||||
* Set browser privacy settings
|
||||
* @param {Object} settings Privacy setting configuration
|
||||
* @return {Promise<boolean>}
|
||||
*/
|
||||
static async setSetting(setting, value) {
|
||||
try {
|
||||
const result = await setting.set({ value });
|
||||
console.info(`Privacy setting updated : ${value}`);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error("Privacy setting failed:", error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure hyperlink auditing
|
||||
* @param {boolean} enabled Whether to enable auditing
|
||||
*/
|
||||
static async configureHyperlinkAuditing(enabled = false) {
|
||||
await this.setSetting(
|
||||
browser.privacy.websites.hyperlinkAuditingEnabled,
|
||||
enabled
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure first party isolation
|
||||
* @param {boolean} enabled Whether to enable isolation
|
||||
*/
|
||||
static async configureFirstPartyIsolation(enabled = true) {
|
||||
await this.setSetting(browser.privacy.websites.firstPartyIsolate, enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure cookie behavior
|
||||
* @param {boolean} allowThirdParty Whether to allow third party cookies
|
||||
*/
|
||||
static async configureCookies(allowThirdParty = false) {
|
||||
try {
|
||||
const cookieConfig = await browser.privacy.websites.cookieConfig.get({});
|
||||
await browser.privacy.websites.cookieConfig.set({
|
||||
value: {
|
||||
behavior: allowThirdParty ? "allow_all" : "reject_third_party",
|
||||
nonPersistentCookies: cookieConfig.value.nonPersistentCookies,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Cookie configuration failed:", error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure referrer policy
|
||||
* @param {boolean} enabled Whether to enable referrers
|
||||
*/
|
||||
static async configureReferrers(enabled = false) {
|
||||
await this.setSetting(browser.privacy.websites.referrersEnabled, enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure fingerprinting resistance
|
||||
* @param {boolean} enabled Whether to enable resistance
|
||||
*/
|
||||
static async configureFingerprinting(enabled = true) {
|
||||
await this.setSetting(
|
||||
browser.privacy.websites.resistFingerprinting,
|
||||
enabled
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure tracking protection
|
||||
* @param {boolean} enabled Whether to enable protection
|
||||
*/
|
||||
static async configureTrackingProtection(enabled = true) {
|
||||
await this.setSetting(
|
||||
browser.privacy.websites.trackingProtectionMode,
|
||||
enabled ? "always" : "never"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure DRM content
|
||||
* @param {boolean} enabled Whether to enable DRM
|
||||
*/
|
||||
static async configureDRM(enabled = false) {
|
||||
const platformInfo = await browser.runtime.getPlatformInfo();
|
||||
if (platformInfo.os === PRIVACY_CONFIG.WINDOWS.OS) {
|
||||
await this.setSetting(
|
||||
browser.privacy.websites.protectedContentEnabled,
|
||||
enabled
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure WebRTC
|
||||
* @param {boolean} enabled Whether to enable WebRTC
|
||||
*/
|
||||
static async configureWebRTC(enabled = false) {
|
||||
try {
|
||||
const snowflake = await browser.management.get(
|
||||
PRIVACY_CONFIG.SNOWFLAKE_ID
|
||||
);
|
||||
console.info("Snowflake detected, preserving WebRTC");
|
||||
return;
|
||||
} catch {
|
||||
await this.setSetting(
|
||||
browser.privacy.network.peerConnectionEnabled,
|
||||
enabled
|
||||
);
|
||||
await this.setSetting(
|
||||
chrome.privacy.network.webRTCIPHandlingPolicy,
|
||||
enabled ? "disable_non_proxied_udp" : "default"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure password saving
|
||||
* @param {boolean} enabled Whether to enable password saving
|
||||
*/
|
||||
static async configurePasswordSaving(enabled = false) {
|
||||
await this.setSetting(
|
||||
browser.privacy.services.passwordSavingEnabled,
|
||||
enabled
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply recommended privacy settings
|
||||
*/
|
||||
static async applyRecommendedSettings() {
|
||||
await Promise.all([
|
||||
this.configureHyperlinkAuditing(false),
|
||||
this.configureFirstPartyIsolation(true),
|
||||
this.configureCookies(false),
|
||||
this.configureFingerprinting(true),
|
||||
this.configureTrackingProtection(true),
|
||||
this.configureDRM(false),
|
||||
this.configureWebRTC(false),
|
||||
this.configurePasswordSaving(false),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset all privacy settings to defaults
|
||||
*/
|
||||
static async resetAllSettings() {
|
||||
await Promise.all([
|
||||
browser.privacy.websites.hyperlinkAuditingEnabled.clear(),
|
||||
browser.privacy.websites.firstPartyIsolate.clear(),
|
||||
browser.privacy.websites.cookieConfig.clear(),
|
||||
browser.privacy.websites.referrersEnabled.clear(),
|
||||
browser.privacy.websites.resistFingerprinting.clear(),
|
||||
browser.privacy.websites.trackingProtectionMode.clear(),
|
||||
browser.privacy.websites.protectedContentEnabled.clear(),
|
||||
browser.privacy.network.peerConnectionEnabled.clear(),
|
||||
browser.privacy.services.passwordSavingEnabled.clear(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
function forgetBrowsingData(storedSettings) {
|
||||
function getSince(selectedSince) {
|
||||
if (selectedSince === "forever") {
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* Data Cleanup Manager for handling browsing data
|
||||
*/
|
||||
class DataCleanupManager {
|
||||
/**
|
||||
* Clean browsing data for I2P domains
|
||||
* @param {Object} options Cleanup options
|
||||
*/
|
||||
static async cleanBrowsingData(options = {}) {
|
||||
const since = this.calculateCleanupTime(
|
||||
options.since || PRIVACY_CONFIG.BROWSING_DATA.SINCE
|
||||
);
|
||||
|
||||
try {
|
||||
const i2pHistory = await browser.history.search({
|
||||
text: "i2p",
|
||||
startTime: 0,
|
||||
});
|
||||
|
||||
for (const item of i2pHistory) {
|
||||
if (this.isI2PUrl(item.url)) {
|
||||
await this.cleanupForDomain(item.url, since);
|
||||
}
|
||||
}
|
||||
|
||||
await this.notifyCleanup();
|
||||
} catch (error) {
|
||||
console.error("Data cleanup failed:", error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate cleanup timestamp
|
||||
* @param {string} timeframe Cleanup timeframe
|
||||
* @returns {number} Timestamp
|
||||
*/
|
||||
static calculateCleanupTime(timeframe) {
|
||||
const times = {
|
||||
hour: () => 1000 * 60 * 60,
|
||||
day: () => 1000 * 60 * 60 * 24,
|
||||
week: () => 1000 * 60 * 60 * 24 * 7,
|
||||
forever: () => 0,
|
||||
};
|
||||
|
||||
const sinceMilliseconds = times[selectedSince].call();
|
||||
return Date.now() - sinceMilliseconds;
|
||||
return timeframe === "forever"
|
||||
? 0
|
||||
: Date.now() - (times[timeframe] || times.forever)();
|
||||
}
|
||||
|
||||
function getTypes(selectedTypes) {
|
||||
let dataTypes = {};
|
||||
for (let item of selectedTypes) {
|
||||
dataTypes[item] = true;
|
||||
/**
|
||||
* Clean up data for specific domain
|
||||
* @param {string} url Domain URL
|
||||
* @param {number} since Timestamp
|
||||
*/
|
||||
static async cleanupForDomain(url, since) {
|
||||
const hostname = this.extractI2PHostname(url);
|
||||
|
||||
await Promise.all([
|
||||
browser.history.deleteUrl({ url }),
|
||||
browser.browsingData.removeCache({}),
|
||||
browser.browsingData.removePasswords({ hostnames: [hostname], since }),
|
||||
browser.browsingData.removeDownloads({ hostnames: [hostname], since }),
|
||||
browser.browsingData.removeFormData({ hostnames: [hostname], since }),
|
||||
browser.browsingData.removeLocalStorage({ hostnames: [hostname], since }),
|
||||
]);
|
||||
|
||||
await this.cleanupContainerCookies(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up container cookies
|
||||
* @param {string} url Domain URL
|
||||
*/
|
||||
static async cleanupContainerCookies(url) {
|
||||
const containers = await browser.contextualIdentities.query({
|
||||
name: PRIVACY_CONFIG.TITLE_PREFACE,
|
||||
});
|
||||
|
||||
for (const container of containers) {
|
||||
const cookies = await browser.cookies.getAll({
|
||||
firstPartyDomain: null,
|
||||
storeId: container.cookieStoreId,
|
||||
});
|
||||
|
||||
for (const cookie of cookies) {
|
||||
await browser.cookies.remove({
|
||||
firstPartyDomain: cookie.firstPartyDomain,
|
||||
name: cookie.name,
|
||||
url: url,
|
||||
});
|
||||
}
|
||||
}
|
||||
return dataTypes;
|
||||
}
|
||||
|
||||
const since = getSince(defaultSettings.since);
|
||||
const dataTypes = getTypes(defaultSettings.dataTypes);
|
||||
/**
|
||||
* Extract I2P hostname from URL
|
||||
* @param {string} url URL to parse
|
||||
* @returns {string} I2P hostname
|
||||
*/
|
||||
static extractI2PHostname(url) {
|
||||
try {
|
||||
const urlObj = new URL(url);
|
||||
if (urlObj.host.endsWith(".i2p")) {
|
||||
return urlObj.host;
|
||||
}
|
||||
|
||||
function notify() {
|
||||
let dataTypesString = Object.keys(dataTypes).join(", ");
|
||||
let sinceString = new Date(since).toLocaleString();
|
||||
browser.notifications.create({
|
||||
if (url.includes(".i2p")) {
|
||||
const parts = url.split("=");
|
||||
for (const part of parts) {
|
||||
const items = part.split("%");
|
||||
for (const item of items) {
|
||||
if (item.includes(".i2p")) {
|
||||
return item.replace("3D", "");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return url.split("/")[2] || url.split("/")[0];
|
||||
} catch (error) {
|
||||
console.error("Hostname extraction failed:", error);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if URL is I2P
|
||||
* @param {string} url URL to check
|
||||
* @returns {boolean}
|
||||
*/
|
||||
static isI2PUrl(url) {
|
||||
const hostname = this.extractI2PHostname(url);
|
||||
return hostname.split(":")[0].endsWith(".i2p");
|
||||
}
|
||||
|
||||
/**
|
||||
* Send cleanup notification
|
||||
*/
|
||||
static async notifyCleanup() {
|
||||
await browser.notifications.create({
|
||||
type: "basic",
|
||||
title: "Removed browsing data",
|
||||
message: `Removed ${dataTypesString}\n for I2P Browsing`,
|
||||
message: "Cleaned I2P browsing data and history",
|
||||
});
|
||||
}
|
||||
|
||||
function deepCleanHistory(historyItems) {
|
||||
console.log("Deep cleaning history");
|
||||
for (let item of historyItems) {
|
||||
if (i2pCheck(item.url)) {
|
||||
browser.history.deleteUrl({
|
||||
url: item.url,
|
||||
});
|
||||
browser.browsingData.removeCache({});
|
||||
console.log("cleared Cache");
|
||||
browser.browsingData
|
||||
.removePasswords({
|
||||
hostnames: [i2pHostName(item.url)],
|
||||
since,
|
||||
})
|
||||
.then(onContextGotLog);
|
||||
console.log("cleared Passwords");
|
||||
browser.browsingData
|
||||
.removeDownloads({
|
||||
hostnames: [i2pHostName(item.url)],
|
||||
since,
|
||||
})
|
||||
.then(onContextGotLog);
|
||||
console.log("cleared Downloads");
|
||||
browser.browsingData
|
||||
.removeFormData({
|
||||
hostnames: [i2pHostName(item.url)],
|
||||
since,
|
||||
})
|
||||
.then(onContextGotLog);
|
||||
console.log("cleared Form Data");
|
||||
browser.browsingData
|
||||
.removeLocalStorage({
|
||||
hostnames: [i2pHostName(item.url)],
|
||||
since,
|
||||
})
|
||||
.then(onContextGotLog);
|
||||
console.log("cleared Local Storage");
|
||||
|
||||
let contexts = browser.contextualIdentities.query({
|
||||
name: titlepref,
|
||||
});
|
||||
|
||||
function deepCleanCookies(cookies) {
|
||||
for (let cookie of cookies) {
|
||||
var removing = browser.cookies.remove({
|
||||
firstPartyDomain: cookie.firstPartyDomain,
|
||||
name: cookie.name,
|
||||
url: item.url,
|
||||
});
|
||||
removing.then(onContextGotLog, onError);
|
||||
}
|
||||
console.log("Cleared cookies");
|
||||
}
|
||||
|
||||
function deepCleanContext(cookieStoreIds) {
|
||||
for (let cookieStoreId of cookieStoreIds) {
|
||||
var removing = browser.cookies.getAll({
|
||||
firstPartyDomain: null,
|
||||
storeId: cookieStoreId.cookieStoreId,
|
||||
});
|
||||
removing.then(deepCleanCookies, onError);
|
||||
}
|
||||
}
|
||||
|
||||
contexts.then(deepCleanContext, onError);
|
||||
}
|
||||
}
|
||||
notify();
|
||||
}
|
||||
|
||||
var searching = browser.history.search({
|
||||
text: "i2p",
|
||||
startTime: 0,
|
||||
});
|
||||
|
||||
searching.then(deepCleanHistory);
|
||||
|
||||
setAllPrivacy();
|
||||
ResetPeerConnection();
|
||||
}
|
||||
|
||||
function i2pHostName(url) {
|
||||
let hostname = "";
|
||||
console.log("(hosts)", url);
|
||||
let u = new URL(url);
|
||||
if (u.host.endsWith(".i2p")) {
|
||||
hostname = u.host;
|
||||
} else if (url.includes("=")) {
|
||||
if (url.includes(".i2p")) {
|
||||
lsit = url.split("=");
|
||||
for (let item in lsit) {
|
||||
var items = lsit[item].split(`\ % `); //"\%")
|
||||
for (let p in items) {
|
||||
if (items[p].includes(".i2p")) {
|
||||
hostname = items[p].replace("3D", 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (hostname != "") {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (url.indexOf("://") > -1) {
|
||||
hostname = url.split("/")[2];
|
||||
} else {
|
||||
hostname = url.split("/")[0];
|
||||
}
|
||||
return hostname;
|
||||
}
|
||||
|
||||
function i2pCheck(url) {
|
||||
let hostname = i2pHostName(url);
|
||||
let postname = hostname.split(":")[0];
|
||||
if (postname.endsWith(".i2p")) {
|
||||
console.log("(hostname) i2p", postname);
|
||||
}
|
||||
return postname.endsWith(".i2p");
|
||||
}
|
||||
|
||||
function onContextGotLog(contexts) {
|
||||
if (contexts != null) {
|
||||
console.log(contexts);
|
||||
}
|
||||
}
|
||||
|
||||
browser.runtime.onMessage.addListener(message);
|
||||
|
||||
function enableHistory() {
|
||||
function checkStoredSettings(storedSettings) {
|
||||
storedSettings["disable_history"] = false;
|
||||
console.log(storedSettings);
|
||||
|
||||
function enablehistory(settings) {
|
||||
console.log("Store History:", settings);
|
||||
}
|
||||
let setting = browser.storage.local.set(storedSettings);
|
||||
setting.then(enablehistory);
|
||||
}
|
||||
const gettingStoredSettings = browser.storage.local.get();
|
||||
gettingStoredSettings.then(checkStoredSettings, onError);
|
||||
}
|
||||
|
||||
function disableHistory() {
|
||||
function checkStoredSettings(storedSettings) {
|
||||
storedSettings["disable_history"] = true;
|
||||
console.log(storedSettings);
|
||||
|
||||
function enablehistory(settings) {
|
||||
console.log("Store History:", settings);
|
||||
}
|
||||
var setting = browser.storage.local.set(storedSettings);
|
||||
setting.then(enablehistory);
|
||||
}
|
||||
const gettingStoredSettings = browser.storage.local.get();
|
||||
gettingStoredSettings.then(checkStoredSettings, onError);
|
||||
}
|
||||
|
||||
function enableReferer() {
|
||||
function checkStoredSettings(storedSettings) {
|
||||
storedSettings["disable_referer"] = false;
|
||||
console.log(storedSettings);
|
||||
|
||||
function enablereferer(settings) {
|
||||
console.log("Store Referer:", settings);
|
||||
}
|
||||
let setting = browser.storage.local.set(storedSettings);
|
||||
setting.then(enablereferer);
|
||||
}
|
||||
const gettingStoredSettings = browser.storage.local.get();
|
||||
gettingStoredSettings.then(checkStoredSettings, onError);
|
||||
}
|
||||
|
||||
function disableReferer() {
|
||||
function checkStoredSettings(storedSettings) {
|
||||
storedSettings["disable_referer"] = true;
|
||||
console.log(storedSettings);
|
||||
|
||||
function enablereferer(settings) {
|
||||
console.log("Store Referer:", settings);
|
||||
}
|
||||
var setting = browser.storage.local.set(storedSettings);
|
||||
setting.then(enablereferer);
|
||||
}
|
||||
const gettingStoredSettings = browser.storage.local.get();
|
||||
gettingStoredSettings.then(checkStoredSettings, onError);
|
||||
}
|
||||
|
||||
function message(recieved) {
|
||||
console.log(recieved);
|
||||
if (recieved.rtc === "enableWebRTC") {
|
||||
console.log("enableWebRTC");
|
||||
AssurePeerConnection();
|
||||
} else if (recieved.rtc === "disableWebRTC") {
|
||||
console.log("disableWebRTC");
|
||||
ResetPeerConnection();
|
||||
}
|
||||
if (recieved.history === "enableHistory") {
|
||||
console.log("enableHistory");
|
||||
enableHistory();
|
||||
} else if (recieved.history === "disableHistory") {
|
||||
console.log("disableHistory");
|
||||
disableHistory();
|
||||
// Initialize privacy settings
|
||||
PrivacyManager.applyRecommendedSettings();
|
||||
|
||||
// Listen for uninstall
|
||||
browser.management.onUninstalled.addListener(async (info) => {
|
||||
const selfInfo = await browser.management.getSelf();
|
||||
if (info.name === selfInfo.name) {
|
||||
await PrivacyManager.resetAllSettings();
|
||||
}
|
||||
});
|
||||
|
||||
// Listen for messages
|
||||
browser.runtime.onMessage.addListener(async (message) => {
|
||||
switch (message.type) {
|
||||
case "cleanupData":
|
||||
await DataCleanupManager.cleanBrowsingData(message.options);
|
||||
break;
|
||||
case "updatePrivacy":
|
||||
await PrivacyManager.applyRecommendedSettings();
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
// Export for testing
|
||||
if (typeof module !== "undefined" && module.exports) {
|
||||
module.exports = {
|
||||
PrivacyManager,
|
||||
DataCleanupManager,
|
||||
PRIVACY_CONFIG,
|
||||
};
|
||||
}
|
||||
|
740
proxy.js
740
proxy.js
@ -1,357 +1,405 @@
|
||||
var titlepref = chrome.i18n.getMessage("titlePreface");
|
||||
var webpref = chrome.i18n.getMessage("webPreface");
|
||||
var routerpref = chrome.i18n.getMessage("routerPreface");
|
||||
var mailpref = chrome.i18n.getMessage("mailPreface");
|
||||
var torrentpref = chrome.i18n.getMessage("torrentPreface");
|
||||
var tunnelpref = chrome.i18n.getMessage("i2ptunnelPreface");
|
||||
var ircpref = chrome.i18n.getMessage("ircPreface");
|
||||
var extensionpref = chrome.i18n.getMessage("extensionPreface");
|
||||
var muwirepref = chrome.i18n.getMessage("muwirePreface");
|
||||
var botepref = chrome.i18n.getMessage("botePreface");
|
||||
var blogpref = chrome.i18n.getMessage("blogPreface");
|
||||
var blogprefpriv = chrome.i18n.getMessage("blogPrefacePrivate");
|
||||
var torpref = chrome.i18n.getMessage("torPreface");
|
||||
var torprefpriv = chrome.i18n.getMessage("torPreface");
|
||||
/**
|
||||
* @fileoverview I2P Proxy Manager
|
||||
* Handles proxy configuration and routing for I2P container tabs
|
||||
*/
|
||||
|
||||
browser.privacy.network.peerConnectionEnabled.set({
|
||||
value: true,
|
||||
});
|
||||
|
||||
chrome.privacy.network.networkPredictionEnabled.set({
|
||||
value: false,
|
||||
});
|
||||
chrome.privacy.network.webRTCIPHandlingPolicy.set({
|
||||
value: "disable_non_proxied_udp",
|
||||
});
|
||||
console.log("Disabled unproxied UDP.");
|
||||
|
||||
function shouldProxyRequest(requestInfo) {
|
||||
return requestInfo.parentFrameId != -1;
|
||||
}
|
||||
|
||||
var handleContextProxyRequest = async function (requestDetails) {
|
||||
if (isProxyHost(requestDetails)) {
|
||||
proxy = {
|
||||
type: proxy_scheme(),
|
||||
host: proxy_host(),
|
||||
port: proxy_port(),
|
||||
};
|
||||
return proxy;
|
||||
}
|
||||
|
||||
function ircProxy() {
|
||||
if (!requestDetails.url.includes("7669")) {
|
||||
proxy = {
|
||||
type: proxy_scheme(),
|
||||
host: proxy_host(),
|
||||
port: proxy_port(),
|
||||
};
|
||||
return proxy;
|
||||
}
|
||||
if (requestDetails.url.includes(":7669")) {
|
||||
proxy = null;
|
||||
return proxy;
|
||||
}
|
||||
}
|
||||
/* This is **NOT** the tor SOCKS5 proxy.
|
||||
These are the rules for visiting the SOCKS5 proxy manager.
|
||||
*/
|
||||
function torProxy() {
|
||||
if (!requestDetails.url.includes("7695")) {
|
||||
proxy = {
|
||||
type: proxy_scheme(),
|
||||
host: proxy_host(),
|
||||
port: proxy_port(),
|
||||
};
|
||||
return proxy;
|
||||
}
|
||||
if (requestDetails.url.includes(":7695")) {
|
||||
proxy = null;
|
||||
return proxy;
|
||||
}
|
||||
}
|
||||
|
||||
function blogProxy() {
|
||||
if (!requestDetails.url.includes("8084")) {
|
||||
proxy = {
|
||||
type: proxy_scheme(),
|
||||
host: proxy_host(),
|
||||
port: proxy_port(),
|
||||
};
|
||||
return proxy;
|
||||
}
|
||||
if (requestDetails.url.includes(":8084")) {
|
||||
proxy = null;
|
||||
return proxy;
|
||||
}
|
||||
}
|
||||
|
||||
function btProxy() {
|
||||
proxy = routerProxy();
|
||||
if (requestDetails.url.includes(":7662")) {
|
||||
proxy = null;
|
||||
return proxy;
|
||||
}
|
||||
console.log("(bt proxy)", proxy);
|
||||
return proxy;
|
||||
}
|
||||
|
||||
function mainProxy() {
|
||||
console.log("(proxy) mainproxy 0");
|
||||
proxy = {
|
||||
type: proxy_scheme(),
|
||||
host: proxy_host(),
|
||||
port: proxy_port(),
|
||||
};
|
||||
let url = new URL(requestDetails.url);
|
||||
if (
|
||||
requestDetails.url.startsWith(
|
||||
"http://" + proxy_host() + ":" + control_port() + "/i2psnark/"
|
||||
)
|
||||
) {
|
||||
//+url.host)) {
|
||||
console.log("(proxy) mainproxy 2", url);
|
||||
proxy = null;
|
||||
}
|
||||
return proxy;
|
||||
}
|
||||
|
||||
function routerProxy() {
|
||||
if (isRouterHost(requestDetails.url)) {
|
||||
proxy = null;
|
||||
return proxy;
|
||||
} else if (!isRouterHost(requestDetails.url)) {
|
||||
proxy = {
|
||||
type: proxy_scheme(),
|
||||
host: proxy_host(),
|
||||
port: proxy_port(),
|
||||
};
|
||||
return proxy;
|
||||
}
|
||||
}
|
||||
try {
|
||||
var handleProxyRequest = function (context) {
|
||||
proxy = {
|
||||
type: proxy_scheme(),
|
||||
host: proxy_host(),
|
||||
port: proxy_port(),
|
||||
};
|
||||
|
||||
if (context == "firefox-default" || context == "firefox-private") {
|
||||
if (!i2pHost(requestDetails.URL))
|
||||
if (!isProxyHost(requestDetails.URL)) proxy = null;
|
||||
return proxy;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-negated-condition
|
||||
if (context != undefined) {
|
||||
console.log("(proxy), context", context);
|
||||
if (context.name == ircpref) {
|
||||
proxy = ircProxy();
|
||||
return proxy;
|
||||
} else if (context.name == torpref) {
|
||||
proxy = torProxy();
|
||||
return proxy;
|
||||
} else if (context.name == blogpref) {
|
||||
proxy = blogProxy();
|
||||
return proxy;
|
||||
} else if (context.name == titlepref) {
|
||||
proxy = mainProxy();
|
||||
return proxy;
|
||||
} else if (context.name == routerpref) {
|
||||
proxy = routerProxy();
|
||||
return proxy;
|
||||
} else if (context.name == torrentpref) {
|
||||
proxy = btProxy();
|
||||
return proxy;
|
||||
} else if (context.name == mailpref) {
|
||||
proxy = routerProxy();
|
||||
return proxy;
|
||||
} else if (context.name == tunnelpref) {
|
||||
proxy = routerProxy();
|
||||
return proxy;
|
||||
} else if (context.name == muwirepref) {
|
||||
proxy = routerProxy();
|
||||
return proxy;
|
||||
} else if (context.name == botepref) {
|
||||
proxy = routerProxy();
|
||||
return proxy;
|
||||
}
|
||||
} else {
|
||||
if (!isRouterHost(requestDetails.url)) {
|
||||
if (isLocalHost(requestDetails.url)) {
|
||||
if (requestDetails.url.includes(":7669")) {
|
||||
proxy = null;
|
||||
} else if (requestDetails.url.includes(":7662")) {
|
||||
proxy = null;
|
||||
} else if (requestDetails.url.includes(":7695")) {
|
||||
proxy = null;
|
||||
} else {
|
||||
console.log(
|
||||
"(proxy) non-routerconsole localhost url, will not interfere",
|
||||
requestDetails.url
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i2pHost(requestDetails)) {
|
||||
proxy = {
|
||||
type: proxy_scheme(),
|
||||
host: proxy_host(),
|
||||
port: proxy_port(),
|
||||
};
|
||||
} else if (isProxyHost(requestDetails)) {
|
||||
proxy = {
|
||||
type: proxy_scheme(),
|
||||
host: proxy_host(),
|
||||
port: proxy_port(),
|
||||
};
|
||||
} else {
|
||||
proxy = null;
|
||||
}
|
||||
if (requestDetails.url.includes("rpc")) {
|
||||
console.log("(proxy for rpc url)", rpc);
|
||||
}
|
||||
/* var tab = tabGet(requestDetails.tabId);
|
||||
tab.then(handleTabRequest,) */
|
||||
return proxy;
|
||||
}
|
||||
};
|
||||
var contextGet = async function (tabInfo) {
|
||||
try {
|
||||
context = await browser.contextualIdentities.get(tabInfo.cookieStoreId);
|
||||
return context;
|
||||
} catch (error) {
|
||||
console.warn(error);
|
||||
return "firefox-default";
|
||||
}
|
||||
};
|
||||
var tabGet = async function (tabId) {
|
||||
try {
|
||||
let tabInfo = await browser.tabs.get(tabId);
|
||||
return tabInfo;
|
||||
} catch (error) {
|
||||
console.log("(proxy)Tab error", error);
|
||||
}
|
||||
};
|
||||
if (isProxyHost(requestDetails)) {
|
||||
proxy = {
|
||||
type: proxy_scheme(),
|
||||
host: proxy_host(),
|
||||
port: proxy_port(),
|
||||
};
|
||||
return proxy;
|
||||
}
|
||||
if (requestDetails.originUrl == browser.runtime.getURL("security.html")) {
|
||||
proxy = {
|
||||
type: proxy_scheme(),
|
||||
host: proxy_host(),
|
||||
port: proxy_port(),
|
||||
};
|
||||
return proxy;
|
||||
}
|
||||
if (
|
||||
requestDetails.cookieStoreId == "firefox-default" ||
|
||||
requestDetails.cookieStoreId == "firefox-private"
|
||||
) {
|
||||
if (browser.windows != undefined) {
|
||||
return browser.proxy.settings.get({});
|
||||
}
|
||||
}
|
||||
if (requestDetails.tabId > 0) {
|
||||
if (requestDetails.url.includes("MuWire")) {
|
||||
console.debug("(proxy) test is muwire host:", requestDetails);
|
||||
return;
|
||||
}
|
||||
if (isProxyHost(requestDetails)) {
|
||||
console.debug("(proxy) test is proxy host:", requestDetails);
|
||||
proxy = {
|
||||
type: proxy_scheme(),
|
||||
host: proxy_host(),
|
||||
port: proxy_port(),
|
||||
};
|
||||
return proxy;
|
||||
} else if (i2pHost(requestDetails)) {
|
||||
console.debug("(proxy) test I2P host:", requestDetails);
|
||||
var tab = tabGet(requestDetails.tabId);
|
||||
requestDetails.tabId = tab;
|
||||
var context = tab.then(contextGet);
|
||||
var proxy = await context.then(handleProxyRequest);
|
||||
//console.log('(proxy)Returning I2P Proxy', proxy);
|
||||
return proxy;
|
||||
} else if (isExtensionHost(requestDetails)) {
|
||||
console.debug("(proxy) test extension host:", requestDetails);
|
||||
return;
|
||||
} else {
|
||||
console.debug("(proxy) test else in:", requestDetails);
|
||||
var tab = tabGet(requestDetails.tabId);
|
||||
var context = tab.then(contextGet);
|
||||
var proxy = await context.then(handleProxyRequest);
|
||||
//console.log("(proxy)Returning I2P Proxy", proxy);
|
||||
return proxy;
|
||||
}
|
||||
/*proxy = {};
|
||||
console.log("(proxy)Returning unset Proxy", proxy);
|
||||
return proxy;*/
|
||||
} else {
|
||||
console.debug("(proxy) test else:", requestDetails);
|
||||
proxy = {
|
||||
type: proxy_scheme(),
|
||||
host: proxy_host(),
|
||||
port: proxy_port(),
|
||||
};
|
||||
//console.log('(proxy for rpc url)', rpc);
|
||||
return proxy;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("(proxy)Not using I2P Proxy.", error);
|
||||
}
|
||||
return { type: "direct" };
|
||||
// Configuration constants
|
||||
const PROXY_CONFIG = {
|
||||
MESSAGES: {
|
||||
TITLE: chrome.i18n.getMessage("titlePreface"),
|
||||
WEB: chrome.i18n.getMessage("webPreface"),
|
||||
ROUTER: chrome.i18n.getMessage("routerPreface"),
|
||||
MAIL: chrome.i18n.getMessage("mailPreface"),
|
||||
TORRENT: chrome.i18n.getMessage("torrentPreface"),
|
||||
TUNNEL: chrome.i18n.getMessage("i2ptunnelPreface"),
|
||||
IRC: chrome.i18n.getMessage("ircPreface"),
|
||||
EXTENSION: chrome.i18n.getMessage("extensionPreface"),
|
||||
MUWIRE: chrome.i18n.getMessage("muwirePreface"),
|
||||
BOTE: chrome.i18n.getMessage("botePreface"),
|
||||
BLOG: chrome.i18n.getMessage("blogPreface"),
|
||||
BLOG_PRIVATE: chrome.i18n.getMessage("blogPrefacePrivate"),
|
||||
TOR: chrome.i18n.getMessage("torPreface"),
|
||||
},
|
||||
PORTS: {
|
||||
IRC: "7669",
|
||||
TOR: "7695",
|
||||
BLOG: "8084",
|
||||
TORRENT: "7662",
|
||||
},
|
||||
};
|
||||
|
||||
function setupProxy() {
|
||||
console.log("Setting up Firefox WebExtension proxy");
|
||||
browser.proxy.onRequest.addListener(handleContextProxyRequest, {
|
||||
urls: ["<all_urls>"],
|
||||
});
|
||||
console.log("i2p settings created for WebExtension Proxy");
|
||||
browser.proxy.onError.addListener(handleContextProxyError);
|
||||
}
|
||||
|
||||
function handleContextProxyError(err) {
|
||||
if (err == 'ProxyInfoData: Invalid proxy server type: "undefined"') {
|
||||
console.warn("(proxy) Invalid proxy server type: ", err);
|
||||
/**
|
||||
* Network Manager for handling WebRTC and network prediction
|
||||
*/
|
||||
class NetworkManager {
|
||||
/**
|
||||
* Initialize network settings
|
||||
*/
|
||||
static async initialize() {
|
||||
try {
|
||||
await Promise.all([
|
||||
browser.privacy.network.peerConnectionEnabled.set({ value: true }),
|
||||
chrome.privacy.network.networkPredictionEnabled.set({ value: false }),
|
||||
chrome.privacy.network.webRTCIPHandlingPolicy.set({
|
||||
value: "disable_non_proxied_udp",
|
||||
}),
|
||||
]);
|
||||
console.info("Network settings initialized");
|
||||
} catch (error) {
|
||||
console.error("Network initialization failed:", error);
|
||||
}
|
||||
}
|
||||
console.error("(proxy) test Context Proxy Error: ", err);
|
||||
}
|
||||
|
||||
function update() {
|
||||
console.log("(proxy) restoring proxy scheme:", proxy_scheme());
|
||||
console.log("(proxy) restoring proxy host:", proxy_host());
|
||||
console.log("(proxy) restoring proxy port:", proxy_port());
|
||||
console.log("(proxy) restoring control host:", control_host());
|
||||
console.log("(proxy) restoring control port:", control_port());
|
||||
}
|
||||
/**
|
||||
* Proxy Manager for handling proxy configuration
|
||||
*/
|
||||
class ProxyManager {
|
||||
constructor() {
|
||||
this.proxyConfig = {
|
||||
type: proxy_scheme(),
|
||||
host: proxy_host(),
|
||||
port: proxy_port(),
|
||||
};
|
||||
|
||||
function updateFromStorage() {
|
||||
console.log("updating settings from storage");
|
||||
chrome.storage.local.get(function () {
|
||||
update();
|
||||
setupProxy();
|
||||
});
|
||||
}
|
||||
this.initialize();
|
||||
}
|
||||
|
||||
//updateFromStorage();
|
||||
browser.storage.onChanged.addListener(updateFromStorage);
|
||||
setupProxy();
|
||||
/**
|
||||
* Initialize proxy settings
|
||||
*/
|
||||
async initialize() {
|
||||
try {
|
||||
await this.setupProxyListener();
|
||||
await this.setupStorageListener();
|
||||
await this.setupWindowListener();
|
||||
console.info("Proxy manager initialized");
|
||||
} catch (error) {
|
||||
console.error("Proxy initialization failed:", error);
|
||||
}
|
||||
}
|
||||
|
||||
var gettingListenerInfo = browser.runtime.getPlatformInfo();
|
||||
gettingListenerInfo.then((got) => {
|
||||
if (browser.windows != undefined) {
|
||||
browser.windows.onCreated.addListener(() => {
|
||||
chrome.storage.local.get(function () {
|
||||
setupProxy();
|
||||
});
|
||||
/**
|
||||
* Setup proxy request listener
|
||||
*/
|
||||
async setupProxyListener() {
|
||||
browser.proxy.onRequest.addListener(this.handleProxyRequest.bind(this), {
|
||||
urls: ["<all_urls>"],
|
||||
});
|
||||
browser.proxy.onError.addListener(this.handleProxyError.bind(this));
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Setup storage change listener
|
||||
*/
|
||||
async setupStorageListener() {
|
||||
browser.storage.onChanged.addListener(this.handleStorageChange.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup window creation listener
|
||||
*/
|
||||
async setupWindowListener() {
|
||||
const platformInfo = await browser.runtime.getPlatformInfo();
|
||||
if (browser.windows) {
|
||||
browser.windows.onCreated.addListener(
|
||||
this.handleWindowCreation.bind(this)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle proxy requests
|
||||
* @param {Object} requestDetails Request details
|
||||
* @return {Object} Proxy configuration
|
||||
*/
|
||||
async handleProxyRequest(requestDetails) {
|
||||
try {
|
||||
// Handle proxy host requests
|
||||
if (isProxyHost(requestDetails)) {
|
||||
return this.proxyConfig;
|
||||
}
|
||||
|
||||
// Handle extension requests
|
||||
if (this.isExtensionRequest(requestDetails)) {
|
||||
return this.proxyConfig;
|
||||
}
|
||||
|
||||
// Handle container requests
|
||||
if (requestDetails.tabId > 0) {
|
||||
return await this.handleContainerRequest(requestDetails);
|
||||
}
|
||||
|
||||
// Handle direct requests
|
||||
return await this.handleDirectRequest(requestDetails);
|
||||
} catch (error) {
|
||||
console.error("Proxy request handling failed:", error);
|
||||
return { type: "direct" };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle container-specific proxy requests
|
||||
* @param {Object} requestDetails Request details
|
||||
* @return {Object} Proxy configuration
|
||||
*/
|
||||
async handleContainerRequest(requestDetails) {
|
||||
try {
|
||||
const tab = await browser.tabs.get(requestDetails.tabId);
|
||||
const context = await this.getContextIdentity(tab);
|
||||
|
||||
if (!context) {
|
||||
return this.getDefaultProxy();
|
||||
}
|
||||
|
||||
return await this.getContainerProxy(context, requestDetails);
|
||||
} catch (error) {
|
||||
console.error("Container request handling failed:", error);
|
||||
return this.getDefaultProxy();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle direct (non-container) proxy requests
|
||||
* @param {Object} requestDetails Request details
|
||||
* @return {Object} Proxy configuration
|
||||
*/
|
||||
async handleDirectRequest(requestDetails) {
|
||||
try {
|
||||
// Check for local service ports first
|
||||
if (isLocalHost(requestDetails.url)) {
|
||||
const localProxyConfig = this.handleLocalServiceRequest(requestDetails);
|
||||
if (localProxyConfig !== undefined) {
|
||||
return localProxyConfig;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle I2P and proxy hosts
|
||||
if (i2pHost(requestDetails)) {
|
||||
console.debug("(proxy) Direct I2P host request:", requestDetails.url);
|
||||
return this.proxyConfig;
|
||||
}
|
||||
|
||||
if (isProxyHost(requestDetails)) {
|
||||
console.debug("(proxy) Direct proxy host request:", requestDetails.url);
|
||||
return this.proxyConfig;
|
||||
}
|
||||
|
||||
// Handle router console requests
|
||||
if (isRouterHost(requestDetails.url)) {
|
||||
console.debug(
|
||||
"(proxy) Direct router console request:",
|
||||
requestDetails.url
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
// RPC request handling
|
||||
if (requestDetails.url.includes("rpc")) {
|
||||
console.debug("(proxy) Direct RPC request:", requestDetails.url);
|
||||
return this.proxyConfig;
|
||||
}
|
||||
|
||||
// Default to direct connection for non-I2P traffic
|
||||
console.debug("(proxy) Direct clearnet request:", requestDetails.url);
|
||||
return { type: "direct" };
|
||||
} catch (error) {
|
||||
console.error("Direct request handling failed:", error);
|
||||
return { type: "direct" };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle local service port requests
|
||||
* @private
|
||||
* @param {Object} requestDetails Request details
|
||||
* @return {Object|undefined} Proxy configuration or undefined
|
||||
*/
|
||||
handleLocalServiceRequest(requestDetails) {
|
||||
// Local service port mapping
|
||||
const LOCAL_SERVICES = {
|
||||
[PROXY_CONFIG.PORTS.IRC]: true, // IRC Console
|
||||
[PROXY_CONFIG.PORTS.TOR]: true, // Tor Console
|
||||
[PROXY_CONFIG.PORTS.BLOG]: true, // Blog Console
|
||||
[PROXY_CONFIG.PORTS.TORRENT]: true, // Torrent Console
|
||||
};
|
||||
|
||||
// Extract port from URL
|
||||
const url = new URL(requestDetails.url);
|
||||
const port = url.port;
|
||||
|
||||
// Return null proxy for local service ports
|
||||
if (LOCAL_SERVICES[port]) {
|
||||
console.debug(
|
||||
`(proxy) Local service request on port ${port} :`,
|
||||
requestDetails.url
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Let the main proxy logic handle other local requests
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get container identity
|
||||
* @param {Object} tab Browser tab
|
||||
* @return {Object} Container context
|
||||
*/
|
||||
async getContextIdentity(tab) {
|
||||
try {
|
||||
if (
|
||||
tab.cookieStoreId === "firefox-default" ||
|
||||
tab.cookieStoreId === "firefox-private"
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
return await browser.contextualIdentities.get(tab.cookieStoreId);
|
||||
} catch (error) {
|
||||
console.error("Context identity lookup failed:", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get container-specific proxy configuration
|
||||
* @param {Object} context Container context
|
||||
* @param {Object} requestDetails Request details
|
||||
* @return {Object} Proxy configuration
|
||||
*/
|
||||
async getContainerProxy(context, requestDetails) {
|
||||
const proxyMap = {
|
||||
[PROXY_CONFIG.MESSAGES.IRC]: () => this.getIRCProxy(requestDetails),
|
||||
[PROXY_CONFIG.MESSAGES.TOR]: () => this.getTorProxy(requestDetails),
|
||||
[PROXY_CONFIG.MESSAGES.BLOG]: () => this.getBlogProxy(requestDetails),
|
||||
[PROXY_CONFIG.MESSAGES.TITLE]: () => this.getMainProxy(requestDetails),
|
||||
[PROXY_CONFIG.MESSAGES.ROUTER]: () => this.getRouterProxy(requestDetails),
|
||||
[PROXY_CONFIG.MESSAGES.TORRENT]: () =>
|
||||
this.getTorrentProxy(requestDetails),
|
||||
};
|
||||
|
||||
const handler = proxyMap[context.name];
|
||||
return handler ? await handler() : this.getDefaultProxy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get service-specific proxy configurations
|
||||
*/
|
||||
getIRCProxy(requestDetails) {
|
||||
return !requestDetails.url.includes(PROXY_CONFIG.PORTS.IRC)
|
||||
? this.proxyConfig
|
||||
: null;
|
||||
}
|
||||
|
||||
getTorProxy(requestDetails) {
|
||||
return !requestDetails.url.includes(PROXY_CONFIG.PORTS.TOR)
|
||||
? this.proxyConfig
|
||||
: null;
|
||||
}
|
||||
|
||||
getBlogProxy(requestDetails) {
|
||||
return !requestDetails.url.includes(PROXY_CONFIG.PORTS.BLOG)
|
||||
? this.proxyConfig
|
||||
: null;
|
||||
}
|
||||
|
||||
getMainProxy(requestDetails) {
|
||||
if (
|
||||
requestDetails.url.startsWith(
|
||||
`http ://${proxy_host()}:${control_port()}/i2psnark/`
|
||||
)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
return this.proxyConfig;
|
||||
}
|
||||
|
||||
getRouterProxy(requestDetails) {
|
||||
return isRouterHost(requestDetails.url) ? null : this.proxyConfig;
|
||||
}
|
||||
|
||||
getTorrentProxy(requestDetails) {
|
||||
return requestDetails.url.includes(PROXY_CONFIG.PORTS.TORRENT)
|
||||
? null
|
||||
: this.getRouterProxy(requestDetails);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default proxy configuration
|
||||
* @return {Object} Default proxy
|
||||
*/
|
||||
getDefaultProxy() {
|
||||
return { type: "direct" };
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle proxy errors
|
||||
* @param {Error} error Proxy error
|
||||
*/
|
||||
handleProxyError(error) {
|
||||
if (error.includes("Invalid proxy server type")) {
|
||||
console.warn("Invalid proxy configuration:", error);
|
||||
} else {
|
||||
console.error("Proxy error:", error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle storage changes
|
||||
*/
|
||||
async handleStorageChange() {
|
||||
try {
|
||||
await this.updateConfig();
|
||||
await this.setupProxyListener();
|
||||
} catch (error) {
|
||||
console.error("Storage update failed:", error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle window creation
|
||||
*/
|
||||
async handleWindowCreation() {
|
||||
try {
|
||||
await this.updateConfig();
|
||||
await this.setupProxyListener();
|
||||
} catch (error) {
|
||||
console.error("Window creation handling failed:", error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update proxy configuration
|
||||
*/
|
||||
async updateConfig() {
|
||||
console.info(
|
||||
"Updating proxy configuration:",
|
||||
`Scheme : ${proxy_scheme()},`,
|
||||
`Host : ${proxy_host()},`,
|
||||
`Port : ${proxy_port()},`,
|
||||
`Control : ${control_host()} :${control_port()}`
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if request is from extension
|
||||
* @param {Object} requestDetails Request details
|
||||
* @return {boolean}
|
||||
*/
|
||||
isExtensionRequest(requestDetails) {
|
||||
return requestDetails.originUrl === browser.runtime.getURL("security.html");
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize managers
|
||||
NetworkManager.initialize();
|
||||
const proxyManager = new ProxyManager();
|
||||
|
||||
// Export for testing
|
||||
if (typeof module !== "undefined" && module.exports) {
|
||||
module.exports = {
|
||||
NetworkManager,
|
||||
ProxyManager,
|
||||
PROXY_CONFIG,
|
||||
};
|
||||
}
|
||||
|
34
proxyinfo.js
34
proxyinfo.js
@ -26,7 +26,7 @@ const MESSAGE_KEYS = {
|
||||
/**
|
||||
* UI Manager for handling element visibility
|
||||
*/
|
||||
class UIManager {
|
||||
class ProxyUIManager {
|
||||
/**
|
||||
* Toggle element visibility
|
||||
* @param {Element|NodeList} elements - Elements to modify
|
||||
@ -125,13 +125,16 @@ class ProxyStatusManager {
|
||||
*/
|
||||
static async handleProxySuccess(response) {
|
||||
console.info("(proxyinfo) Proxy check successful");
|
||||
UIManager.updateContent(UI_ELEMENTS.PROXY_STATUS, MESSAGE_KEYS.SUCCESS);
|
||||
ProxyUIManager.updateContent(
|
||||
UI_ELEMENTS.PROXY_STATUS,
|
||||
MESSAGE_KEYS.SUCCESS
|
||||
);
|
||||
|
||||
const readinessElements = UIManager.getElements(
|
||||
const readinessElements = ProxyUIManager.getElements(
|
||||
UI_ELEMENTS.READINESS_CLASS
|
||||
);
|
||||
if (readinessElements) {
|
||||
UIManager.toggleVisibility(readinessElements, true);
|
||||
ProxyUIManager.toggleVisibility(readinessElements, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,13 +144,16 @@ class ProxyStatusManager {
|
||||
*/
|
||||
static async handleProxyError(error) {
|
||||
console.error("(proxyinfo) Proxy check failed:", error);
|
||||
UIManager.updateContent(UI_ELEMENTS.PROXY_STATUS, MESSAGE_KEYS.FAILURE);
|
||||
ProxyUIManager.updateContent(
|
||||
UI_ELEMENTS.PROXY_STATUS,
|
||||
MESSAGE_KEYS.FAILURE
|
||||
);
|
||||
|
||||
const readinessElements = UIManager.getElements(
|
||||
const readinessElements = ProxyUIManager.getElements(
|
||||
UI_ELEMENTS.READINESS_CLASS
|
||||
);
|
||||
if (readinessElements) {
|
||||
UIManager.toggleVisibility(readinessElements, false);
|
||||
ProxyUIManager.toggleVisibility(readinessElements, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -161,15 +167,19 @@ class ProxyStatusManager {
|
||||
|
||||
try {
|
||||
await fetch(logoUrl);
|
||||
const consoleLinks = UIManager.getElements(UI_ELEMENTS.CONSOLE_LINKS);
|
||||
const consoleLinks = ProxyUIManager.getElements(
|
||||
UI_ELEMENTS.CONSOLE_LINKS
|
||||
);
|
||||
if (consoleLinks) {
|
||||
UIManager.toggleVisibility(consoleLinks, true);
|
||||
ProxyUIManager.toggleVisibility(consoleLinks, true);
|
||||
}
|
||||
console.info("(proxyinfo) Console check successful");
|
||||
} catch (error) {
|
||||
const consoleLinks = UIManager.getElements(UI_ELEMENTS.CONSOLE_LINKS);
|
||||
const consoleLinks = ProxyUIManager.getElements(
|
||||
UI_ELEMENTS.CONSOLE_LINKS
|
||||
);
|
||||
if (consoleLinks) {
|
||||
UIManager.toggleVisibility(consoleLinks, false);
|
||||
ProxyUIManager.toggleVisibility(consoleLinks, false);
|
||||
}
|
||||
console.error("(proxyinfo) Console check failed:", error);
|
||||
}
|
||||
@ -198,7 +208,7 @@ document.addEventListener("DOMContentLoaded", initializeProxyChecks, {
|
||||
if (typeof module !== "undefined" && module.exports) {
|
||||
module.exports = {
|
||||
ProxyStatusManager,
|
||||
UIManager,
|
||||
UIManager: ProxyUIManager,
|
||||
PROXY_CONFIG,
|
||||
UI_ELEMENTS,
|
||||
};
|
||||
|
Reference in New Issue
Block a user