mirror of
https://github.com/bitwarden/browser
synced 2026-02-10 05:30:01 +00:00
move the call to background
This commit is contained in:
@@ -78,7 +78,6 @@ import { ClientType } from "@bitwarden/common/enums";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ProcessReloadServiceAbstraction } from "@bitwarden/common/key-management/abstractions/process-reload.service";
|
||||
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
||||
import { BulkEncryptServiceImplementation } from "@bitwarden/common/key-management/crypto/services/bulk-encrypt.service.implementation";
|
||||
import { EncryptServiceImplementation } from "@bitwarden/common/key-management/crypto/services/encrypt.service.implementation";
|
||||
import { FallbackBulkEncryptService } from "@bitwarden/common/key-management/crypto/services/fallback-bulk-encrypt.service";
|
||||
import { MultithreadEncryptServiceImplementation } from "@bitwarden/common/key-management/crypto/services/multithread-encrypt.service.implementation";
|
||||
@@ -712,7 +711,6 @@ export default class MainBackground {
|
||||
this.vaultTimeoutSettingsService,
|
||||
);
|
||||
|
||||
// Initialize phishing detection services
|
||||
const phishingApiService = new PhishingApiService(this.apiService);
|
||||
PhishingDetectionService.initialize(
|
||||
phishingApiService,
|
||||
@@ -1334,23 +1332,10 @@ export default class MainBackground {
|
||||
this.commandsBackground.init();
|
||||
this.contextMenusBackground?.init();
|
||||
this.idleBackground.init();
|
||||
this.webRequestBackground?.startListening();
|
||||
await this.webRequestBackground?.startListening();
|
||||
this.syncServiceListener?.listener$().subscribe();
|
||||
await this.autoSubmitLoginBackground.init();
|
||||
|
||||
// Set up phishing detection tab event listeners
|
||||
const phishingDetectionService = new PhishingDetectionService();
|
||||
phishingDetectionService.setupTabEventListeners();
|
||||
|
||||
if (
|
||||
BrowserApi.isManifestVersion(2) &&
|
||||
(await this.configService.getFeatureFlag(FeatureFlag.PM4154_BulkEncryptionService))
|
||||
) {
|
||||
await this.bulkEncryptService.setFeatureFlagEncryptService(
|
||||
new BulkEncryptServiceImplementation(this.cryptoFunctionService, this.logService),
|
||||
);
|
||||
}
|
||||
|
||||
// If the user is logged out, switch to the next account
|
||||
const active = await firstValueFrom(this.accountService.activeAccount$);
|
||||
if (active != null) {
|
||||
|
||||
@@ -5,7 +5,7 @@ export class PhishingApiService implements PhishingApiServiceAbstraction {
|
||||
constructor(private apiService: ApiService) {}
|
||||
|
||||
async getKnownPhishingDomains(): Promise<string[]> {
|
||||
const response = await this.apiService.send("GET", "/phishing/domains", null, true, true);
|
||||
const response = await this.apiService.send("GET", "/phishing-domains", null, false, true);
|
||||
return response as string[];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,13 +13,17 @@ export class PhishingDetectionService {
|
||||
private static knownPhishingDomains = new Set<string>();
|
||||
private static lastUpdateTime: number = 0;
|
||||
private static readonly UPDATE_INTERVAL = 24 * 60 * 60 * 1000; // 24 hours in milliseconds
|
||||
private static readonly RETRY_INTERVAL = 5 * 60 * 1000; // 5 minutes
|
||||
private static readonly MAX_RETRIES = 3;
|
||||
private static readonly STORAGE_KEY = "phishing_domains_cache";
|
||||
private static phishingApiService: PhishingApiServiceAbstraction;
|
||||
private static logService: LogService;
|
||||
private static storageService: AbstractStorageService;
|
||||
private static taskSchedulerService: TaskSchedulerService;
|
||||
private static updateCacheSubscription: Subscription | null = null;
|
||||
private static retrySubscription: Subscription | null = null;
|
||||
private static isUpdating = false;
|
||||
private static retryCount = 0;
|
||||
|
||||
static initialize(
|
||||
phishingApiService: PhishingApiServiceAbstraction,
|
||||
@@ -49,13 +53,19 @@ export class PhishingDetectionService {
|
||||
|
||||
// Set up periodic updates every 24 hours
|
||||
this.setupPeriodicUpdates();
|
||||
|
||||
// Set up tab listener
|
||||
this.setupTabEventListeners();
|
||||
}
|
||||
|
||||
private static setupPeriodicUpdates() {
|
||||
// Clean up any existing subscription
|
||||
// Clean up any existing subscriptions
|
||||
if (this.updateCacheSubscription) {
|
||||
this.updateCacheSubscription.unsubscribe();
|
||||
}
|
||||
if (this.retrySubscription) {
|
||||
this.retrySubscription.unsubscribe();
|
||||
}
|
||||
|
||||
this.updateCacheSubscription = this.taskSchedulerService.setInterval(
|
||||
ScheduledTaskNames.phishingDomainUpdate,
|
||||
@@ -63,6 +73,39 @@ export class PhishingDetectionService {
|
||||
);
|
||||
}
|
||||
|
||||
private static scheduleRetry() {
|
||||
// If we've exceeded max retries, stop retrying
|
||||
if (this.retryCount >= this.MAX_RETRIES) {
|
||||
this.logService.warning(
|
||||
`Max retries (${this.MAX_RETRIES}) reached for phishing domain update. Will try again in ${this.UPDATE_INTERVAL / (1000 * 60 * 60)} hours.`,
|
||||
);
|
||||
this.retryCount = 0;
|
||||
if (this.retrySubscription) {
|
||||
this.retrySubscription.unsubscribe();
|
||||
this.retrySubscription = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Clean up existing retry subscription if any
|
||||
if (this.retrySubscription) {
|
||||
this.retrySubscription.unsubscribe();
|
||||
}
|
||||
|
||||
// Increment retry count
|
||||
this.retryCount++;
|
||||
|
||||
// Schedule a retry in 5 minutes
|
||||
this.retrySubscription = this.taskSchedulerService.setInterval(
|
||||
ScheduledTaskNames.phishingDomainUpdate,
|
||||
this.RETRY_INTERVAL,
|
||||
);
|
||||
|
||||
this.logService.info(
|
||||
`Scheduled retry ${this.retryCount}/${this.MAX_RETRIES} for phishing domain update in ${this.RETRY_INTERVAL / (1000 * 60)} minutes`,
|
||||
);
|
||||
}
|
||||
|
||||
private static async loadCachedDomains() {
|
||||
try {
|
||||
const cachedData = await this.storageService.get<{ domains: string[]; timestamp: number }>(
|
||||
@@ -99,7 +142,9 @@ export class PhishingDetectionService {
|
||||
|
||||
this.isUpdating = true;
|
||||
try {
|
||||
this.logService.info("Starting phishing domains update...");
|
||||
const domains = await PhishingDetectionService.phishingApiService.getKnownPhishingDomains();
|
||||
this.logService.info("Received phishing domains response");
|
||||
|
||||
// Clear old domains to prevent memory leaks
|
||||
PhishingDetectionService.knownPhishingDomains.clear();
|
||||
@@ -119,8 +164,31 @@ export class PhishingDetectionService {
|
||||
domains: Array.from(this.knownPhishingDomains),
|
||||
timestamp: this.lastUpdateTime,
|
||||
});
|
||||
|
||||
// Reset retry count and clear retry subscription on success
|
||||
this.retryCount = 0;
|
||||
if (this.retrySubscription) {
|
||||
this.retrySubscription.unsubscribe();
|
||||
this.retrySubscription = null;
|
||||
}
|
||||
|
||||
this.logService.info(
|
||||
`Successfully updated phishing domains cache with ${this.knownPhishingDomains.size} domains`,
|
||||
);
|
||||
} catch (error) {
|
||||
PhishingDetectionService.logService.error("Failed to update phishing domains:", error);
|
||||
this.logService.error("Error details:", error);
|
||||
if (
|
||||
error?.message?.includes("Access token not found") ||
|
||||
error?.message?.includes("Failed to decode access token")
|
||||
) {
|
||||
this.logService.info(
|
||||
"Authentication required for phishing domain update, will retry when authenticated",
|
||||
);
|
||||
this.scheduleRetry();
|
||||
} else {
|
||||
PhishingDetectionService.logService.error("Failed to update phishing domains:", error);
|
||||
throw error;
|
||||
}
|
||||
} finally {
|
||||
this.isUpdating = false;
|
||||
}
|
||||
@@ -131,9 +199,14 @@ export class PhishingDetectionService {
|
||||
this.updateCacheSubscription.unsubscribe();
|
||||
this.updateCacheSubscription = null;
|
||||
}
|
||||
if (this.retrySubscription) {
|
||||
this.retrySubscription.unsubscribe();
|
||||
this.retrySubscription = null;
|
||||
}
|
||||
this.knownPhishingDomains.clear();
|
||||
this.lastUpdateTime = 0;
|
||||
this.isUpdating = false;
|
||||
this.retryCount = 0;
|
||||
}
|
||||
|
||||
static async getActiveUrl(): Promise<string> {
|
||||
@@ -150,7 +223,7 @@ export class PhishingDetectionService {
|
||||
/*
|
||||
This listener will check the URL when the tab has finished loading.
|
||||
*/
|
||||
setupTabEventListeners(): void {
|
||||
private static setupTabEventListeners(): void {
|
||||
BrowserApi.addListener(chrome.tabs.onUpdated, async (tabId, changeInfo, tab) => {
|
||||
if (changeInfo.status === "complete") {
|
||||
const activeUrl = await PhishingDetectionService.getActiveUrl();
|
||||
|
||||
Reference in New Issue
Block a user