mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-30 13:03:53 +01:00
Merge pull request #717 from bitwarden/add-totp-quick-copy-buttons
Add main menu copy and shortcut and context copy for totp
This commit is contained in:
commit
a0e80fc486
@ -53,6 +53,6 @@ export class SendComponent extends BaseSendComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get selectedSendType() {
|
get selectedSendType() {
|
||||||
return this.sends.find((s) => s.id === this.sendId).type;
|
return this.sends.find(s => s.id === this.sendId).type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,11 +40,14 @@ import { EventType } from 'jslib/enums/eventType';
|
|||||||
import { CipherView } from 'jslib/models/view/cipherView';
|
import { CipherView } from 'jslib/models/view/cipherView';
|
||||||
import { FolderView } from 'jslib/models/view/folderView';
|
import { FolderView } from 'jslib/models/view/folderView';
|
||||||
|
|
||||||
|
import { userError } from '@angular/compiler-cli/src/transformers/util';
|
||||||
import { EventService } from 'jslib/abstractions/event.service';
|
import { EventService } from 'jslib/abstractions/event.service';
|
||||||
import { I18nService } from 'jslib/abstractions/i18n.service';
|
import { I18nService } from 'jslib/abstractions/i18n.service';
|
||||||
import { MessagingService } from 'jslib/abstractions/messaging.service';
|
import { MessagingService } from 'jslib/abstractions/messaging.service';
|
||||||
import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service';
|
import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service';
|
||||||
import { SyncService } from 'jslib/abstractions/sync.service';
|
import { SyncService } from 'jslib/abstractions/sync.service';
|
||||||
|
import { TotpService } from 'jslib/abstractions/totp.service';
|
||||||
|
import { UserService } from 'jslib/abstractions/user.service';
|
||||||
|
|
||||||
const SyncInterval = 6 * 60 * 60 * 1000; // 6 hours
|
const SyncInterval = 6 * 60 * 60 * 1000; // 6 hours
|
||||||
const BroadcasterSubscriptionId = 'VaultComponent';
|
const BroadcasterSubscriptionId = 'VaultComponent';
|
||||||
@ -77,6 +80,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
addCollectionIds: string[] = null;
|
addCollectionIds: string[] = null;
|
||||||
showingModal = false;
|
showingModal = false;
|
||||||
deleted = false;
|
deleted = false;
|
||||||
|
userHasPremiumAccess = false;
|
||||||
|
|
||||||
private modal: ModalComponent = null;
|
private modal: ModalComponent = null;
|
||||||
|
|
||||||
@ -85,9 +89,11 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
private broadcasterService: BroadcasterService, private changeDetectorRef: ChangeDetectorRef,
|
private broadcasterService: BroadcasterService, private changeDetectorRef: ChangeDetectorRef,
|
||||||
private ngZone: NgZone, private syncService: SyncService, private analytics: Angulartics2,
|
private ngZone: NgZone, private syncService: SyncService, private analytics: Angulartics2,
|
||||||
private toasterService: ToasterService, private messagingService: MessagingService,
|
private toasterService: ToasterService, private messagingService: MessagingService,
|
||||||
private platformUtilsService: PlatformUtilsService, private eventService: EventService) { }
|
private platformUtilsService: PlatformUtilsService, private eventService: EventService,
|
||||||
|
private totpService: TotpService, private userService: UserService) { }
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
|
this.userHasPremiumAccess = await this.userService.canAccessPremium();
|
||||||
this.broadcasterService.subscribe(BroadcasterSubscriptionId, (message: any) => {
|
this.broadcasterService.subscribe(BroadcasterSubscriptionId, (message: any) => {
|
||||||
this.ngZone.run(async () => {
|
this.ngZone.run(async () => {
|
||||||
let detectChanges = true;
|
let detectChanges = true;
|
||||||
@ -170,6 +176,14 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
this.copyValue(pCipher.login.password, 'password');
|
this.copyValue(pCipher.login.password, 'password');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'copyTotp':
|
||||||
|
const tComponent = this.addEditComponent == null ? this.viewComponent : this.addEditComponent;
|
||||||
|
const tCipher = tComponent != null ? tComponent.cipher : null;
|
||||||
|
if (this.cipherId != null && tCipher != null && tCipher.id === this.cipherId &&
|
||||||
|
tCipher.login != null && tCipher.login.hasTotp && this.userHasPremiumAccess) {
|
||||||
|
const value = await this.totpService.getCode(tCipher.login.totp);
|
||||||
|
this.copyValue(value, 'verificationCodeTotp');
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
detectChanges = false;
|
detectChanges = false;
|
||||||
break;
|
break;
|
||||||
@ -308,6 +322,15 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
if (cipher.login.hasTotp && (cipher.organizationUseTotp || this.userHasPremiumAccess)) {
|
||||||
|
menu.append(new remote.MenuItem({
|
||||||
|
label: this.i18nService.t('copyVerificationCodeTotp'),
|
||||||
|
click: async () => {
|
||||||
|
const value = await this.totpService.getCode(cipher.login.totp);
|
||||||
|
this.copyValue(value, 'verificationCodeTotp');
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case CipherType.Card:
|
case CipherType.Card:
|
||||||
if (cipher.card.number != null || cipher.card.code != null) {
|
if (cipher.card.number != null || cipher.card.code != null) {
|
||||||
|
@ -367,6 +367,9 @@
|
|||||||
"copyUri": {
|
"copyUri": {
|
||||||
"message": "Copy URI"
|
"message": "Copy URI"
|
||||||
},
|
},
|
||||||
|
"copyVerificationCodeTotp": {
|
||||||
|
"message": "Copy Verification Code (TOTP)"
|
||||||
|
},
|
||||||
"length": {
|
"length": {
|
||||||
"message": "Length"
|
"message": "Length"
|
||||||
},
|
},
|
||||||
|
@ -38,6 +38,7 @@ export class MenuMain extends BaseMenu {
|
|||||||
searchVault: MenuItem;
|
searchVault: MenuItem;
|
||||||
copyUsername: MenuItem;
|
copyUsername: MenuItem;
|
||||||
copyPassword: MenuItem;
|
copyPassword: MenuItem;
|
||||||
|
copyTotp: MenuItem;
|
||||||
unlockedRequiredMenuItems: MenuItem[] = [];
|
unlockedRequiredMenuItems: MenuItem[] = [];
|
||||||
|
|
||||||
constructor(private main: Main) {
|
constructor(private main: Main) {
|
||||||
@ -67,6 +68,7 @@ export class MenuMain extends BaseMenu {
|
|||||||
this.searchVault = this.menu.getMenuItemById('searchVault');
|
this.searchVault = this.menu.getMenuItemById('searchVault');
|
||||||
this.copyUsername = this.menu.getMenuItemById('copyUsername');
|
this.copyUsername = this.menu.getMenuItemById('copyUsername');
|
||||||
this.copyPassword = this.menu.getMenuItemById('copyPassword');
|
this.copyPassword = this.menu.getMenuItemById('copyPassword');
|
||||||
|
this.copyTotp = this.menu.getMenuItemById('copyTotp');
|
||||||
|
|
||||||
this.unlockedRequiredMenuItems = [
|
this.unlockedRequiredMenuItems = [
|
||||||
this.addNewLogin, this.addNewItem, this.addNewFolder,
|
this.addNewLogin, this.addNewItem, this.addNewFolder,
|
||||||
@ -170,6 +172,12 @@ export class MenuMain extends BaseMenu {
|
|||||||
click: () => this.main.messagingService.send('copyPassword'),
|
click: () => this.main.messagingService.send('copyPassword'),
|
||||||
accelerator: 'CmdOrCtrl+P',
|
accelerator: 'CmdOrCtrl+P',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: this.main.i18nService.t('copyVerificationCodeTotp'),
|
||||||
|
id: 'copyTotp',
|
||||||
|
click: () => this.main.messagingService.send('copyTotp'),
|
||||||
|
accelerator: 'CmdOrCtrl+T',
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (!isWindowsStore() && !isMacAppStore()) {
|
if (!isWindowsStore() && !isMacAppStore()) {
|
||||||
|
@ -73,8 +73,8 @@ export class NativeMessagingMain {
|
|||||||
'allowed_origins': [
|
'allowed_origins': [
|
||||||
'chrome-extension://nngceckbapebfimnlniiiahkandclblb/',
|
'chrome-extension://nngceckbapebfimnlniiiahkandclblb/',
|
||||||
'chrome-extension://jbkfoedolllekgbhcbcoahefnbanhhlh/',
|
'chrome-extension://jbkfoedolllekgbhcbcoahefnbanhhlh/',
|
||||||
'chrome-extension://ccnckbpmaceehanjmeomladnmlffdjgn/'
|
'chrome-extension://ccnckbpmaceehanjmeomladnmlffdjgn/',
|
||||||
]
|
],
|
||||||
}};
|
}};
|
||||||
|
|
||||||
switch (process.platform) {
|
switch (process.platform) {
|
||||||
|
12
tslint.json
12
tslint.json
@ -58,6 +58,18 @@
|
|||||||
"semicolon": [
|
"semicolon": [
|
||||||
true,
|
true,
|
||||||
"always"
|
"always"
|
||||||
|
],
|
||||||
|
"trailing-comma": [
|
||||||
|
true,
|
||||||
|
{
|
||||||
|
"multiline": {
|
||||||
|
"objects": "always",
|
||||||
|
"arrays": "always",
|
||||||
|
"functions": "ignore",
|
||||||
|
"typeLiterals": "ignore"
|
||||||
|
},
|
||||||
|
"singleline": "never"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user