diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index 5cc964c2c2d..ac62ad1c9a8 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -1309,6 +1309,13 @@ export default class MainBackground { // Only the "true" background should run migrations await this.stateService.init({ runMigrations: true }); + this.configService.serverConfig$.subscribe((newConfig) => { + if (newConfig != null) { + this.encryptService.onServerConfigChange(newConfig); + this.bulkEncryptService.onServerConfigChange(newConfig); + } + }); + // This is here instead of in in the InitService b/c we don't plan for // side effects to run in the Browser InitService. const accounts = await firstValueFrom(this.accountService.accounts$); diff --git a/apps/browser/src/popup/services/init.service.ts b/apps/browser/src/popup/services/init.service.ts index fe6fba85a4b..c9fe7161259 100644 --- a/apps/browser/src/popup/services/init.service.ts +++ b/apps/browser/src/popup/services/init.service.ts @@ -3,6 +3,9 @@ import { inject, Inject, Injectable } from "@angular/core"; import { AbstractThemingService } from "@bitwarden/angular/platform/services/theming/theming.service.abstraction"; import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service"; +import { BulkEncryptService } from "@bitwarden/common/key-management/crypto/abstractions/bulk-encrypt.service"; +import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService as LogServiceAbstraction } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; @@ -27,6 +30,9 @@ export class InitService { private themingService: AbstractThemingService, private sdkLoadService: SdkLoadService, private viewCacheService: PopupViewCacheService, + private configService: ConfigService, + private encryptService: EncryptService, + private bulkEncryptService: BulkEncryptService, @Inject(DOCUMENT) private document: Document, ) {} @@ -34,6 +40,12 @@ export class InitService { return async () => { await this.sdkLoadService.loadAndInit(); await this.stateService.init({ runMigrations: false }); // Browser background is responsible for migrations + this.configService.serverConfig$.subscribe((newConfig) => { + if (newConfig != null) { + this.encryptService.onServerConfigChange(newConfig); + this.bulkEncryptService.onServerConfigChange(newConfig); + } + }); await this.i18nService.init(); this.twoFactorService.init(); await this.viewCacheService.init(); diff --git a/apps/browser/src/vault/guards/at-risk-passwords.guard.ts b/apps/browser/src/vault/guards/at-risk-passwords.guard.ts index ee991c81239..6bcdddfde81 100644 --- a/apps/browser/src/vault/guards/at-risk-passwords.guard.ts +++ b/apps/browser/src/vault/guards/at-risk-passwords.guard.ts @@ -4,8 +4,9 @@ import { switchMap, tap } from "rxjs"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { TaskService } from "@bitwarden/common/vault/tasks"; +import { filterOutNullish } from "@bitwarden/common/vault/utils/observable-utilities"; import { ToastService } from "@bitwarden/components"; -import { filterOutNullish, TaskService } from "@bitwarden/vault"; export const canAccessAtRiskPasswords: CanActivateFn = () => { const accountService = inject(AccountService); diff --git a/apps/browser/src/vault/popup/components/at-risk-callout/at-risk-password-callout.component.ts b/apps/browser/src/vault/popup/components/at-risk-callout/at-risk-password-callout.component.ts index 5e46f3cd3d9..eb5cd459111 100644 --- a/apps/browser/src/vault/popup/components/at-risk-callout/at-risk-password-callout.component.ts +++ b/apps/browser/src/vault/popup/components/at-risk-callout/at-risk-password-callout.component.ts @@ -4,9 +4,10 @@ import { RouterModule } from "@angular/router"; import { map, switchMap } from "rxjs"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { SecurityTaskType, TaskService } from "@bitwarden/common/vault/tasks"; +import { filterOutNullish } from "@bitwarden/common/vault/utils/observable-utilities"; import { AnchorLinkDirective, CalloutModule } from "@bitwarden/components"; import { I18nPipe } from "@bitwarden/ui-common"; -import { filterOutNullish, SecurityTaskType, TaskService } from "@bitwarden/vault"; // TODO: This component will need to be reworked to use the new EndUserNotificationService in PM-10609 diff --git a/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.spec.ts b/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.spec.ts index 3bf786ad5b7..25bf3ce3716 100644 --- a/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.spec.ts +++ b/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.spec.ts @@ -16,14 +16,12 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { SecurityTask, SecurityTaskType, TaskService } from "@bitwarden/common/vault/tasks"; import { DialogService, ToastService } from "@bitwarden/components"; import { ChangeLoginPasswordService, DefaultChangeLoginPasswordService, PasswordRepromptService, - SecurityTask, - SecurityTaskType, - TaskService, } from "@bitwarden/vault"; import { PopupHeaderComponent } from "../../../../platform/popup/layout/popup-header.component"; diff --git a/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.ts b/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.ts index dd3d53fed7d..6711673751c 100644 --- a/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.ts +++ b/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.ts @@ -15,6 +15,8 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { SecurityTaskType, TaskService } from "@bitwarden/common/vault/tasks"; +import { filterOutNullish } from "@bitwarden/common/vault/utils/observable-utilities"; import { BadgeModule, ButtonModule, @@ -28,10 +30,7 @@ import { import { ChangeLoginPasswordService, DefaultChangeLoginPasswordService, - filterOutNullish, PasswordRepromptService, - SecurityTaskType, - TaskService, VaultCarouselModule, } from "@bitwarden/vault"; diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts b/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts index 92276ef633f..f8bbb930f72 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts @@ -170,7 +170,7 @@ export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy { this.cipherService .failedToDecryptCiphers$(activeUserId) .pipe( - map((ciphers) => ciphers.filter((c) => !c.isDeleted)), + map((ciphers) => (ciphers ? ciphers.filter((c) => !c.isDeleted) : [])), filter((ciphers) => ciphers.length > 0), take(1), takeUntilDestroyed(this.destroyRef), diff --git a/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.ts b/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.ts index b9eae380ca0..6b64e1191fc 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.ts @@ -33,19 +33,17 @@ import { CipherAuthorizationService } from "@bitwarden/common/vault/services/cip import { AsyncActionsModule, ButtonModule, + CalloutModule, DialogService, IconButtonModule, SearchModule, ToastService, - CalloutModule, } from "@bitwarden/components"; import { ChangeLoginPasswordService, CipherViewComponent, CopyCipherFieldService, DefaultChangeLoginPasswordService, - DefaultTaskService, - TaskService, } from "@bitwarden/vault"; import { BrowserApi } from "../../../../../platform/browser/browser-api"; @@ -95,7 +93,6 @@ type LoadAction = providers: [ { provide: ViewPasswordHistoryService, useClass: BrowserViewPasswordHistoryService }, { provide: PremiumUpgradePromptService, useClass: BrowserPremiumUpgradePromptService }, - { provide: TaskService, useClass: DefaultTaskService }, { provide: ChangeLoginPasswordService, useClass: DefaultChangeLoginPasswordService }, ], }) diff --git a/apps/browser/src/vault/popup/services/vault-popup-items.service.ts b/apps/browser/src/vault/popup/services/vault-popup-items.service.ts index dac6a141d41..5f2ec858ed6 100644 --- a/apps/browser/src/vault/popup/services/vault-popup-items.service.ts +++ b/apps/browser/src/vault/popup/services/vault-popup-items.service.ts @@ -108,7 +108,7 @@ export class VaultPopupItemsService { this.cipherService.failedToDecryptCiphers$(userId), ]), ), - map(([ciphers, failedToDecryptCiphers]) => [...failedToDecryptCiphers, ...ciphers]), + map(([ciphers, failedToDecryptCiphers]) => [...(failedToDecryptCiphers || []), ...ciphers]), ), ), shareReplay({ refCount: true, bufferSize: 1 }), diff --git a/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts b/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts index 187c8772e88..6cce5796cbe 100644 --- a/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts +++ b/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts @@ -12,7 +12,6 @@ import { startWith, switchMap, take, - tap, } from "rxjs"; import { CollectionService, CollectionView } from "@bitwarden/admin-console/common"; @@ -360,10 +359,10 @@ export class VaultPopupListFiltersService { switchMap((userId) => { // Observable of cipher views const cipherViews$ = this.cipherService.cipherViews$(userId).pipe( - tap((cipherViews) => { - this.cipherViews = Object.values(cipherViews); + map((ciphers) => { + this.cipherViews = ciphers ? Object.values(ciphers) : []; + return this.cipherViews; }), - map((ciphers) => Object.values(ciphers)), ); return combineLatest([ diff --git a/apps/cli/src/service-container/service-container.ts b/apps/cli/src/service-container/service-container.ts index 6a4651bcd5a..0642c1f3e62 100644 --- a/apps/cli/src/service-container/service-container.ts +++ b/apps/cli/src/service-container/service-container.ts @@ -283,6 +283,7 @@ export class ServiceContainer { cipherAuthorizationService: CipherAuthorizationService; ssoUrlService: SsoUrlService; masterPasswordApiService: MasterPasswordApiServiceAbstraction; + bulkEncryptService: FallbackBulkEncryptService; constructor() { let p = null; @@ -314,6 +315,7 @@ export class ServiceContainer { this.logService, true, ); + this.bulkEncryptService = new FallbackBulkEncryptService(this.encryptService); this.storageService = new LowdbStorageService(this.logService, null, p, false, true); this.secureStorageService = new NodeEnvSecureStorageService( this.storageService, @@ -686,7 +688,7 @@ export class ServiceContainer { this.stateService, this.autofillSettingsService, this.encryptService, - new FallbackBulkEncryptService(this.encryptService), + this.bulkEncryptService, this.cipherFileUploadService, this.configService, this.stateProvider, @@ -885,6 +887,12 @@ export class ServiceContainer { await this.sdkLoadService.loadAndInit(); await this.storageService.init(); await this.stateService.init(); + this.configService.serverConfig$.subscribe((newConfig) => { + if (newConfig != null) { + this.encryptService.onServerConfigChange(newConfig); + this.bulkEncryptService.onServerConfigChange(newConfig); + } + }); this.containerService.attachToGlobal(global); await this.i18nService.init(); this.twoFactorService.init(); diff --git a/apps/desktop/src/app/services/init.service.ts b/apps/desktop/src/app/services/init.service.ts index 08efa4a592e..e68491faaa3 100644 --- a/apps/desktop/src/app/services/init.service.ts +++ b/apps/desktop/src/app/services/init.service.ts @@ -7,8 +7,10 @@ import { WINDOW } from "@bitwarden/angular/services/injection-tokens"; import { EventUploadService as EventUploadServiceAbstraction } from "@bitwarden/common/abstractions/event/event-upload.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { TwoFactorService as TwoFactorServiceAbstraction } from "@bitwarden/common/auth/abstractions/two-factor.service"; +import { BulkEncryptService } from "@bitwarden/common/key-management/crypto/abstractions/bulk-encrypt.service"; import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { DefaultVaultTimeoutService } from "@bitwarden/common/key-management/vault-timeout"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { SdkLoadService } from "@bitwarden/common/platform/abstractions/sdk/sdk-load.service"; @@ -49,6 +51,8 @@ export class InitService { private sshAgentService: SshAgentService, private autofillService: DesktopAutofillService, private sdkLoadService: SdkLoadService, + private configService: ConfigService, + private bulkEncryptService: BulkEncryptService, @Inject(DOCUMENT) private document: Document, ) {} @@ -59,6 +63,13 @@ export class InitService { this.nativeMessagingService.init(); await this.stateService.init({ runMigrations: false }); // Desktop will run them in main process + this.configService.serverConfig$.subscribe((newConfig) => { + if (newConfig != null) { + this.encryptService.onServerConfigChange(newConfig); + this.bulkEncryptService.onServerConfigChange(newConfig); + } + }); + const accounts = await firstValueFrom(this.accountService.accounts$); const setUserKeyInMemoryPromises = []; for (const userId of Object.keys(accounts) as UserId[]) { diff --git a/apps/desktop/src/app/tools/send/add-edit.component.html b/apps/desktop/src/app/tools/send/add-edit.component.html index 3d8231d07ce..0bf2e1778e0 100644 --- a/apps/desktop/src/app/tools/send/add-edit.component.html +++ b/apps/desktop/src/app/tools/send/add-edit.component.html @@ -282,14 +282,9 @@