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:
commit
30793a0d9b
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user