Files
ShieldAI/packages/extension/src/lib/settings.ts
Michael Freno de0ddac65d Add ShieldAI browser extension with phishing & spam detection (FRE-4576)
- Extension package: Manifest V3, background service worker, content scripts
- Phishing detection engine with heuristic analysis (typosquatting, entropy, TLD, brand impersonation)
- Local URL caching layer (Storage API) for <100ms cached lookups
- Popup UI with protection status, stats, and phishing report button
- Options page for settings management (blocked/allowed domains, feature toggles)
- Server-side extension routes: URL check, phishing report, auth, stats, exposure check
- Tier-aware feature gating (Basic/Plus/Premium)
- 25 passing tests for phishing detection heuristics
- Declarative net request rules for known phishing patterns
- DarkWatch integration for credential exposure checks
- Firefox compatibility layer via build modes

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-09 21:53:29 -04:00

118 lines
3.3 KiB
TypeScript

import { ExtensionSettings, SubscriptionTier, TIER_FEATURES, MessageType } from '../types';
const DEFAULT_SETTINGS: ExtensionSettings = {
apiKey: '',
apiBaseUrl: 'https://api.shieldai.com',
authToken: null,
userId: null,
tier: null,
enabled: true,
activeBlocking: false,
darkWatchEnabled: false,
spamProtectionEnabled: true,
showNotifications: true,
blockedDomains: [],
allowedDomains: [],
lastSyncAt: null,
};
export class SettingsManager {
private settings: ExtensionSettings = { ...DEFAULT_SETTINGS };
private loaded = false;
async load(): Promise<ExtensionSettings> {
if (this.loaded) return this.settings;
const stored = await chrome.storage.sync.get('shieldaiSettings');
if (stored.shieldaiSettings) {
this.settings = { ...DEFAULT_SETTINGS, ...stored.shieldaiSettings };
}
this.loaded = true;
return this.settings;
}
async get(): Promise<ExtensionSettings> {
if (!this.loaded) await this.load();
return { ...this.settings };
}
async update(partial: Partial<ExtensionSettings>): Promise<ExtensionSettings> {
await this.load();
this.settings = { ...this.settings, ...partial };
await chrome.storage.sync.set({ shieldaiSettings: this.settings });
return { ...this.settings };
}
async getAuthToken(): Promise<string | null> {
await this.load();
return this.settings.authToken;
}
async isLoggedIn(): Promise<boolean> {
await this.load();
return this.settings.authToken !== null && this.settings.userId !== null;
}
async getTier(): Promise<SubscriptionTier | null> {
await this.load();
return this.settings.tier;
}
async getFeatures(): Promise<typeof TIER_FEATURES[SubscriptionTier]> {
const tier = await this.getTier();
if (tier) return TIER_FEATURES[tier];
return TIER_FEATURES[SubscriptionTier.BASIC];
}
async isDomainBlocked(domain: string): Promise<boolean> {
await this.load();
return this.settings.blockedDomains.some(
(d) => d.toLowerCase() === domain.toLowerCase()
);
}
async isDomainAllowed(domain: string): Promise<boolean> {
await this.load();
return this.settings.allowedDomains.some(
(d) => d.toLowerCase() === domain.toLowerCase()
);
}
async isProtectionEnabled(): Promise<boolean> {
await this.load();
return this.settings.enabled;
}
async toggleProtection(): Promise<boolean> {
await this.load();
this.settings.enabled = !this.settings.enabled;
await chrome.storage.sync.set({ shieldaiSettings: this.settings });
return this.settings.enabled;
}
async addBlockedDomain(domain: string): Promise<void> {
await this.load();
const lower = domain.toLowerCase();
if (!this.settings.blockedDomains.includes(lower)) {
this.settings.blockedDomains.push(lower);
await chrome.storage.sync.set({ shieldaiSettings: this.settings });
}
}
async removeBlockedDomain(domain: string): Promise<void> {
await this.load();
this.settings.blockedDomains = this.settings.blockedDomains.filter(
(d) => d !== domain.toLowerCase()
);
await chrome.storage.sync.set({ shieldaiSettings: this.settings });
}
async reset(): Promise<void> {
this.settings = { ...DEFAULT_SETTINGS };
this.loaded = true;
await chrome.storage.sync.set({ shieldaiSettings: this.settings });
}
}
export const settingsManager = new SettingsManager();