From f793ff0aa57ef9ffcf09323d1f557c7c24509c1e Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Tue, 2 Oct 2018 23:09:19 -0400 Subject: [PATCH] refactor toaster to platform showToast --- package-lock.json | 5 ---- package.json | 1 - src/abstractions/platformUtils.service.ts | 3 +- src/angular/components/add-edit.component.ts | 14 ++++----- .../components/attachments.component.ts | 19 ++++++------ .../components/environment.component.ts | 6 ++-- src/angular/components/export.component.ts | 7 ++--- .../components/folder-add-edit.component.ts | 10 +++---- src/angular/components/hint.component.ts | 12 ++++---- src/angular/components/lock.component.ts | 7 ++--- src/angular/components/login.component.ts | 10 +++---- .../password-generator-history.component.ts | 6 ++-- .../password-generator.component.ts | 6 ++-- .../components/password-history.component.ts | 6 ++-- src/angular/components/premium.component.ts | 5 ++-- src/angular/components/register.component.ts | 15 +++++----- .../two-factor-options.component.ts | 5 +--- .../components/two-factor.component.ts | 9 +++--- src/angular/components/view.component.ts | 16 +++++----- src/angular/services/validation.service.ts | 29 ++++--------------- .../services/electronPlatformUtils.service.ts | 11 +++---- 21 files changed, 85 insertions(+), 117 deletions(-) diff --git a/package-lock.json b/package-lock.json index 55c82348cc..4668dfc380 100644 --- a/package-lock.json +++ b/package-lock.json @@ -229,11 +229,6 @@ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "dev": true }, - "angular2-toaster": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/angular2-toaster/-/angular2-toaster-6.1.0.tgz", - "integrity": "sha512-++CtP7Xx3zNG1U+1nlop8rfA0nqkKqEhKGCtdcT2dB+CTQKkSOod5A6TMdTOZbdm/edaAzT8E0fHt9RrPRTDbA==" - }, "angulartics2": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/angulartics2/-/angulartics2-6.3.0.tgz", diff --git a/package.json b/package.json index 61e070e276..09029ed887 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,6 @@ "@angular/upgrade": "6.1.7", "@aspnet/signalr": "1.0.3", "@aspnet/signalr-protocol-msgpack": "1.0.3", - "angular2-toaster": "6.1.0", "angulartics2": "6.3.0", "core-js": "2.5.7", "electron-log": "2.2.14", diff --git a/src/abstractions/platformUtils.service.ts b/src/abstractions/platformUtils.service.ts index debb19f6ae..f24b0f5706 100644 --- a/src/abstractions/platformUtils.service.ts +++ b/src/abstractions/platformUtils.service.ts @@ -21,7 +21,8 @@ export abstract class PlatformUtilsService { getApplicationVersion: () => string; supportsU2f: (win: Window) => boolean; supportsDuo: () => boolean; - showToast: (type: 'error' | 'success' | 'warning' | 'info', title: string, text: string) => void; + showToast: (type: 'error' | 'success' | 'warning' | 'info', title: string, text: string | string[], + options?: any) => void; showDialog: (text: string, title?: string, confirmText?: string, cancelText?: string, type?: string) => Promise; isDev: () => boolean; diff --git a/src/angular/components/add-edit.component.ts b/src/angular/components/add-edit.component.ts index 0e9f2cdbbc..9642c8afb3 100644 --- a/src/angular/components/add-edit.component.ts +++ b/src/angular/components/add-edit.component.ts @@ -4,7 +4,6 @@ import { Output, } from '@angular/core'; -import { ToasterService } from 'angular2-toaster'; import { Angulartics2 } from 'angulartics2'; import { CipherType } from '../../enums/cipherType'; @@ -61,7 +60,7 @@ export class AddEditComponent { constructor(protected cipherService: CipherService, protected folderService: FolderService, protected i18nService: I18nService, protected platformUtilsService: PlatformUtilsService, - protected analytics: Angulartics2, protected toasterService: ToasterService, + protected analytics: Angulartics2, protected auditService: AuditService, protected stateService: StateService) { this.typeOptions = [ { name: i18nService.t('typeLogin'), value: CipherType.Login }, @@ -152,7 +151,7 @@ export class AddEditComponent { async submit(): Promise { if (this.cipher.name == null || this.cipher.name === '') { - this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'), + this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), this.i18nService.t('nameRequired')); return false; } @@ -169,7 +168,7 @@ export class AddEditComponent { await this.formPromise; this.cipher.id = cipher.id; this.analytics.eventTrack.next({ action: this.editMode ? 'Edited Cipher' : 'Added Cipher' }); - this.toasterService.popAsync('success', null, + this.platformUtilsService.showToast('success', null, this.i18nService.t(this.editMode ? 'editedItem' : 'addedItem')); this.onSavedCipher.emit(this.cipher); return true; @@ -238,7 +237,7 @@ export class AddEditComponent { this.deletePromise = this.deleteCipher(); await this.deletePromise; this.analytics.eventTrack.next({ action: 'Deleted Cipher' }); - this.toasterService.popAsync('success', null, this.i18nService.t('deletedItem')); + this.platformUtilsService.showToast('success', null, this.i18nService.t('deletedItem')); this.onDeletedCipher.emit(this.cipher); } catch { } @@ -301,9 +300,10 @@ export class AddEditComponent { this.checkPasswordPromise = null; if (matches > 0) { - this.toasterService.popAsync('warning', null, this.i18nService.t('passwordExposed', matches.toString())); + this.platformUtilsService.showToast('warning', null, + this.i18nService.t('passwordExposed', matches.toString())); } else { - this.toasterService.popAsync('success', null, this.i18nService.t('passwordSafe')); + this.platformUtilsService.showToast('success', null, this.i18nService.t('passwordSafe')); } } diff --git a/src/angular/components/attachments.component.ts b/src/angular/components/attachments.component.ts index b24c7fd11e..05f6f241d6 100644 --- a/src/angular/components/attachments.component.ts +++ b/src/angular/components/attachments.component.ts @@ -5,7 +5,6 @@ import { Output, } from '@angular/core'; -import { ToasterService } from 'angular2-toaster'; import { Angulartics2 } from 'angulartics2'; import { CipherService } from '../../abstractions/cipher.service'; @@ -32,7 +31,7 @@ export class AttachmentsComponent implements OnInit { deletePromises: { [id: string]: Promise; } = {}; constructor(protected cipherService: CipherService, protected analytics: Angulartics2, - protected toasterService: ToasterService, protected i18nService: I18nService, + protected i18nService: I18nService, protected cryptoService: CryptoService, protected userService: UserService, protected platformUtilsService: PlatformUtilsService, protected win: Window) { } @@ -63,7 +62,7 @@ export class AttachmentsComponent implements OnInit { async submit() { if (!this.hasUpdatedKey) { - this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'), + this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), this.i18nService.t('updateKey')); return; } @@ -71,13 +70,13 @@ export class AttachmentsComponent implements OnInit { const fileEl = document.getElementById('file') as HTMLInputElement; const files = fileEl.files; if (files == null || files.length === 0) { - this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'), + this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), this.i18nService.t('selectFile')); return; } if (files[0].size > 104857600) { // 100 MB - this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'), + this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), this.i18nService.t('maxFileSize')); return; } @@ -87,7 +86,7 @@ export class AttachmentsComponent implements OnInit { this.cipherDomain = await this.formPromise; this.cipher = await this.cipherDomain.decrypt(); this.analytics.eventTrack.next({ action: 'Added Attachment' }); - this.toasterService.popAsync('success', null, this.i18nService.t('attachmentSaved')); + this.platformUtilsService.showToast('success', null, this.i18nService.t('attachmentSaved')); this.onUploadedAttachment.emit(); } catch { } @@ -114,7 +113,7 @@ export class AttachmentsComponent implements OnInit { this.deletePromises[attachment.id] = this.deleteCipherAttachment(attachment.id); await this.deletePromises[attachment.id]; this.analytics.eventTrack.next({ action: 'Deleted Attachment' }); - this.toasterService.popAsync('success', null, this.i18nService.t('deletedAttachment')); + this.platformUtilsService.showToast('success', null, this.i18nService.t('deletedAttachment')); const i = this.cipher.attachments.indexOf(attachment); if (i > -1) { this.cipher.attachments.splice(i, 1); @@ -132,7 +131,7 @@ export class AttachmentsComponent implements OnInit { } if (!this.canAccessAttachments) { - this.toasterService.popAsync('error', this.i18nService.t('premiumRequired'), + this.platformUtilsService.showToast('error', this.i18nService.t('premiumRequired'), this.i18nService.t('premiumRequiredDesc')); return; } @@ -140,7 +139,7 @@ export class AttachmentsComponent implements OnInit { a.downloading = true; const response = await fetch(new Request(attachment.url, { cache: 'no-cache' })); if (response.status !== 200) { - this.toasterService.popAsync('error', null, this.i18nService.t('errorOccurred')); + this.platformUtilsService.showToast('error', null, this.i18nService.t('errorOccurred')); a.downloading = false; return; } @@ -151,7 +150,7 @@ export class AttachmentsComponent implements OnInit { const decBuf = await this.cryptoService.decryptFromBytes(buf, key); this.platformUtilsService.saveFile(this.win, decBuf, null, attachment.fileName); } catch (e) { - this.toasterService.popAsync('error', null, this.i18nService.t('errorOccurred')); + this.platformUtilsService.showToast('error', null, this.i18nService.t('errorOccurred')); } a.downloading = false; diff --git a/src/angular/components/environment.component.ts b/src/angular/components/environment.component.ts index d7d4226d9b..8c2456ad69 100644 --- a/src/angular/components/environment.component.ts +++ b/src/angular/components/environment.component.ts @@ -3,11 +3,11 @@ import { Output, } from '@angular/core'; -import { ToasterService } from 'angular2-toaster'; import { Angulartics2 } from 'angulartics2'; import { EnvironmentService } from '../../abstractions/environment.service'; import { I18nService } from '../../abstractions/i18n.service'; +import { PlatformUtilsService } from '../../abstractions/platformUtils.service'; export class EnvironmentComponent { @Output() onSaved = new EventEmitter(); @@ -20,7 +20,7 @@ export class EnvironmentComponent { baseUrl: string; showCustom = false; - constructor(protected analytics: Angulartics2, protected toasterService: ToasterService, + constructor(protected analytics: Angulartics2, protected platformUtilsService: PlatformUtilsService, protected environmentService: EnvironmentService, protected i18nService: I18nService) { this.baseUrl = environmentService.baseUrl || ''; this.webVaultUrl = environmentService.webVaultUrl || ''; @@ -49,7 +49,7 @@ export class EnvironmentComponent { this.notificationsUrl = resUrls.notifications; this.analytics.eventTrack.next({ action: 'Set Environment URLs' }); - this.toasterService.popAsync('success', null, this.i18nService.t('environmentSaved')); + this.platformUtilsService.showToast('success', null, this.i18nService.t('environmentSaved')); this.saved(); } diff --git a/src/angular/components/export.component.ts b/src/angular/components/export.component.ts index 128a36d9ab..6980210ffe 100644 --- a/src/angular/components/export.component.ts +++ b/src/angular/components/export.component.ts @@ -1,4 +1,3 @@ -import { ToasterService } from 'angular2-toaster'; import { Angulartics2 } from 'angulartics2'; import { @@ -18,14 +17,14 @@ export class ExportComponent { masterPassword: string; showPassword = false; - constructor(protected analytics: Angulartics2, protected toasterService: ToasterService, + constructor(protected analytics: Angulartics2, protected cryptoService: CryptoService, protected i18nService: I18nService, protected platformUtilsService: PlatformUtilsService, protected exportService: ExportService, protected win: Window) { } async submit() { if (this.masterPassword == null || this.masterPassword === '') { - this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'), + this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), this.i18nService.t('invalidMasterPassword')); return; } @@ -41,7 +40,7 @@ export class ExportComponent { this.saved(); } catch { } } else { - this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'), + this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), this.i18nService.t('invalidMasterPassword')); } } diff --git a/src/angular/components/folder-add-edit.component.ts b/src/angular/components/folder-add-edit.component.ts index c84be649c1..ac20449c8f 100644 --- a/src/angular/components/folder-add-edit.component.ts +++ b/src/angular/components/folder-add-edit.component.ts @@ -5,7 +5,6 @@ import { Output, } from '@angular/core'; -import { ToasterService } from 'angular2-toaster'; import { Angulartics2 } from 'angulartics2'; import { FolderService } from '../../abstractions/folder.service'; @@ -26,8 +25,7 @@ export class FolderAddEditComponent implements OnInit { deletePromise: Promise; constructor(protected folderService: FolderService, protected i18nService: I18nService, - protected analytics: Angulartics2, protected toasterService: ToasterService, - protected platformUtilsService: PlatformUtilsService) { } + protected analytics: Angulartics2, protected platformUtilsService: PlatformUtilsService) { } async ngOnInit() { this.editMode = this.folderId != null; @@ -44,7 +42,7 @@ export class FolderAddEditComponent implements OnInit { async submit(): Promise { if (this.folder.name == null || this.folder.name === '') { - this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'), + this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), this.i18nService.t('nameRequired')); return false; } @@ -54,7 +52,7 @@ export class FolderAddEditComponent implements OnInit { this.formPromise = this.folderService.saveWithServer(folder); await this.formPromise; this.analytics.eventTrack.next({ action: this.editMode ? 'Edited Folder' : 'Added Folder' }); - this.toasterService.popAsync('success', null, + this.platformUtilsService.showToast('success', null, this.i18nService.t(this.editMode ? 'editedFolder' : 'addedFolder')); this.onSavedFolder.emit(this.folder); return true; @@ -75,7 +73,7 @@ export class FolderAddEditComponent implements OnInit { this.deletePromise = this.folderService.deleteWithServer(this.folder.id); await this.deletePromise; this.analytics.eventTrack.next({ action: 'Deleted Folder' }); - this.toasterService.popAsync('success', null, this.i18nService.t('deletedFolder')); + this.platformUtilsService.showToast('success', null, this.i18nService.t('deletedFolder')); this.onDeletedFolder.emit(this.folder); } catch { } diff --git a/src/angular/components/hint.component.ts b/src/angular/components/hint.component.ts index be8a8ec8e4..3726d48566 100644 --- a/src/angular/components/hint.component.ts +++ b/src/angular/components/hint.component.ts @@ -1,12 +1,12 @@ import { Router } from '@angular/router'; -import { ToasterService } from 'angular2-toaster'; import { Angulartics2 } from 'angulartics2'; import { PasswordHintRequest } from '../../models/request/passwordHintRequest'; import { ApiService } from '../../abstractions/api.service'; import { I18nService } from '../../abstractions/i18n.service'; +import { PlatformUtilsService } from '../../abstractions/platformUtils.service'; export class HintComponent { email: string = ''; @@ -15,17 +15,17 @@ export class HintComponent { protected successRoute = 'login'; constructor(protected router: Router, protected analytics: Angulartics2, - protected toasterService: ToasterService, protected i18nService: I18nService, - protected apiService: ApiService) { } + protected i18nService: I18nService, protected apiService: ApiService, + protected platformUtilsService: PlatformUtilsService) { } async submit() { if (this.email == null || this.email === '') { - this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'), + this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), this.i18nService.t('emailRequired')); return; } if (this.email.indexOf('@') === -1) { - this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'), + this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), this.i18nService.t('invalidEmail')); return; } @@ -34,7 +34,7 @@ export class HintComponent { this.formPromise = this.apiService.postPasswordHint(new PasswordHintRequest(this.email)); await this.formPromise; this.analytics.eventTrack.next({ action: 'Requested Hint' }); - this.toasterService.popAsync('success', null, this.i18nService.t('masterPassSent')); + this.platformUtilsService.showToast('success', null, this.i18nService.t('masterPassSent')); this.router.navigate([this.successRoute]); } catch { } } diff --git a/src/angular/components/lock.component.ts b/src/angular/components/lock.component.ts index 695fa3679b..31f7c86cee 100644 --- a/src/angular/components/lock.component.ts +++ b/src/angular/components/lock.component.ts @@ -1,6 +1,5 @@ import { Router } from '@angular/router'; -import { ToasterService } from 'angular2-toaster'; import { Angulartics2 } from 'angulartics2'; import { CryptoService } from '../../abstractions/crypto.service'; @@ -16,13 +15,13 @@ export class LockComponent { protected successRoute: string = 'vault'; constructor(protected router: Router, protected analytics: Angulartics2, - protected toasterService: ToasterService, protected i18nService: I18nService, + protected i18nService: I18nService, protected platformUtilsService: PlatformUtilsService, protected messagingService: MessagingService, protected userService: UserService, protected cryptoService: CryptoService) { } async submit() { if (this.masterPassword == null || this.masterPassword === '') { - this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'), + this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), this.i18nService.t('masterPassRequired')); return; } @@ -39,7 +38,7 @@ export class LockComponent { this.messagingService.send('unlocked'); this.router.navigate([this.successRoute]); } else { - this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'), + this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), this.i18nService.t('invalidMasterPassword')); } } diff --git a/src/angular/components/login.component.ts b/src/angular/components/login.component.ts index 9e5557f9c3..105d24d7de 100644 --- a/src/angular/components/login.component.ts +++ b/src/angular/components/login.component.ts @@ -4,13 +4,13 @@ import { } from '@angular/core'; import { Router } from '@angular/router'; -import { ToasterService } from 'angular2-toaster'; import { Angulartics2 } from 'angulartics2'; import { AuthResult } from '../../models/domain/authResult'; import { AuthService } from '../../abstractions/auth.service'; import { I18nService } from '../../abstractions/i18n.service'; +import { PlatformUtilsService } from '../../abstractions/platformUtils.service'; import { StorageService } from '../../abstractions/storage.service'; import { Utils } from '../../misc/utils'; @@ -34,7 +34,7 @@ export class LoginComponent implements OnInit { protected successRoute = 'vault'; constructor(protected authService: AuthService, protected router: Router, - protected analytics: Angulartics2, protected toasterService: ToasterService, + protected analytics: Angulartics2, protected platformUtilsService: PlatformUtilsService, protected i18nService: I18nService, private storageService: StorageService) { } async ngOnInit() { @@ -55,17 +55,17 @@ export class LoginComponent implements OnInit { async submit() { if (this.email == null || this.email === '') { - this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'), + this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), this.i18nService.t('emailRequired')); return; } if (this.email.indexOf('@') === -1) { - this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'), + this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), this.i18nService.t('invalidEmail')); return; } if (this.masterPassword == null || this.masterPassword === '') { - this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'), + this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), this.i18nService.t('masterPassRequired')); return; } diff --git a/src/angular/components/password-generator-history.component.ts b/src/angular/components/password-generator-history.component.ts index 45c1006992..ae3915269a 100644 --- a/src/angular/components/password-generator-history.component.ts +++ b/src/angular/components/password-generator-history.component.ts @@ -1,4 +1,3 @@ -import { ToasterService } from 'angular2-toaster'; import { Angulartics2 } from 'angulartics2'; import { OnInit } from '@angular/core'; @@ -14,7 +13,7 @@ export class PasswordGeneratorHistoryComponent implements OnInit { constructor(protected passwordGenerationService: PasswordGenerationService, protected analytics: Angulartics2, protected platformUtilsService: PlatformUtilsService, protected i18nService: I18nService, - protected toasterService: ToasterService, private win: Window) { } + private win: Window) { } async ngOnInit() { this.history = await this.passwordGenerationService.getHistory(); @@ -29,6 +28,7 @@ export class PasswordGeneratorHistoryComponent implements OnInit { this.analytics.eventTrack.next({ action: 'Copied Historical Password' }); const copyOptions = this.win != null ? { window: this.win } : null; this.platformUtilsService.copyToClipboard(password, copyOptions); - this.toasterService.popAsync('info', null, this.i18nService.t('valueCopied', this.i18nService.t('password'))); + this.platformUtilsService.showToast('info', null, + this.i18nService.t('valueCopied', this.i18nService.t('password'))); } } diff --git a/src/angular/components/password-generator.component.ts b/src/angular/components/password-generator.component.ts index c6cd72fb6d..600791c84a 100644 --- a/src/angular/components/password-generator.component.ts +++ b/src/angular/components/password-generator.component.ts @@ -1,4 +1,3 @@ -import { ToasterService } from 'angular2-toaster'; import { Angulartics2 } from 'angulartics2'; import { @@ -23,7 +22,7 @@ export class PasswordGeneratorComponent implements OnInit { constructor(protected passwordGenerationService: PasswordGenerationService, protected analytics: Angulartics2, protected platformUtilsService: PlatformUtilsService, protected i18nService: I18nService, - protected toasterService: ToasterService, private win: Window) { } + private win: Window) { } async ngOnInit() { this.options = await this.passwordGenerationService.getOptions(); @@ -63,7 +62,8 @@ export class PasswordGeneratorComponent implements OnInit { this.analytics.eventTrack.next({ action: 'Copied Generated Password' }); const copyOptions = this.win != null ? { window: this.win } : null; this.platformUtilsService.copyToClipboard(this.password, copyOptions); - this.toasterService.popAsync('info', null, this.i18nService.t('valueCopied', this.i18nService.t('password'))); + this.platformUtilsService.showToast('info', null, + this.i18nService.t('valueCopied', this.i18nService.t('password'))); } select() { diff --git a/src/angular/components/password-history.component.ts b/src/angular/components/password-history.component.ts index b847f9ea33..e46e4ce0d9 100644 --- a/src/angular/components/password-history.component.ts +++ b/src/angular/components/password-history.component.ts @@ -1,4 +1,3 @@ -import { ToasterService } from 'angular2-toaster'; import { Angulartics2 } from 'angulartics2'; import { OnInit } from '@angular/core'; @@ -15,7 +14,7 @@ export class PasswordHistoryComponent implements OnInit { constructor(protected cipherService: CipherService, protected analytics: Angulartics2, protected platformUtilsService: PlatformUtilsService, protected i18nService: I18nService, - protected toasterService: ToasterService, private win: Window) { } + private win: Window) { } async ngOnInit() { const cipher = await this.cipherService.get(this.cipherId); @@ -27,6 +26,7 @@ export class PasswordHistoryComponent implements OnInit { this.analytics.eventTrack.next({ action: 'Copied Password History' }); const copyOptions = this.win != null ? { window: this.win } : null; this.platformUtilsService.copyToClipboard(password, copyOptions); - this.toasterService.popAsync('info', null, this.i18nService.t('valueCopied', this.i18nService.t('password'))); + this.platformUtilsService.showToast('info', null, + this.i18nService.t('valueCopied', this.i18nService.t('password'))); } } diff --git a/src/angular/components/premium.component.ts b/src/angular/components/premium.component.ts index 4c3adeb536..a6981c80d9 100644 --- a/src/angular/components/premium.component.ts +++ b/src/angular/components/premium.component.ts @@ -1,6 +1,5 @@ import { OnInit } from '@angular/core'; -import { ToasterService } from 'angular2-toaster'; import { Angulartics2 } from 'angulartics2'; import { ApiService } from '../../abstractions/api.service'; @@ -13,7 +12,7 @@ export class PremiumComponent implements OnInit { price: number = 10; refreshPromise: Promise; - constructor(protected analytics: Angulartics2, protected toasterService: ToasterService, + constructor(protected analytics: Angulartics2, protected i18nService: I18nService, protected platformUtilsService: PlatformUtilsService, protected tokenService: TokenService, protected apiService: ApiService) { } @@ -25,7 +24,7 @@ export class PremiumComponent implements OnInit { try { this.refreshPromise = this.apiService.refreshIdentityToken(); await this.refreshPromise; - this.toasterService.popAsync('success', null, this.i18nService.t('refreshComplete')); + this.platformUtilsService.showToast('success', null, this.i18nService.t('refreshComplete')); this.isPremium = this.tokenService.getPremium(); } catch { } } diff --git a/src/angular/components/register.component.ts b/src/angular/components/register.component.ts index f30e8bff55..fe9a747981 100644 --- a/src/angular/components/register.component.ts +++ b/src/angular/components/register.component.ts @@ -1,6 +1,5 @@ import { Router } from '@angular/router'; -import { ToasterService } from 'angular2-toaster'; import { Angulartics2 } from 'angulartics2'; import { KeysRequest } from '../../models/request/keysRequest'; @@ -27,34 +26,34 @@ export class RegisterComponent { protected successRoute = 'login'; constructor(protected authService: AuthService, protected router: Router, - protected analytics: Angulartics2, protected toasterService: ToasterService, + protected analytics: Angulartics2, protected i18nService: I18nService, protected cryptoService: CryptoService, protected apiService: ApiService, protected stateService: StateService, protected platformUtilsService: PlatformUtilsService) { } async submit() { if (this.email == null || this.email === '') { - this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'), + this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), this.i18nService.t('emailRequired')); return; } if (this.email.indexOf('@') === -1) { - this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'), + this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), this.i18nService.t('invalidEmail')); return; } if (this.masterPassword == null || this.masterPassword === '') { - this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'), + this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), this.i18nService.t('masterPassRequired')); return; } if (this.masterPassword.length < 8) { - this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'), + this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), this.i18nService.t('masterPassLength')); return; } if (this.masterPassword !== this.confirmMasterPassword) { - this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'), + this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), this.i18nService.t('masterPassDoesntMatch')); return; } @@ -81,7 +80,7 @@ export class RegisterComponent { this.formPromise = this.apiService.postRegister(request); await this.formPromise; this.analytics.eventTrack.next({ action: 'Registered' }); - this.toasterService.popAsync('success', null, this.i18nService.t('newAccountCreated')); + this.platformUtilsService.showToast('success', null, this.i18nService.t('newAccountCreated')); this.router.navigate([this.successRoute], { queryParams: { email: this.email } }); } catch { } } diff --git a/src/angular/components/two-factor-options.component.ts b/src/angular/components/two-factor-options.component.ts index 998ad76743..d930b5e9fb 100644 --- a/src/angular/components/two-factor-options.component.ts +++ b/src/angular/components/two-factor-options.component.ts @@ -6,7 +6,6 @@ import { } from '@angular/core'; import { Router } from '@angular/router'; -import { ToasterService } from 'angular2-toaster'; import { Angulartics2 } from 'angulartics2'; import { TwoFactorProviderType } from '../../enums/twoFactorProviderType'; @@ -15,8 +14,6 @@ import { AuthService } from '../../abstractions/auth.service'; import { I18nService } from '../../abstractions/i18n.service'; import { PlatformUtilsService } from '../../abstractions/platformUtils.service'; -import { TwoFactorProviders } from '../../services/auth.service'; - export class TwoFactorOptionsComponent implements OnInit { @Output() onProviderSelected = new EventEmitter(); @Output() onRecoverSelected = new EventEmitter(); @@ -24,7 +21,7 @@ export class TwoFactorOptionsComponent implements OnInit { providers: any[] = []; constructor(protected authService: AuthService, protected router: Router, - protected analytics: Angulartics2, protected toasterService: ToasterService, + protected analytics: Angulartics2, protected i18nService: I18nService, protected platformUtilsService: PlatformUtilsService, protected win: Window) { } diff --git a/src/angular/components/two-factor.component.ts b/src/angular/components/two-factor.component.ts index 705340681e..dc08df0e9a 100644 --- a/src/angular/components/two-factor.component.ts +++ b/src/angular/components/two-factor.component.ts @@ -4,7 +4,6 @@ import { } from '@angular/core'; import { Router } from '@angular/router'; -import { ToasterService } from 'angular2-toaster'; import { Angulartics2 } from 'angulartics2'; import { DeviceType } from '../../enums/deviceType'; @@ -43,7 +42,7 @@ export class TwoFactorComponent implements OnInit, OnDestroy { protected successRoute = 'vault'; constructor(protected authService: AuthService, protected router: Router, - protected analytics: Angulartics2, protected toasterService: ToasterService, + protected analytics: Angulartics2, protected i18nService: I18nService, protected apiService: ApiService, protected platformUtilsService: PlatformUtilsService, protected win: Window, protected environmentService: EnvironmentService) { @@ -69,7 +68,7 @@ export class TwoFactorComponent implements OnInit, OnDestroy { this.token = token; this.submit(); }, (error: string) => { - this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'), error); + this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), error); }, (info: string) => { if (info === 'ready') { this.u2fReady = true; @@ -147,7 +146,7 @@ export class TwoFactorComponent implements OnInit, OnDestroy { async submit() { if (this.token == null || this.token === '') { - this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'), + this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), this.i18nService.t('verificationCodeRequired')); return; } @@ -196,7 +195,7 @@ export class TwoFactorComponent implements OnInit, OnDestroy { this.emailPromise = this.apiService.postTwoFactorEmail(request); await this.emailPromise; if (doToast) { - this.toasterService.popAsync('success', null, + this.platformUtilsService.showToast('success', null, this.i18nService.t('verificationCodeEmailSent', this.twoFactorEmail)); } } catch { } diff --git a/src/angular/components/view.component.ts b/src/angular/components/view.component.ts index 240384d8f5..11c5c16ca6 100644 --- a/src/angular/components/view.component.ts +++ b/src/angular/components/view.component.ts @@ -8,7 +8,6 @@ import { Output, } from '@angular/core'; -import { ToasterService } from 'angular2-toaster'; import { Angulartics2 } from 'angulartics2'; import { CipherType } from '../../enums/cipherType'; @@ -50,7 +49,7 @@ export class ViewComponent implements OnDestroy, OnInit { private totpInterval: any; constructor(protected cipherService: CipherService, protected totpService: TotpService, - protected tokenService: TokenService, protected toasterService: ToasterService, + protected tokenService: TokenService, protected cryptoService: CryptoService, protected platformUtilsService: PlatformUtilsService, protected i18nService: I18nService, protected analytics: Angulartics2, protected auditService: AuditService, protected win: Window, @@ -120,9 +119,10 @@ export class ViewComponent implements OnDestroy, OnInit { const matches = await this.checkPasswordPromise; if (matches > 0) { - this.toasterService.popAsync('warning', null, this.i18nService.t('passwordExposed', matches.toString())); + this.platformUtilsService.showToast('warning', null, + this.i18nService.t('passwordExposed', matches.toString())); } else { - this.toasterService.popAsync('success', null, this.i18nService.t('passwordSafe')); + this.platformUtilsService.showToast('success', null, this.i18nService.t('passwordSafe')); } } @@ -148,7 +148,7 @@ export class ViewComponent implements OnDestroy, OnInit { this.analytics.eventTrack.next({ action: 'Copied ' + aType }); const copyOptions = this.win != null ? { window: this.win } : null; this.platformUtilsService.copyToClipboard(value, copyOptions); - this.toasterService.popAsync('info', null, + this.platformUtilsService.showToast('info', null, this.i18nService.t('valueCopied', this.i18nService.t(typeI18nKey))); } @@ -159,7 +159,7 @@ export class ViewComponent implements OnDestroy, OnInit { } if (this.cipher.organizationId == null && !this.canAccessPremium) { - this.toasterService.popAsync('error', this.i18nService.t('premiumRequired'), + this.platformUtilsService.showToast('error', this.i18nService.t('premiumRequired'), this.i18nService.t('premiumRequiredDesc')); return; } @@ -167,7 +167,7 @@ export class ViewComponent implements OnDestroy, OnInit { a.downloading = true; const response = await fetch(new Request(attachment.url, { cache: 'no-cache' })); if (response.status !== 200) { - this.toasterService.popAsync('error', null, this.i18nService.t('errorOccurred')); + this.platformUtilsService.showToast('error', null, this.i18nService.t('errorOccurred')); a.downloading = false; return; } @@ -178,7 +178,7 @@ export class ViewComponent implements OnDestroy, OnInit { const decBuf = await this.cryptoService.decryptFromBytes(buf, key); this.platformUtilsService.saveFile(this.win, decBuf, null, attachment.fileName); } catch (e) { - this.toasterService.popAsync('error', null, this.i18nService.t('errorOccurred')); + this.platformUtilsService.showToast('error', null, this.i18nService.t('errorOccurred')); } a.downloading = false; diff --git a/src/angular/services/validation.service.ts b/src/angular/services/validation.service.ts index dbef4e9a7e..c5c3e293ae 100644 --- a/src/angular/services/validation.service.ts +++ b/src/angular/services/validation.service.ts @@ -1,21 +1,11 @@ -import { - Injectable, - SecurityContext, -} from '@angular/core'; -import { DomSanitizer } from '@angular/platform-browser'; - -import { - BodyOutputType, - Toast, - ToasterService, -} from 'angular2-toaster'; +import { Injectable } from '@angular/core'; import { I18nService } from '../../abstractions/i18n.service'; +import { PlatformUtilsService } from '../../abstractions/platformUtils.service'; @Injectable() export class ValidationService { - constructor(private toasterService: ToasterService, private i18nService: I18nService, - private sanitizer: DomSanitizer) { } + constructor(private i18nService: I18nService, private platformUtilsService: PlatformUtilsService) { } showError(data: any): string[] { const defaultErrorMessage = this.i18nService.t('unexpectedError'); @@ -45,18 +35,11 @@ export class ValidationService { } if (errors.length === 1) { - this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'), errors[0]); + this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), errors[0]); } else if (errors.length > 1) { - let errorMessage = ''; - errors.forEach((e) => errorMessage += ('

' + this.sanitizer.sanitize(SecurityContext.HTML, e) + '

')); - const toast: Toast = { - type: 'error', - title: this.i18nService.t('errorOccurred'), - body: errorMessage, - bodyOutputType: BodyOutputType.TrustedHtml, + this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), errors, { timeout: 5000 * errors.length, - }; - this.toasterService.popAsync(toast); + }); } return errors; diff --git a/src/electron/services/electronPlatformUtils.service.ts b/src/electron/services/electronPlatformUtils.service.ts index b4c0ed84a7..acf2845fcd 100644 --- a/src/electron/services/electronPlatformUtils.service.ts +++ b/src/electron/services/electronPlatformUtils.service.ts @@ -140,14 +140,15 @@ export class ElectronPlatformUtilsService implements PlatformUtilsService { return true; } - showToast(type: 'error' | 'success' | 'warning' | 'info', title: string, text: string, global?: any): void { - if (global == null && Utils.isBrowser) { - global = window; + showToast(type: 'error' | 'success' | 'warning' | 'info', title: string, text: string | string[], + options?: any): void { + if ((options == null || options.global == null) && Utils.isBrowser) { + options.global = window; } - if (global == null || global.BitwardenToasterService == null) { + if (options.global == null || options.global.BitwardenToasterService == null) { throw new Error('BitwardenToasterService not available on global.'); } - global.BitwardenToasterService.popAsync(type, title, text); + options.global.BitwardenToasterService.popAsync(type, title, text); } showDialog(text: string, title?: string, confirmText?: string, cancelText?: string, type?: string):