initial commit
This commit is contained in:
commit
dded3d2fac
19 files changed
+2888
No files matched your search
+238
@@ -0,0 +1,238 @@
|
||||
// Global configuration reference for backward compatibility
|
||||
// configManager is available via window.configManager from config-manager.js
|
||||
let config = window.configManager.getConfig();
|
||||
|
||||
// Initialization
|
||||
async function init() {
|
||||
await configManager.load();
|
||||
config = configManager.getConfig(); // Update global reference
|
||||
setupProxyListener();
|
||||
|
||||
// Subscribe to configuration changes
|
||||
configManager.addListener((event, data) => {
|
||||
config = configManager.getConfig(); // Update global reference
|
||||
});
|
||||
}
|
||||
|
||||
// Setup proxy listener
|
||||
// SECURITY NOTE: The extension only routes traffic through user-configured proxies.
|
||||
// No data is collected or transmitted externally. All proxy settings are user-controlled.
|
||||
function setupProxyListener() {
|
||||
// Listen for all URLs to apply domain-specific proxy routing
|
||||
// This permission is required but only routes traffic through user-specified proxies
|
||||
browser.proxy.onRequest.addListener(
|
||||
handleProxyRequest,
|
||||
{ urls: ["<all_urls>"] }
|
||||
);
|
||||
|
||||
// Listener for automatic proxy authentication
|
||||
// SECURITY NOTE: Credentials are only used for proxy authentication and stored locally
|
||||
browser.webRequest.onAuthRequired.addListener(
|
||||
handleAuthRequired,
|
||||
{ urls: ["<all_urls>"] },
|
||||
["blocking"]
|
||||
);
|
||||
|
||||
// Track tabs to determine origin domain for proxy configuration
|
||||
// SECURITY NOTE: Only tracks domain names, no URL content or personal data
|
||||
browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
|
||||
if (changeInfo.status === 'loading' && tab.url) {
|
||||
updateTabOrigin(tabId, tab.url);
|
||||
}
|
||||
});
|
||||
|
||||
browser.tabs.onRemoved.addListener((tabId) => {
|
||||
delete config.activeTabs[tabId];
|
||||
});
|
||||
}
|
||||
|
||||
// Extract domain from URL
|
||||
function getDomainFromUrl(url) {
|
||||
try {
|
||||
const urlObj = new URL(url);
|
||||
return urlObj.hostname.replace(/^www\./, '');
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Determine origin for tab
|
||||
function updateTabOrigin(tabId, url) {
|
||||
const domain = getDomainFromUrl(url);
|
||||
if (domain) {
|
||||
config.activeTabs[tabId] = domain;
|
||||
}
|
||||
}
|
||||
|
||||
// Get proxy settings for domain
|
||||
function getProxyConfigForDomain(domain) {
|
||||
return config.domains[domain];
|
||||
}
|
||||
|
||||
// Proxy request handler
|
||||
function handleProxyRequest(requestInfo) {
|
||||
const { tabId, url, originUrl, type } = requestInfo;
|
||||
|
||||
// Determine request domain
|
||||
let domain;
|
||||
|
||||
if (originUrl) {
|
||||
// For sub-requests use origin
|
||||
domain = getDomainFromUrl(originUrl);
|
||||
} else if (tabId in config.activeTabs) {
|
||||
// For main requests use stored tab origin
|
||||
domain = config.activeTabs[tabId];
|
||||
} else {
|
||||
// Fallback option
|
||||
domain = getDomainFromUrl(url);
|
||||
}
|
||||
|
||||
if (!domain) {
|
||||
return { type: 'direct' };
|
||||
}
|
||||
|
||||
// Check domain configuration
|
||||
const proxyConfig = getProxyConfigForDomain(domain);
|
||||
|
||||
if (!proxyConfig || !proxyConfig.enabled) {
|
||||
return { type: 'direct' };
|
||||
}
|
||||
|
||||
// Form proxy object
|
||||
const proxyObj = {
|
||||
type: proxyConfig.type,
|
||||
host: proxyConfig.host,
|
||||
port: parseInt(proxyConfig.port, 10)
|
||||
};
|
||||
|
||||
// Add authentication if present
|
||||
if (proxyConfig.username) {
|
||||
proxyObj.username = proxyConfig.username;
|
||||
}
|
||||
|
||||
if (proxyConfig.password) {
|
||||
proxyObj.password = proxyConfig.password;
|
||||
}
|
||||
|
||||
return proxyObj;
|
||||
}
|
||||
|
||||
// Authentication request handler
|
||||
function handleAuthRequired(details) {
|
||||
const { url, originUrl, tabId, isProxy, realm } = details;
|
||||
|
||||
// Process only proxy authentication
|
||||
if (!isProxy) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// Determine request domain
|
||||
let domain;
|
||||
|
||||
if (originUrl) {
|
||||
domain = getDomainFromUrl(originUrl);
|
||||
} else if (tabId in config.activeTabs) {
|
||||
domain = config.activeTabs[tabId];
|
||||
} else {
|
||||
domain = getDomainFromUrl(url);
|
||||
}
|
||||
|
||||
if (!domain) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// Get proxy configuration for domain
|
||||
const proxyConfig = getProxyConfigForDomain(domain);
|
||||
|
||||
if (!proxyConfig || !proxyConfig.enabled || !proxyConfig.username || !proxyConfig.password) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// Return credentials for authentication
|
||||
return {
|
||||
authCredentials: {
|
||||
username: proxyConfig.username,
|
||||
password: proxyConfig.password
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Message handler from other extension parts
|
||||
browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
if (message.action === 'getConfig') {
|
||||
sendResponse({ config: configManager.getConfig() });
|
||||
} else if (message.action === 'updateDomain') {
|
||||
configManager.updateDomain(message.domain, message.domainConfig)
|
||||
.then(() => sendResponse({ success: true }))
|
||||
.catch(error => sendResponse({ success: false, error: error.message }));
|
||||
return true; // Async response
|
||||
} else if (message.action === 'removeDomain') {
|
||||
configManager.removeDomain(message.domain)
|
||||
.then(() => sendResponse({ success: true }))
|
||||
.catch(error => sendResponse({ success: false, error: error.message }));
|
||||
return true; // Async response
|
||||
} else if (message.action === 'toggleProxy') {
|
||||
// Quick enable/disable proxy for domain
|
||||
const domain = message.domain;
|
||||
const enabled = message.enabled;
|
||||
const domainConfig = configManager.getDomainConfig(domain);
|
||||
|
||||
if (domainConfig) {
|
||||
// If domain is already configured, just change enabled
|
||||
domainConfig.enabled = enabled;
|
||||
configManager.updateDomain(domain, domainConfig)
|
||||
.then(() => sendResponse({ success: true }))
|
||||
.catch(error => sendResponse({ success: false, error: error.message }));
|
||||
} else {
|
||||
// If domain is not configured, send error
|
||||
sendResponse({ success: false, error: 'Domain not configured' });
|
||||
}
|
||||
return true; // Async response
|
||||
} else if (message.action === 'reloadConfig') {
|
||||
configManager.reload()
|
||||
.then(() => sendResponse({ success: true }))
|
||||
.catch(error => sendResponse({ success: false, error: error.message }));
|
||||
return true; // Async response
|
||||
} else if (message.action === 'getProfiles') {
|
||||
sendResponse({ profiles: configManager.getProfiles() });
|
||||
} else if (message.action === 'updateProfile') {
|
||||
configManager.updateProfile(message.profileName, message.profileConfig)
|
||||
.then(() => sendResponse({ success: true }))
|
||||
.catch(error => sendResponse({ success: false, error: error.message }));
|
||||
return true; // Async response
|
||||
} else if (message.action === 'removeProfile') {
|
||||
configManager.removeProfile(message.profileName)
|
||||
.then(() => sendResponse({ success: true }))
|
||||
.catch(error => sendResponse({ success: false, error: error.message }));
|
||||
return true; // Async response
|
||||
} else if (message.action === 'getProfile') {
|
||||
sendResponse({ profile: configManager.getProfileConfig(message.profileName) });
|
||||
} else if (message.action === 'updateSettings') {
|
||||
configManager.updateSettings(message.settings || {})
|
||||
.then(() => sendResponse({ success: true, settings: configManager.getConfig().settings }))
|
||||
.catch(error => sendResponse({ success: false, error: error.message }));
|
||||
return true;
|
||||
} else if (message.action === 'clearAllDomains') {
|
||||
configManager.config.domains = {};
|
||||
configManager.save()
|
||||
.then(() => sendResponse({ success: true }))
|
||||
.catch(error => sendResponse({ success: false, error: error.message }));
|
||||
return true;
|
||||
} else if (message.action === 'clearAllProfiles') {
|
||||
configManager.config.profiles = {};
|
||||
configManager.save()
|
||||
.then(() => sendResponse({ success: true }))
|
||||
.catch(error => sendResponse({ success: false, error: error.message }));
|
||||
return true;
|
||||
} else if (message.action === 'clearEverything') {
|
||||
configManager.config.domains = {};
|
||||
configManager.config.profiles = {};
|
||||
configManager.save()
|
||||
.then(() => sendResponse({ success: true }))
|
||||
.catch(error => sendResponse({ success: false, error: error.message }));
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// Initialization on load
|
||||
init();
|
||||
Reference in new issue
Block a user