From a4cb908390867e4c886057c673c1d305cb89efa9 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Wed, 25 Apr 2018 15:49:10 -0400 Subject: [PATCH] menu and main keytar storage service --- .vscode/launch.json | 19 +++++++ jslib | 2 +- src/main.ts | 11 +++- src/main/menu.main.ts | 112 +++++++++++++++++++++++++++++++++++++ src/main/messaging.main.ts | 34 ++--------- 5 files changed, 146 insertions(+), 32 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 src/main/menu.main.ts diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..8d80d2f3 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,19 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug Main Process", + "type": "node", + "request": "launch", + "cwd": "${workspaceRoot}/build", + "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron", + "windows": { + "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd" + }, + "args": [ + "." + ] + } + ] + } + \ No newline at end of file diff --git a/jslib b/jslib index 6e6dc422..42bf9b2e 160000 --- a/jslib +++ b/jslib @@ -1 +1 @@ -Subproject commit 6e6dc422ac13047427d21d44463a5de2a3db7ebb +Subproject commit 42bf9b2edbafcda5d180df6d2746f19881a63315 diff --git a/src/main.ts b/src/main.ts index cc3fafa8..4bbae4ed 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3,9 +3,11 @@ import * as path from 'path'; // import { ElectronMainMessagingService } from 'jslib/electron/services/desktopMainMessaging.service'; +import { MenuMain } from './main/menu.main'; import { MessagingMain } from './main/messaging.main'; import { I18nService } from './services/i18n.service'; +import { KeytarStorageListener } from 'jslib/electron/keytarStorageListener'; import { ElectronLogService } from 'jslib/electron/services/electronLog.service'; import { ElectronStorageService } from 'jslib/electron/services/electronStorage.service'; import { WindowMain } from 'jslib/electron/window.main'; @@ -14,9 +16,11 @@ export class Main { logService: ElectronLogService; i18nService: I18nService; storageService: ElectronStorageService; + keytarStorageListener: KeytarStorageListener; windowMain: WindowMain; messagingMain: MessagingMain; + menuMain: MenuMain; constructor() { // Set paths for portable builds @@ -48,12 +52,17 @@ export class Main { // this.messagingService = new DesktopMainMessagingService(this); this.windowMain = new WindowMain(this.storageService); - this.messagingMain = new MessagingMain(this); + this.menuMain = new MenuMain(this); + this.messagingMain = new MessagingMain(this.windowMain); + + this.keytarStorageListener = new KeytarStorageListener('Bitwarden Directory Connector'); } bootstrap() { + this.keytarStorageListener.init(); this.windowMain.init().then(async () => { await this.i18nService.init(app.getLocale()); + this.menuMain.init(); this.messagingMain.init(); }, (e: any) => { // tslint:disable-next-line diff --git a/src/main/menu.main.ts b/src/main/menu.main.ts new file mode 100644 index 00000000..286b962c --- /dev/null +++ b/src/main/menu.main.ts @@ -0,0 +1,112 @@ +import { + app, + BrowserWindow, + clipboard, + dialog, + ipcMain, + Menu, + MenuItem, + MenuItemConstructorOptions, + shell, +} from 'electron'; + +import { Main } from '../main'; + +import { BaseMenu } from 'jslib/electron/baseMenu'; + +import { ConstantsService } from 'jslib/services/constants.service'; + +export class MenuMain extends BaseMenu { + menu: Menu; + logOut: MenuItem; + + constructor(private main: Main) { + super(main.i18nService, main.windowMain, 'Bitwarden Directory Connector', + () => { /* TODO: Log Out Message */ }); + } + + init() { + this.initProperties(); + this.initContextMenu(); + this.initApplicationMenu(); + + this.logOut = this.menu.getMenuItemById('logOut'); + this.updateApplicationMenuState(false, true); + } + + updateApplicationMenuState(isAuthenticated: boolean, isLocked: boolean) { + this.logOut.enabled = isAuthenticated; + } + + private initApplicationMenu() { + const accountSubmenu: MenuItemConstructorOptions[] = [ + this.logOutMenuItemOptions, + ]; + + const template: MenuItemConstructorOptions[] = [ + { + label: this.i18nService.t('file'), + submenu: [ this.logOutMenuItemOptions ], + }, + this.editMenuItemOptions, + { + label: this.main.i18nService.t('view'), + submenu: this.viewSubMenuItemOptions, + }, + this.windowMenuItemOptions, + ]; + + const firstMenuOptions: MenuItemConstructorOptions[] = [ + { type: 'separator' }, + { + label: this.i18nService.t('settings'), + id: 'settings', + click: () => { /* Something */ }, + }, + ]; + + const updateMenuItem = { + label: this.i18nService.t('checkForUpdates'), + click: () => { /* Something */ }, + id: 'checkForUpdates', + }; + + if (process.platform === 'darwin') { + const firstMenuPart: MenuItemConstructorOptions[] = [ + { + label: this.i18nService.t('aboutBitwarden'), + role: 'about', + }, + updateMenuItem, + ]; + + template.unshift({ + label: this.appName, + submenu: firstMenuPart.concat(firstMenuOptions, [ + { type: 'separator' }, + ], this.macAppMenuItemOptions), + }); + + // Window menu + template[template.length - 1].submenu = this.macWindowSubmenuOptions; + } else { + // File menu + template[0].submenu = (template[0].submenu as MenuItemConstructorOptions[]).concat( + firstMenuOptions); + + // About menu + const aboutMenuAdditions: MenuItemConstructorOptions[] = [ + { type: 'separator' }, + updateMenuItem, + ]; + + aboutMenuAdditions.push(this.aboutMenuItemOptions); + + template[template.length - 1].submenu = + (template[template.length - 1].submenu as MenuItemConstructorOptions[]).concat(aboutMenuAdditions); + } + + this.menu = Menu.buildFromTemplate(template); + Menu.setApplicationMenu(this.menu); + } +} diff --git a/src/main/messaging.main.ts b/src/main/messaging.main.ts index 942fede1..b07cc7a6 100644 --- a/src/main/messaging.main.ts +++ b/src/main/messaging.main.ts @@ -3,44 +3,18 @@ import { ipcMain, } from 'electron'; -import { - deletePassword, - getPassword, - setPassword, -} from 'keytar'; +import { WindowMain } from 'jslib/electron/window.main'; -import { Main } from '../main'; - -const KeytarService = 'Bitwarden'; const SyncInterval = 5 * 60 * 1000; // 5 minutes export class MessagingMain { private syncTimeout: NodeJS.Timer; - constructor(private main: Main) { } + constructor(private windowMain: WindowMain) { } init() { this.scheduleNextSync(); ipcMain.on('messagingService', async (event: any, message: any) => this.onMessage(message)); - - ipcMain.on('keytar', async (event: any, message: any) => { - try { - let val: string = null; - if (message.action && message.key) { - if (message.action === 'getPassword') { - val = await getPassword(KeytarService, message.key); - } else if (message.action === 'setPassword' && message.value) { - await setPassword(KeytarService, message.key, message.value); - } else if (message.action === 'deletePassword') { - await deletePassword(KeytarService, message.key); - } - } - - event.returnValue = val; - } catch { - event.returnValue = null; - } - }); } onMessage(message: any) { @@ -62,11 +36,11 @@ export class MessagingMain { } this.syncTimeout = global.setTimeout(() => { - if (this.main.windowMain.win == null) { + if (this.windowMain.win == null) { return; } - this.main.windowMain.win.webContents.send('messagingService', { + this.windowMain.win.webContents.send('messagingService', { command: 'checkSyncVault', }); }, SyncInterval);