move to base menu and keytar storage from jslib
This commit is contained in:
parent
b87f648eeb
commit
8239c0cc53
2
jslib
2
jslib
|
@ -1 +1 @@
|
||||||
Subproject commit 05e6d2c0f0aa6cae6a5e53fac6dccf2a1d75a555
|
Subproject commit 42bf9b2edbafcda5d180df6d2746f19881a63315
|
|
@ -11,6 +11,7 @@ import { UpdaterMain } from './main/updater.main';
|
||||||
|
|
||||||
import { ConstantsService } from 'jslib/services/constants.service';
|
import { ConstantsService } from 'jslib/services/constants.service';
|
||||||
|
|
||||||
|
import { KeytarStorageListener } from 'jslib/electron/keytarStorageListener';
|
||||||
import { ElectronLogService } from 'jslib/electron/services/electronLog.service';
|
import { ElectronLogService } from 'jslib/electron/services/electronLog.service';
|
||||||
import { ElectronStorageService } from 'jslib/electron/services/electronStorage.service';
|
import { ElectronStorageService } from 'jslib/electron/services/electronStorage.service';
|
||||||
import { WindowMain } from 'jslib/electron/window.main';
|
import { WindowMain } from 'jslib/electron/window.main';
|
||||||
|
@ -20,6 +21,7 @@ export class Main {
|
||||||
i18nService: I18nService;
|
i18nService: I18nService;
|
||||||
storageService: ElectronStorageService;
|
storageService: ElectronStorageService;
|
||||||
messagingService: DesktopMainMessagingService;
|
messagingService: DesktopMainMessagingService;
|
||||||
|
keytarStorageListener: KeytarStorageListener;
|
||||||
|
|
||||||
windowMain: WindowMain;
|
windowMain: WindowMain;
|
||||||
messagingMain: MessagingMain;
|
messagingMain: MessagingMain;
|
||||||
|
@ -61,9 +63,12 @@ export class Main {
|
||||||
this.updaterMain = new UpdaterMain(this);
|
this.updaterMain = new UpdaterMain(this);
|
||||||
this.menuMain = new MenuMain(this);
|
this.menuMain = new MenuMain(this);
|
||||||
this.powerMonitorMain = new PowerMonitorMain(this);
|
this.powerMonitorMain = new PowerMonitorMain(this);
|
||||||
|
|
||||||
|
this.keytarStorageListener = new KeytarStorageListener('Bitwarden');
|
||||||
}
|
}
|
||||||
|
|
||||||
bootstrap() {
|
bootstrap() {
|
||||||
|
this.keytarStorageListener.init();
|
||||||
this.windowMain.init().then(async () => {
|
this.windowMain.init().then(async () => {
|
||||||
const locale = await this.storageService.get<string>(ConstantsService.localeKey);
|
const locale = await this.storageService.get<string>(ConstantsService.localeKey);
|
||||||
await this.i18nService.init(locale != null ? locale : app.getLocale());
|
await this.i18nService.init(locale != null ? locale : app.getLocale());
|
||||||
|
|
|
@ -12,11 +12,13 @@ import {
|
||||||
|
|
||||||
import { Main } from '../main';
|
import { Main } from '../main';
|
||||||
|
|
||||||
|
import { BaseMenu } from 'jslib/electron/baseMenu';
|
||||||
|
|
||||||
import { isMacAppStore, isSnapStore, isWindowsStore } from 'jslib/electron/utils';
|
import { isMacAppStore, isSnapStore, isWindowsStore } from 'jslib/electron/utils';
|
||||||
|
|
||||||
import { ConstantsService } from 'jslib/services/constants.service';
|
import { ConstantsService } from 'jslib/services/constants.service';
|
||||||
|
|
||||||
export class MenuMain {
|
export class MenuMain extends BaseMenu {
|
||||||
menu: Menu;
|
menu: Menu;
|
||||||
updateMenuItem: MenuItem;
|
updateMenuItem: MenuItem;
|
||||||
addNewLogin: MenuItem;
|
addNewLogin: MenuItem;
|
||||||
|
@ -35,9 +37,12 @@ export class MenuMain {
|
||||||
searchVault: MenuItem;
|
searchVault: MenuItem;
|
||||||
unlockedRequiredMenuItems: MenuItem[] = [];
|
unlockedRequiredMenuItems: MenuItem[] = [];
|
||||||
|
|
||||||
constructor(private main: Main) { }
|
constructor(private main: Main) {
|
||||||
|
super(main.i18nService, main.windowMain, 'Bitwarden', () => this.main.messagingService.send('logout'));
|
||||||
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
|
this.initProperties();
|
||||||
this.initContextMenu();
|
this.initContextMenu();
|
||||||
this.initApplicationMenu();
|
this.initApplicationMenu();
|
||||||
|
|
||||||
|
@ -73,86 +78,6 @@ export class MenuMain {
|
||||||
this.logOut.enabled = isAuthenticated;
|
this.logOut.enabled = isAuthenticated;
|
||||||
}
|
}
|
||||||
|
|
||||||
private initContextMenu() {
|
|
||||||
if (this.main.windowMain.win == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const selectionMenu = Menu.buildFromTemplate([
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('copy'),
|
|
||||||
role: 'copy',
|
|
||||||
},
|
|
||||||
{ type: 'separator' },
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('selectAll'),
|
|
||||||
role: 'selectall',
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
const inputMenu = Menu.buildFromTemplate([
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('undo'),
|
|
||||||
role: 'undo',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('redo'),
|
|
||||||
role: 'redo',
|
|
||||||
},
|
|
||||||
{ type: 'separator' },
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('cut'),
|
|
||||||
role: 'cut',
|
|
||||||
enabled: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('copy'),
|
|
||||||
role: 'copy',
|
|
||||||
enabled: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('paste'),
|
|
||||||
role: 'paste',
|
|
||||||
},
|
|
||||||
{ type: 'separator' },
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('selectAll'),
|
|
||||||
role: 'selectall',
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
const inputSelectionMenu = Menu.buildFromTemplate([
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('cut'),
|
|
||||||
role: 'cut',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('copy'),
|
|
||||||
role: 'copy',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('paste'),
|
|
||||||
role: 'paste',
|
|
||||||
},
|
|
||||||
{ type: 'separator' },
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('selectAll'),
|
|
||||||
role: 'selectall',
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
this.main.windowMain.win.webContents.on('context-menu', (e, props) => {
|
|
||||||
const selected = props.selectionText && props.selectionText.trim() !== '';
|
|
||||||
if (props.isEditable && selected) {
|
|
||||||
inputSelectionMenu.popup(this.main.windowMain.win);
|
|
||||||
} else if (props.isEditable) {
|
|
||||||
inputMenu.popup(this.main.windowMain.win);
|
|
||||||
} else if (selected) {
|
|
||||||
selectionMenu.popup(this.main.windowMain.win);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private initApplicationMenu() {
|
private initApplicationMenu() {
|
||||||
const accountSubmenu: MenuItemConstructorOptions[] = [
|
const accountSubmenu: MenuItemConstructorOptions[] = [
|
||||||
{
|
{
|
||||||
|
@ -210,24 +135,7 @@ export class MenuMain {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ type: 'separator' },
|
{ type: 'separator' },
|
||||||
{
|
this.logOutMenuItemOptions,
|
||||||
label: this.main.i18nService.t('logOut'),
|
|
||||||
id: 'logOut',
|
|
||||||
click: () => {
|
|
||||||
const result = dialog.showMessageBox(this.main.windowMain.win, {
|
|
||||||
title: this.main.i18nService.t('logOut'),
|
|
||||||
message: this.main.i18nService.t('logOut'),
|
|
||||||
detail: this.main.i18nService.t('logOutConfirmation'),
|
|
||||||
buttons: [this.main.i18nService.t('logOut'), this.main.i18nService.t('cancel')],
|
|
||||||
cancelId: 1,
|
|
||||||
defaultId: 0,
|
|
||||||
noLink: true,
|
|
||||||
});
|
|
||||||
if (result === 0) {
|
|
||||||
this.main.messagingService.send('logout');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
if (!isMacAppStore() && !isWindowsStore()) {
|
if (!isMacAppStore() && !isWindowsStore()) {
|
||||||
|
@ -287,40 +195,10 @@ export class MenuMain {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
this.editMenuItemOptions,
|
||||||
label: this.main.i18nService.t('edit'),
|
|
||||||
submenu: [
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('undo'),
|
|
||||||
role: 'undo',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('redo'),
|
|
||||||
role: 'redo',
|
|
||||||
},
|
|
||||||
{ type: 'separator' },
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('cut'),
|
|
||||||
role: 'cut',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('copy'),
|
|
||||||
role: 'copy',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('paste'),
|
|
||||||
role: 'paste',
|
|
||||||
},
|
|
||||||
{ type: 'separator' },
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('selectAll'),
|
|
||||||
role: 'selectall',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: this.main.i18nService.t('view'),
|
label: this.main.i18nService.t('view'),
|
||||||
submenu: [
|
submenu: ([
|
||||||
{
|
{
|
||||||
label: this.main.i18nService.t('searchVault'),
|
label: this.main.i18nService.t('searchVault'),
|
||||||
id: 'searchVault',
|
id: 'searchVault',
|
||||||
|
@ -340,53 +218,13 @@ export class MenuMain {
|
||||||
click: () => this.main.messagingService.send('openPasswordHistory'),
|
click: () => this.main.messagingService.send('openPasswordHistory'),
|
||||||
},
|
},
|
||||||
{ type: 'separator' },
|
{ type: 'separator' },
|
||||||
{
|
] as MenuItemConstructorOptions[]).concat(this.viewSubMenuItemOptions),
|
||||||
label: this.main.i18nService.t('zoomIn'),
|
|
||||||
role: 'zoomin', accelerator: 'CmdOrCtrl+=',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('zoomOut'),
|
|
||||||
role: 'zoomout', accelerator: 'CmdOrCtrl+-',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('resetZoom'),
|
|
||||||
role: 'resetzoom', accelerator: 'CmdOrCtrl+0',
|
|
||||||
},
|
|
||||||
{ type: 'separator' },
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('toggleFullScreen'),
|
|
||||||
role: 'togglefullscreen',
|
|
||||||
},
|
|
||||||
{ type: 'separator' },
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('reload'),
|
|
||||||
role: 'forcereload',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('toggleDevTools'),
|
|
||||||
role: 'toggledevtools',
|
|
||||||
accelerator: 'F12',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: this.main.i18nService.t('account'),
|
label: this.main.i18nService.t('account'),
|
||||||
submenu: accountSubmenu,
|
submenu: accountSubmenu,
|
||||||
},
|
},
|
||||||
{
|
this.windowMenuItemOptions,
|
||||||
label: this.main.i18nService.t('window'),
|
|
||||||
role: 'window',
|
|
||||||
submenu: [
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('minimize'),
|
|
||||||
role: 'minimize',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('close'),
|
|
||||||
role: 'close',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: this.main.i18nService.t('help'),
|
label: this.main.i18nService.t('help'),
|
||||||
role: 'help',
|
role: 'help',
|
||||||
|
@ -531,54 +369,14 @@ export class MenuMain {
|
||||||
}
|
}
|
||||||
|
|
||||||
template.unshift({
|
template.unshift({
|
||||||
label: 'Bitwarden',
|
label: this.appName,
|
||||||
submenu: firstMenuPart.concat(firstMenuOptions, [
|
submenu: firstMenuPart.concat(firstMenuOptions, [
|
||||||
{ type: 'separator' },
|
{ type: 'separator' },
|
||||||
{
|
], this.macAppMenuItemOptions),
|
||||||
label: this.main.i18nService.t('services'),
|
|
||||||
role: 'services', submenu: [],
|
|
||||||
},
|
|
||||||
{ type: 'separator' },
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('hideBitwarden'),
|
|
||||||
role: 'hide',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('hideOthers'),
|
|
||||||
role: 'hideothers',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('showAll'),
|
|
||||||
role: 'unhide',
|
|
||||||
},
|
|
||||||
{ type: 'separator' },
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('quitBitwarden'),
|
|
||||||
role: 'quit',
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Window menu
|
// Window menu
|
||||||
template[template.length - 2].submenu = [
|
template[template.length - 2].submenu = this.macWindowSubmenuOptions;
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('close'),
|
|
||||||
role: isMacAppStore() ? 'quit' : 'close',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('minimize'),
|
|
||||||
role: 'minimize',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('zoom'),
|
|
||||||
role: 'zoom',
|
|
||||||
},
|
|
||||||
{ type: 'separator' },
|
|
||||||
{
|
|
||||||
label: this.main.i18nService.t('bringAllToFront'),
|
|
||||||
role: 'front',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
} else {
|
} else {
|
||||||
// File menu
|
// File menu
|
||||||
template[0].submenu = (template[0].submenu as MenuItemConstructorOptions[]).concat(
|
template[0].submenu = (template[0].submenu as MenuItemConstructorOptions[]).concat(
|
||||||
|
@ -593,27 +391,7 @@ export class MenuMain {
|
||||||
aboutMenuAdditions.push(updateMenuItem);
|
aboutMenuAdditions.push(updateMenuItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
aboutMenuAdditions.push({
|
aboutMenuAdditions.push(this.aboutMenuItemOptions);
|
||||||
label: this.main.i18nService.t('aboutBitwarden'),
|
|
||||||
click: () => {
|
|
||||||
const aboutInformation = this.main.i18nService.t('version', app.getVersion()) +
|
|
||||||
'\nShell ' + process.versions.electron +
|
|
||||||
'\nRenderer ' + process.versions.chrome +
|
|
||||||
'\nNode ' + process.versions.node +
|
|
||||||
'\nArchitecture ' + process.arch;
|
|
||||||
const result = dialog.showMessageBox(this.main.windowMain.win, {
|
|
||||||
title: 'Bitwarden',
|
|
||||||
message: 'Bitwarden',
|
|
||||||
detail: aboutInformation,
|
|
||||||
type: 'info',
|
|
||||||
noLink: true,
|
|
||||||
buttons: [this.main.i18nService.t('ok'), this.main.i18nService.t('copy')],
|
|
||||||
});
|
|
||||||
if (result === 1) {
|
|
||||||
clipboard.writeText(aboutInformation);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
template[template.length - 1].submenu =
|
template[template.length - 1].submenu =
|
||||||
(template[template.length - 1].submenu as MenuItemConstructorOptions[]).concat(aboutMenuAdditions);
|
(template[template.length - 1].submenu as MenuItemConstructorOptions[]).concat(aboutMenuAdditions);
|
||||||
|
|
|
@ -1,17 +1,7 @@
|
||||||
import {
|
import { ipcMain } from 'electron';
|
||||||
app,
|
|
||||||
ipcMain,
|
|
||||||
} from 'electron';
|
|
||||||
|
|
||||||
import {
|
|
||||||
deletePassword,
|
|
||||||
getPassword,
|
|
||||||
setPassword,
|
|
||||||
} from 'keytar';
|
|
||||||
|
|
||||||
import { Main } from '../main';
|
import { Main } from '../main';
|
||||||
|
|
||||||
const KeytarService = 'Bitwarden';
|
|
||||||
const SyncInterval = 5 * 60 * 1000; // 5 minutes
|
const SyncInterval = 5 * 60 * 1000; // 5 minutes
|
||||||
|
|
||||||
export class MessagingMain {
|
export class MessagingMain {
|
||||||
|
@ -22,25 +12,6 @@ export class MessagingMain {
|
||||||
init() {
|
init() {
|
||||||
this.scheduleNextSync();
|
this.scheduleNextSync();
|
||||||
ipcMain.on('messagingService', async (event: any, message: any) => this.onMessage(message));
|
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) {
|
onMessage(message: any) {
|
||||||
|
|
Loading…
Reference in New Issue