import { Component, OnInit, } from '@angular/core'; import { ToasterService } from 'angular2-toaster'; import { Angulartics2 } from 'angulartics2'; import swal from 'sweetalert'; import { DeviceType } from 'jslib/enums/deviceType'; import { CryptoService } from 'jslib/abstractions/crypto.service'; import { I18nService } from 'jslib/abstractions/i18n.service'; import { LockService } from 'jslib/abstractions/lock.service'; import { MessagingService } from 'jslib/abstractions/messaging.service'; import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service'; import { StateService } from 'jslib/abstractions/state.service'; import { StorageService } from 'jslib/abstractions/storage.service'; import { UserService } from 'jslib/abstractions/user.service'; import { ConstantsService } from 'jslib/services/constants.service'; import { ElectronConstants } from 'jslib/electron/electronConstants'; import { Utils } from 'jslib/misc/utils'; @Component({ selector: 'app-settings', templateUrl: 'settings.component.html', }) export class SettingsComponent implements OnInit { lockOption: number = null; pin: boolean = null; disableFavicons: boolean = false; enableMinToTray: boolean = false; enableCloseToTray: boolean = false; enableTray: boolean = false; showMinToTray: boolean = false; startToTray: boolean = false; locale: string; lockOptions: any[]; localeOptions: any[]; theme: string; themeOptions: any[]; clearClipboard: number; clearClipboardOptions: any[]; constructor(private analytics: Angulartics2, private toasterService: ToasterService, private i18nService: I18nService, private platformUtilsService: PlatformUtilsService, private storageService: StorageService, private lockService: LockService, private stateService: StateService, private messagingService: MessagingService, private userService: UserService, private cryptoService: CryptoService) { this.lockOptions = [ // { name: i18nService.t('immediately'), value: 0 }, { name: i18nService.t('oneMinute'), value: 1 }, { name: i18nService.t('fiveMinutes'), value: 5 }, { name: i18nService.t('fifteenMinutes'), value: 15 }, { name: i18nService.t('thirtyMinutes'), value: 30 }, { name: i18nService.t('oneHour'), value: 60 }, { name: i18nService.t('fourHours'), value: 240 }, { name: i18nService.t('onIdle'), value: -4 }, { name: i18nService.t('onSleep'), value: -3 }, // { name: i18nService.t('onLocked'), value: -2 }, { name: i18nService.t('onRestart'), value: -1 }, { name: i18nService.t('never'), value: null }, ]; const localeOptions: any[] = []; i18nService.supportedTranslationLocales.forEach((locale) => { localeOptions.push({ name: locale, value: locale }); }); localeOptions.sort(Utils.getSortFunction(i18nService, 'name')); localeOptions.splice(0, 0, { name: i18nService.t('default'), value: null }); this.localeOptions = localeOptions; this.themeOptions = [ { name: i18nService.t('default'), value: null }, { name: i18nService.t('light'), value: 'light' }, { name: i18nService.t('dark'), value: 'dark' }, { name: 'Nord', value: 'nord' }, ]; this.clearClipboardOptions = [ { name: i18nService.t('never'), value: null }, { name: i18nService.t('tenSeconds'), value: 10 }, { name: i18nService.t('twentySeconds'), value: 20 }, { name: i18nService.t('thirtySeconds'), value: 30 }, { name: i18nService.t('oneMinute'), value: 60 }, { name: i18nService.t('twoMinutes'), value: 120 }, { name: i18nService.t('fiveMinutes'), value: 300 }, ]; } async ngOnInit() { this.showMinToTray = this.platformUtilsService.getDevice() === DeviceType.WindowsDesktop; this.lockOption = await this.storageService.get(ConstantsService.lockOptionKey); const pinSet = await this.lockService.isPinLockSet(); this.pin = pinSet[0] || pinSet[1]; this.disableFavicons = await this.storageService.get(ConstantsService.disableFaviconKey); this.enableMinToTray = await this.storageService.get(ElectronConstants.enableMinimizeToTrayKey); this.enableCloseToTray = await this.storageService.get(ElectronConstants.enableCloseToTrayKey); this.enableTray = await this.storageService.get(ElectronConstants.enableTrayKey); this.startToTray = await this.storageService.get(ElectronConstants.enableStartToTrayKey); this.locale = await this.storageService.get(ConstantsService.localeKey); this.theme = await this.storageService.get(ConstantsService.themeKey); this.clearClipboard = await this.storageService.get(ConstantsService.clearClipboardKey); } async saveLockOption() { await this.lockService.setLockOption(this.lockOption != null ? this.lockOption : null); } async updatePin() { if (this.pin) { const div = document.createElement('div'); const label = document.createElement('label'); label.className = 'checkbox'; const checkboxText = document.createElement('span'); const restartText = document.createTextNode(this.i18nService.t('lockWithMasterPassOnRestart')); checkboxText.appendChild(restartText); label.innerHTML = ''; label.appendChild(checkboxText); div.innerHTML = ''; (div.querySelector('#pin-val') as HTMLInputElement).placeholder = this.i18nService.t('pin'); div.appendChild(label); const submitted = await swal({ text: this.i18nService.t('setYourPinCode'), content: { element: div }, buttons: [this.i18nService.t('cancel'), this.i18nService.t('submit')], }); let pin: string = null; let masterPassOnRestart: boolean = null; if (submitted) { pin = (document.getElementById('pin-val') as HTMLInputElement).value; masterPassOnRestart = (document.getElementById('master-pass-restart') as HTMLInputElement).checked; } if (pin != null && pin.trim() !== '') { if (masterPassOnRestart) { const encPin = await this.cryptoService.encrypt(pin); await this.storageService.save(ConstantsService.protectedPin, encPin.encryptedString); } else { const kdf = await this.userService.getKdf(); const kdfIterations = await this.userService.getKdfIterations(); const email = await this.userService.getEmail(); const pinKey = await this.cryptoService.makePinKey(pin, email, kdf, kdfIterations); const key = await this.cryptoService.getKey(); const pinProtectedKey = await this.cryptoService.encrypt(key.key, pinKey); await this.storageService.save(ConstantsService.pinProtectedKey, pinProtectedKey.encryptedString); } } else { this.pin = false; } } if (!this.pin) { await this.storageService.remove(ConstantsService.pinProtectedKey); await this.storageService.remove(ConstantsService.protectedPin); } } async saveFavicons() { await this.storageService.save(ConstantsService.disableFaviconKey, this.disableFavicons); await this.stateService.save(ConstantsService.disableFaviconKey, this.disableFavicons); this.messagingService.send('refreshCiphers'); this.callAnalytics('Favicons', !this.disableFavicons); } async saveMinToTray() { await this.storageService.save(ElectronConstants.enableMinimizeToTrayKey, this.enableMinToTray); this.callAnalytics('MinimizeToTray', this.enableMinToTray); } async saveCloseToTray() { await this.storageService.save(ElectronConstants.enableCloseToTrayKey, this.enableCloseToTray); this.callAnalytics('CloseToTray', this.enableCloseToTray); } async saveTray() { await this.storageService.save(ElectronConstants.enableTrayKey, this.enableTray); this.callAnalytics('Tray', this.enableTray); this.messagingService.send(this.enableTray ? 'showTray' : 'removeTray'); } async saveStartToTray() { await this.storageService.save(ElectronConstants.enableStartToTrayKey, this.startToTray); this.callAnalytics('StartToTray', this.startToTray); } async saveLocale() { await this.storageService.save(ConstantsService.localeKey, this.locale); this.analytics.eventTrack.next({ action: 'Set Locale ' + this.locale }); } async saveTheme() { await this.storageService.save(ConstantsService.themeKey, this.theme); this.analytics.eventTrack.next({ action: 'Set Theme ' + this.theme }); window.setTimeout(() => window.location.reload(), 200); } async saveClearClipboard() { await this.storageService.save(ConstantsService.clearClipboardKey, this.clearClipboard); this.analytics.eventTrack.next({ action: 'Set Clear Clipboard ' + (this.clearClipboard == null ? 'Disabled' : this.clearClipboard), }); } private callAnalytics(name: string, enabled: boolean) { const status = enabled ? 'Enabled' : 'Disabled'; this.analytics.eventTrack.next({ action: `${status} ${name}` }); } }