2018-01-09 20:26:20 +01:00
|
|
|
import { CipherType } from 'jslib/enums';
|
|
|
|
|
|
|
|
import {
|
2018-01-09 22:20:15 +01:00
|
|
|
ApiService,
|
|
|
|
AppIdService,
|
2018-01-10 04:22:49 +01:00
|
|
|
ConstantsService,
|
2018-01-10 04:28:21 +01:00
|
|
|
ContainerService,
|
2018-01-09 20:26:20 +01:00
|
|
|
CryptoService,
|
2018-01-10 02:20:45 +01:00
|
|
|
EnvironmentService,
|
2018-01-10 04:39:38 +01:00
|
|
|
FolderService,
|
2018-01-09 23:55:28 +01:00
|
|
|
PasswordGenerationService,
|
2018-01-10 04:47:53 +01:00
|
|
|
SettingsService,
|
2018-01-09 22:20:15 +01:00
|
|
|
TokenService,
|
2018-01-09 23:45:17 +01:00
|
|
|
TotpService,
|
2018-01-09 23:37:40 +01:00
|
|
|
UserService,
|
2018-01-09 20:26:20 +01:00
|
|
|
UtilsService,
|
|
|
|
} from 'jslib/services';
|
|
|
|
|
|
|
|
import {
|
2018-01-09 22:20:15 +01:00
|
|
|
ApiService as ApiServiceAbstraction,
|
|
|
|
AppIdService as AppIdServiceAbstraction,
|
2018-01-09 20:26:20 +01:00
|
|
|
CryptoService as CryptoServiceAbstraction,
|
2018-01-10 02:20:45 +01:00
|
|
|
EnvironmentService as EnvironmentServiceAbstraction,
|
2018-01-10 04:39:38 +01:00
|
|
|
FolderService as FolderServiceAbstraction,
|
2018-01-09 20:26:20 +01:00
|
|
|
MessagingService as MessagingServiceAbstraction,
|
2018-01-09 23:55:28 +01:00
|
|
|
PasswordGenerationService as PasswordGenerationServiceAbstraction,
|
2018-01-09 20:26:20 +01:00
|
|
|
PlatformUtilsService as PlatformUtilsServiceAbstraction,
|
2018-01-10 04:47:53 +01:00
|
|
|
SettingsService as SettingsServiceAbstraction,
|
2018-01-09 20:26:20 +01:00
|
|
|
StorageService as StorageServiceAbstraction,
|
2018-01-09 22:20:15 +01:00
|
|
|
TokenService as TokenServiceAbstraction,
|
2018-01-09 23:45:17 +01:00
|
|
|
TotpService as TotpServiceAbstraction,
|
2018-01-09 23:37:40 +01:00
|
|
|
UserService as UserServiceAbstraction,
|
2018-01-09 20:26:20 +01:00
|
|
|
UtilsService as UtilsServiceAbstraction,
|
|
|
|
} from 'jslib/abstractions';
|
2017-12-05 23:04:30 +01:00
|
|
|
|
2017-12-07 21:36:24 +01:00
|
|
|
import BrowserApi from '../browser/browserApi';
|
|
|
|
|
2017-12-07 21:06:37 +01:00
|
|
|
import CommandsBackground from './commands.background';
|
2017-12-07 22:02:15 +01:00
|
|
|
import ContextMenusBackground from './contextMenus.background';
|
2018-01-04 23:04:26 +01:00
|
|
|
import IdleBackground from './idle.background';
|
2017-12-07 21:06:37 +01:00
|
|
|
import RuntimeBackground from './runtime.background';
|
|
|
|
import TabsBackground from './tabs.background';
|
2017-12-07 03:54:38 +01:00
|
|
|
import WebRequestBackground from './webRequest.background';
|
2017-12-07 21:06:37 +01:00
|
|
|
import WindowsBackground from './windows.background';
|
2017-12-07 03:54:38 +01:00
|
|
|
|
2017-12-05 23:04:30 +01:00
|
|
|
import AutofillService from '../services/autofill.service';
|
2018-01-04 22:06:00 +01:00
|
|
|
import BrowserMessagingService from '../services/browserMessaging.service';
|
2018-01-05 22:38:50 +01:00
|
|
|
import BrowserPlatformUtilsService from '../services/browserPlatformUtils.service';
|
2018-01-04 22:15:06 +01:00
|
|
|
import BrowserStorageService from '../services/browserStorage.service';
|
2017-12-05 23:04:30 +01:00
|
|
|
import CipherService from '../services/cipher.service';
|
|
|
|
import CollectionService from '../services/collection.service';
|
2017-12-06 19:51:49 +01:00
|
|
|
import i18nService from '../services/i18n.service';
|
2017-12-05 23:04:30 +01:00
|
|
|
import LockService from '../services/lock.service';
|
|
|
|
import SyncService from '../services/sync.service';
|
2018-01-04 16:51:08 +01:00
|
|
|
|
2017-12-05 23:04:30 +01:00
|
|
|
export default class MainBackground {
|
2018-01-09 20:26:20 +01:00
|
|
|
messagingService: MessagingServiceAbstraction;
|
|
|
|
storageService: StorageServiceAbstraction;
|
2017-12-06 19:51:49 +01:00
|
|
|
i18nService: any;
|
2018-01-09 20:26:20 +01:00
|
|
|
platformUtilsService: PlatformUtilsServiceAbstraction;
|
|
|
|
utilsService: UtilsServiceAbstraction;
|
2017-12-05 23:04:30 +01:00
|
|
|
constantsService: ConstantsService;
|
2018-01-09 20:26:20 +01:00
|
|
|
cryptoService: CryptoServiceAbstraction;
|
2018-01-09 22:20:15 +01:00
|
|
|
tokenService: TokenServiceAbstraction;
|
|
|
|
appIdService: AppIdServiceAbstraction;
|
|
|
|
apiService: ApiServiceAbstraction;
|
2018-01-10 02:20:45 +01:00
|
|
|
environmentService: EnvironmentServiceAbstraction;
|
2018-01-09 23:37:40 +01:00
|
|
|
userService: UserServiceAbstraction;
|
2018-01-10 04:47:53 +01:00
|
|
|
settingsService: SettingsServiceAbstraction;
|
2017-12-05 23:04:30 +01:00
|
|
|
cipherService: CipherService;
|
2018-01-10 04:39:38 +01:00
|
|
|
folderService: FolderServiceAbstraction;
|
2017-12-05 23:04:30 +01:00
|
|
|
collectionService: CollectionService;
|
|
|
|
lockService: LockService;
|
|
|
|
syncService: SyncService;
|
2018-01-09 23:55:28 +01:00
|
|
|
passwordGenerationService: PasswordGenerationServiceAbstraction;
|
2018-01-09 23:45:17 +01:00
|
|
|
totpService: TotpServiceAbstraction;
|
2017-12-05 23:04:30 +01:00
|
|
|
autofillService: AutofillService;
|
2018-01-07 06:15:12 +01:00
|
|
|
containerService: ContainerService;
|
2017-12-05 23:04:30 +01:00
|
|
|
|
2017-12-07 21:06:37 +01:00
|
|
|
onUpdatedRan: boolean;
|
|
|
|
onReplacedRan: boolean;
|
2017-12-07 21:36:24 +01:00
|
|
|
loginToAutoFill: any = null;
|
|
|
|
loginsToAdd: any[] = [];
|
2017-12-07 21:06:37 +01:00
|
|
|
|
|
|
|
private commandsBackground: CommandsBackground;
|
2017-12-07 22:02:15 +01:00
|
|
|
private contextMenusBackground: ContextMenusBackground;
|
2018-01-04 23:04:26 +01:00
|
|
|
private idleBackground: IdleBackground;
|
2017-12-07 21:06:37 +01:00
|
|
|
private runtimeBackground: RuntimeBackground;
|
|
|
|
private tabsBackground: TabsBackground;
|
2017-12-07 03:54:38 +01:00
|
|
|
private webRequestBackground: WebRequestBackground;
|
2017-12-07 21:06:37 +01:00
|
|
|
private windowsBackground: WindowsBackground;
|
2017-12-07 03:54:38 +01:00
|
|
|
|
2017-12-05 23:04:30 +01:00
|
|
|
private sidebarAction: any;
|
|
|
|
private buildingContextMenu: boolean;
|
|
|
|
private menuOptionsLoaded: any[] = [];
|
2017-12-06 05:28:31 +01:00
|
|
|
private syncTimeout: number;
|
2017-12-05 23:04:30 +01:00
|
|
|
|
2017-12-06 19:51:49 +01:00
|
|
|
constructor() {
|
2017-12-05 23:04:30 +01:00
|
|
|
// Services
|
2018-01-09 20:26:20 +01:00
|
|
|
this.utilsService = new UtilsService();
|
2018-01-05 22:38:50 +01:00
|
|
|
this.platformUtilsService = new BrowserPlatformUtilsService();
|
2018-01-05 22:30:15 +01:00
|
|
|
this.messagingService = new BrowserMessagingService(this.platformUtilsService);
|
|
|
|
this.storageService = new BrowserStorageService(this.platformUtilsService);
|
|
|
|
this.i18nService = i18nService(this.platformUtilsService);
|
|
|
|
this.constantsService = new ConstantsService(this.i18nService, this.platformUtilsService);
|
2018-01-09 20:26:20 +01:00
|
|
|
this.cryptoService = new CryptoService(this.storageService,
|
2018-01-04 20:16:40 +01:00
|
|
|
this.storageService);
|
2018-01-04 16:51:08 +01:00
|
|
|
this.tokenService = new TokenService(this.storageService);
|
|
|
|
this.appIdService = new AppIdService(this.storageService);
|
2018-01-05 22:30:15 +01:00
|
|
|
this.apiService = new ApiService(this.tokenService, this.platformUtilsService,
|
2017-12-15 15:58:26 +01:00
|
|
|
(expired: boolean) => this.logout(expired));
|
2018-01-04 16:51:08 +01:00
|
|
|
this.environmentService = new EnvironmentService(this.apiService, this.storageService);
|
|
|
|
this.userService = new UserService(this.tokenService, this.storageService);
|
|
|
|
this.settingsService = new SettingsService(this.userService, this.storageService);
|
2017-12-06 05:28:31 +01:00
|
|
|
this.cipherService = new CipherService(this.cryptoService, this.userService, this.settingsService,
|
2018-01-04 16:51:08 +01:00
|
|
|
this.apiService, this.storageService);
|
2018-01-10 04:41:08 +01:00
|
|
|
this.folderService = new FolderService(this.cryptoService, this.userService, this.i18nService.noneFolder,
|
2018-01-04 16:51:08 +01:00
|
|
|
this.apiService, this.storageService);
|
|
|
|
this.collectionService = new CollectionService(this.cryptoService, this.userService, this.storageService);
|
2017-12-05 23:04:30 +01:00
|
|
|
this.lockService = new LockService(this.cipherService, this.folderService, this.collectionService,
|
2018-01-05 22:30:15 +01:00
|
|
|
this.cryptoService, this.platformUtilsService, this.storageService,
|
2018-01-04 16:51:08 +01:00
|
|
|
() => this.setIcon(), () => this.refreshBadgeAndMenu());
|
2017-12-05 23:04:30 +01:00
|
|
|
this.syncService = new SyncService(this.userService, this.apiService, this.settingsService,
|
2017-12-07 04:28:33 +01:00
|
|
|
this.folderService, this.cipherService, this.cryptoService, this.collectionService,
|
2018-01-04 22:06:00 +01:00
|
|
|
this.storageService, this.messagingService, (expired: boolean) => this.logout(expired));
|
2018-01-04 16:51:08 +01:00
|
|
|
this.passwordGenerationService = new PasswordGenerationService(this.cryptoService, this.storageService);
|
|
|
|
this.totpService = new TotpService(this.storageService);
|
2017-12-05 23:04:30 +01:00
|
|
|
this.autofillService = new AutofillService(this.cipherService, this.tokenService,
|
2018-01-05 22:30:15 +01:00
|
|
|
this.totpService, this.utilsService, this.platformUtilsService);
|
2018-01-07 06:15:12 +01:00
|
|
|
this.containerService = new ContainerService(this.cryptoService, this.platformUtilsService);
|
2017-12-05 23:04:30 +01:00
|
|
|
|
|
|
|
// Other fields
|
|
|
|
this.sidebarAction = (typeof opr !== 'undefined') && opr.sidebarAction ?
|
2017-12-05 23:18:20 +01:00
|
|
|
opr.sidebarAction : (window as any).chrome.sidebarAction;
|
2017-12-07 03:54:38 +01:00
|
|
|
|
|
|
|
// Background
|
2017-12-07 21:06:37 +01:00
|
|
|
this.commandsBackground = new CommandsBackground(this, this.passwordGenerationService);
|
2017-12-07 22:02:15 +01:00
|
|
|
this.contextMenusBackground = new ContextMenusBackground(this, this.cipherService,
|
|
|
|
this.passwordGenerationService);
|
2018-01-04 23:04:26 +01:00
|
|
|
this.idleBackground = new IdleBackground(this, this.lockService, this.storageService);
|
2018-01-05 22:30:15 +01:00
|
|
|
this.runtimeBackground = new RuntimeBackground(this, this.autofillService, this.cipherService,
|
|
|
|
this.platformUtilsService);
|
2017-12-07 21:06:37 +01:00
|
|
|
this.tabsBackground = new TabsBackground(this);
|
2018-01-05 22:30:15 +01:00
|
|
|
this.webRequestBackground = new WebRequestBackground(this.platformUtilsService, this.cipherService);
|
2017-12-07 21:06:37 +01:00
|
|
|
this.windowsBackground = new WindowsBackground(this);
|
2017-12-05 23:04:30 +01:00
|
|
|
}
|
|
|
|
|
2017-12-06 05:37:32 +01:00
|
|
|
async bootstrap() {
|
2018-01-07 06:15:12 +01:00
|
|
|
this.containerService.attachToWindow(window);
|
|
|
|
|
2017-12-07 21:06:37 +01:00
|
|
|
await this.commandsBackground.init();
|
2017-12-07 22:02:15 +01:00
|
|
|
await this.contextMenusBackground.init();
|
2018-01-04 23:04:26 +01:00
|
|
|
await this.idleBackground.init();
|
2017-12-07 21:06:37 +01:00
|
|
|
await this.runtimeBackground.init();
|
|
|
|
await this.tabsBackground.init();
|
2017-12-07 03:54:38 +01:00
|
|
|
await this.webRequestBackground.init();
|
2017-12-07 21:06:37 +01:00
|
|
|
await this.windowsBackground.init();
|
2017-12-07 03:54:38 +01:00
|
|
|
|
2017-12-06 05:37:32 +01:00
|
|
|
await this.environmentService.setUrlsFromStorage();
|
2017-12-07 04:28:33 +01:00
|
|
|
await this.setIcon();
|
2017-12-06 05:37:32 +01:00
|
|
|
this.cleanupLoginsToAdd();
|
2017-12-07 04:28:33 +01:00
|
|
|
await this.fullSync(true);
|
2017-12-06 05:28:31 +01:00
|
|
|
}
|
|
|
|
|
2017-12-07 22:02:15 +01:00
|
|
|
async setIcon() {
|
|
|
|
if (!chrome.browserAction && !this.sidebarAction) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const isAuthenticated = await this.userService.isAuthenticated();
|
|
|
|
const key = await this.cryptoService.getKey();
|
|
|
|
|
|
|
|
let suffix = '';
|
|
|
|
if (!isAuthenticated) {
|
|
|
|
suffix = '_gray';
|
|
|
|
} else if (!key) {
|
|
|
|
suffix = '_locked';
|
|
|
|
}
|
|
|
|
|
|
|
|
await this.actionSetIcon(chrome.browserAction, suffix);
|
|
|
|
await this.actionSetIcon(this.sidebarAction, suffix);
|
|
|
|
}
|
|
|
|
|
|
|
|
async refreshBadgeAndMenu() {
|
|
|
|
if (!chrome.windows || !chrome.contextMenus) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const tab = await BrowserApi.getTabFromCurrentWindowId();
|
|
|
|
if (!tab) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-01-04 16:51:08 +01:00
|
|
|
const disabled = await this.storageService.get<boolean>(ConstantsService.disableContextMenuItemKey);
|
2017-12-07 22:02:15 +01:00
|
|
|
if (!disabled) {
|
|
|
|
await this.buildContextMenu();
|
|
|
|
await this.contextMenuReady(tab, true);
|
|
|
|
} else {
|
|
|
|
await this.contextMenusRemoveAll();
|
|
|
|
await this.contextMenuReady(tab, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async logout(expired: boolean) {
|
|
|
|
const userId = await this.userService.getUserId();
|
|
|
|
|
|
|
|
await Promise.all([
|
|
|
|
this.syncService.setLastSync(new Date(0)),
|
|
|
|
this.tokenService.clearToken(),
|
|
|
|
this.cryptoService.clearKeys(),
|
|
|
|
this.userService.clear(),
|
|
|
|
this.settingsService.clear(userId),
|
|
|
|
this.cipherService.clear(userId),
|
|
|
|
this.folderService.clear(userId),
|
|
|
|
this.passwordGenerationService.clear(),
|
|
|
|
]);
|
|
|
|
|
2018-01-04 22:06:00 +01:00
|
|
|
this.messagingService.send('doneLoggingOut', { expired: expired });
|
2017-12-07 22:02:15 +01:00
|
|
|
|
|
|
|
await this.setIcon();
|
|
|
|
await this.refreshBadgeAndMenu();
|
|
|
|
}
|
|
|
|
|
|
|
|
collectPageDetailsForContentScript(tab: any, sender: string, frameId: number = null) {
|
|
|
|
if (tab == null || !tab.id) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const options: any = {};
|
|
|
|
if (frameId != null) {
|
|
|
|
options.frameId = frameId;
|
|
|
|
}
|
|
|
|
|
|
|
|
chrome.tabs.sendMessage(tab.id, {
|
|
|
|
command: 'collectPageDetails',
|
|
|
|
tab: tab,
|
|
|
|
sender: sender,
|
|
|
|
}, options, () => {
|
|
|
|
if (chrome.runtime.lastError) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
async checkLoginsToAdd(tab: any = null): Promise<any> {
|
|
|
|
if (!this.loginsToAdd.length) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tab != null) {
|
|
|
|
this.doCheck(tab);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const currentTab = await BrowserApi.getTabFromCurrentWindow();
|
|
|
|
if (currentTab != null) {
|
|
|
|
this.doCheck(currentTab);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-05 23:04:30 +01:00
|
|
|
private async buildContextMenu() {
|
|
|
|
if (!chrome.contextMenus || this.buildingContextMenu) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.buildingContextMenu = true;
|
|
|
|
await this.contextMenusRemoveAll();
|
|
|
|
|
|
|
|
await this.contextMenusCreate({
|
|
|
|
type: 'normal',
|
|
|
|
id: 'root',
|
|
|
|
contexts: ['all'],
|
2017-12-06 05:28:31 +01:00
|
|
|
title: 'bitwarden',
|
2017-12-05 23:04:30 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
await this.contextMenusCreate({
|
|
|
|
type: 'normal',
|
|
|
|
id: 'autofill',
|
|
|
|
parentId: 'root',
|
|
|
|
contexts: ['all'],
|
2017-12-06 05:28:31 +01:00
|
|
|
title: this.i18nService.autoFill,
|
2017-12-05 23:04:30 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
// Firefox & Edge do not support writing to the clipboard from background
|
2018-01-05 22:30:15 +01:00
|
|
|
if (!this.platformUtilsService.isFirefox() && !this.platformUtilsService.isEdge()) {
|
2017-12-05 23:04:30 +01:00
|
|
|
await this.contextMenusCreate({
|
|
|
|
type: 'normal',
|
|
|
|
id: 'copy-username',
|
|
|
|
parentId: 'root',
|
|
|
|
contexts: ['all'],
|
2017-12-06 05:28:31 +01:00
|
|
|
title: this.i18nService.copyUsername,
|
2017-12-05 23:04:30 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
await this.contextMenusCreate({
|
|
|
|
type: 'normal',
|
|
|
|
id: 'copy-password',
|
|
|
|
parentId: 'root',
|
|
|
|
contexts: ['all'],
|
2017-12-06 05:28:31 +01:00
|
|
|
title: this.i18nService.copyPassword,
|
2017-12-05 23:04:30 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
await this.contextMenusCreate({
|
|
|
|
type: 'separator',
|
2017-12-06 05:28:31 +01:00
|
|
|
parentId: 'root',
|
2017-12-05 23:04:30 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
await this.contextMenusCreate({
|
|
|
|
type: 'normal',
|
|
|
|
id: 'generate-password',
|
|
|
|
parentId: 'root',
|
|
|
|
contexts: ['all'],
|
2017-12-06 05:28:31 +01:00
|
|
|
title: this.i18nService.generatePasswordCopied,
|
2017-12-05 23:04:30 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
this.buildingContextMenu = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private async contextMenuReady(tab: any, contextMenuEnabled: boolean) {
|
|
|
|
await this.loadMenuAndUpdateBadge(tab.url, tab.id, contextMenuEnabled);
|
|
|
|
this.onUpdatedRan = this.onReplacedRan = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private async loadMenuAndUpdateBadge(url: string, tabId: number, contextMenuEnabled: boolean) {
|
|
|
|
if (!url || (!chrome.browserAction && !this.sidebarAction)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-01-05 22:30:15 +01:00
|
|
|
const tabDomain = this.platformUtilsService.getDomain(url);
|
2017-12-05 23:04:30 +01:00
|
|
|
if (tabDomain == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.actionSetBadgeBackgroundColor(chrome.browserAction);
|
|
|
|
this.actionSetBadgeBackgroundColor(this.sidebarAction);
|
|
|
|
|
|
|
|
this.menuOptionsLoaded = [];
|
|
|
|
try {
|
|
|
|
const ciphers = await this.cipherService.getAllDecryptedForDomain(tabDomain);
|
|
|
|
ciphers.sort(this.cipherService.sortCiphersByLastUsedThenName);
|
|
|
|
|
|
|
|
if (contextMenuEnabled) {
|
2017-12-06 05:28:31 +01:00
|
|
|
ciphers.forEach((cipher) => {
|
|
|
|
this.loadLoginContextMenuOptions(cipher);
|
2017-12-05 23:04:30 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-12-06 05:28:31 +01:00
|
|
|
let theText = '';
|
2017-12-05 23:04:30 +01:00
|
|
|
if (ciphers.length > 0 && ciphers.length < 9) {
|
|
|
|
theText = ciphers.length.toString();
|
|
|
|
} else if (ciphers.length > 0) {
|
|
|
|
theText = '9+';
|
|
|
|
} else {
|
|
|
|
if (contextMenuEnabled) {
|
2017-12-07 04:10:02 +01:00
|
|
|
await this.loadNoLoginsContextMenuOptions(this.i18nService.noMatchingLogins);
|
2017-12-05 23:04:30 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.browserActionSetBadgeText(theText, tabId);
|
|
|
|
this.sidebarActionSetBadgeText(theText, tabId);
|
|
|
|
} catch (e) {
|
|
|
|
if (contextMenuEnabled) {
|
2017-12-07 04:10:02 +01:00
|
|
|
await this.loadNoLoginsContextMenuOptions(this.i18nService.vaultLocked);
|
2017-12-05 23:04:30 +01:00
|
|
|
}
|
|
|
|
this.browserActionSetBadgeText('', tabId);
|
|
|
|
this.sidebarActionSetBadgeText('', tabId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private async loadLoginContextMenuOptions(cipher: any) {
|
2018-01-09 20:26:20 +01:00
|
|
|
if (cipher == null || cipher.type !== CipherType.Login) {
|
2017-12-05 23:04:30 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-12-07 03:54:38 +01:00
|
|
|
let title = cipher.name;
|
|
|
|
if (cipher.login.username && cipher.login.username !== '') {
|
|
|
|
title += (' (' + cipher.login.username + ')');
|
|
|
|
}
|
2017-12-05 23:04:30 +01:00
|
|
|
await this.loadContextMenuOptions(title, cipher.id, cipher);
|
|
|
|
}
|
|
|
|
|
|
|
|
private async loadNoLoginsContextMenuOptions(noLoginsMessage: string) {
|
|
|
|
await this.loadContextMenuOptions(noLoginsMessage, 'noop', null);
|
|
|
|
}
|
|
|
|
|
|
|
|
private async loadContextMenuOptions(title: string, idSuffix: string, cipher: any) {
|
|
|
|
if (!chrome.contextMenus || this.menuOptionsLoaded.indexOf(idSuffix) > -1 ||
|
2018-01-09 20:26:20 +01:00
|
|
|
(cipher != null && cipher.type !== CipherType.Login)) {
|
2017-12-05 23:04:30 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.menuOptionsLoaded.push(idSuffix);
|
|
|
|
|
2017-12-07 04:10:02 +01:00
|
|
|
if (cipher == null || (cipher.login.password && cipher.login.password !== '')) {
|
2017-12-05 23:04:30 +01:00
|
|
|
await this.contextMenusCreate({
|
|
|
|
type: 'normal',
|
|
|
|
id: 'autofill_' + idSuffix,
|
|
|
|
parentId: 'autofill',
|
|
|
|
contexts: ['all'],
|
2017-12-06 05:28:31 +01:00
|
|
|
title: title,
|
2017-12-05 23:04:30 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-01-05 22:30:15 +01:00
|
|
|
if (this.platformUtilsService.isFirefox()) {
|
2017-12-05 23:04:30 +01:00
|
|
|
// Firefox does not support writing to the clipboard from background
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-12-07 04:10:02 +01:00
|
|
|
if (cipher == null || (cipher.login.username && cipher.login.username !== '')) {
|
2017-12-05 23:04:30 +01:00
|
|
|
await this.contextMenusCreate({
|
|
|
|
type: 'normal',
|
|
|
|
id: 'copy-username_' + idSuffix,
|
|
|
|
parentId: 'copy-username',
|
|
|
|
contexts: ['all'],
|
2017-12-06 05:28:31 +01:00
|
|
|
title: title,
|
2017-12-05 23:04:30 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-12-07 04:10:02 +01:00
|
|
|
if (cipher == null || (cipher.login.password && cipher.login.password !== '')) {
|
2017-12-05 23:04:30 +01:00
|
|
|
await this.contextMenusCreate({
|
|
|
|
type: 'normal',
|
|
|
|
id: 'copy-password_' + idSuffix,
|
|
|
|
parentId: 'copy-password',
|
|
|
|
contexts: ['all'],
|
2017-12-06 05:28:31 +01:00
|
|
|
title: title,
|
2017-12-05 23:04:30 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-06 05:28:31 +01:00
|
|
|
private cleanupLoginsToAdd() {
|
|
|
|
for (let i = this.loginsToAdd.length - 1; i >= 0; i--) {
|
|
|
|
if (this.loginsToAdd[i].expires < new Date()) {
|
|
|
|
this.loginsToAdd.splice(i, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setTimeout(() => this.cleanupLoginsToAdd(), 2 * 60 * 1000); // check every 2 minutes
|
|
|
|
}
|
|
|
|
|
|
|
|
private doCheck(tab: any) {
|
|
|
|
if (tab == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-01-05 22:30:15 +01:00
|
|
|
const tabDomain = this.platformUtilsService.getDomain(tab.url);
|
2017-12-06 05:28:31 +01:00
|
|
|
if (tabDomain == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (let i = 0; i < this.loginsToAdd.length; i++) {
|
|
|
|
if (this.loginsToAdd[i].tabId !== tab.id || this.loginsToAdd[i].domain !== tabDomain) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2017-12-07 21:36:24 +01:00
|
|
|
BrowserApi.tabSendMessage(tab, 'openNotificationBar', {
|
2017-12-06 05:28:31 +01:00
|
|
|
type: 'add',
|
|
|
|
});
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private async fullSync(override: boolean = false) {
|
|
|
|
const syncInternal = 6 * 60 * 60 * 1000; // 6 hours
|
|
|
|
const lastSync = await this.syncService.getLastSync();
|
|
|
|
|
|
|
|
let lastSyncAgo = syncInternal + 1;
|
|
|
|
if (lastSync != null) {
|
|
|
|
lastSyncAgo = new Date().getTime() - lastSync.getTime();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (override || lastSyncAgo >= syncInternal) {
|
|
|
|
await this.syncService.fullSync(override);
|
|
|
|
this.scheduleNextSync();
|
|
|
|
} else {
|
|
|
|
this.scheduleNextSync();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private scheduleNextSync() {
|
|
|
|
if (this.syncTimeout) {
|
|
|
|
clearTimeout(this.syncTimeout);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.syncTimeout = setTimeout(async () => await this.fullSync(), 5 * 60 * 1000); // check every 5 minutes
|
|
|
|
}
|
|
|
|
|
|
|
|
// Browser API Helpers
|
2017-12-05 23:04:30 +01:00
|
|
|
|
|
|
|
private contextMenusRemoveAll() {
|
|
|
|
return new Promise((resolve) => {
|
2017-12-06 05:28:31 +01:00
|
|
|
chrome.contextMenus.removeAll(() => {
|
2017-12-05 23:04:30 +01:00
|
|
|
resolve();
|
|
|
|
if (chrome.runtime.lastError) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
private contextMenusCreate(options: any) {
|
|
|
|
return new Promise((resolve) => {
|
2017-12-06 05:28:31 +01:00
|
|
|
chrome.contextMenus.create(options, () => {
|
2017-12-05 23:04:30 +01:00
|
|
|
resolve();
|
|
|
|
if (chrome.runtime.lastError) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-12-07 03:54:38 +01:00
|
|
|
private async actionSetIcon(theAction: any, suffix: string): Promise<any> {
|
2017-12-05 23:04:30 +01:00
|
|
|
if (!theAction || !theAction.setIcon) {
|
2017-12-07 03:54:38 +01:00
|
|
|
return;
|
2017-12-05 23:04:30 +01:00
|
|
|
}
|
|
|
|
|
2017-12-07 03:54:38 +01:00
|
|
|
const options = {
|
|
|
|
path: {
|
|
|
|
19: 'images/icon19' + suffix + '.png',
|
|
|
|
38: 'images/icon38' + suffix + '.png',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2018-01-05 22:30:15 +01:00
|
|
|
if (this.platformUtilsService.isFirefox()) {
|
2017-12-07 03:54:38 +01:00
|
|
|
await theAction.setIcon(options);
|
|
|
|
} else {
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
theAction.setIcon(options, () => resolve());
|
2017-12-05 23:04:30 +01:00
|
|
|
});
|
2017-12-07 03:54:38 +01:00
|
|
|
}
|
2017-12-05 23:04:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private actionSetBadgeBackgroundColor(action: any) {
|
|
|
|
if (action && action.setBadgeBackgroundColor) {
|
|
|
|
action.setBadgeBackgroundColor({ color: '#294e5f' });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private browserActionSetBadgeText(text: string, tabId: number) {
|
|
|
|
if (chrome.browserAction && chrome.browserAction.setBadgeText) {
|
|
|
|
chrome.browserAction.setBadgeText({
|
|
|
|
text: text,
|
2017-12-06 05:28:31 +01:00
|
|
|
tabId: tabId,
|
2017-12-05 23:04:30 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private sidebarActionSetBadgeText(text: string, tabId: number) {
|
|
|
|
if (!this.sidebarAction) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.sidebarAction.setBadgeText) {
|
|
|
|
this.sidebarAction.setBadgeText({
|
|
|
|
text: text,
|
2017-12-06 05:28:31 +01:00
|
|
|
tabId: tabId,
|
2017-12-05 23:04:30 +01:00
|
|
|
});
|
|
|
|
} else if (this.sidebarAction.setTitle) {
|
|
|
|
let title = 'bitwarden';
|
|
|
|
if (text && text !== '') {
|
|
|
|
title += (' [' + text + ']');
|
|
|
|
}
|
|
|
|
|
|
|
|
this.sidebarAction.setTitle({
|
|
|
|
title: title,
|
2017-12-06 05:28:31 +01:00
|
|
|
tabId: tabId,
|
2017-12-05 23:04:30 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|