Merge branch 'master' into verify-email-for-send
This commit is contained in:
commit
30793a0d9b
|
@ -1,5 +1,3 @@
|
|||
import { remote } from 'electron';
|
||||
|
||||
import {
|
||||
Component,
|
||||
NgZone,
|
||||
|
@ -19,6 +17,7 @@ import { UserService } from 'jslib/abstractions/user.service';
|
|||
import { SendComponent as BaseSendComponent } from 'jslib/angular/components/send/send.component';
|
||||
|
||||
import { BroadcasterService } from 'jslib/angular/services/broadcaster.service';
|
||||
import { invokeMenu, RendererMenuItem } from 'jslib/electron/utils';
|
||||
|
||||
import { SendView } from 'jslib/models/view/sendView';
|
||||
|
||||
|
@ -112,18 +111,19 @@ export class SendComponent extends BaseSendComponent implements OnInit, OnDestro
|
|||
}
|
||||
|
||||
viewSendMenu(send: SendView) {
|
||||
const menu = new remote.Menu();
|
||||
menu.append(new remote.MenuItem({
|
||||
const menu: RendererMenuItem[] = [];
|
||||
menu.push({
|
||||
label: this.i18nService.t('copyLink'),
|
||||
click: () => this.copy(send),
|
||||
}));
|
||||
menu.append(new remote.MenuItem({
|
||||
});
|
||||
menu.push({
|
||||
label: this.i18nService.t('delete'),
|
||||
click: async () => {
|
||||
await this.delete(send);
|
||||
await this.deletedSend(send);
|
||||
},
|
||||
}));
|
||||
menu.popup({ window: remote.getCurrentWindow() });
|
||||
});
|
||||
|
||||
invokeMenu(menu);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import { remote } from 'electron';
|
||||
|
||||
import {
|
||||
APP_INITIALIZER,
|
||||
LOCALE_ID,
|
||||
|
@ -12,7 +10,7 @@ import { ElectronLogService } from 'jslib/electron/services/electronLog.service'
|
|||
import { ElectronPlatformUtilsService } from 'jslib/electron/services/electronPlatformUtils.service';
|
||||
import { ElectronRendererMessagingService } from 'jslib/electron/services/electronRendererMessaging.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 { DeviceType } from 'jslib/enums/deviceType';
|
||||
|
@ -94,7 +92,7 @@ const i18nService = new I18nService(window.navigator.language, './locales');
|
|||
const stateService = new StateService();
|
||||
const broadcasterService = new 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 secureStorageService: StorageServiceAbstraction = new ElectronRendererSecureStorageService();
|
||||
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,
|
||||
i18nService, cipherService);
|
||||
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,
|
||||
i18nService, cryptoFunctionService);
|
||||
const policyService = new PolicyService(userService, storageService);
|
||||
|
@ -158,8 +156,11 @@ export function initFactory(): Function {
|
|||
htmlEl.classList.add('locale_' + i18nService.translationLocale);
|
||||
let theme = await storageService.get<string>(ConstantsService.themeKey);
|
||||
if (theme == null) {
|
||||
theme = platformUtilsService.getDevice() === DeviceType.MacOsDesktop &&
|
||||
remote.nativeTheme.shouldUseDarkColors ? 'dark' : 'light';
|
||||
if (platformUtilsService.getDevice() === DeviceType.MacOsDesktop) {
|
||||
theme = await platformUtilsService.getDefaultSystemTheme();
|
||||
} else {
|
||||
theme = 'light';
|
||||
}
|
||||
}
|
||||
htmlEl.classList.add('theme_' + theme);
|
||||
stateService.save(ConstantsService.disableFaviconKey,
|
||||
|
@ -167,7 +168,7 @@ export function initFactory(): Function {
|
|||
|
||||
let installAction = null;
|
||||
const installedVersion = await storageService.get<string>(ConstantsService.installedVersionKey);
|
||||
const currentVersion = platformUtilsService.getApplicationVersion();
|
||||
const currentVersion = await platformUtilsService.getApplicationVersion();
|
||||
if (installedVersion == null) {
|
||||
installAction = 'install';
|
||||
} else if (installedVersion !== currentVersion) {
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import { remote } from 'electron';
|
||||
|
||||
import {
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
|
@ -26,7 +24,6 @@ import { AddEditComponent } from './add-edit.component';
|
|||
import { AttachmentsComponent } from './attachments.component';
|
||||
import { CiphersComponent } from './ciphers.component';
|
||||
import { CollectionsComponent } from './collections.component';
|
||||
import { ExportComponent } from './export.component';
|
||||
import { FolderAddEditComponent } from './folder-add-edit.component';
|
||||
import { GroupingsComponent } from './groupings.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 { FolderView } from 'jslib/models/view/folderView';
|
||||
|
||||
import { userError } from '@angular/compiler-cli/src/transformers/util';
|
||||
import { EventService } from 'jslib/abstractions/event.service';
|
||||
import { I18nService } from 'jslib/abstractions/i18n.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 { TotpService } from 'jslib/abstractions/totp.service';
|
||||
import { UserService } from 'jslib/abstractions/user.service';
|
||||
import { invokeMenu, RendererMenuItem } from 'jslib/electron/utils';
|
||||
|
||||
const BroadcasterSubscriptionId = 'VaultComponent';
|
||||
|
||||
|
@ -243,88 +240,90 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
viewCipherMenu(cipher: CipherView) {
|
||||
const menu = new remote.Menu();
|
||||
menu.append(new remote.MenuItem({
|
||||
label: this.i18nService.t('view'),
|
||||
click: () => this.functionWithChangeDetection(() => {
|
||||
this.viewCipher(cipher);
|
||||
}),
|
||||
}));
|
||||
const menu: RendererMenuItem[] = [
|
||||
{
|
||||
label: this.i18nService.t('view'),
|
||||
click: () => this.functionWithChangeDetection(() => {
|
||||
this.viewCipher(cipher);
|
||||
}),
|
||||
},
|
||||
];
|
||||
if (!cipher.isDeleted) {
|
||||
menu.append(new remote.MenuItem({
|
||||
menu.push({
|
||||
label: this.i18nService.t('edit'),
|
||||
click: () => this.functionWithChangeDetection(() => {
|
||||
this.editCipher(cipher);
|
||||
}),
|
||||
}));
|
||||
menu.append(new remote.MenuItem({
|
||||
});
|
||||
menu.push({
|
||||
label: this.i18nService.t('clone'),
|
||||
click: () => this.functionWithChangeDetection(() => {
|
||||
this.cloneCipher(cipher);
|
||||
}),
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
switch (cipher.type) {
|
||||
case CipherType.Login:
|
||||
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) {
|
||||
menu.append(new remote.MenuItem({
|
||||
menu.push({
|
||||
label: this.i18nService.t('launch'),
|
||||
click: () => this.platformUtilsService.launchUri(cipher.login.launchUri),
|
||||
}));
|
||||
});
|
||||
}
|
||||
if (cipher.login.username != null) {
|
||||
menu.append(new remote.MenuItem({
|
||||
menu.push({
|
||||
label: this.i18nService.t('copyUsername'),
|
||||
click: () => this.copyValue(cipher.login.username, 'username'),
|
||||
}));
|
||||
});
|
||||
}
|
||||
if (cipher.login.password != null && cipher.viewPassword) {
|
||||
menu.append(new remote.MenuItem({
|
||||
menu.push({
|
||||
label: this.i18nService.t('copyPassword'),
|
||||
click: () => {
|
||||
this.copyValue(cipher.login.password, 'password');
|
||||
this.eventService.collect(EventType.Cipher_ClientCopiedPassword, cipher.id);
|
||||
},
|
||||
}));
|
||||
});
|
||||
}
|
||||
if (cipher.login.hasTotp && (cipher.organizationUseTotp || this.userHasPremiumAccess)) {
|
||||
menu.append(new remote.MenuItem({
|
||||
menu.push({
|
||||
label: this.i18nService.t('copyVerificationCodeTotp'),
|
||||
click: async () => {
|
||||
const value = await this.totpService.getCode(cipher.login.totp);
|
||||
this.copyValue(value, 'verificationCodeTotp');
|
||||
},
|
||||
}));
|
||||
});
|
||||
}
|
||||
break;
|
||||
case CipherType.Card:
|
||||
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) {
|
||||
menu.append(new remote.MenuItem({
|
||||
menu.push({
|
||||
label: this.i18nService.t('copyNumber'),
|
||||
click: () => this.copyValue(cipher.card.number, 'number'),
|
||||
}));
|
||||
});
|
||||
}
|
||||
if (cipher.card.code != null) {
|
||||
menu.append(new remote.MenuItem({
|
||||
menu.push({
|
||||
label: this.i18nService.t('copySecurityCode'),
|
||||
click: () => {
|
||||
this.copyValue(cipher.card.code, 'securityCode');
|
||||
this.eventService.collect(EventType.Cipher_ClientCopiedCardCode, cipher.id);
|
||||
},
|
||||
}));
|
||||
});
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
menu.popup({ window: remote.getCurrentWindow() });
|
||||
|
||||
invokeMenu(menu);
|
||||
}
|
||||
|
||||
async editCipher(cipher: CipherView) {
|
||||
|
@ -366,24 +365,27 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
addCipherOptions() {
|
||||
const menu = new remote.Menu();
|
||||
menu.append(new remote.MenuItem({
|
||||
label: this.i18nService.t('typeLogin'),
|
||||
click: () => this.addCipherWithChangeDetection(CipherType.Login),
|
||||
}));
|
||||
menu.append(new remote.MenuItem({
|
||||
label: this.i18nService.t('typeCard'),
|
||||
click: () => this.addCipherWithChangeDetection(CipherType.Card),
|
||||
}));
|
||||
menu.append(new remote.MenuItem({
|
||||
label: this.i18nService.t('typeIdentity'),
|
||||
click: () => this.addCipherWithChangeDetection(CipherType.Identity),
|
||||
}));
|
||||
menu.append(new remote.MenuItem({
|
||||
label: this.i18nService.t('typeSecureNote'),
|
||||
click: () => this.addCipherWithChangeDetection(CipherType.SecureNote),
|
||||
}));
|
||||
menu.popup({ window: remote.getCurrentWindow() });
|
||||
const menu: RendererMenuItem[] = [
|
||||
{
|
||||
label: this.i18nService.t('typeLogin'),
|
||||
click: () => this.addCipherWithChangeDetection(CipherType.Login),
|
||||
},
|
||||
{
|
||||
label: this.i18nService.t('typeCard'),
|
||||
click: () => this.addCipherWithChangeDetection(CipherType.Card),
|
||||
},
|
||||
{
|
||||
label: this.i18nService.t('typeIdentity'),
|
||||
click: () => this.addCipherWithChangeDetection(CipherType.Identity),
|
||||
},
|
||||
{
|
||||
label: this.i18nService.t('typeSecureNote'),
|
||||
click: () => this.addCipherWithChangeDetection(CipherType.SecureNote),
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
invokeMenu(menu);
|
||||
}
|
||||
|
||||
async savedCipher(cipher: CipherView) {
|
||||
|
|
Loading…
Reference in New Issue