1
0
mirror of https://github.com/bitwarden/desktop synced 2026-02-22 04:13:35 +00:00

[feature] Enable locking any account from the menu

This commit is contained in:
addison
2021-11-02 20:49:49 -04:00
parent b40d262ef9
commit b9da4457a7
3 changed files with 83 additions and 57 deletions

View File

@@ -148,13 +148,12 @@ export class AppComponent implements OnInit {
this.logOut(!!message.expired);
break;
case 'lockVault':
await this.vaultTimeoutService.lock(true);
await this.vaultTimeoutService.lock(true, message.userId);
break;
case 'locked':
if (this.modal != null) {
this.modal.close();
}
await this.stateService.purge();
this.router.navigate(['lock']);
this.notificationsService.updateConnection();
this.updateAppMenu();
@@ -331,24 +330,25 @@ export class AppComponent implements OnInit {
const stateAccounts = this.stateService.accounts?.getValue();
if (stateAccounts == null || Object.keys(stateAccounts).length < 1) {
this.messagingService.send('updateAppMenu', { accounts: null, activeUserId: null });
return;
}
const accounts: { [userId: string]: any } = {};
for (const i in stateAccounts) {
if (i != null) {
const userId = stateAccounts[i].userId;
accounts[userId] = {
isAuthenticated: await this.stateService.getIsAuthenticated({
userId: userId, storageLocation: StorageLocation.Memory,
}),
isLocked: await this.vaultTimeoutService.isLocked(userId),
};
} else {
const accounts: { [userId: string]: any } = {};
for (const i in stateAccounts) {
if (i != null) {
const userId = stateAccounts[i].userId;
accounts[userId] = {
isAuthenticated: await this.stateService.getIsAuthenticated({
userId: userId, storageLocation: StorageLocation.Memory,
}),
isLocked: await this.vaultTimeoutService.isLocked(userId),
email: stateAccounts[i].email,
userId: stateAccounts[i].userId,
};
}
}
this.messagingService.send('updateAppMenu', { accounts: accounts, activeUserId: await this.stateService.getUserId() });
}
this.messagingService.send('updateAppMenu', { accounts: accounts, activeUserId: await this.stateService.getUserId() });
} catch (e) {
this.logService.debug(e);
this.logService.error(e);
}
}

View File

@@ -707,8 +707,8 @@
"loading": {
"message": "Loading..."
},
"lockNow": {
"message": "Lock Now"
"lockVault": {
"message": "Lock Vault"
},
"passwordGenerator": {
"message": "Password Generator"

View File

@@ -68,35 +68,60 @@ export class MenuMain extends BaseMenu {
this.unlockedRequiredMenuItems = [
this.addNewLogin, this.addNewItem, this.addNewFolder,
this.syncVault, this.exportVault, this.settings, this.lockNow, this.twoStepLogin, this.fingerprintPhrase,
this.syncVault, this.exportVault, this.settings, this.twoStepLogin, this.fingerprintPhrase,
this.changeMasterPass, this.premiumMembership, this.passwordGenerator, this.passwordHistory,
this.searchVault, this.copyUsername, this.copyPassword];
this.updateApplicationMenuState();
}
updateApplicationMenuState(accounts?: { [userId: string]: { isAuthenticated: boolean, isLocked: boolean }}, activeUserId?: string) {
const isAuthenticated = accounts != null ?
accounts[activeUserId]?.isAuthenticated ?? false :
false;
const isLocked = accounts != null ?
accounts[activeUserId]?.isLocked ?? true :
true;
this.unlockedRequiredMenuItems.forEach((mi: MenuItem) => {
if (mi != null) {
mi.enabled = isAuthenticated && !isLocked;
}
});
updateApplicationMenuState(accounts?: { [userId: string]: { isAuthenticated: boolean, isLocked: boolean, userId: string, email: string }}, activeUserId?: string) {
this.updateAuthBasedMenuState(accounts, activeUserId);
if (this.menu != null) {
Menu.setApplicationMenu(this.menu);
}
}
if (this.logOut != null) {
this.logOut.enabled = isAuthenticated;
private updateAuthBasedMenuState(accounts?: {[userId: string]: { isAuthenticated: boolean, isLocked: boolean, userId: string, email: string}}, activeUserId?: string) {
accounts == null ?
this.lockAuthBasedMenuItems() :
this.tryUnlockAuthBasedMenuItems(accounts, activeUserId);
}
private lockAuthBasedMenuItems() {
this.logOut.enabled = false;
this.lockNow.enabled = false;
this.unlockedRequiredMenuItems.forEach((mi: MenuItem) => {
if (mi != null) {
mi.enabled = false;
}
});
}
private tryUnlockAuthBasedMenuItems(accounts: {[userId: string]: { isAuthenticated: boolean, isLocked: boolean, userId: string, email: string},}, activeUserId: string) {
this.tryUnlockActiveAccountAuthBasedMenuItems(accounts[activeUserId]);
this.lockNow.enabled = true;
for (const i in accounts) {
if (this.lockNow.submenu.getMenuItemById(`lockNow_${accounts[i].userId}`) == null) {
const options: MenuItemConstructorOptions = {
label: accounts[i].email,
id: `lockNow_${accounts[i].userId}`,
click: () => this.main.messagingService.send('lockVault', { userId: accounts[i].userId }),
};
this.lockNow.submenu.insert(0, new MenuItem(options));
}
}
}
private tryUnlockActiveAccountAuthBasedMenuItems(activeAccount: { isAuthenticated: boolean, isLocked: boolean, userId: string, email: string}) {
this.logOut.enabled = activeAccount.isAuthenticated;
this.unlockedRequiredMenuItems.forEach((mi: MenuItem) => {
if (mi != null) {
mi.enabled = activeAccount.isAuthenticated && !activeAccount.isLocked;
}
});
}
private initApplicationMenu() {
const accountSubmenu: MenuItemConstructorOptions[] = [
{
@@ -140,25 +165,6 @@ export class MenuMain extends BaseMenu {
id: 'fingerprintPhrase',
click: () => this.main.messagingService.send('showFingerprintPhrase'),
},
{ type: 'separator' },
{
label: this.i18nService.t('logOut'),
id: 'logOut',
click: async () => {
const result = await dialog.showMessageBox(this.windowMain.win, {
title: this.i18nService.t('logOut'),
message: this.i18nService.t('logOut'),
detail: this.i18nService.t('logOutConfirmation'),
buttons: [this.i18nService.t('logOut'), this.i18nService.t('cancel')],
cancelId: 1,
defaultId: 0,
noLink: true,
});
if (result.response === 0) {
this.main.messagingService.send('logout');
}
},
},
];
this.editMenuItemOptions.submenu = (this.editMenuItemOptions.submenu as MenuItemConstructorOptions[]).concat([
@@ -413,10 +419,30 @@ export class MenuMain extends BaseMenu {
accelerator: 'CmdOrCtrl+,',
},
{
label: this.main.i18nService.t('lockNow'),
label: this.main.i18nService.t('lockVault'),
id: 'lockNow',
click: () => this.main.messagingService.send('lockVault'),
accelerator: 'CmdOrCtrl+L',
submenu: [
// List of vaults
],
},
{
label: this.i18nService.t('logOut'),
id: 'logOut',
click: async () => {
const result = await dialog.showMessageBox(this.windowMain.win, {
title: this.i18nService.t('logOut'),
message: this.i18nService.t('logOut'),
detail: this.i18nService.t('logOutConfirmation'),
buttons: [this.i18nService.t('logOut'), this.i18nService.t('cancel')],
cancelId: 1,
defaultId: 0,
noLink: true,
});
if (result.response === 0) {
this.main.messagingService.send('logout');
}
},
},
];