[Key Connector] Add support for key connector and OTP (#2156)

Co-authored-by: Hinton <oscar@oscarhinton.com>
This commit is contained in:
Thomas Rittson 2021-11-10 03:59:51 +10:00 committed by GitHub
parent 0039d4aaea
commit cf28435ce3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 139 additions and 43 deletions

2
jslib

@ -1 +1 @@
Subproject commit 2db9e1ce0d7a702f07f20ecb916dd8191ff617e1
Subproject commit 8f177e2d3a879b854db5c6e6d7d386b24d637a66

View File

@ -121,6 +121,9 @@
"continue": {
"message": "Continue"
},
"requestVerificationCode": {
"message": "Request one-time password"
},
"verificationCode": {
"message": "Verification Code"
},
@ -411,6 +414,9 @@
"verificationCodeRequired": {
"message": "Verification code is required."
},
"invalidVerificationCode": {
"message": "Invalid verification code"
},
"valueCopied": {
"message": "$VALUE$ copied",
"description": "Value has been copied to the clipboard.",
@ -1821,5 +1827,23 @@
},
"copyCustomFieldNameNotUnique": {
"message": "No unique identifier found."
},
"convertOrganizationEncryptionDesc": {
"message": "$ORGANIZATION$ is using SSO with a self-hosted key server. A master password is no longer required to log in for members of this organization.",
"placeholders": {
"organization": {
"content": "$1",
"example": "My Org Name"
}
}
},
"leaveOrganization": {
"message": "Leave Organization"
},
"removeMasterPassword": {
"message": "Remove Master Password"
},
"removedMasterPassword": {
"message": "Master password removed."
}
}

View File

@ -17,6 +17,7 @@ import { EventService } from 'jslib-common/services/event.service';
import { ExportService } from 'jslib-common/services/export.service';
import { FileUploadService } from 'jslib-common/services/fileUpload.service';
import { FolderService } from 'jslib-common/services/folder.service';
import { KeyConnectorService } from 'jslib-common/services/keyConnector.service';
import { NotificationsService } from 'jslib-common/services/notifications.service';
import { PasswordGenerationService } from 'jslib-common/services/passwordGeneration.service';
import { PolicyService } from 'jslib-common/services/policy.service';
@ -45,6 +46,7 @@ import { ExportService as ExportServiceAbstraction } from 'jslib-common/abstract
import { FileUploadService as FileUploadServiceAbstraction } from 'jslib-common/abstractions/fileUpload.service';
import { FolderService as FolderServiceAbstraction } from 'jslib-common/abstractions/folder.service';
import { I18nService as I18nServiceAbstraction } from 'jslib-common/abstractions/i18n.service';
import { KeyConnectorService as KeyConnectorServiceAbstraction } from 'jslib-common/abstractions/keyConnector.service';
import { LogService as LogServiceAbstraction } from 'jslib-common/abstractions/log.service';
import { MessagingService as MessagingServiceAbstraction } from 'jslib-common/abstractions/messaging.service';
import { NotificationsService as NotificationsServiceAbstraction } from 'jslib-common/abstractions/notifications.service';
@ -64,8 +66,6 @@ import { UserService as UserServiceAbstraction } from 'jslib-common/abstractions
import { VaultTimeoutService as VaultTimeoutServiceAbstraction } from 'jslib-common/abstractions/vaultTimeout.service';
import { AutofillService as AutofillServiceAbstraction } from '../services/abstractions/autofill.service';
import { Utils } from 'jslib-common/misc/utils';
import { BrowserApi } from '../browser/browserApi';
import { SafariApp } from '../browser/safariApp';
@ -125,6 +125,7 @@ export default class MainBackground {
popupUtilsService: PopupUtilsService;
sendService: SendServiceAbstraction;
fileUploadService: FileUploadServiceAbstraction;
keyConnectorService: KeyConnectorServiceAbstraction;
onUpdatedRan: boolean;
onReplacedRan: boolean;
@ -195,9 +196,12 @@ export default class MainBackground {
this.storageService, this.i18nService, this.cryptoFunctionService);
this.stateService = new StateService();
this.policyService = new PolicyService(this.userService, this.storageService, this.apiService);
this.keyConnectorService = new KeyConnectorService(this.storageService, this.userService, this.cryptoService,
this.apiService, this.environmentService, this.tokenService, this.logService);
this.vaultTimeoutService = new VaultTimeoutService(this.cipherService, this.folderService,
this.collectionService, this.cryptoService, this.platformUtilsService, this.storageService,
this.messagingService, this.searchService, this.userService, this.tokenService, this.policyService,
this.keyConnectorService,
async () => {
if (this.notificationsService != null) {
this.notificationsService.updateConnection(false);
@ -212,7 +216,8 @@ export default class MainBackground {
this.syncService = new SyncService(this.userService, this.apiService, this.settingsService,
this.folderService, this.cipherService, this.cryptoService, this.collectionService,
this.storageService, this.messagingService, this.policyService, this.sendService,
this.logService, async (expired: boolean) => await this.logout(expired));
this.logService, this.tokenService, this.keyConnectorService,
async (expired: boolean) => await this.logout(expired));
this.eventService = new EventService(this.storageService, this.apiService, this.userService,
this.cipherService, this.logService);
this.passwordGenerationService = new PasswordGenerationService(this.cryptoService, this.storageService,
@ -271,7 +276,8 @@ export default class MainBackground {
const message = Object.assign({}, { command: subscriber }, arg);
that.runtimeBackground.processMessage(message, that, null);
}
}(), this.vaultTimeoutService, this.logService, this.cryptoFunctionService);
}(), this.vaultTimeoutService, this.logService, this.cryptoFunctionService, this.environmentService,
this.keyConnectorService);
}
async bootstrap() {
@ -362,6 +368,7 @@ export default class MainBackground {
this.policyService.clear(userId),
this.passwordGenerationService.clear(),
this.vaultTimeoutService.clear(),
this.keyConnectorService.clear(),
]);
this.searchService.clearIndex();

