From afb30d5e0b21e64b2fd2ffc3cb1ea72430c31833 Mon Sep 17 00:00:00 2001 From: Thomas Rittson <31796059+eliykat@users.noreply.github.com> Date: Wed, 10 Nov 2021 04:00:01 +1000 Subject: [PATCH] [Key Connector] Add support for key connector and OTP (#1135) Co-authored-by: Hinton --- jslib | 2 +- src/app/accounts/lock.component.ts | 6 ++- .../accounts/remove-password.component.html | 18 +++++++++ src/app/accounts/remove-password.component.ts | 10 +++++ src/app/app-routing.module.ts | 7 ++++ src/app/app.component.ts | 37 ++++++++++++++----- src/app/app.module.ts | 14 ++++--- src/app/services.module.ts | 16 ++++++-- src/app/vault/add-edit.component.html | 2 +- src/app/vault/add-edit.component.ts | 8 ++-- src/app/vault/export.component.html | 21 +++-------- src/app/vault/export.component.ts | 27 +++----------- src/locales/en/messages.json | 30 +++++++++++++++ src/main/menu.main.ts | 26 ++++++++----- src/main/messaging.main.ts | 3 +- src/scss/pages.scss | 12 ++++-- 16 files changed, 162 insertions(+), 77 deletions(-) create mode 100644 src/app/accounts/remove-password.component.html create mode 100644 src/app/accounts/remove-password.component.ts diff --git a/jslib b/jslib index 2db9e1ce..8f177e2d 160000 --- a/jslib +++ b/jslib @@ -1 +1 @@ -Subproject commit 2db9e1ce0d7a702f07f20ecb916dd8191ff617e1 +Subproject commit 8f177e2d3a879b854db5c6e6d7d386b24d637a66 diff --git a/src/app/accounts/lock.component.ts b/src/app/accounts/lock.component.ts index f74012f4..2f0db827 100644 --- a/src/app/accounts/lock.component.ts +++ b/src/app/accounts/lock.component.ts @@ -13,6 +13,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'; @@ -43,9 +44,10 @@ export class LockComponent extends BaseLockComponent implements OnDestroy { environmentService: EnvironmentService, stateService: StateService, apiService: ApiService, private route: ActivatedRoute, private broadcasterService: BroadcasterService, private ngZone: NgZone, - logService: LogService) { + logService: LogService, keyConnectorService: KeyConnectorService) { super(router, i18nService, platformUtilsService, messagingService, userService, cryptoService, - storageService, vaultTimeoutService, environmentService, stateService, apiService, logService); + storageService, vaultTimeoutService, environmentService, stateService, apiService, logService, + keyConnectorService); } async ngOnInit() { diff --git a/src/app/accounts/remove-password.component.html b/src/app/accounts/remove-password.component.html new file mode 100644 index 00000000..bf2ef627 --- /dev/null +++ b/src/app/accounts/remove-password.component.html @@ -0,0 +1,18 @@ +
+
+

{{'removeMasterPassword' | i18n}}

+

{{'convertOrganizationEncryptionDesc' | i18n : organization.name}}

+
+ + +
+
+
diff --git a/src/app/accounts/remove-password.component.ts b/src/app/accounts/remove-password.component.ts new file mode 100644 index 00000000..c8326949 --- /dev/null +++ b/src/app/accounts/remove-password.component.ts @@ -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 { +} diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 7346ba69..2b10fd18 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -12,6 +12,7 @@ import { HintComponent } from './accounts/hint.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 { TwoFactorComponent } from './accounts/two-factor.component'; @@ -54,6 +55,12 @@ const routes: Routes = [ component: UpdateTempPasswordComponent, canActivate: [AuthGuardService], }, + { + path: 'remove-password', + component: RemovePasswordComponent, + canActivate: [AuthGuardService], + data: { titleId: 'removeMasterPassword' }, + }, ]; @NgModule({ diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 80ef640c..e81e1550 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -30,6 +30,7 @@ import { CryptoService } from 'jslib-common/abstractions/crypto.service'; import { EventService } from 'jslib-common/abstractions/event.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 } from 'jslib-common/abstractions/log.service'; import { MessagingService } from 'jslib-common/abstractions/messaging.service'; import { NotificationsService } from 'jslib-common/abstractions/notifications.service'; @@ -108,12 +109,13 @@ 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 modalService: ModalService) { } + private policyService: PolicyService, private modalService: ModalService, + private keyConnectorService: KeyConnectorService) { } ngOnInit() { this.ngZone.runOutsideAngular(() => { setTimeout(async () => { - await this.updateAppMenu(); + await this.updateAppMenu('auth'); }, 1000); window.onmousemove = () => this.recordActivity(); @@ -130,7 +132,7 @@ export class AppComponent implements OnInit { case 'loggedIn': case 'unlocked': this.notificationsService.updateConnection(); - this.updateAppMenu(); + this.updateAppMenu('auth'); this.systemService.cancelProcessReload(); break; case 'loggedOut': @@ -138,7 +140,7 @@ export class AppComponent implements OnInit { this.modal.close(); } this.notificationsService.updateConnection(); - this.updateAppMenu(); + this.updateAppMenu('auth'); this.systemService.startProcessReload(); await this.systemService.clearPendingClipboard(); break; @@ -158,7 +160,7 @@ export class AppComponent implements OnInit { this.stateService.purge(); this.router.navigate(['lock']); this.notificationsService.updateConnection(); - this.updateAppMenu(); + this.updateAppMenu('auth'); this.systemService.startProcessReload(); await this.systemService.clearPendingClipboard(); break; @@ -168,6 +170,7 @@ export class AppComponent implements OnInit { case 'syncStarted': break; case 'syncCompleted': + await this.updateAppMenu('sync'); break; case 'openSettings': await this.openModal(SettingsComponent, this.settingsRef); @@ -269,6 +272,10 @@ export class AppComponent implements OnInit { await this.openPasswordGenerator(); } break; + case 'convertAccountToKeyConnector': + this.keyConnectorService.setConvertAccountRequired(true); + this.router.navigate(['/remove-password']); + break; } }); }); @@ -327,11 +334,20 @@ export class AppComponent implements OnInit { }); } - private async updateAppMenu() { - this.messagingService.send('updateAppMenu', { - isAuthenticated: await this.userService.isAuthenticated(), - isLocked: await this.vaultTimeoutService.isLocked(), - }); + private async updateAppMenu(type: 'auth' | 'sync') { + let data: any; + if (type === 'sync') { + data = { + enableChangeMasterPass: !await this.keyConnectorService.getUsesKeyConnector(), + }; + } else { + data = { + isAuthenticated: await this.userService.isAuthenticated(), + isLocked: await this.vaultTimeoutService.isLocked(), + }; + } + + this.messagingService.send('updateAppMenu', data); } private async logOut(expired: boolean) { @@ -352,6 +368,7 @@ export class AppComponent implements OnInit { this.vaultTimeoutService.clear(), this.stateService.purge(), this.policyService.clear(userId), + this.keyConnectorService.clear(), ]); this.vaultTimeoutService.biometricLocked = true; diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 641333f1..80c7c12a 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -22,6 +22,7 @@ import { LockComponent } from './accounts/lock.component'; import { LoginComponent } from './accounts/login.component'; import { PremiumComponent } from './accounts/premium.component'; import { RegisterComponent } from './accounts/register.component'; +import { RemovePasswordComponent } from './accounts/remove-password.component'; import { SetPasswordComponent } from './accounts/set-password.component'; import { SettingsComponent } from './accounts/settings.component'; import { SsoComponent } from './accounts/sso.component'; @@ -32,6 +33,7 @@ import { VaultTimeoutInputComponent } from './accounts/vault-timeout-input.compo 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 { A11yTitleDirective } from 'jslib-angular/directives/a11y-title.directive'; import { ApiActionDirective } from 'jslib-angular/directives/api-action.directive'; @@ -181,6 +183,7 @@ registerLocaleData(localeZhTw, 'zh-TW'); declarations: [ A11yTitleDirective, AddEditComponent, + AddEditCustomFieldsComponent, ApiActionDirective, AppComponent, AttachmentsComponent, @@ -206,14 +209,17 @@ registerLocaleData(localeZhTw, 'zh-TW'); PasswordGeneratorComponent, PasswordGeneratorHistoryComponent, PasswordHistoryComponent, + PasswordRepromptComponent, PremiumComponent, RegisterComponent, + RemovePasswordComponent, SearchCiphersPipe, SelectCopyDirective, SendAddEditComponent, - SendEffluxDatesComponent, SendComponent, + SendEffluxDatesComponent, SetPasswordComponent, + SetPinComponent, SettingsComponent, ShareComponent, SsoComponent, @@ -224,11 +230,9 @@ registerLocaleData(localeZhTw, 'zh-TW'); TwoFactorOptionsComponent, UpdateTempPasswordComponent, VaultComponent, - ViewComponent, - PasswordRepromptComponent, - SetPinComponent, VaultTimeoutInputComponent, - AddEditCustomFieldsComponent, + VerifyMasterPasswordComponent, + ViewComponent, ViewCustomFieldsComponent, ], providers: [DatePipe], diff --git a/src/app/services.module.ts b/src/app/services.module.ts index dd501231..846dc82b 100644 --- a/src/app/services.module.ts +++ b/src/app/services.module.ts @@ -36,6 +36,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'; @@ -48,6 +49,7 @@ import { SystemService } from 'jslib-common/services/system.service'; import { TokenService } from 'jslib-common/services/token.service'; import { TotpService } from 'jslib-common/services/totp.service'; import { UserService } from 'jslib-common/services/user.service'; +import { UserVerificationService } from 'jslib-common/services/userVerification.service'; import { VaultTimeoutService } from 'jslib-common/services/vaultTimeout.service'; import { WebCryptoFunctionService } from 'jslib-common/services/webCryptoFunction.service'; @@ -66,6 +68,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'; @@ -85,6 +88,7 @@ import { SystemService as SystemServiceAbstraction } from 'jslib-common/abstract import { TokenService as TokenServiceAbstraction } from 'jslib-common/abstractions/token.service'; import { TotpService as TotpServiceAbstraction } from 'jslib-common/abstractions/totp.service'; import { UserService as UserServiceAbstraction } from 'jslib-common/abstractions/user.service'; +import { UserVerificationService as UserVerificationServiceAbstraction } from 'jslib-common/abstractions/userVerification.service'; import { VaultTimeoutService as VaultTimeoutServiceAbstraction } from 'jslib-common/abstractions/vaultTimeout.service'; import { ThemeType } from 'jslib-common/enums/themeType'; @@ -120,17 +124,21 @@ searchService = new SearchService(cipherService, logService, i18nService); const sendService = new SendService(cryptoService, userService, apiService, fileUploadService, storageService, i18nService, cryptoFunctionService); const policyService = new PolicyService(userService, storageService, apiService); +const keyConnectorService = new KeyConnectorService(storageService, userService, cryptoService, apiService, + environmentService, tokenService, logService); const vaultTimeoutService = new VaultTimeoutService(cipherService, folderService, collectionService, cryptoService, platformUtilsService, storageService, messagingService, searchService, userService, tokenService, - policyService, null, async () => messagingService.send('logout', { expired: false })); + policyService, keyConnectorService, null, async () => messagingService.send('logout', { expired: false })); const syncService = new SyncService(userService, apiService, settingsService, folderService, cipherService, cryptoService, collectionService, storageService, messagingService, policyService, - sendService, logService, async (expired: boolean) => messagingService.send('logout', { expired: expired })); + sendService, logService, tokenService, keyConnectorService, + async (expired: boolean) => messagingService.send('logout', { expired: expired })); const passwordGenerationService = new PasswordGenerationService(cryptoService, storageService, policyService); const totpService = new TotpService(storageService, cryptoFunctionService, logService); const containerService = new ContainerService(cryptoService); const authService = new AuthService(cryptoService, apiService, userService, tokenService, appIdService, - i18nService, platformUtilsService, messagingService, vaultTimeoutService, logService, cryptoFunctionService); + i18nService, platformUtilsService, messagingService, vaultTimeoutService, logService, cryptoFunctionService, + environmentService, keyConnectorService); const exportService = new ExportService(folderService, cipherService, apiService, cryptoService); const auditService = new AuditService(cryptoFunctionService, apiService); const notificationsService = new NotificationsService(userService, syncService, appIdService, @@ -229,6 +237,8 @@ export function initFactory(): Function { { provide: CryptoFunctionServiceAbstraction, useValue: cryptoFunctionService }, { provide: NativeMessagingService, useValue: nativeMessagingService }, { provide: FileUploadServiceAbstraction, useValue: fileUploadService }, + { provide: KeyConnectorServiceAbstraction, useValue: keyConnectorService }, + { provide: UserVerificationServiceAbstraction, useClass: UserVerificationService }, { provide: PasswordRepromptServiceAbstraction, useClass: PasswordRepromptService }, { provide: APP_INITIALIZER, diff --git a/src/app/vault/add-edit.component.html b/src/app/vault/add-edit.component.html index 7345ef53..6a335e82 100644 --- a/src/app/vault/add-edit.component.html +++ b/src/app/vault/add-edit.component.html @@ -249,7 +249,7 @@ -
+