1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-11-24 12:06:15 +01:00

Merge branch 'master' into verify-email-for-send

This commit is contained in:
Thomas Rittson 2021-04-09 15:41:49 +10:00
commit 30793a0d9b
3 changed files with 67 additions and 64 deletions

View File

@ -1,5 +1,3 @@
import { remote } from 'electron';
import { import {
Component, Component,
NgZone, NgZone,
@ -19,6 +17,7 @@ import { UserService } from 'jslib/abstractions/user.service';
import { SendComponent as BaseSendComponent } from 'jslib/angular/components/send/send.component'; import { SendComponent as BaseSendComponent } from 'jslib/angular/components/send/send.component';
import { BroadcasterService } from 'jslib/angular/services/broadcaster.service'; import { BroadcasterService } from 'jslib/angular/services/broadcaster.service';
import { invokeMenu, RendererMenuItem } from 'jslib/electron/utils';
import { SendView } from 'jslib/models/view/sendView'; import { SendView } from 'jslib/models/view/sendView';
@ -112,18 +111,19 @@ export class SendComponent extends BaseSendComponent implements OnInit, OnDestro
} }
viewSendMenu(send: SendView) { viewSendMenu(send: SendView) {
const menu = new remote.Menu(); const menu: RendererMenuItem[] = [];
menu.append(new remote.MenuItem({ menu.push({
label: this.i18nService.t('copyLink'), label: this.i18nService.t('copyLink'),
click: () => this.copy(send), click: () => this.copy(send),
})); });
menu.append(new remote.MenuItem({ menu.push({
label: this.i18nService.t('delete'), label: this.i18nService.t('delete'),
click: async () => { click: async () => {
await this.delete(send); await this.delete(send);
await this.deletedSend(send); await this.deletedSend(send);
}, },
})); });
menu.popup({ window: remote.getCurrentWindow() });
invokeMenu(menu);
} }
} }

View File