View File

@ -8,6 +8,7 @@ import { ApiService } from 'jslib-common/abstractions/api.service';
import { CryptoService } from 'jslib-common/abstractions/crypto.service';
import { EnvironmentService } from 'jslib-common/abstractions/environment.service';
import { I18nService } from 'jslib-common/abstractions/i18n.service';
import { KeyConnectorService } from 'jslib-common/abstractions/keyConnector.service';
import { LogService } from 'jslib-common/abstractions/log.service';
import { MessagingService } from 'jslib-common/abstractions/messaging.service';
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
@ -30,9 +31,10 @@ export class LockComponent extends BaseLockComponent {
userService: UserService, cryptoService: CryptoService,
storageService: StorageService, vaultTimeoutService: VaultTimeoutService,
environmentService: EnvironmentService, stateService: StateService,
apiService: ApiService, logService: LogService) {
apiService: ApiService, logService: LogService, keyConnectorService: KeyConnectorService) {
super(router, i18nService, platformUtilsService, messagingService, userService, cryptoService,
storageService, vaultTimeoutService, environmentService, stateService, apiService, logService);
storageService, vaultTimeoutService, environmentService, stateService, apiService, logService,
keyConnectorService);
this.successRoute = '/tabs/current';
this.isInitialLockScreen = (window as any).previousPopupUrl == null;
}

View File

@ -0,0 +1,29 @@
<header>
<div class="left"></div>
<div class="center">
<span class="title">{{'removeMasterPassword' | i18n}}</span>
</div>
<div class="right"></div>
</header>
<content>
<div class="box">
<div class="box-content">
<div class="box-content-row" appBoxRow>
<p>{{'convertOrganizationEncryptionDesc' | i18n : organization.name}}</p>
</div>
<div class="box-content-row">
<button type="button" class="btn block primary" (click)="convert()" [disabled]="actionPromise">
<i class="fa fa-spinner fa-spin" title="{{'loading' | i18n}}" aria-hidden="true" *ngIf="continuing"></i>
{{'removeMasterPassword' | i18n}}
</button>
</div>
<div class="box-content-row">
<button type="button" class="btn btn-outline-secondary block" (click)="leave()" [disabled]="actionPromise">
<i class="fa fa-spinner fa-spin" title="{{'loading' | i18n}}" aria-hidden="true" *ngIf="leaving"></i>
{{'leaveOrganization' | i18n}}
</button>
</div>
</div>
</div>
</content>

View File

@ -0,0 +1,10 @@
import { Component } from '@angular/core';
import { RemovePasswordComponent as BaseRemovePasswordComponent } from 'jslib-angular/components/remove-password.component';
@Component({
selector: 'app-remove-password',
templateUrl: 'remove-password.component.html',
})
export class RemovePasswordComponent extends BaseRemovePasswordComponent {
}

