mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-24 12:06:15 +01:00
Add password show/hide to reprompt (#959)
This commit is contained in:
parent
5b4931e260
commit
2ba8925b81
2
jslib
2
jslib
@ -1 +1 @@
|
|||||||
Subproject commit 1f0127966e85aa29f9e50144de9b2a03b00de5d4
|
Subproject commit daa4f6f9a6dc84d6cd9a937be6b5392d2cf51eca
|
@ -1,6 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
Component,
|
Component,
|
||||||
ComponentFactoryResolver,
|
|
||||||
NgZone,
|
NgZone,
|
||||||
OnDestroy,
|
OnDestroy,
|
||||||
ViewChild,
|
ViewChild,
|
||||||
@ -24,9 +23,9 @@ import { SyncService } from 'jslib-common/abstractions/sync.service';
|
|||||||
import { UserService } from 'jslib-common/abstractions/user.service';
|
import { UserService } from 'jslib-common/abstractions/user.service';
|
||||||
|
|
||||||
import { BroadcasterService } from 'jslib-angular/services/broadcaster.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 { LoginComponent as BaseLoginComponent } from 'jslib-angular/components/login.component';
|
||||||
import { ModalComponent } from 'jslib-angular/components/modal.component';
|
|
||||||
|
|
||||||
const BroadcasterSubscriptionId = 'LoginComponent';
|
const BroadcasterSubscriptionId = 'LoginComponent';
|
||||||
|
|
||||||
@ -42,7 +41,7 @@ export class LoginComponent extends BaseLoginComponent implements OnDestroy {
|
|||||||
private deferFocus: boolean = null;
|
private deferFocus: boolean = null;
|
||||||
|
|
||||||
constructor(authService: AuthService, router: Router, i18nService: I18nService,
|
constructor(authService: AuthService, router: Router, i18nService: I18nService,
|
||||||
syncService: SyncService, private componentFactoryResolver: ComponentFactoryResolver,
|
syncService: SyncService, private modalService: ModalService,
|
||||||
platformUtilsService: PlatformUtilsService, stateService: StateService,
|
platformUtilsService: PlatformUtilsService, stateService: StateService,
|
||||||
environmentService: EnvironmentService, passwordGenerationService: PasswordGenerationService,
|
environmentService: EnvironmentService, passwordGenerationService: PasswordGenerationService,
|
||||||
cryptoFunctionService: CryptoFunctionService, storageService: StorageService,
|
cryptoFunctionService: CryptoFunctionService, storageService: StorageService,
|
||||||
@ -89,20 +88,16 @@ export class LoginComponent extends BaseLoginComponent implements OnDestroy {
|
|||||||
this.broadcasterService.unsubscribe(BroadcasterSubscriptionId);
|
this.broadcasterService.unsubscribe(BroadcasterSubscriptionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
settings() {
|
async settings() {
|
||||||
const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent);
|
const [modal, childComponent] = await this.modalService.openViewRef(EnvironmentComponent, this.environmentModal);
|
||||||
const modal = this.environmentModal.createComponent(factory).instance;
|
|
||||||
modal.onShown.subscribe(() => {
|
modal.onShown.subscribe(() => {
|
||||||
this.showingModal = true;
|
this.showingModal = true;
|
||||||
});
|
});
|
||||||
modal.onClosed.subscribe(() => {
|
modal.onClosed.subscribe(() => {
|
||||||
this.showingModal = false;
|
this.showingModal = false;
|
||||||
modal.onShown.unsubscribe();
|
|
||||||
modal.onClosed.unsubscribe();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const childComponent = modal.show<EnvironmentComponent>(EnvironmentComponent,
|
|
||||||
this.environmentModal);
|
|
||||||
childComponent.onSaved.subscribe(() => {
|
childComponent.onSaved.subscribe(() => {
|
||||||
modal.close();
|
modal.close();
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
Component,
|
Component,
|
||||||
ComponentFactoryResolver,
|
|
||||||
ViewChild,
|
ViewChild,
|
||||||
ViewContainerRef,
|
ViewContainerRef,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
@ -24,7 +23,8 @@ import { StorageService } from 'jslib-common/abstractions/storage.service';
|
|||||||
import { SyncService } from 'jslib-common/abstractions/sync.service';
|
import { SyncService } from 'jslib-common/abstractions/sync.service';
|
||||||
import { UserService } from 'jslib-common/abstractions/user.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';
|
import { TwoFactorComponent as BaseTwoFactorComponent } from 'jslib-angular/components/two-factor.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -39,7 +39,7 @@ export class TwoFactorComponent extends BaseTwoFactorComponent {
|
|||||||
constructor(authService: AuthService, router: Router,
|
constructor(authService: AuthService, router: Router,
|
||||||
i18nService: I18nService, apiService: ApiService,
|
i18nService: I18nService, apiService: ApiService,
|
||||||
platformUtilsService: PlatformUtilsService, syncService: SyncService,
|
platformUtilsService: PlatformUtilsService, syncService: SyncService,
|
||||||
environmentService: EnvironmentService, private componentFactoryResolver: ComponentFactoryResolver,
|
environmentService: EnvironmentService, private modalService: ModalService,
|
||||||
stateService: StateService, storageService: StorageService, route: ActivatedRoute,
|
stateService: StateService, storageService: StorageService, route: ActivatedRoute,
|
||||||
private userService: UserService) {
|
private userService: UserService) {
|
||||||
super(authService, router, i18nService, apiService, platformUtilsService, window, environmentService,
|
super(authService, router, i18nService, apiService, platformUtilsService, window, environmentService,
|
||||||
@ -53,20 +53,16 @@ export class TwoFactorComponent extends BaseTwoFactorComponent {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
anotherMethod() {
|
async anotherMethod() {
|
||||||
const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent);
|
const [modal, childComponent] = await this.modalService.openViewRef(TwoFactorOptionsComponent, this.twoFactorOptionsModal);
|
||||||
const modal = this.twoFactorOptionsModal.createComponent(factory).instance;
|
|
||||||
modal.onShown.subscribe(() => {
|
modal.onShown.subscribe(() => {
|
||||||
this.showingModal = true;
|
this.showingModal = true;
|
||||||
});
|
});
|
||||||
modal.onClosed.subscribe(() => {
|
modal.onClosed.subscribe(() => {
|
||||||
this.showingModal = false;
|
this.showingModal = false;
|
||||||
modal.onShown.unsubscribe();
|
|
||||||
modal.onClosed.unsubscribe();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const childComponent = modal.show<TwoFactorOptionsComponent>(TwoFactorOptionsComponent,
|
|
||||||
this.twoFactorOptionsModal);
|
|
||||||
childComponent.onProviderSelected.subscribe(async (provider: TwoFactorProviderType) => {
|
childComponent.onProviderSelected.subscribe(async (provider: TwoFactorProviderType) => {
|
||||||
modal.close();
|
modal.close();
|
||||||
this.selectedProviderType = provider;
|
this.selectedProviderType = provider;
|
||||||
|
@ -22,8 +22,6 @@ import { PremiumComponent } from './accounts/premium.component';
|
|||||||
import { SettingsComponent } from './accounts/settings.component';
|
import { SettingsComponent } from './accounts/settings.component';
|
||||||
import { PasswordGeneratorHistoryComponent } from './vault/password-generator-history.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 { BroadcasterService } from 'jslib-angular/services/broadcaster.service';
|
||||||
|
|
||||||
import { AuthService } from 'jslib-common/abstractions/auth.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 { 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 { ExportComponent } from './vault/export.component';
|
||||||
import { FolderAddEditComponent } from './vault/folder-add-edit.component';
|
import { FolderAddEditComponent } from './vault/folder-add-edit.component';
|
||||||
import { PasswordGeneratorComponent } from './vault/password-generator.component';
|
import { PasswordGeneratorComponent } from './vault/password-generator.component';
|
||||||
@ -91,7 +91,7 @@ export class AppComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
|
|
||||||
private lastActivity: number = null;
|
private lastActivity: number = null;
|
||||||
private modal: ModalComponent = null;
|
private modal: ModalRef = null;
|
||||||
private idleTimer: number = null;
|
private idleTimer: number = null;
|
||||||
private isIdle = false;
|
private isIdle = false;
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ export class AppComponent implements OnInit {
|
|||||||
private searchService: SearchService, private notificationsService: NotificationsService,
|
private searchService: SearchService, private notificationsService: NotificationsService,
|
||||||
private platformUtilsService: PlatformUtilsService, private systemService: SystemService,
|
private platformUtilsService: PlatformUtilsService, private systemService: SystemService,
|
||||||
private stateService: StateService, private eventService: EventService,
|
private stateService: StateService, private eventService: EventService,
|
||||||
private policyService: PolicyService) { }
|
private policyService: PolicyService, private modalService: ModalService) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.ngZone.runOutsideAngular(() => {
|
this.ngZone.runOutsideAngular(() => {
|
||||||
@ -170,10 +170,10 @@ export class AppComponent implements OnInit {
|
|||||||
case 'syncCompleted':
|
case 'syncCompleted':
|
||||||
break;
|
break;
|
||||||
case 'openSettings':
|
case 'openSettings':
|
||||||
this.openModal<SettingsComponent>(SettingsComponent, this.settingsRef);
|
await this.openModal<SettingsComponent>(SettingsComponent, this.settingsRef);
|
||||||
break;
|
break;
|
||||||
case 'openPremium':
|
case 'openPremium':
|
||||||
this.openModal<PremiumComponent>(PremiumComponent, this.premiumRef);
|
await this.openModal<PremiumComponent>(PremiumComponent, this.premiumRef);
|
||||||
break;
|
break;
|
||||||
case 'showFingerprintPhrase':
|
case 'showFingerprintPhrase':
|
||||||
const fingerprint = await this.cryptoService.getFingerprint(
|
const fingerprint = await this.cryptoService.getFingerprint(
|
||||||
@ -188,7 +188,7 @@ export class AppComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'openPasswordHistory':
|
case 'openPasswordHistory':
|
||||||
this.openModal<PasswordGeneratorHistoryComponent>(
|
await this.openModal<PasswordGeneratorHistoryComponent>(
|
||||||
PasswordGeneratorHistoryComponent, this.passwordHistoryRef);
|
PasswordGeneratorHistoryComponent, this.passwordHistoryRef);
|
||||||
break;
|
break;
|
||||||
case 'showToast':
|
case 'showToast':
|
||||||
@ -207,7 +207,7 @@ export class AppComponent implements OnInit {
|
|||||||
this.i18nService.t('premiumRequiredDesc'), this.i18nService.t('premiumRequired'),
|
this.i18nService.t('premiumRequiredDesc'), this.i18nService.t('premiumRequired'),
|
||||||
this.i18nService.t('learnMore'), this.i18nService.t('cancel'));
|
this.i18nService.t('learnMore'), this.i18nService.t('cancel'));
|
||||||
if (premiumConfirmed) {
|
if (premiumConfirmed) {
|
||||||
this.openModal<PremiumComponent>(PremiumComponent, this.premiumRef);
|
await this.openModal<PremiumComponent>(PremiumComponent, this.premiumRef);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'emailVerificationRequired':
|
case 'emailVerificationRequired':
|
||||||
@ -281,9 +281,8 @@ export class AppComponent implements OnInit {
|
|||||||
this.modal.close();
|
this.modal.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent);
|
const [modal, childComponent] = await this.modalService.openViewRef(ExportComponent, this.exportVaultModalRef);
|
||||||
this.modal = this.exportVaultModalRef.createComponent(factory).instance;
|
this.modal = modal;
|
||||||
const childComponent = this.modal.show<ExportComponent>(ExportComponent, this.exportVaultModalRef);
|
|
||||||
|
|
||||||
childComponent.onSaved.subscribe(() => {
|
childComponent.onSaved.subscribe(() => {
|
||||||
this.modal.close();
|
this.modal.close();
|
||||||
@ -299,10 +298,9 @@ export class AppComponent implements OnInit {
|
|||||||
this.modal.close();
|
this.modal.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent);
|
const [modal, childComponent] = await this.modalService.openViewRef(FolderAddEditComponent,
|
||||||
this.modal = this.folderAddEditModalRef.createComponent(factory).instance;
|
this.folderAddEditModalRef, comp => comp.folderId = null);
|
||||||
const childComponent = this.modal.show<FolderAddEditComponent>(
|
this.modal = modal;
|
||||||
FolderAddEditComponent, this.folderAddEditModalRef, true, comp => comp.folderId = null);
|
|
||||||
|
|
||||||
childComponent.onSavedFolder.subscribe(async () => {
|
childComponent.onSavedFolder.subscribe(async () => {
|
||||||
this.modal.close();
|
this.modal.close();
|
||||||
@ -319,10 +317,8 @@ export class AppComponent implements OnInit {
|
|||||||
this.modal.close();
|
this.modal.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent);
|
[this.modal] = await this.modalService.openViewRef(PasswordGeneratorComponent, this.folderAddEditModalRef,
|
||||||
this.modal = this.passwordGeneratorModalRef.createComponent(factory).instance;
|
comp => comp.showSelect = false);
|
||||||
this.modal.show<PasswordGeneratorComponent>(PasswordGeneratorComponent,
|
|
||||||
this.passwordGeneratorModalRef, true, comp => comp.showSelect = false);
|
|
||||||
|
|
||||||
this.modal.onClosed.subscribe(() => {
|
this.modal.onClosed.subscribe(() => {
|
||||||
this.modal = null;
|
this.modal = null;
|
||||||
@ -401,14 +397,12 @@ export class AppComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private openModal<T>(type: Type<T>, ref: ViewContainerRef) {
|
private async openModal<T>(type: Type<T>, ref: ViewContainerRef) {
|
||||||
if (this.modal != null) {
|
if (this.modal != null) {
|
||||||
this.modal.close();
|
this.modal.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent);
|
[this.modal] = await this.modalService.openViewRef(type, ref);
|
||||||
this.modal = ref.createComponent(factory).instance;
|
|
||||||
this.modal.show<T>(type, ref);
|
|
||||||
|
|
||||||
this.modal.onClosed.subscribe(() => {
|
this.modal.onClosed.subscribe(() => {
|
||||||
this.modal = null;
|
this.modal = null;
|
||||||
|
@ -30,7 +30,6 @@ import { UpdateTempPasswordComponent } from './accounts/update-temp-password.com
|
|||||||
|
|
||||||
import { CalloutComponent } from 'jslib-angular/components/callout.component';
|
import { CalloutComponent } from 'jslib-angular/components/callout.component';
|
||||||
import { IconComponent } from 'jslib-angular/components/icon.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 { A11yTitleDirective } from 'jslib-angular/directives/a11y-title.directive';
|
||||||
import { ApiActionDirective } from 'jslib-angular/directives/api-action.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 { NavComponent } from './layout/nav.component';
|
||||||
|
|
||||||
|
import { PasswordRepromptComponent } from './components/password-reprompt.component';
|
||||||
|
|
||||||
import { registerLocaleData } from '@angular/common';
|
import { registerLocaleData } from '@angular/common';
|
||||||
import localeAf from '@angular/common/locales/af';
|
import localeAf from '@angular/common/locales/af';
|
||||||
import localeAz from '@angular/common/locales/az';
|
import localeAz from '@angular/common/locales/az';
|
||||||
@ -195,7 +196,6 @@ registerLocaleData(localeZhTw, 'zh-TW');
|
|||||||
IconComponent,
|
IconComponent,
|
||||||
LockComponent,
|
LockComponent,
|
||||||
LoginComponent,
|
LoginComponent,
|
||||||
ModalComponent,
|
|
||||||
NavComponent,
|
NavComponent,
|
||||||
PasswordGeneratorComponent,
|
PasswordGeneratorComponent,
|
||||||
PasswordGeneratorHistoryComponent,
|
PasswordGeneratorHistoryComponent,
|
||||||
@ -219,6 +219,7 @@ registerLocaleData(localeZhTw, 'zh-TW');
|
|||||||
UpdateTempPasswordComponent,
|
UpdateTempPasswordComponent,
|
||||||
VaultComponent,
|
VaultComponent,
|
||||||
ViewComponent,
|
ViewComponent,
|
||||||
|
PasswordRepromptComponent,
|
||||||
],
|
],
|
||||||
providers: [DatePipe],
|
providers: [DatePipe],
|
||||||
bootstrap: [AppComponent],
|
bootstrap: [AppComponent],
|
||||||
|
38
src/app/components/password-reprompt.component.html
Normal file
38
src/app/components/password-reprompt.component.html
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<div class="modal fade" tabindex="-1" role="dialog" aria-modal="true" aria-labelledby="confirmUserTitle">
|
||||||
|
<div class="modal-dialog modal-dialog-scrollable" role="document">
|
||||||
|
<form class="modal-content" #form (ngSubmit)="submit()">
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-header">{{'passwordConfirmation' | i18n}}</div>
|
||||||
|
<div class="box-content">
|
||||||
|
<div class="box-content-row box-content-row-flex" appBoxRow>
|
||||||
|
<div class="row-main">
|
||||||
|
<label for="masterPassword">{{'masterPass' | i18n}}</label>
|
||||||
|
<input id="masterPassword" type="{{showPassword ? 'text' : 'password'}}" name="MasterPassword"
|
||||||
|
class="monospaced" [(ngModel)]="masterPassword" required appAutofocus>
|
||||||
|
</div>
|
||||||
|
<div class="action-buttons">
|
||||||
|
<a class="row-btn" href="#" appStopClick appBlurClick role="button"
|
||||||
|
appA11yTitle="{{'toggleVisibility' | i18n}}" (click)="togglePassword()">
|
||||||
|
<i class="fa fa-lg" aria-hidden="true"
|
||||||
|
[ngClass]="{'fa-eye': !showPassword, 'fa-eye-slash': showPassword}"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="box-footer">
|
||||||
|
{{'passwordConfirmationDesc' | i18n}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="submit" class="btn btn-primary btn-submit" appBlurClick>
|
||||||
|
<span>{{'ok' | i18n}}</span>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal">
|
||||||
|
{{'cancel' | i18n}}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
8
src/app/components/password-reprompt.component.ts
Normal file
8
src/app/components/password-reprompt.component.ts
Normal file
@ -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 {}
|
@ -7,17 +7,19 @@ import {
|
|||||||
import { ToasterModule } from 'angular2-toaster';
|
import { ToasterModule } from 'angular2-toaster';
|
||||||
|
|
||||||
import { ElectronLogService } from 'jslib-electron/services/electronLog.service';
|
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 { ElectronRendererMessagingService } from 'jslib-electron/services/electronRendererMessaging.service';
|
||||||
import { ElectronRendererSecureStorageService } from 'jslib-electron/services/electronRendererSecureStorage.service';
|
import { ElectronRendererSecureStorageService } from 'jslib-electron/services/electronRendererSecureStorage.service';
|
||||||
import { ElectronRendererStorageService } from 'jslib-electron/services/electronRendererStorage.service';
|
import { ElectronRendererStorageService } from 'jslib-electron/services/electronRendererStorage.service';
|
||||||
|
|
||||||
import { ElectronPlatformUtilsService } from '../services/electronPlatformUtils.service';
|
|
||||||
import { I18nService } from '../services/i18n.service';
|
import { I18nService } from '../services/i18n.service';
|
||||||
import { NativeMessagingService } from '../services/nativeMessaging.service';
|
import { NativeMessagingService } from '../services/nativeMessaging.service';
|
||||||
|
import { PasswordRepromptService } from '../services/passwordReprompt.service';
|
||||||
|
|
||||||
import { AuthGuardService } from 'jslib-angular/services/auth-guard.service';
|
import { AuthGuardService } from 'jslib-angular/services/auth-guard.service';
|
||||||
import { BroadcasterService } from 'jslib-angular/services/broadcaster.service';
|
import { BroadcasterService } from 'jslib-angular/services/broadcaster.service';
|
||||||
import { LockGuardService } from 'jslib-angular/services/lock-guard.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 { UnauthGuardService } from 'jslib-angular/services/unauth-guard.service';
|
||||||
import { ValidationService } from 'jslib-angular/services/validation.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 { FolderService } from 'jslib-common/services/folder.service';
|
||||||
import { NotificationsService } from 'jslib-common/services/notifications.service';
|
import { NotificationsService } from 'jslib-common/services/notifications.service';
|
||||||
import { PasswordGenerationService } from 'jslib-common/services/passwordGeneration.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 { PolicyService } from 'jslib-common/services/policy.service';
|
||||||
import { SearchService } from 'jslib-common/services/search.service';
|
import { SearchService } from 'jslib-common/services/search.service';
|
||||||
import { SendService } from 'jslib-common/services/send.service';
|
import { SendService } from 'jslib-common/services/send.service';
|
||||||
@ -137,7 +138,6 @@ const systemService = new SystemService(storageService, vaultTimeoutService, mes
|
|||||||
null);
|
null);
|
||||||
const nativeMessagingService = new NativeMessagingService(cryptoFunctionService, cryptoService, platformUtilsService,
|
const nativeMessagingService = new NativeMessagingService(cryptoFunctionService, cryptoService, platformUtilsService,
|
||||||
logService, i18nService, userService, messagingService, vaultTimeoutService, storageService);
|
logService, i18nService, userService, messagingService, vaultTimeoutService, storageService);
|
||||||
const passwordRepromptService = new PasswordRepromptService(i18nService, cryptoService, platformUtilsService);
|
|
||||||
|
|
||||||
containerService.attachToGlobal(window);
|
containerService.attachToGlobal(window);
|
||||||
|
|
||||||
@ -191,6 +191,7 @@ export function initFactory(): Function {
|
|||||||
AuthGuardService,
|
AuthGuardService,
|
||||||
UnauthGuardService,
|
UnauthGuardService,
|
||||||
LockGuardService,
|
LockGuardService,
|
||||||
|
ModalService,
|
||||||
{ provide: AuditServiceAbstraction, useValue: auditService },
|
{ provide: AuditServiceAbstraction, useValue: auditService },
|
||||||
{ provide: AuthServiceAbstraction, useValue: authService },
|
{ provide: AuthServiceAbstraction, useValue: authService },
|
||||||
{ provide: CipherServiceAbstraction, useValue: cipherService },
|
{ provide: CipherServiceAbstraction, useValue: cipherService },
|
||||||
@ -224,7 +225,7 @@ export function initFactory(): Function {
|
|||||||
{ provide: CryptoFunctionServiceAbstraction, useValue: cryptoFunctionService },
|
{ provide: CryptoFunctionServiceAbstraction, useValue: cryptoFunctionService },
|
||||||
{ provide: NativeMessagingService, useValue: nativeMessagingService },
|
{ provide: NativeMessagingService, useValue: nativeMessagingService },
|
||||||
{ provide: FileUploadServiceAbstraction, useValue: fileUploadService },
|
{ provide: FileUploadServiceAbstraction, useValue: fileUploadService },
|
||||||
{ provide: PasswordRepromptServiceAbstraction, useValue: passwordRepromptService },
|
{ provide: PasswordRepromptServiceAbstraction, useClass: PasswordRepromptService },
|
||||||
{
|
{
|
||||||
provide: APP_INITIALIZER,
|
provide: APP_INITIALIZER,
|
||||||
useFactory: initFactory,
|
useFactory: initFactory,
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
ChangeDetectorRef,
|
ChangeDetectorRef,
|
||||||
Component,
|
Component,
|
||||||
ComponentFactoryResolver,
|
|
||||||
NgZone,
|
NgZone,
|
||||||
OnDestroy,
|
OnDestroy,
|
||||||
OnInit,
|
OnInit,
|
||||||
@ -17,8 +16,6 @@ import { ToasterService } from 'angular2-toaster';
|
|||||||
|
|
||||||
import { BroadcasterService } from 'jslib-angular/services/broadcaster.service';
|
import { BroadcasterService } from 'jslib-angular/services/broadcaster.service';
|
||||||
|
|
||||||
import { ModalComponent } from 'jslib-angular/components/modal.component';
|
|
||||||
|
|
||||||
import { AddEditComponent } from './add-edit.component';
|
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';
|
||||||
@ -37,6 +34,9 @@ import { EventType } from 'jslib-common/enums/eventType';
|
|||||||
import { CipherView } from 'jslib-common/models/view/cipherView';
|
import { CipherView } from 'jslib-common/models/view/cipherView';
|
||||||
import { FolderView } from 'jslib-common/models/view/folderView';
|
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 { EventService } from 'jslib-common/abstractions/event.service';
|
||||||
import { I18nService } from 'jslib-common/abstractions/i18n.service';
|
import { I18nService } from 'jslib-common/abstractions/i18n.service';
|
||||||
import { MessagingService } from 'jslib-common/abstractions/messaging.service';
|
import { MessagingService } from 'jslib-common/abstractions/messaging.service';
|
||||||
@ -78,15 +78,16 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
deleted = false;
|
deleted = false;
|
||||||
userHasPremiumAccess = false;
|
userHasPremiumAccess = false;
|
||||||
|
|
||||||
private modal: ModalComponent = null;
|
private modal: ModalRef = null;
|
||||||
|
|
||||||
constructor(private route: ActivatedRoute, private router: Router,
|
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 broadcasterService: BroadcasterService, private changeDetectorRef: ChangeDetectorRef,
|
||||||
private ngZone: NgZone, private syncService: SyncService,
|
private ngZone: NgZone, private syncService: SyncService,
|
||||||
private toasterService: ToasterService, private messagingService: MessagingService,
|
private toasterService: ToasterService, private messagingService: MessagingService,
|
||||||
private platformUtilsService: PlatformUtilsService, private eventService: EventService,
|
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() {
|
async ngOnInit() {
|
||||||
this.userHasPremiumAccess = await this.userService.canAccessPremium();
|
this.userHasPremiumAccess = await this.userService.canAccessPremium();
|
||||||
@ -422,15 +423,15 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
await this.ciphersComponent.refresh();
|
await this.ciphersComponent.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
editCipherAttachments(cipher: CipherView) {
|
async editCipherAttachments(cipher: CipherView) {
|
||||||
if (this.modal != null) {
|
if (this.modal != null) {
|
||||||
this.modal.close();
|
this.modal.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent);
|
const [modal, childComponent] = await this.modalService.openViewRef(AttachmentsComponent, this.attachmentsModalRef,
|
||||||
this.modal = this.attachmentsModalRef.createComponent(factory).instance;
|
comp => comp.cipherId = cipher.id);
|
||||||
const childComponent = this.modal.show<AttachmentsComponent>(AttachmentsComponent, this.attachmentsModalRef,
|
this.modal = modal;
|
||||||
true, comp => comp.cipherId = cipher.id);
|
|
||||||
let madeAttachmentChanges = false;
|
let madeAttachmentChanges = false;
|
||||||
childComponent.onUploadedAttachment.subscribe(() => madeAttachmentChanges = true);
|
childComponent.onUploadedAttachment.subscribe(() => madeAttachmentChanges = true);
|
||||||
childComponent.onDeletedAttachment.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) {
|
if (this.modal != null) {
|
||||||
this.modal.close();
|
this.modal.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent);
|
const [modal, childComponent] = await this.modalService.openViewRef(ShareComponent, this.shareModalRef,
|
||||||
this.modal = this.shareModalRef.createComponent(factory).instance;
|
|
||||||
const childComponent = this.modal.show<ShareComponent>(ShareComponent, this.shareModalRef, true,
|
|
||||||
comp => comp.cipherId = cipher.id);
|
comp => comp.cipherId = cipher.id);
|
||||||
|
this.modal = modal;
|
||||||
|
|
||||||
childComponent.onSharedCipher.subscribe(async () => {
|
childComponent.onSharedCipher.subscribe(async () => {
|
||||||
this.modal.close();
|
this.modal.close();
|
||||||
@ -464,15 +464,14 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
cipherCollections(cipher: CipherView) {
|
async cipherCollections(cipher: CipherView) {
|
||||||
if (this.modal != null) {
|
if (this.modal != null) {
|
||||||
this.modal.close();
|
this.modal.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent);
|
const [modal, childComponent] = await this.modalService.openViewRef(CollectionsComponent, this.collectionsModalRef,
|
||||||
this.modal = this.collectionsModalRef.createComponent(factory).instance;
|
comp => comp.cipherId = cipher.id);
|
||||||
const childComponent = this.modal.show<CollectionsComponent>(CollectionsComponent, this.collectionsModalRef,
|
this.modal = modal;
|
||||||
true, comp => comp.cipherId = cipher.id);
|
|
||||||
|
|
||||||
childComponent.onSavedCollections.subscribe(() => {
|
childComponent.onSavedCollections.subscribe(() => {
|
||||||
this.modal.close();
|
this.modal.close();
|
||||||
@ -483,15 +482,14 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
viewCipherPasswordHistory(cipher: CipherView) {
|
async viewCipherPasswordHistory(cipher: CipherView) {
|
||||||
if (this.modal != null) {
|
if (this.modal != null) {
|
||||||
this.modal.close();
|
this.modal.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent);
|
[this.modal] = await this.modalService.openViewRef(PasswordHistoryComponent, this.passwordHistoryModalRef,
|
||||||
this.modal = this.passwordHistoryModalRef.createComponent(factory).instance;
|
comp => comp.cipherId = cipher.id);
|
||||||
this.modal.show<PasswordHistoryComponent>(PasswordHistoryComponent,
|
|
||||||
this.passwordHistoryModalRef, true, comp => comp.cipherId = cipher.id);
|
|
||||||
this.modal.onClosed.subscribe(async () => {
|
this.modal.onClosed.subscribe(async () => {
|
||||||
this.modal = null;
|
this.modal = null;
|
||||||
});
|
});
|
||||||
@ -559,10 +557,9 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
this.modal.close();
|
this.modal.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent);
|
const [modal, childComponent] = await this.modalService.openViewRef(PasswordGeneratorComponent, this.passwordGeneratorModalRef,
|
||||||
this.modal = this.passwordGeneratorModalRef.createComponent(factory).instance;
|
comp => comp.showSelect = showSelect);
|
||||||
const childComponent = this.modal.show<PasswordGeneratorComponent>(PasswordGeneratorComponent,
|
this.modal = modal;
|
||||||
this.passwordGeneratorModalRef, true, comp => comp.showSelect = showSelect);
|
|
||||||
|
|
||||||
childComponent.onSelected.subscribe((password: string) => {
|
childComponent.onSelected.subscribe((password: string) => {
|
||||||
this.modal.close();
|
this.modal.close();
|
||||||
@ -587,10 +584,9 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
this.modal.close();
|
this.modal.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent);
|
const [modal, childComponent] = await this.modalService.openViewRef(FolderAddEditComponent, this.folderAddEditModalRef,
|
||||||
this.modal = this.folderAddEditModalRef.createComponent(factory).instance;
|
comp => comp.folderId = folderId);
|
||||||
const childComponent = this.modal.show<FolderAddEditComponent>(
|
this.modal = modal;
|
||||||
FolderAddEditComponent, this.folderAddEditModalRef, true, comp => comp.folderId = folderId);
|
|
||||||
|
|
||||||
childComponent.onSavedFolder.subscribe(async (folder: FolderView) => {
|
childComponent.onSavedFolder.subscribe(async (folder: FolderView) => {
|
||||||
this.modal.close();
|
this.modal.close();
|
||||||
|
@ -415,3 +415,8 @@ app-root > #loading {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.password-reprompt {
|
||||||
|
text-align: left;
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
@ -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<boolean>):
|
|
||||||
Promise<boolean> {
|
|
||||||
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<any> => {
|
|
||||||
if (await passwordValidation(value)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.i18nService.t('invalidMasterPassword');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return result.isConfirmed;
|
|
||||||
}
|
|
||||||
}
|
|
9
src/services/passwordReprompt.service.ts
Normal file
9
src/services/passwordReprompt.service.ts
Normal file
@ -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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user