diff --git a/jslib b/jslib index 1f0127966e..daa4f6f9a6 160000 --- a/jslib +++ b/jslib @@ -1 +1 @@ -Subproject commit 1f0127966e85aa29f9e50144de9b2a03b00de5d4 +Subproject commit daa4f6f9a6dc84d6cd9a937be6b5392d2cf51eca diff --git a/src/app/accounts/login.component.ts b/src/app/accounts/login.component.ts index 1e34fcd50b..2be0be5bd0 100644 --- a/src/app/accounts/login.component.ts +++ b/src/app/accounts/login.component.ts @@ -1,6 +1,5 @@ import { Component, - ComponentFactoryResolver, NgZone, OnDestroy, ViewChild, @@ -24,9 +23,9 @@ import { SyncService } from 'jslib-common/abstractions/sync.service'; import { UserService } from 'jslib-common/abstractions/user.service'; import { BroadcasterService } from 'jslib-angular/services/broadcaster.service'; +import { ModalService } from 'jslib-angular/services/modal.service'; import { LoginComponent as BaseLoginComponent } from 'jslib-angular/components/login.component'; -import { ModalComponent } from 'jslib-angular/components/modal.component'; const BroadcasterSubscriptionId = 'LoginComponent'; @@ -42,7 +41,7 @@ export class LoginComponent extends BaseLoginComponent implements OnDestroy { private deferFocus: boolean = null; constructor(authService: AuthService, router: Router, i18nService: I18nService, - syncService: SyncService, private componentFactoryResolver: ComponentFactoryResolver, + syncService: SyncService, private modalService: ModalService, platformUtilsService: PlatformUtilsService, stateService: StateService, environmentService: EnvironmentService, passwordGenerationService: PasswordGenerationService, cryptoFunctionService: CryptoFunctionService, storageService: StorageService, @@ -89,20 +88,16 @@ export class LoginComponent extends BaseLoginComponent implements OnDestroy { this.broadcasterService.unsubscribe(BroadcasterSubscriptionId); } - settings() { - const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent); - const modal = this.environmentModal.createComponent(factory).instance; + async settings() { + const [modal, childComponent] = await this.modalService.openViewRef(EnvironmentComponent, this.environmentModal); + modal.onShown.subscribe(() => { this.showingModal = true; }); modal.onClosed.subscribe(() => { this.showingModal = false; - modal.onShown.unsubscribe(); - modal.onClosed.unsubscribe(); }); - const childComponent = modal.show(EnvironmentComponent, - this.environmentModal); childComponent.onSaved.subscribe(() => { modal.close(); }); diff --git a/src/app/accounts/two-factor.component.ts b/src/app/accounts/two-factor.component.ts index f81c39289b..dfefde3bd8 100644 --- a/src/app/accounts/two-factor.component.ts +++ b/src/app/accounts/two-factor.component.ts @@ -1,6 +1,5 @@ import { Component, - ComponentFactoryResolver, ViewChild, ViewContainerRef, } from '@angular/core'; @@ -24,7 +23,8 @@ import { StorageService } from 'jslib-common/abstractions/storage.service'; import { SyncService } from 'jslib-common/abstractions/sync.service'; import { UserService } from 'jslib-common/abstractions/user.service'; -import { ModalComponent } from 'jslib-angular/components/modal.component'; +import { ModalService } from 'jslib-angular/services/modal.service'; + import { TwoFactorComponent as BaseTwoFactorComponent } from 'jslib-angular/components/two-factor.component'; @Component({ @@ -39,7 +39,7 @@ export class TwoFactorComponent extends BaseTwoFactorComponent { constructor(authService: AuthService, router: Router, i18nService: I18nService, apiService: ApiService, platformUtilsService: PlatformUtilsService, syncService: SyncService, - environmentService: EnvironmentService, private componentFactoryResolver: ComponentFactoryResolver, + environmentService: EnvironmentService, private modalService: ModalService, stateService: StateService, storageService: StorageService, route: ActivatedRoute, private userService: UserService) { super(authService, router, i18nService, apiService, platformUtilsService, window, environmentService, @@ -53,20 +53,16 @@ export class TwoFactorComponent extends BaseTwoFactorComponent { }; } - anotherMethod() { - const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent); - const modal = this.twoFactorOptionsModal.createComponent(factory).instance; + async anotherMethod() { + const [modal, childComponent] = await this.modalService.openViewRef(TwoFactorOptionsComponent, this.twoFactorOptionsModal); + modal.onShown.subscribe(() => { this.showingModal = true; }); modal.onClosed.subscribe(() => { this.showingModal = false; - modal.onShown.unsubscribe(); - modal.onClosed.unsubscribe(); }); - const childComponent = modal.show(TwoFactorOptionsComponent, - this.twoFactorOptionsModal); childComponent.onProviderSelected.subscribe(async (provider: TwoFactorProviderType) => { modal.close(); this.selectedProviderType = provider; diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 7aaa8f798d..f3a4da543b 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -22,8 +22,6 @@ import { PremiumComponent } from './accounts/premium.component'; import { SettingsComponent } from './accounts/settings.component'; import { PasswordGeneratorHistoryComponent } from './vault/password-generator-history.component'; -import { ModalComponent } from 'jslib-angular/components/modal.component'; - import { BroadcasterService } from 'jslib-angular/services/broadcaster.service'; import { AuthService } from 'jslib-common/abstractions/auth.service'; @@ -52,6 +50,8 @@ import { ConstantsService } from 'jslib-common/services/constants.service'; import { CipherType } from 'jslib-common/enums/cipherType'; +import { ModalRef } from 'jslib-angular/components/modal/modal.ref'; +import { ModalService } from 'jslib-angular/services/modal.service'; import { ExportComponent } from './vault/export.component'; import { FolderAddEditComponent } from './vault/folder-add-edit.component'; import { PasswordGeneratorComponent } from './vault/password-generator.component'; @@ -91,7 +91,7 @@ export class AppComponent implements OnInit { }); private lastActivity: number = null; - private modal: ModalComponent = null; + private modal: ModalRef = null; private idleTimer: number = null; private isIdle = false; @@ -108,7 +108,7 @@ export class AppComponent implements OnInit { private searchService: SearchService, private notificationsService: NotificationsService, private platformUtilsService: PlatformUtilsService, private systemService: SystemService, private stateService: StateService, private eventService: EventService, - private policyService: PolicyService) { } + private policyService: PolicyService, private modalService: ModalService) { } ngOnInit() { this.ngZone.runOutsideAngular(() => { @@ -170,10 +170,10 @@ export class AppComponent implements OnInit { case 'syncCompleted': break; case 'openSettings': - this.openModal(SettingsComponent, this.settingsRef); + await this.openModal(SettingsComponent, this.settingsRef); break; case 'openPremium': - this.openModal(PremiumComponent, this.premiumRef); + await this.openModal(PremiumComponent, this.premiumRef); break; case 'showFingerprintPhrase': const fingerprint = await this.cryptoService.getFingerprint( @@ -188,7 +188,7 @@ export class AppComponent implements OnInit { } break; case 'openPasswordHistory': - this.openModal( + await this.openModal( PasswordGeneratorHistoryComponent, this.passwordHistoryRef); break; case 'showToast': @@ -207,7 +207,7 @@ export class AppComponent implements OnInit { this.i18nService.t('premiumRequiredDesc'), this.i18nService.t('premiumRequired'), this.i18nService.t('learnMore'), this.i18nService.t('cancel')); if (premiumConfirmed) { - this.openModal(PremiumComponent, this.premiumRef); + await this.openModal(PremiumComponent, this.premiumRef); } break; case 'emailVerificationRequired': @@ -281,9 +281,8 @@ export class AppComponent implements OnInit { this.modal.close(); } - const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent); - this.modal = this.exportVaultModalRef.createComponent(factory).instance; - const childComponent = this.modal.show(ExportComponent, this.exportVaultModalRef); + const [modal, childComponent] = await this.modalService.openViewRef(ExportComponent, this.exportVaultModalRef); + this.modal = modal; childComponent.onSaved.subscribe(() => { this.modal.close(); @@ -299,10 +298,9 @@ export class AppComponent implements OnInit { this.modal.close(); } - const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent); - this.modal = this.folderAddEditModalRef.createComponent(factory).instance; - const childComponent = this.modal.show( - FolderAddEditComponent, this.folderAddEditModalRef, true, comp => comp.folderId = null); + const [modal, childComponent] = await this.modalService.openViewRef(FolderAddEditComponent, + this.folderAddEditModalRef, comp => comp.folderId = null); + this.modal = modal; childComponent.onSavedFolder.subscribe(async () => { this.modal.close(); @@ -319,10 +317,8 @@ export class AppComponent implements OnInit { this.modal.close(); } - const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent); - this.modal = this.passwordGeneratorModalRef.createComponent(factory).instance; - this.modal.show(PasswordGeneratorComponent, - this.passwordGeneratorModalRef, true, comp => comp.showSelect = false); + [this.modal] = await this.modalService.openViewRef(PasswordGeneratorComponent, this.folderAddEditModalRef, + comp => comp.showSelect = false); this.modal.onClosed.subscribe(() => { this.modal = null; @@ -401,14 +397,12 @@ export class AppComponent implements OnInit { } } - private openModal(type: Type, ref: ViewContainerRef) { + private async openModal(type: Type, ref: ViewContainerRef) { if (this.modal != null) { this.modal.close(); } - const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent); - this.modal = ref.createComponent(factory).instance; - this.modal.show(type, ref); + [this.modal] = await this.modalService.openViewRef(type, ref); this.modal.onClosed.subscribe(() => { this.modal = null; diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 21753882b5..7899e8a209 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -30,7 +30,6 @@ import { UpdateTempPasswordComponent } from './accounts/update-temp-password.com import { CalloutComponent } from 'jslib-angular/components/callout.component'; import { IconComponent } from 'jslib-angular/components/icon.component'; -import { ModalComponent } from 'jslib-angular/components/modal.component'; import { A11yTitleDirective } from 'jslib-angular/directives/a11y-title.directive'; import { ApiActionDirective } from 'jslib-angular/directives/api-action.directive'; @@ -68,6 +67,8 @@ import { SendComponent } from './send/send.component'; import { NavComponent } from './layout/nav.component'; +import { PasswordRepromptComponent } from './components/password-reprompt.component'; + import { registerLocaleData } from '@angular/common'; import localeAf from '@angular/common/locales/af'; import localeAz from '@angular/common/locales/az'; @@ -195,7 +196,6 @@ registerLocaleData(localeZhTw, 'zh-TW'); IconComponent, LockComponent, LoginComponent, - ModalComponent, NavComponent, PasswordGeneratorComponent, PasswordGeneratorHistoryComponent, @@ -219,6 +219,7 @@ registerLocaleData(localeZhTw, 'zh-TW'); UpdateTempPasswordComponent, VaultComponent, ViewComponent, + PasswordRepromptComponent, ], providers: [DatePipe], bootstrap: [AppComponent], diff --git a/src/app/components/password-reprompt.component.html b/src/app/components/password-reprompt.component.html new file mode 100644 index 0000000000..6a5e670dea --- /dev/null +++ b/src/app/components/password-reprompt.component.html @@ -0,0 +1,38 @@ + diff --git a/src/app/components/password-reprompt.component.ts b/src/app/components/password-reprompt.component.ts new file mode 100644 index 0000000000..b3204f9422 --- /dev/null +++ b/src/app/components/password-reprompt.component.ts @@ -0,0 +1,8 @@ +import { Component } from '@angular/core'; + +import { PasswordRepromptComponent as BasePasswordRepromptComponent } from 'jslib-angular/components/password-reprompt.component'; + +@Component({ + templateUrl: 'password-reprompt.component.html', +}) +export class PasswordRepromptComponent extends BasePasswordRepromptComponent {} diff --git a/src/app/services.module.ts b/src/app/services.module.ts index acacb2b88d..1f4c8a5545 100644 --- a/src/app/services.module.ts +++ b/src/app/services.module.ts @@ -7,17 +7,19 @@ import { import { ToasterModule } from 'angular2-toaster'; 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 { ElectronRendererStorageService } from 'jslib-electron/services/electronRendererStorage.service'; -import { ElectronPlatformUtilsService } from '../services/electronPlatformUtils.service'; import { I18nService } from '../services/i18n.service'; import { NativeMessagingService } from '../services/nativeMessaging.service'; +import { PasswordRepromptService } from '../services/passwordReprompt.service'; import { AuthGuardService } from 'jslib-angular/services/auth-guard.service'; import { BroadcasterService } from 'jslib-angular/services/broadcaster.service'; import { LockGuardService } from 'jslib-angular/services/lock-guard.service'; +import { ModalService } from 'jslib-angular/services/modal.service'; import { UnauthGuardService } from 'jslib-angular/services/unauth-guard.service'; import { ValidationService } from 'jslib-angular/services/validation.service'; @@ -36,7 +38,6 @@ import { FileUploadService } from 'jslib-common/services/fileUpload.service'; import { FolderService } from 'jslib-common/services/folder.service'; import { NotificationsService } from 'jslib-common/services/notifications.service'; import { PasswordGenerationService } from 'jslib-common/services/passwordGeneration.service'; -import { PasswordRepromptService } from 'jslib-common/services/passwordReprompt.service'; import { PolicyService } from 'jslib-common/services/policy.service'; import { SearchService } from 'jslib-common/services/search.service'; import { SendService } from 'jslib-common/services/send.service'; @@ -137,7 +138,6 @@ const systemService = new SystemService(storageService, vaultTimeoutService, mes null); const nativeMessagingService = new NativeMessagingService(cryptoFunctionService, cryptoService, platformUtilsService, logService, i18nService, userService, messagingService, vaultTimeoutService, storageService); -const passwordRepromptService = new PasswordRepromptService(i18nService, cryptoService, platformUtilsService); containerService.attachToGlobal(window); @@ -191,6 +191,7 @@ export function initFactory(): Function { AuthGuardService, UnauthGuardService, LockGuardService, + ModalService, { provide: AuditServiceAbstraction, useValue: auditService }, { provide: AuthServiceAbstraction, useValue: authService }, { provide: CipherServiceAbstraction, useValue: cipherService }, @@ -224,7 +225,7 @@ export function initFactory(): Function { { provide: CryptoFunctionServiceAbstraction, useValue: cryptoFunctionService }, { provide: NativeMessagingService, useValue: nativeMessagingService }, { provide: FileUploadServiceAbstraction, useValue: fileUploadService }, - { provide: PasswordRepromptServiceAbstraction, useValue: passwordRepromptService }, + { provide: PasswordRepromptServiceAbstraction, useClass: PasswordRepromptService }, { provide: APP_INITIALIZER, useFactory: initFactory, diff --git a/src/app/vault/vault.component.ts b/src/app/vault/vault.component.ts index 75b7504661..77f17d52e0 100644 --- a/src/app/vault/vault.component.ts +++ b/src/app/vault/vault.component.ts @@ -1,7 +1,6 @@ import { ChangeDetectorRef, Component, - ComponentFactoryResolver, NgZone, OnDestroy, OnInit, @@ -17,8 +16,6 @@ import { ToasterService } from 'angular2-toaster'; import { BroadcasterService } from 'jslib-angular/services/broadcaster.service'; -import { ModalComponent } from 'jslib-angular/components/modal.component'; - import { AddEditComponent } from './add-edit.component'; import { AttachmentsComponent } from './attachments.component'; import { CiphersComponent } from './ciphers.component'; @@ -37,6 +34,9 @@ import { EventType } from 'jslib-common/enums/eventType'; import { CipherView } from 'jslib-common/models/view/cipherView'; import { FolderView } from 'jslib-common/models/view/folderView'; +import { ModalRef } from 'jslib-angular/components/modal/modal.ref'; + +import { ModalService } from 'jslib-angular/services/modal.service'; import { EventService } from 'jslib-common/abstractions/event.service'; import { I18nService } from 'jslib-common/abstractions/i18n.service'; import { MessagingService } from 'jslib-common/abstractions/messaging.service'; @@ -78,15 +78,16 @@ export class VaultComponent implements OnInit, OnDestroy { deleted = false; userHasPremiumAccess = false; - private modal: ModalComponent = null; + private modal: ModalRef = null; constructor(private route: ActivatedRoute, private router: Router, - private componentFactoryResolver: ComponentFactoryResolver, private i18nService: I18nService, + private i18nService: I18nService, private modalService: ModalService, private broadcasterService: BroadcasterService, private changeDetectorRef: ChangeDetectorRef, private ngZone: NgZone, private syncService: SyncService, private toasterService: ToasterService, private messagingService: MessagingService, private platformUtilsService: PlatformUtilsService, private eventService: EventService, - private totpService: TotpService, private userService: UserService, private passwordRepromptService: PasswordRepromptService) { } + private totpService: TotpService, private userService: UserService, + private passwordRepromptService: PasswordRepromptService) { } async ngOnInit() { this.userHasPremiumAccess = await this.userService.canAccessPremium(); @@ -422,15 +423,15 @@ export class VaultComponent implements OnInit, OnDestroy { await this.ciphersComponent.refresh(); } - editCipherAttachments(cipher: CipherView) { + async editCipherAttachments(cipher: CipherView) { if (this.modal != null) { this.modal.close(); } - const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent); - this.modal = this.attachmentsModalRef.createComponent(factory).instance; - const childComponent = this.modal.show(AttachmentsComponent, this.attachmentsModalRef, - true, comp => comp.cipherId = cipher.id); + const [modal, childComponent] = await this.modalService.openViewRef(AttachmentsComponent, this.attachmentsModalRef, + comp => comp.cipherId = cipher.id); + this.modal = modal; + let madeAttachmentChanges = false; childComponent.onUploadedAttachment.subscribe(() => madeAttachmentChanges = true); childComponent.onDeletedAttachment.subscribe(() => madeAttachmentChanges = true); @@ -444,15 +445,14 @@ export class VaultComponent implements OnInit, OnDestroy { }); } - shareCipher(cipher: CipherView) { + async shareCipher(cipher: CipherView) { if (this.modal != null) { this.modal.close(); } - const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent); - this.modal = this.shareModalRef.createComponent(factory).instance; - const childComponent = this.modal.show(ShareComponent, this.shareModalRef, true, + const [modal, childComponent] = await this.modalService.openViewRef(ShareComponent, this.shareModalRef, comp => comp.cipherId = cipher.id); + this.modal = modal; childComponent.onSharedCipher.subscribe(async () => { this.modal.close(); @@ -464,15 +464,14 @@ export class VaultComponent implements OnInit, OnDestroy { }); } - cipherCollections(cipher: CipherView) { + async cipherCollections(cipher: CipherView) { if (this.modal != null) { this.modal.close(); } - const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent); - this.modal = this.collectionsModalRef.createComponent(factory).instance; - const childComponent = this.modal.show(CollectionsComponent, this.collectionsModalRef, - true, comp => comp.cipherId = cipher.id); + const [modal, childComponent] = await this.modalService.openViewRef(CollectionsComponent, this.collectionsModalRef, + comp => comp.cipherId = cipher.id); + this.modal = modal; childComponent.onSavedCollections.subscribe(() => { this.modal.close(); @@ -483,15 +482,14 @@ export class VaultComponent implements OnInit, OnDestroy { }); } - viewCipherPasswordHistory(cipher: CipherView) { + async viewCipherPasswordHistory(cipher: CipherView) { if (this.modal != null) { this.modal.close(); } - const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent); - this.modal = this.passwordHistoryModalRef.createComponent(factory).instance; - this.modal.show(PasswordHistoryComponent, - this.passwordHistoryModalRef, true, comp => comp.cipherId = cipher.id); + [this.modal] = await this.modalService.openViewRef(PasswordHistoryComponent, this.passwordHistoryModalRef, + comp => comp.cipherId = cipher.id); + this.modal.onClosed.subscribe(async () => { this.modal = null; }); @@ -559,10 +557,9 @@ export class VaultComponent implements OnInit, OnDestroy { this.modal.close(); } - const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent); - this.modal = this.passwordGeneratorModalRef.createComponent(factory).instance; - const childComponent = this.modal.show(PasswordGeneratorComponent, - this.passwordGeneratorModalRef, true, comp => comp.showSelect = showSelect); + const [modal, childComponent] = await this.modalService.openViewRef(PasswordGeneratorComponent, this.passwordGeneratorModalRef, + comp => comp.showSelect = showSelect); + this.modal = modal; childComponent.onSelected.subscribe((password: string) => { this.modal.close(); @@ -587,10 +584,9 @@ export class VaultComponent implements OnInit, OnDestroy { this.modal.close(); } - const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent); - this.modal = this.folderAddEditModalRef.createComponent(factory).instance; - const childComponent = this.modal.show( - FolderAddEditComponent, this.folderAddEditModalRef, true, comp => comp.folderId = folderId); + const [modal, childComponent] = await this.modalService.openViewRef(FolderAddEditComponent, this.folderAddEditModalRef, + comp => comp.folderId = folderId); + this.modal = modal; childComponent.onSavedFolder.subscribe(async (folder: FolderView) => { this.modal.close(); diff --git a/src/scss/misc.scss b/src/scss/misc.scss index b3f94ade31..de680bd3a2 100644 --- a/src/scss/misc.scss +++ b/src/scss/misc.scss @@ -415,3 +415,8 @@ app-root > #loading { margin: 0; } } + +.password-reprompt { + text-align: left; + margin-top: 15px; +} diff --git a/src/services/electronPlatformUtils.service.ts b/src/services/electronPlatformUtils.service.ts deleted file mode 100644 index 0933273fe2..0000000000 --- a/src/services/electronPlatformUtils.service.ts +++ /dev/null @@ -1,42 +0,0 @@ -import Swal from 'sweetalert2'; - -import { I18nService } from 'jslib-common/abstractions/i18n.service'; -import { MessagingService } from 'jslib-common/abstractions/messaging.service'; -import { StorageService } from 'jslib-common/abstractions/storage.service'; -import { - ElectronPlatformUtilsService as BaseElectronPlatformUtilsService -} from 'jslib-electron/services/electronPlatformUtils.service'; - -export class ElectronPlatformUtilsService extends BaseElectronPlatformUtilsService { - - constructor(i18nService: I18nService, messagingService: MessagingService, - isDesktopApp: boolean, storageService: StorageService) { - super(i18nService, messagingService, isDesktopApp, storageService); - } - - async showPasswordDialog(title: string, body: string, passwordValidation: (value: string) => Promise): - Promise { - const result = await Swal.fire({ - heightAuto: false, - titleText: title, - input: 'password', - text: body, - confirmButtonText: this.i18nService.t('ok'), - showCancelButton: true, - cancelButtonText: this.i18nService.t('cancel'), - inputAttributes: { - autocapitalize: 'off', - autocorrect: 'off', - }, - inputValidator: async (value: string): Promise => { - if (await passwordValidation(value)) { - return false; - } - - return this.i18nService.t('invalidMasterPassword'); - }, - }); - - return result.isConfirmed; - } -} diff --git a/src/services/passwordReprompt.service.ts b/src/services/passwordReprompt.service.ts new file mode 100644 index 0000000000..58ea4fb743 --- /dev/null +++ b/src/services/passwordReprompt.service.ts @@ -0,0 +1,9 @@ +import { Injectable } from '@angular/core'; + +import { PasswordRepromptService as BasePasswordRepromptService } from 'jslib-angular/services/passwordReprompt.service'; +import { PasswordRepromptComponent } from '../app/components/password-reprompt.component'; + +@Injectable() +export class PasswordRepromptService extends BasePasswordRepromptService { + component = PasswordRepromptComponent; +}