View File

@ -16,6 +16,7 @@ import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.se
import { StateService } from 'jslib-common/abstractions/state.service';
import { StorageService } from 'jslib-common/abstractions/storage.service';
import { SyncService } from 'jslib-common/abstractions/sync.service';
import { VaultTimeoutService } from 'jslib-common/abstractions/vaultTimeout.service';
import { SsoComponent as BaseSsoComponent } from 'jslib-angular/components/sso.component';
import { BrowserApi } from '../../browser/browserApi';
@ -30,7 +31,8 @@ export class SsoComponent extends BaseSsoComponent {
storageService: StorageService, stateService: StateService,
platformUtilsService: PlatformUtilsService, apiService: ApiService,
cryptoFunctionService: CryptoFunctionService, passwordGenerationService: PasswordGenerationService,
syncService: SyncService, environmentService: EnvironmentService, logService: LogService) {
syncService: SyncService, environmentService: EnvironmentService, logService: LogService,
private vaultTimeoutService: VaultTimeoutService) {
super(authService, router, i18nService, route, storageService, stateService, platformUtilsService,
apiService, cryptoFunctionService, environmentService, passwordGenerationService, logService);
@ -41,7 +43,11 @@ export class SsoComponent extends BaseSsoComponent {
super.onSuccessfulLogin = async () => {
await syncService.fullSync(true);
BrowserApi.reloadOpenWindows();
if (await this.vaultTimeoutService.isLocked()) {
// If the vault is unlocked then this will clear keys from memory, which we don't want to do
BrowserApi.reloadOpenWindows();
}
const thisWindow = window.open('', '_self');
thisWindow.close();
};

View File

@ -18,6 +18,7 @@ import { HomeComponent } from './accounts/home.component';
import { LockComponent } from './accounts/lock.component';
import { LoginComponent } from './accounts/login.component';
import { RegisterComponent } from './accounts/register.component';
import { RemovePasswordComponent } from './accounts/remove-password.component';
import { SetPasswordComponent } from './accounts/set-password.component';
import { SsoComponent } from './accounts/sso.component';
import { TwoFactorOptionsComponent } from './accounts/two-factor-options.component';
@ -105,6 +106,12 @@ const routes: Routes = [
component: SetPasswordComponent,
data: { state: 'set-password' },
},
{
path: 'remove-password',
component: RemovePasswordComponent,
canActivate: [AuthGuardService],
data: { state: 'remove-password' },
},
{
path: 'register',
component: RegisterComponent,

View File

@ -26,6 +26,7 @@ import { BroadcasterService } from 'jslib-angular/services/broadcaster.service';
import { AuthService } from 'jslib-common/abstractions/auth.service';
import { I18nService } from 'jslib-common/abstractions/i18n.service';
import { KeyConnectorService } from 'jslib-common/abstractions/keyConnector.service';
import { MessagingService } from 'jslib-common/abstractions/messaging.service';
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
import { StateService } from 'jslib-common/abstractions/state.service';
@ -33,7 +34,6 @@ import { StorageService } from 'jslib-common/abstractions/storage.service';
import { ConstantsService } from 'jslib-common/services/constants.service';
import BrowserPlatformUtilsService from 'src/services/browserPlatformUtils.service';
import { routerTransition } from './app-routing.animations';
@Component({
@ -63,7 +63,8 @@ export class AppComponent implements OnInit {
private i18nService: I18nService, private router: Router,
private stateService: StateService, private messagingService: MessagingService,
private changeDetectorRef: ChangeDetectorRef, private ngZone: NgZone,
private sanitizer: DomSanitizer, private platformUtilsService: PlatformUtilsService) { }
private sanitizer: DomSanitizer, private platformUtilsService: PlatformUtilsService,
private keyConnectoService: KeyConnectorService) { }
ngOnInit() {
if (BrowserApi.getBackgroundPage() == null) {
@ -121,6 +122,11 @@ export class AppComponent implements OnInit {
this.ngZone.run(() => {
this.router.navigate(['/']);
});
} else if (msg.command === 'convertAccountToKeyConnector') {
this.ngZone.run(async () => {
await this.keyConnectoService.setConvertAccountRequired(true);
this.router.navigate(['/remove-password']);
});
} else {
msg.webExtSender = sender;
this.broadcasterService.send(msg);

View File

@ -17,6 +17,7 @@ import { HomeComponent } from './accounts/home.component';
import { LockComponent } from './accounts/lock.component';
import { LoginComponent } from './accounts/login.component';
import { RegisterComponent } from './accounts/register.component';
import { RemovePasswordComponent } from './accounts/remove-password.component';
import { SetPasswordComponent } from './accounts/set-password.component';
import { SsoComponent } from './accounts/sso.component';
import { TwoFactorOptionsComponent } from './accounts/two-factor-options.component';
@ -83,6 +84,7 @@ import { SetPinComponent } from './components/set-pin.component';
import { CalloutComponent } from 'jslib-angular/components/callout.component';
import { IconComponent } from 'jslib-angular/components/icon.component';
import { VerifyMasterPasswordComponent } from 'jslib-angular/components/verify-master-password.component';
import {
CurrencyPipe,
@ -192,6 +194,7 @@ registerLocaleData(localeZhTw, 'zh-TW');
A11yTitleDirective,
ActionButtonsComponent,
AddEditComponent,
AddEditCustomFieldsComponent,
ApiActionDirective,
AppComponent,
AttachmentsComponent,
@ -212,8 +215,8 @@ registerLocaleData(localeZhTw, 'zh-TW');
FolderAddEditComponent,
FoldersComponent,
GroupingsComponent,
HomeComponent,
HintComponent,
HomeComponent,
I18nPipe,
IconComponent,
InputVerbatimDirective,
@ -223,6 +226,7 @@ registerLocaleData(localeZhTw, 'zh-TW');
PasswordGeneratorComponent,
PasswordGeneratorHistoryComponent,
PasswordHistoryComponent,
PasswordRepromptComponent,
PopOutComponent,
PremiumComponent,
PrivateModeComponent,
@ -235,6 +239,7 @@ registerLocaleData(localeZhTw, 'zh-TW');
SendListComponent,
SendTypeComponent,
SetPasswordComponent,
SetPinComponent,
SettingsComponent,
ShareComponent,
SsoComponent,
@ -243,15 +248,14 @@ registerLocaleData(localeZhTw, 'zh-TW');
SyncComponent,
TabsComponent,
TrueFalseValueDirective,
TwoFactorOptionsComponent,
TwoFactorComponent,
TwoFactorOptionsComponent,
UpdateTempPasswordComponent,
ViewComponent,
PasswordRepromptComponent,
SetPinComponent,
VaultTimeoutInputComponent,
AddEditCustomFieldsComponent,
VerifyMasterPasswordComponent,
ViewComponent,
ViewCustomFieldsComponent,
RemovePasswordComponent,
],
entryComponents: [],
providers: [

View File

@ -33,6 +33,7 @@ import { ExportService } from 'jslib-common/abstractions/export.service';
import { FileUploadService } from 'jslib-common/abstractions/fileUpload.service';
import { FolderService } from 'jslib-common/abstractions/folder.service';
import { I18nService } from 'jslib-common/abstractions/i18n.service';
import { KeyConnectorService } from 'jslib-common/abstractions/keyConnector.service';
import { LogService as LogServiceAbstraction } from 'jslib-common/abstractions/log.service';
import { MessagingService } from 'jslib-common/abstractions/messaging.service';
import { NotificationsService } from 'jslib-common/abstractions/notifications.service';
@ -49,6 +50,7 @@ import { SyncService } from 'jslib-common/abstractions/sync.service';
import { TokenService } from 'jslib-common/abstractions/token.service';
import { TotpService } from 'jslib-common/abstractions/totp.service';
import { UserService } from 'jslib-common/abstractions/user.service';
import { UserVerificationService as UserVerificationServiceAbstraction } from 'jslib-common/abstractions/userVerification.service';
import { VaultTimeoutService } from 'jslib-common/abstractions/vaultTimeout.service';
import { AutofillService } from '../../services/abstractions/autofill.service';
@ -59,6 +61,7 @@ import { ConsoleLogService } from 'jslib-common/services/consoleLog.service';
import { ConstantsService } from 'jslib-common/services/constants.service';
import { SearchService } from 'jslib-common/services/search.service';
import { StateService } from 'jslib-common/services/state.service';
import { UserVerificationService } from 'jslib-common/services/userVerification.service';
import { PopupSearchService } from './popup-search.service';
import { PopupUtilsService } from './popup-utils.service';
@ -182,6 +185,7 @@ export function initFactory(platformUtilsService: PlatformUtilsService, i18nServ
{ provide: AutofillService, useFactory: getBgService<AutofillService>('autofillService'), deps: [] },
{ provide: ExportService, useFactory: getBgService<ExportService>('exportService'), deps: [] },
{ provide: SendService, useFactory: getBgService<SendService>('sendService'), deps: [] },
{ provide: KeyConnectorService, useFactory: getBgService<KeyConnectorService>('keyConnectorService'), deps: [] },
{
provide: VaultTimeoutService,
useFactory: getBgService<VaultTimeoutService>('vaultTimeoutService'),
@ -204,6 +208,7 @@ export function initFactory(platformUtilsService: PlatformUtilsService, i18nServ
deps: [],
},
{ provide: PasswordRepromptServiceAbstraction, useClass: PasswordRepromptService },
{ provide: UserVerificationServiceAbstraction, useClass: UserVerificationService },
],
})
export class ServicesModule {

View File

@ -1,4 +1,4 @@
<form (ngSubmit)="submit()">
<form (ngSubmit)="submit()" [formGroup]="exportForm">
<header>
<div class="left">
<a routerLink="/tabs/settings">
@ -10,7 +10,7 @@
<span class="title">{{'exportVault' | i18n}}</span>
</div>
<div class="right">
<button appBlurClick type="submit" [disabled]="disabledByPolicy">{{'submit' | i18n}}</button>
<button appBlurClick type="submit" [disabled]="!exportForm.enabled">{{'submit' | i18n}}</button>
</div>
</header>
<content>
@ -22,25 +22,14 @@
<div class="box-content">
<div class="box-content-row" appBoxRow>
<label for="format">{{'fileFormat' | i18n}}</label>
<select id="format" name="Format" [(ngModel)]="format" [disabled]="disabledByPolicy">
<option value="json">.json</option>
<option value="csv">.csv</option>
<option value="encrypted_json">.json (Encrypted)</option>
<select id="format" name="Format" formControlName="format">
<option *ngFor="let f of formatOptions" [value]="f.value">{{f.name}}</option>
</select>
</div>
<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 appInputVerbatim appAutofocus
[disabled]="disabledByPolicy">
</div>
<div class="action-buttons">
<button type="button" class="row-btn" appStopClick appBlurClick
appA11yTitle="{{'toggleVisibility' | i18n}}" (click)="togglePassword()">
<i class="fa fa-lg" aria-hidden="true"
[ngClass]="{'fa-eye': !showPassword, 'fa-eye-slash': showPassword}"></i>
</button>
<app-verify-master-password ngDefaultControl formControlName="secret" name="Secret">
</app-verify-master-password>
</div>
</div>
</div>

View File

@ -1,4 +1,5 @@
import { Component } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { Router } from '@angular/router';
import { CryptoService } from 'jslib-common/abstractions/crypto.service';
@ -8,6 +9,7 @@ import { I18nService } from 'jslib-common/abstractions/i18n.service';
import { LogService } from 'jslib-common/abstractions/log.service';
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
import { PolicyService } from 'jslib-common/abstractions/policy.service';
import { UserVerificationService } from 'jslib-common/abstractions/userVerification.service';
import { ExportComponent as BaseExportComponent } from 'jslib-angular/components/export.component';
@ -19,9 +21,9 @@ export class ExportComponent extends BaseExportComponent {
constructor(cryptoService: CryptoService, i18nService: I18nService,
platformUtilsService: PlatformUtilsService, exportService: ExportService,
eventService: EventService, policyService: PolicyService, private router: Router,
logService: LogService) {
logService: LogService, userVerificationService: UserVerificationService, fb: FormBuilder) {
super(cryptoService, i18nService, platformUtilsService, exportService, eventService, policyService, window,
logService);
logService, userVerificationService, fb);
}
protected saved() {

View File

@ -71,7 +71,7 @@
<span><i class="fa fa-chevron-right fa-lg row-sub-icon" aria-hidden="true"></i></span>
</a>
<button type="button" class="box-content-row box-content-row-flex text-default" appStopClick appBlurClick
(click)="changePassword()">
(click)="changePassword()" *ngIf="showChangeMasterPass">
<div class="row-main">{{'changeMasterPassword' | i18n}}</div>
<i class="fa fa-chevron-right fa-lg row-sub-icon" aria-hidden="true"></i>
</button>

View File

@ -18,6 +18,7 @@ import { ConstantsService } from 'jslib-common/services/constants.service';
import { CryptoService } from 'jslib-common/abstractions/crypto.service';
import { EnvironmentService } from 'jslib-common/abstractions/environment.service';
import { I18nService } from 'jslib-common/abstractions/i18n.service';
import { KeyConnectorService } from 'jslib-common/abstractions/keyConnector.service';
import { MessagingService } from 'jslib-common/abstractions/messaging.service';
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
import { StorageService } from 'jslib-common/abstractions/storage.service';
@ -58,6 +59,7 @@ export class SettingsComponent implements OnInit {
biometric: boolean = false;
disableAutoBiometricsPrompt = true;
previousVaultTimeout: number = null;
showChangeMasterPass = true;
vaultTimeout: FormControl = new FormControl(null);
@ -66,7 +68,8 @@ export class SettingsComponent implements OnInit {
public messagingService: MessagingService, private router: Router,
private environmentService: EnvironmentService, private cryptoService: CryptoService,
private userService: UserService, private popupUtilsService: PopupUtilsService,
private modalService: ModalService, private toasterService: ToasterService) {
private modalService: ModalService, private toasterService: ToasterService,
private keyConnectorService: KeyConnectorService) {
}
async ngOnInit() {
@ -118,6 +121,7 @@ export class SettingsComponent implements OnInit {
this.biometric = await this.vaultTimeoutService.isBiometricLockSet();
this.disableAutoBiometricsPrompt = await this.storageService.get<boolean>(
ConstantsService.disableAutoBiometricsPromptKey) ?? true;
this.showChangeMasterPass = !await this.keyConnectorService.getUsesKeyConnector();
}
async saveVaultTimeout(newValue: number) {

View File

@ -290,7 +290,7 @@
<label for="favorite">{{'favorite' | i18n}}</label>
<input id="favorite" type="checkbox" name="Favorite" [(ngModel)]="cipher.favorite">
</div>
<div class="box-content-row box-content-row-checkbox" appBoxRow>
<div class="box-content-row box-content-row-checkbox" appBoxRow *ngIf="canUseReprompt">
<label for="passwordPrompt">
{{'passwordPrompt' | i18n}}
<a target="_blank" rel="noopener" appA11yTitle="{{'learnMore' | i18n}}"
@ -298,8 +298,7 @@
<i class="fa fa-question-circle-o" aria-hidden="true"></i>
</a>
</label>
<input id="passwordPrompt" type="checkbox" name="PasswordPrompt" [ngModel]="reprompt"
(change)="repromptChanged()">
<input id="passwordPrompt" type="checkbox" name="PasswordPrompt" [ngModel]="reprompt" (change)="repromptChanged()">
</div>
<button type="button" class="box-content-row box-content-row-flex text-default" appStopClick appBlurClick
(click)="attachments()" *ngIf="editMode && showAttachments && !cloneMode">

View File

@ -17,6 +17,7 @@ import { FolderService } from 'jslib-common/abstractions/folder.service';
import { I18nService } from 'jslib-common/abstractions/i18n.service';
import { LogService } from 'jslib-common/abstractions/log.service';
import { MessagingService } from 'jslib-common/abstractions/messaging.service';
import { PasswordRepromptService } from 'jslib-common/abstractions/passwordReprompt.service';
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
import { PolicyService } from 'jslib-common/abstractions/policy.service';
import { StateService } from 'jslib-common/abstractions/state.service';
@ -51,9 +52,10 @@ export class AddEditComponent extends BaseAddEditComponent {
private router: Router, private location: Location,
eventService: EventService, policyService: PolicyService,
private popupUtilsService: PopupUtilsService, private storageService: StorageService,
logService: LogService) {
logService: LogService, passwordRepromptService: PasswordRepromptService) {
super(cipherService, folderService, i18nService, platformUtilsService, auditService, stateService,
userService, collectionService, messagingService, eventService, policyService, logService);
userService, collectionService, messagingService, eventService, policyService, passwordRepromptService,
logService);
}
async ngOnInit() {