@ -1,5 +1,3 @@
import { remote } from 'electron';
import { import {
APP_INITIALIZER, APP_INITIALIZER,
LOCALE_ID, LOCALE_ID,
@ -12,7 +10,7 @@ import { ElectronLogService } from 'jslib/electron/services/electronLog.service'
import { ElectronPlatformUtilsService } from 'jslib/electron/services/electronPlatformUtils.service'; import { ElectronPlatformUtilsService } from 'jslib/electron/services/electronPlatformUtils.service';
import { ElectronRendererMessagingService } from 'jslib/electron/services/electronRendererMessaging.service'; import { ElectronRendererMessagingService } from 'jslib/electron/services/electronRendererMessaging.service';
import { ElectronRendererSecureStorageService } from 'jslib/electron/services/electronRendererSecureStorage.service'; import { ElectronRendererSecureStorageService } from 'jslib/electron/services/electronRendererSecureStorage.service';
import { ElectronStorageService } from 'jslib/electron/services/electronStorage.service'; import { ElectronRendererStorageService } from 'jslib/electron/services/electronRendererStorage.service';
import { isDev } from 'jslib/electron/utils'; import { isDev } from 'jslib/electron/utils';
import { DeviceType } from 'jslib/enums/deviceType'; import { DeviceType } from 'jslib/enums/deviceType';
@ -94,7 +92,7 @@ const i18nService = new I18nService(window.navigator.language, './locales');
const stateService = new StateService(); const stateService = new StateService();
const broadcasterService = new BroadcasterService(); const broadcasterService = new BroadcasterService();
const messagingService = new ElectronRendererMessagingService(broadcasterService); const messagingService = new ElectronRendererMessagingService(broadcasterService);
const storageService: StorageServiceAbstraction = new ElectronStorageService(remote.app.getPath('userData')); const storageService: StorageServiceAbstraction = new ElectronRendererStorageService();
const platformUtilsService = new ElectronPlatformUtilsService(i18nService, messagingService, true, storageService); const platformUtilsService = new ElectronPlatformUtilsService(i18nService, messagingService, true, storageService);
const secureStorageService: StorageServiceAbstraction = new ElectronRendererSecureStorageService(); const secureStorageService: StorageServiceAbstraction = new ElectronRendererSecureStorageService();
const cryptoFunctionService: CryptoFunctionServiceAbstraction = new WebCryptoFunctionService(window, const cryptoFunctionService: CryptoFunctionServiceAbstraction = new WebCryptoFunctionService(window,
@ -114,7 +112,7 @@ const cipherService = new CipherService(cryptoService, userService, settingsServ
const folderService = new FolderService(cryptoService, userService, apiService, storageService, const folderService = new FolderService(cryptoService, userService, apiService, storageService,
i18nService, cipherService); i18nService, cipherService);
const collectionService = new CollectionService(cryptoService, userService, storageService, i18nService); const collectionService = new CollectionService(cryptoService, userService, storageService, i18nService);
searchService = new SearchService(cipherService, logService); searchService = new SearchService(cipherService, logService, i18nService);
const sendService = new SendService(cryptoService, userService, apiService, fileUploadService, storageService, const sendService = new SendService(cryptoService, userService, apiService, fileUploadService, storageService,
i18nService, cryptoFunctionService); i18nService, cryptoFunctionService);
const policyService = new PolicyService(userService, storageService); const policyService = new PolicyService(userService, storageService);
@ -158,8 +156,11 @@ export function initFactory(): Function {
htmlEl.classList.add('locale_' + i18nService.translationLocale); htmlEl.classList.add('locale_' + i18nService.translationLocale);
let theme = await storageService.get<string>(ConstantsService.themeKey); let theme = await storageService.get<string>(ConstantsService.themeKey);
if (theme == null) { if (theme == null) {
theme = platformUtilsService.getDevice() === DeviceType.MacOsDesktop && if (platformUtilsService.getDevice() === DeviceType.MacOsDesktop) {
remote.nativeTheme.shouldUseDarkColors ? 'dark' : 'light'; theme = await platformUtilsService.getDefaultSystemTheme();
} else {
theme = 'light';
}
} }
htmlEl.classList.add('theme_' + theme); htmlEl.classList.add('theme_' + theme);
stateService.save(ConstantsService.disableFaviconKey, stateService.save(ConstantsService.disableFaviconKey,
@ -167,7 +168,7 @@ export function initFactory(): Function {
let installAction = null; let installAction = null;
const installedVersion = await storageService.get<string>(ConstantsService.installedVersionKey); const installedVersion = await storageService.get<string>(ConstantsService.installedVersionKey);
const currentVersion = platformUtilsService.getApplicationVersion(); const currentVersion = await platformUtilsService.getApplicationVersion();
if (installedVersion == null) { if (installedVersion == null) {
installAction = 'install'; installAction = 'install';
} else if (installedVersion !== currentVersion) { } else if (installedVersion !== currentVersion) {

View File

@ -1,5 +1,3 @@
import { remote } from 'electron';
import { import {
ChangeDetectorRef, ChangeDetectorRef,
Component, Component,
@ -26,7 +24,6 @@ import { AddEditComponent } from './add-edit.component';
import { AttachmentsComponent } from './attachments.component'; import { AttachmentsComponent } from './attachments.component';
import { CiphersComponent } from './ciphers.component'; import { CiphersComponent } from './ciphers.component';
import { CollectionsComponent } from './collections.component'; import { CollectionsComponent } from './collections.component';
import { ExportComponent } from './export.component';
import { FolderAddEditComponent } from './folder-add-edit.component'; import { FolderAddEditComponent } from './folder-add-edit.component';
import { GroupingsComponent } from './groupings.component'; import { GroupingsComponent } from './groupings.component';
import { PasswordGeneratorComponent } from './password-generator.component'; import { PasswordGeneratorComponent } from './password-generator.component';
@ -40,7 +37,6 @@ 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';
@ -48,6 +44,7 @@ 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 { TotpService } from 'jslib/abstractions/totp.service';
import { UserService } from 'jslib/abstractions/user.service'; import { UserService } from 'jslib/abstractions/user.service';
import { invokeMenu, RendererMenuItem } from 'jslib/electron/utils';
const BroadcasterSubscriptionId = 'VaultComponent'; const BroadcasterSubscriptionId = 'VaultComponent';
@ -243,88 +240,90 @@ export class VaultComponent implements OnInit, OnDestroy {
} }
viewCipherMenu(cipher: CipherView) { viewCipherMenu(cipher: CipherView) {
const menu = new remote.Menu(); const menu: RendererMenuItem[] = [
menu.append(new remote.MenuItem({ {
label: this.i18nService.t('view'), label: this.i18nService.t('view'),
click: () => this.functionWithChangeDetection(() => { click: () => this.functionWithChangeDetection(() => {
this.viewCipher(cipher); this.viewCipher(cipher);
}), }),
})); },
];
if (!cipher.isDeleted) { if (!cipher.isDeleted) {
menu.append(new remote.MenuItem({ menu.push({
label: this.i18nService.t('edit'), label: this.i18nService.t('edit'),
click: () => this.functionWithChangeDetection(() => { click: () => this.functionWithChangeDetection(() => {
this.editCipher(cipher); this.editCipher(cipher);
}), }),
})); });
menu.append(new remote.MenuItem({ menu.push({
label: this.i18nService.t('clone'), label: this.i18nService.t('clone'),
click: () => this.functionWithChangeDetection(() => { click: () => this.functionWithChangeDetection(() => {
this.cloneCipher(cipher); this.cloneCipher(cipher);
}), }),
})); });
} }
switch (cipher.type) { switch (cipher.type) {
case CipherType.Login: case CipherType.Login:
if (cipher.login.canLaunch || cipher.login.username != null || cipher.login.password != null) { if (cipher.login.canLaunch || cipher.login.username != null || cipher.login.password != null) {
menu.append(new remote.MenuItem({ type: 'separator' })); menu.push({ type: 'separator' });
} }
if (cipher.login.canLaunch) { if (cipher.login.canLaunch) {
menu.append(new remote.MenuItem({ menu.push({
label: this.i18nService.t('launch'), label: this.i18nService.t('launch'),
click: () => this.platformUtilsService.launchUri(cipher.login.launchUri), click: () => this.platformUtilsService.launchUri(cipher.login.launchUri),
})); });
} }
if (cipher.login.username != null) { if (cipher.login.username != null) {
menu.append(new remote.MenuItem({ menu.push({
label: this.i18nService.t('copyUsername'), label: this.i18nService.t('copyUsername'),
click: () => this.copyValue(cipher.login.username, 'username'), click: () => this.copyValue(cipher.login.username, 'username'),
})); });
} }
if (cipher.login.password != null && cipher.viewPassword) { if (cipher.login.password != null && cipher.viewPassword) {
menu.append(new remote.MenuItem({ menu.push({
label: this.i18nService.t('copyPassword'), label: this.i18nService.t('copyPassword'),
click: () => { click: () => {
this.copyValue(cipher.login.password, 'password'); this.copyValue(cipher.login.password, 'password');
this.eventService.collect(EventType.Cipher_ClientCopiedPassword, cipher.id); this.eventService.collect(EventType.Cipher_ClientCopiedPassword, cipher.id);
}, },
})); });
} }
if (cipher.login.hasTotp && (cipher.organizationUseTotp || this.userHasPremiumAccess)) { if (cipher.login.hasTotp && (cipher.organizationUseTotp || this.userHasPremiumAccess)) {
menu.append(new remote.MenuItem({ menu.push({
label: this.i18nService.t('copyVerificationCodeTotp'), label: this.i18nService.t('copyVerificationCodeTotp'),
click: async () => { click: async () => {
const value = await this.totpService.getCode(cipher.login.totp); const value = await this.totpService.getCode(cipher.login.totp);
this.copyValue(value, 'verificationCodeTotp'); 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) {
menu.append(new remote.MenuItem({ type: 'separator' })); menu.push({ type: 'separator' });
} }
if (cipher.card.number != null) { if (cipher.card.number != null) {
menu.append(new remote.MenuItem({ menu.push({
label: this.i18nService.t('copyNumber'), label: this.i18nService.t('copyNumber'),
click: () => this.copyValue(cipher.card.number, 'number'), click: () => this.copyValue(cipher.card.number, 'number'),
})); });
} }
if (cipher.card.code != null) { if (cipher.card.code != null) {
menu.append(new remote.MenuItem({ menu.push({
label: this.i18nService.t('copySecurityCode'), label: this.i18nService.t('copySecurityCode'),
click: () => { click: () => {
this.copyValue(cipher.card.code, 'securityCode'); this.copyValue(cipher.card.code, 'securityCode');
this.eventService.collect(EventType.Cipher_ClientCopiedCardCode, cipher.id); this.eventService.collect(EventType.Cipher_ClientCopiedCardCode, cipher.id);
}, },
})); });
} }
break; break;
default: default:
break; break;
} }
menu.popup({ window: remote.getCurrentWindow() });
invokeMenu(menu);
} }
async editCipher(cipher: CipherView) { async editCipher(cipher: CipherView) {
@ -366,24 +365,27 @@ export class VaultComponent implements OnInit, OnDestroy {
} }
addCipherOptions() { addCipherOptions() {
const menu = new remote.Menu(); const menu: RendererMenuItem[] = [
menu.append(new remote.MenuItem({ {
label: this.i18nService.t('typeLogin'), label: this.i18nService.t('typeLogin'),
click: () => this.addCipherWithChangeDetection(CipherType.Login), click: () => this.addCipherWithChangeDetection(CipherType.Login),
})); },
menu.append(new remote.MenuItem({ {
label: this.i18nService.t('typeCard'), label: this.i18nService.t('typeCard'),
click: () => this.addCipherWithChangeDetection(CipherType.Card), click: () => this.addCipherWithChangeDetection(CipherType.Card),
})); },
menu.append(new remote.MenuItem({ {
label: this.i18nService.t('typeIdentity'), label: this.i18nService.t('typeIdentity'),
click: () => this.addCipherWithChangeDetection(CipherType.Identity), click: () => this.addCipherWithChangeDetection(CipherType.Identity),
})); },
menu.append(new remote.MenuItem({ {
label: this.i18nService.t('typeSecureNote'), label: this.i18nService.t('typeSecureNote'),
click: () => this.addCipherWithChangeDetection(CipherType.SecureNote), click: () => this.addCipherWithChangeDetection(CipherType.SecureNote),
})); },
menu.popup({ window: remote.getCurrentWindow() });
];
invokeMenu(menu);
} }
async savedCipher(cipher: CipherView) { async savedCipher(cipher: CipherView) {