147 lines
3.8 KiB
JavaScript
147 lines
3.8 KiB
JavaScript
// Centralized configuration manager for Firefox Proxy Switcher
|
|
|
|
// Default configuration
|
|
const DEFAULT_CONFIG = {
|
|
domains: {},
|
|
profiles: {}, // profileName -> profileConfig
|
|
settings: {
|
|
theme: 'system'
|
|
},
|
|
activeTabs: {} // tabId -> domain for tracking active tabs
|
|
};
|
|
|
|
// Centralized configuration manager
|
|
class ConfigManager {
|
|
constructor() {
|
|
this.config = { ...DEFAULT_CONFIG };
|
|
this.listeners = [];
|
|
}
|
|
|
|
// Load configuration from storage
|
|
// SECURITY NOTE: Data is stored locally only, never transmitted externally
|
|
async load() {
|
|
try {
|
|
const stored = await browser.storage.local.get('config');
|
|
this.config = {
|
|
...DEFAULT_CONFIG,
|
|
...stored.config,
|
|
settings: { ...DEFAULT_CONFIG.settings, ...(stored.config && stored.config.settings) }
|
|
};
|
|
|
|
this.notifyListeners('loaded');
|
|
return this.config;
|
|
} catch (error) {
|
|
console.error('Failed to load config:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Save configuration to storage
|
|
// SECURITY NOTE: All proxy credentials and settings remain on user's device
|
|
async save() {
|
|
try {
|
|
await browser.storage.local.set({ config: this.config });
|
|
|
|
this.notifyListeners('saved');
|
|
return true;
|
|
} catch (error) {
|
|
console.error('Failed to save config:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Reload configuration
|
|
async reload() {
|
|
return await this.load();
|
|
}
|
|
|
|
// Get current configuration
|
|
getConfig() {
|
|
return { ...this.config };
|
|
}
|
|
|
|
// Update general extension settings
|
|
async updateSettings(settings) {
|
|
this.config.settings = { ...this.config.settings, ...settings };
|
|
await this.save();
|
|
this.notifyListeners('settingsUpdated', this.config.settings);
|
|
}
|
|
|
|
// Update domain
|
|
async updateDomain(domain, domainConfig) {
|
|
// Ensure tags is an array of strings
|
|
if (domainConfig.tags && typeof domainConfig.tags === 'string') {
|
|
domainConfig.tags = domainConfig.tags.split(',').map(tag => tag.trim()).filter(tag => tag);
|
|
} else if (!domainConfig.tags) {
|
|
domainConfig.tags = [];
|
|
}
|
|
this.config.domains[domain] = domainConfig;
|
|
await this.save();
|
|
this.notifyListeners('domainUpdated', { domain, config: domainConfig });
|
|
}
|
|
|
|
// Remove domain
|
|
async removeDomain(domain) {
|
|
if (this.config.domains[domain]) {
|
|
delete this.config.domains[domain];
|
|
await this.save();
|
|
this.notifyListeners('domainRemoved', { domain });
|
|
}
|
|
}
|
|
|
|
// Get domain configuration
|
|
getDomainConfig(domain) {
|
|
return this.config.domains[domain] || null;
|
|
}
|
|
|
|
// Update profile
|
|
async updateProfile(profileName, profileConfig) {
|
|
this.config.profiles[profileName] = profileConfig;
|
|
await this.save();
|
|
this.notifyListeners('profileUpdated', { profileName, config: profileConfig });
|
|
}
|
|
|
|
// Remove profile
|
|
async removeProfile(profileName) {
|
|
if (this.config.profiles[profileName]) {
|
|
delete this.config.profiles[profileName];
|
|
await this.save();
|
|
this.notifyListeners('profileRemoved', { profileName });
|
|
}
|
|
}
|
|
|
|
// Get profile configuration
|
|
getProfileConfig(profileName) {
|
|
return this.config.profiles[profileName] || null;
|
|
}
|
|
|
|
// Get all profiles
|
|
getProfiles() {
|
|
return { ...this.config.profiles };
|
|
}
|
|
|
|
// Add change listener
|
|
addListener(callback) {
|
|
this.listeners.push(callback);
|
|
}
|
|
|
|
// Notify listeners
|
|
notifyListeners(event, data) {
|
|
this.listeners.forEach(callback => {
|
|
try {
|
|
callback(event, data);
|
|
} catch (error) {
|
|
console.error('Error in config listener:', error);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
// Create global instance of configuration manager
|
|
const configManager = new ConfigManager();
|
|
|
|
// Create global variable for use in other scripts
|
|
window.ConfigManager = ConfigManager;
|
|
window.configManager = configManager;
|
|
window.DEFAULT_CONFIG = DEFAULT_CONFIG;
|