From 8f1757401e09579af934da7262d5e4c4061c6d66 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Thu, 7 Dec 2017 15:06:37 -0500 Subject: [PATCH] separating background apis to their own classes --- src/background/commands.background.ts | 59 ++++++++++++++++ src/background/main.background.ts | 97 ++++++--------------------- src/background/runtime.background.ts | 26 +++++++ src/background/tabs.background.ts | 37 ++++++++++ src/background/windows.background.ts | 23 +++++++ src/browser/browserApi.ts | 32 +++++++++ 6 files changed, 199 insertions(+), 75 deletions(-) create mode 100644 src/background/commands.background.ts create mode 100644 src/background/runtime.background.ts create mode 100644 src/background/tabs.background.ts create mode 100644 src/background/windows.background.ts create mode 100644 src/browser/browserApi.ts diff --git a/src/background/commands.background.ts b/src/background/commands.background.ts new file mode 100644 index 0000000000..2d2deded06 --- /dev/null +++ b/src/background/commands.background.ts @@ -0,0 +1,59 @@ +import BrowserApi from '../browser/browserApi'; + +import MainBackground from './main.background'; + +import PasswordGenerationService from '../services/passwordGeneration.service'; +import UtilsService from '../services/utils.service'; + +export default class CommandsBackground { + private commands: any; + + constructor(private main: MainBackground, private passwordGenerationService: PasswordGenerationService) { + this.commands = chrome.commands; + } + + async init() { + if (!this.commands) { + return; + } + + this.commands.onCommand.addListener(async (command: any) => { + switch (command) { + case 'generate_password': + await this.generatePasswordToClipboard(); + break; + case 'autofill_login': + await this.autoFillLogin(); + break; + default: + break; + } + }); + } + + private async generatePasswordToClipboard() { + const options = await this.passwordGenerationService.getOptions(); + const password = PasswordGenerationService.generatePassword(options); + UtilsService.copyToClipboard(password); + this.passwordGenerationService.addHistory(password); + + (window as any).ga('send', { + hitType: 'event', + eventAction: 'Generated Password From Command', + }); + } + + private async autoFillLogin() { + const tab = await BrowserApi.getTabFromCurrentWindowId(); + if (tab == null) { + return; + } + + this.main.collectPageDetailsForContentScript(tab, 'autofill_cmd'); + + (window as any).ga('send', { + hitType: 'event', + eventAction: 'Autofilled From Command', + }); + } +} diff --git a/src/background/main.background.ts b/src/background/main.background.ts index 077cd452ce..dc6e186ea2 100644 --- a/src/background/main.background.ts +++ b/src/background/main.background.ts @@ -2,7 +2,11 @@ import { CipherType } from '../enums/cipherType.enum'; import { Cipher } from '../models/domain/cipher'; +import CommandsBackground from './commands.background'; +import RuntimeBackground from './runtime.background'; +import TabsBackground from './tabs.background'; import WebRequestBackground from './webRequest.background'; +import WindowsBackground from './windows.background'; import ApiService from '../services/api.service'; import AppIdService from '../services/appId.service'; @@ -43,12 +47,17 @@ export default class MainBackground { totpService: TotpService; autofillService: AutofillService; + onUpdatedRan: boolean; + onReplacedRan: boolean; + + private commandsBackground: CommandsBackground; + private runtimeBackground: RuntimeBackground; + private tabsBackground: TabsBackground; private webRequestBackground: WebRequestBackground; + private windowsBackground: WindowsBackground; private sidebarAction: any; private buildingContextMenu: boolean; - private onUpdatedRan: boolean; - private onReplacedRan: boolean; private menuOptionsLoaded: any[] = []; private loginToAutoFill: any = null; private pageDetailsToAutoFill: any[] = []; @@ -88,36 +97,15 @@ export default class MainBackground { opr.sidebarAction : (window as any).chrome.sidebarAction; // Background + this.commandsBackground = new CommandsBackground(this, this.passwordGenerationService); + this.runtimeBackground = new RuntimeBackground(this); + this.tabsBackground = new TabsBackground(this); this.webRequestBackground = new WebRequestBackground(this.utilsService, this.cipherService); + this.windowsBackground = new WindowsBackground(this); } async bootstrap() { // Chrome APIs - if (chrome.commands) { - chrome.commands.onCommand.addListener((command: any) => { - if (command === 'generate_password') { - (window as any).ga('send', { - hitType: 'event', - eventAction: 'Generated Password From Command', - }); - this.passwordGenerationService.getOptions().then((options) => { - const password = PasswordGenerationService.generatePassword(options); - UtilsService.copyToClipboard(password); - this.passwordGenerationService.addHistory(password); - }); - } else if (command === 'autofill_login') { - this.tabsQueryFirst({ active: true, windowId: chrome.windows.WINDOW_ID_CURRENT }).then((tab) => { - if (tab != null) { - (window as any).ga('send', { - hitType: 'event', - eventAction: 'Autofilled From Command', - }); - this.collectPageDetailsForContentScript(tab, 'autofill_cmd'); - } - }); - } - }); - } chrome.runtime.onMessage.addListener(async (msg: any, sender: any, sendResponse: any) => { if (msg.command === 'loggedIn' || msg.command === 'unlocked' || msg.command === 'locked') { @@ -170,51 +158,6 @@ export default class MainBackground { } }); - if (chrome.runtime.onInstalled) { - chrome.runtime.onInstalled.addListener((details: any) => { - (window as any).ga('send', { - hitType: 'event', - eventAction: 'onInstalled ' + details.reason, - }); - - if (details.reason === 'install') { - chrome.tabs.create({ url: 'https://bitwarden.com/browser-start/' }); - } - }); - } - - chrome.tabs.onActivated.addListener(async (activeInfo: any) => { - await this.refreshBadgeAndMenu(); - }); - - chrome.tabs.onReplaced.addListener(async (addedTabId: any, removedTabId: any) => { - if (this.onReplacedRan) { - return; - } - this.onReplacedRan = true; - await this.checkLoginsToAdd(); - await this.refreshBadgeAndMenu(); - }); - - chrome.tabs.onUpdated.addListener(async (tabId: any, changeInfo: any, tab: any) => { - if (this.onUpdatedRan) { - return; - } - this.onUpdatedRan = true; - await this.checkLoginsToAdd(); - await this.refreshBadgeAndMenu(); - }); - - if (chrome.windows) { - chrome.windows.onFocusChanged.addListener(async (windowId: any) => { - if (windowId === null || windowId < 0) { - return; - } - - await this.refreshBadgeAndMenu(); - }); - } - if (chrome.contextMenus) { chrome.contextMenus.onClicked.addListener(async (info: any, tab: any) => { if (info.menuItemId === 'generate-password') { @@ -270,7 +213,11 @@ export default class MainBackground { } // Bootstrap + await this.commandsBackground.init(); + await this.runtimeBackground.init(); + await this.tabsBackground.init(); await this.webRequestBackground.init(); + await this.windowsBackground.init(); await this.environmentService.setUrlsFromStorage(); await this.setIcon(); @@ -355,7 +302,7 @@ export default class MainBackground { await this.actionSetIcon(this.sidebarAction, suffix); } - private async refreshBadgeAndMenu() { + async refreshBadgeAndMenu() { if (!chrome.windows || !chrome.contextMenus) { return; } @@ -534,7 +481,7 @@ export default class MainBackground { await this.refreshBadgeAndMenu(); } - private collectPageDetailsForContentScript(tab: any, sender: string, frameId: number = null) { + collectPageDetailsForContentScript(tab: any, sender: string, frameId: number = null) { if (tab == null || !tab.id) { return; } @@ -645,7 +592,7 @@ export default class MainBackground { } } - private async checkLoginsToAdd(tab: any = null): Promise { + async checkLoginsToAdd(tab: any = null): Promise { if (!this.loginsToAdd.length) { return; } diff --git a/src/background/runtime.background.ts b/src/background/runtime.background.ts new file mode 100644 index 0000000000..52bced652d --- /dev/null +++ b/src/background/runtime.background.ts @@ -0,0 +1,26 @@ +import MainBackground from './main.background'; + +export default class RuntimeBackground { + private runtime: any; + + constructor(private main: MainBackground) { + this.runtime = chrome.runtime; + } + + async init() { + if (!this.runtime || this.runtime.onInstalled) { + return; + } + + this.runtime.onInstalled.addListener((details: any) => { + (window as any).ga('send', { + hitType: 'event', + eventAction: 'onInstalled ' + details.reason, + }); + + if (details.reason === 'install') { + chrome.tabs.create({ url: 'https://bitwarden.com/browser-start/' }); + } + }); + } +} diff --git a/src/background/tabs.background.ts b/src/background/tabs.background.ts new file mode 100644 index 0000000000..198db0af1a --- /dev/null +++ b/src/background/tabs.background.ts @@ -0,0 +1,37 @@ +import MainBackground from './main.background'; + +export default class TabsBackground { + private tabs: any; + + constructor(private main: MainBackground) { + this.tabs = chrome.tabs; + } + + async init() { + if (!this.tabs) { + return; + } + + this.tabs.onActivated.addListener(async (activeInfo: any) => { + await this.main.refreshBadgeAndMenu(); + }); + + this.tabs.onReplaced.addListener(async (addedTabId: any, removedTabId: any) => { + if (this.main.onReplacedRan) { + return; + } + this.main.onReplacedRan = true; + await this.main.checkLoginsToAdd(); + await this.main.refreshBadgeAndMenu(); + }); + + this.tabs.onUpdated.addListener(async (tabId: any, changeInfo: any, tab: any) => { + if (this.main.onUpdatedRan) { + return; + } + this.main.onUpdatedRan = true; + await this.main.checkLoginsToAdd(); + await this.main.refreshBadgeAndMenu(); + }); + } +} diff --git a/src/background/windows.background.ts b/src/background/windows.background.ts new file mode 100644 index 0000000000..c0fcc0b263 --- /dev/null +++ b/src/background/windows.background.ts @@ -0,0 +1,23 @@ +import MainBackground from './main.background'; + +export default class WindowsBackground { + private windows: any; + + constructor(private main: MainBackground) { + this.windows = chrome.windows; + } + + async init() { + if (!this.windows) { + return; + } + + this.windows.onFocusChanged.addListener(async (windowId: any) => { + if (windowId === null || windowId < 0) { + return; + } + + await this.main.refreshBadgeAndMenu(); + }); + } +} diff --git a/src/browser/browserApi.ts b/src/browser/browserApi.ts new file mode 100644 index 0000000000..99aef19d7c --- /dev/null +++ b/src/browser/browserApi.ts @@ -0,0 +1,32 @@ +export default class BrowserApi { + static async getTabFromCurrentWindowId(): Promise { + return await BrowserApi.tabsQueryFirst({ + active: true, + windowId: chrome.windows.WINDOW_ID_CURRENT, + }); + } + + static async getTabFromCurrentWindow(): Promise { + return await BrowserApi.tabsQueryFirst({ + active: true, + currentWindow: true, + }); + } + + static tabsQuery(options: any): Promise { + return new Promise((resolve) => { + chrome.tabs.query(options, (tabs: any[]) => { + resolve(tabs); + }); + }); + } + + static async tabsQueryFirst(options: any): Promise { + const tabs = await BrowserApi.tabsQuery(options); + if (tabs.length > 0) { + return tabs[0]; + } + + return null; + } +}