From c6dccc354c0ecc7f6e58bf3f3d80fed16ad25c8a Mon Sep 17 00:00:00 2001 From: Justin Baur <19896123+justindbaur@users.noreply.github.com> Date: Tue, 27 Sep 2022 16:25:19 -0400 Subject: [PATCH] [PS-1092] Organization Service Observables (#3462) * Update imports * Implement observables in a few places * Add tests * Get all clients working * Use _destroy * Address PR feedback * Address PR feedback * Address feedback --- .../browser/src/background/main.background.ts | 12 +- .../organization-service.factory.ts | 15 +- .../sync-notifier-service.factory.ts | 17 ++ .../src/popup/services/services.module.ts | 2 +- .../src/popup/vault/add-edit.component.ts | 2 +- .../src/popup/vault/ciphers.component.ts | 4 +- .../src/popup/vault/current-tab.component.ts | 4 +- .../src/popup/vault/share.component.html | 134 +++++------ .../src/popup/vault/share.component.ts | 2 +- .../popup/vault/vault-select.component.html | 129 ++++++----- .../src/popup/vault/vault-select.component.ts | 111 ++++----- .../src/services/vaultFilter.service.ts | 2 +- apps/cli/src/bw.ts | 12 +- .../commands/convertToKeyConnector.command.ts | 1 - apps/cli/src/commands/get.command.ts | 2 +- apps/cli/src/commands/import.command.ts | 2 +- apps/cli/src/commands/list.command.ts | 2 +- .../src/app/vault/add-edit.component.ts | 2 +- .../src/app/vault/share.component.html | 134 +++++------ apps/desktop/src/app/vault/share.component.ts | 2 +- .../trial-initiation/billing.component.ts | 2 +- .../src/app/common/base.people.component.ts | 7 +- .../organization-switcher.component.html | 6 +- .../organization-switcher.component.ts | 22 +- .../web/src/app/layouts/navbar.component.html | 8 +- apps/web/src/app/layouts/navbar.component.ts | 39 +--- .../guards/org-permissions.guard.spec.ts | 16 +- .../guards/org-permissions.guard.ts | 9 +- .../organization-layout.component.html | 78 ++++--- .../layouts/organization-layout.component.ts | 94 ++++---- .../manage/collection-add-edit.component.ts | 2 +- .../manage/collections.component.ts | 2 +- .../organizations/manage/events.component.ts | 2 +- .../organizations/manage/manage.component.ts | 2 +- .../organizations/manage/people.component.ts | 2 +- .../manage/policies.component.ts | 2 +- .../organizations/navigation-permissions.ts | 29 --- .../organization-routing.module.ts | 12 +- .../policies/master-password.component.ts | 2 +- .../policies/reset-password.component.ts | 2 +- .../settings/account.component.ts | 16 +- .../settings/delete-organization.component.ts | 2 +- .../organization-subscription.component.ts | 4 +- .../settings/settings.component.ts | 2 +- ...milies-for-enterprise-setup.component.html | 4 +- ...families-for-enterprise-setup.component.ts | 28 ++- .../exposed-passwords-report.component.ts | 2 +- .../import-export/org-import.component.ts | 2 +- .../inactive-two-factor-report.component.ts | 2 +- .../reused-passwords-report.component.ts | 2 +- .../organizations/tools/tools.component.ts | 2 +- .../unsecured-websites-report.component.ts | 2 +- .../tools/weak-passwords-report.component.ts | 2 +- .../organizations/vault/add-edit.component.ts | 2 +- .../organizations/vault/ciphers.component.ts | 2 +- .../organizations/vault/vault.component.ts | 2 +- .../src/app/settings/add-credit.component.ts | 2 +- .../app/settings/change-password.component.ts | 2 +- .../settings/emergency-access.component.ts | 2 +- .../settings/emergency-add-edit.component.ts | 2 +- .../settings/organization-plans.component.ts | 2 +- .../src/app/settings/settings.component.ts | 2 +- .../sponsored-families.component.html | 12 +- .../settings/sponsored-families.component.ts | 118 +++++----- apps/web/src/app/vault/add-edit.component.ts | 2 +- .../web/src/app/vault/bulk-share.component.ts | 17 +- apps/web/src/app/vault/ciphers.component.ts | 2 +- apps/web/src/app/vault/share.component.html | 145 ++++++------ apps/web/src/app/vault/share.component.ts | 2 +- .../organization-options.component.ts | 4 +- .../shared/vault-filter.service.ts | 2 +- apps/web/src/app/vault/vault.component.ts | 2 +- .../app/organizations/manage/sso.component.ts | 2 +- .../organizations-routing.module.ts | 2 +- .../providers/clients/clients.component.ts | 2 +- .../src/components/add-edit.component.ts | 2 +- .../export-scope-callout.component.ts | 6 +- .../components/remove-password.component.ts | 6 +- .../angular/src/components/share.component.ts | 57 +++-- .../src/services/jslib-services.module.ts | 20 +- .../services/vault-filter.service.ts | 6 +- .../organization/organization.service.spec.ts | 210 ++++++++++++++++++ .../src/abstractions/organization.service.ts | 11 - .../organization.service.abstraction.ts | 53 +++++ libs/common/src/abstractions/state.service.ts | 6 + .../sync/sync.service.abstraction.ts | 5 - .../sync/syncNotifier.service.abstraction.ts | 8 + libs/common/src/misc/utils.ts | 12 +- libs/common/src/services/event.service.ts | 2 +- .../src/services/keyConnector.service.ts | 2 +- .../src/services/organization.service.ts | 56 ----- .../organization/organization-api.service.ts | 22 +- .../organization/organization.service.ts | 119 ++++++++++ .../src/services/policy/policy-api.service.ts | 2 +- .../src/services/policy/policy.service.ts | 2 +- libs/common/src/services/state.service.ts | 6 + libs/common/src/services/sync/sync.service.ts | 32 +-- .../src/services/sync/syncNotifier.service.ts | 18 ++ libs/common/src/types/checkable.ts | 9 + libs/common/src/types/syncEventArgs.ts | 37 ++- 100 files changed, 1225 insertions(+), 813 deletions(-) create mode 100644 apps/browser/src/background/service_factories/sync-notifier-service.factory.ts delete mode 100644 apps/web/src/app/organizations/navigation-permissions.ts create mode 100644 libs/common/spec/services/organization/organization.service.spec.ts delete mode 100644 libs/common/src/abstractions/organization.service.ts create mode 100644 libs/common/src/abstractions/organization/organization.service.abstraction.ts create mode 100644 libs/common/src/abstractions/sync/syncNotifier.service.abstraction.ts delete mode 100644 libs/common/src/services/organization.service.ts create mode 100644 libs/common/src/services/organization/organization.service.ts create mode 100644 libs/common/src/services/sync/syncNotifier.service.ts create mode 100644 libs/common/src/types/checkable.ts diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index 99114bc007..cf83b6e78d 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -16,7 +16,7 @@ import { KeyConnectorService as KeyConnectorServiceAbstraction } from "@bitwarde import { LogService as LogServiceAbstraction } from "@bitwarden/common/abstractions/log.service"; import { MessagingService as MessagingServiceAbstraction } from "@bitwarden/common/abstractions/messaging.service"; import { NotificationsService as NotificationsServiceAbstraction } from "@bitwarden/common/abstractions/notifications.service"; -import { OrganizationService as OrganizationServiceAbstraction } from "@bitwarden/common/abstractions/organization.service"; +import { OrganizationService as OrganizationServiceAbstraction } from "@bitwarden/common/abstractions/organization/organization.service.abstraction"; import { PasswordGenerationService as PasswordGenerationServiceAbstraction } from "@bitwarden/common/abstractions/passwordGeneration.service"; import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from "@bitwarden/common/abstractions/platformUtils.service"; import { PolicyApiServiceAbstraction } from "@bitwarden/common/abstractions/policy/policy-api.service.abstraction"; @@ -27,6 +27,7 @@ import { SendService as SendServiceAbstraction } from "@bitwarden/common/abstrac import { SettingsService as SettingsServiceAbstraction } from "@bitwarden/common/abstractions/settings.service"; import { AbstractStorageService } from "@bitwarden/common/abstractions/storage.service"; import { SyncService as SyncServiceAbstraction } from "@bitwarden/common/abstractions/sync/sync.service.abstraction"; +import { SyncNotifierService as SyncNotifierServiceAbstraction } from "@bitwarden/common/abstractions/sync/syncNotifier.service.abstraction"; import { SystemService as SystemServiceAbstraction } from "@bitwarden/common/abstractions/system.service"; import { TokenService as TokenServiceAbstraction } from "@bitwarden/common/abstractions/token.service"; import { TotpService as TotpServiceAbstraction } from "@bitwarden/common/abstractions/totp.service"; @@ -58,7 +59,7 @@ import { FolderApiService } from "@bitwarden/common/services/folder/folder-api.s import { KeyConnectorService } from "@bitwarden/common/services/keyConnector.service"; import { MemoryStorageService } from "@bitwarden/common/services/memoryStorage.service"; import { NotificationsService } from "@bitwarden/common/services/notifications.service"; -import { OrganizationService } from "@bitwarden/common/services/organization.service"; +import { OrganizationService } from "@bitwarden/common/services/organization/organization.service"; import { PasswordGenerationService } from "@bitwarden/common/services/passwordGeneration.service"; import { PolicyApiService } from "@bitwarden/common/services/policy/policy-api.service"; import { PolicyService } from "@bitwarden/common/services/policy/policy.service"; @@ -68,6 +69,7 @@ import { SendService } from "@bitwarden/common/services/send.service"; import { SettingsService } from "@bitwarden/common/services/settings.service"; import { StateMigrationService } from "@bitwarden/common/services/stateMigration.service"; import { SyncService } from "@bitwarden/common/services/sync/sync.service"; +import { SyncNotifierService } from "@bitwarden/common/services/sync/syncNotifier.service"; import { SystemService } from "@bitwarden/common/services/system.service"; import { TokenService } from "@bitwarden/common/services/token.service"; import { TotpService } from "@bitwarden/common/services/totp.service"; @@ -158,6 +160,7 @@ export default class MainBackground { folderApiService: FolderApiServiceAbstraction; policyApiService: PolicyApiServiceAbstraction; userVerificationApiService: UserVerificationApiServiceAbstraction; + syncNotifierService: SyncNotifierServiceAbstraction; // Passed to the popup for Safari to workaround issues with theming, downloading, etc. backgroundWindow = window; @@ -298,7 +301,8 @@ export default class MainBackground { this.cryptoFunctionService, this.stateService ); - this.organizationService = new OrganizationService(this.stateService); + this.syncNotifierService = new SyncNotifierService(); + this.organizationService = new OrganizationService(this.stateService, this.syncNotifierService); this.policyService = new PolicyService(this.stateService, this.organizationService); this.policyApiService = new PolicyApiService( this.policyService, @@ -388,9 +392,9 @@ export default class MainBackground { this.logService, this.keyConnectorService, this.stateService, - this.organizationService, this.providerService, this.folderApiService, + this.syncNotifierService, logoutCallback ); this.eventService = new EventService( diff --git a/apps/browser/src/background/service_factories/organization-service.factory.ts b/apps/browser/src/background/service_factories/organization-service.factory.ts index 87692e6439..2e7c31b596 100644 --- a/apps/browser/src/background/service_factories/organization-service.factory.ts +++ b/apps/browser/src/background/service_factories/organization-service.factory.ts @@ -1,12 +1,17 @@ -import { OrganizationService as AbstractOrganizationService } from "@bitwarden/common/abstractions/organization.service"; -import { OrganizationService } from "@bitwarden/common/services/organization.service"; +import { OrganizationService as AbstractOrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction"; +import { OrganizationService } from "@bitwarden/common/services/organization/organization.service"; import { FactoryOptions, CachedServices, factory } from "./factory-options"; import { stateServiceFactory, StateServiceInitOptions } from "./state-service.factory"; +import { + syncNotifierServiceFactory, + SyncNotifierServiceInitOptions, +} from "./sync-notifier-service.factory"; type OrganizationServiceFactoryOptions = FactoryOptions; export type OrganizationServiceInitOptions = OrganizationServiceFactoryOptions & + SyncNotifierServiceInitOptions & StateServiceInitOptions; export function organizationServiceFactory( @@ -17,6 +22,10 @@ export function organizationServiceFactory( cache, "organizationService", opts, - async () => new OrganizationService(await stateServiceFactory(cache, opts)) + async () => + new OrganizationService( + await stateServiceFactory(cache, opts), + await syncNotifierServiceFactory(cache, opts) + ) ); } diff --git a/apps/browser/src/background/service_factories/sync-notifier-service.factory.ts b/apps/browser/src/background/service_factories/sync-notifier-service.factory.ts new file mode 100644 index 0000000000..58699bdff5 --- /dev/null +++ b/apps/browser/src/background/service_factories/sync-notifier-service.factory.ts @@ -0,0 +1,17 @@ +import { SyncNotifierService as AbstractSyncNotifierService } from "@bitwarden/common/abstractions/sync/syncNotifier.service.abstraction"; +import { SyncNotifierService } from "@bitwarden/common/services/sync/syncNotifier.service"; + +import { FactoryOptions, CachedServices, factory } from "./factory-options"; + +type SyncNotifierServiceFactoryOptions = FactoryOptions; + +export type SyncNotifierServiceInitOptions = SyncNotifierServiceFactoryOptions; + +export function syncNotifierServiceFactory( + cache: { syncNotifierService?: AbstractSyncNotifierService } & CachedServices, + opts: SyncNotifierServiceInitOptions +): Promise { + return factory(cache, "syncNotifierService", opts, () => + Promise.resolve(new SyncNotifierService()) + ); +} diff --git a/apps/browser/src/popup/services/services.module.ts b/apps/browser/src/popup/services/services.module.ts index 87c1dd17e9..a79028a26d 100644 --- a/apps/browser/src/popup/services/services.module.ts +++ b/apps/browser/src/popup/services/services.module.ts @@ -26,7 +26,7 @@ import { KeyConnectorService } from "@bitwarden/common/abstractions/keyConnector import { LogService as LogServiceAbstraction } from "@bitwarden/common/abstractions/log.service"; import { MessagingService } from "@bitwarden/common/abstractions/messaging.service"; import { NotificationsService } from "@bitwarden/common/abstractions/notifications.service"; -import { OrganizationService } from "@bitwarden/common/abstractions/organization.service"; +import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction"; import { PasswordGenerationService } from "@bitwarden/common/abstractions/passwordGeneration.service"; import { PasswordRepromptService as PasswordRepromptServiceAbstraction } from "@bitwarden/common/abstractions/passwordReprompt.service"; import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service"; diff --git a/apps/browser/src/popup/vault/add-edit.component.ts b/apps/browser/src/popup/vault/add-edit.component.ts index f5062051c2..d220a24a0d 100644 --- a/apps/browser/src/popup/vault/add-edit.component.ts +++ b/apps/browser/src/popup/vault/add-edit.component.ts @@ -12,7 +12,7 @@ import { FolderService } from "@bitwarden/common/abstractions/folder/folder.serv import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/abstractions/log.service"; import { MessagingService } from "@bitwarden/common/abstractions/messaging.service"; -import { OrganizationService } from "@bitwarden/common/abstractions/organization.service"; +import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction"; import { PasswordRepromptService } from "@bitwarden/common/abstractions/passwordReprompt.service"; import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service"; import { PolicyService } from "@bitwarden/common/abstractions/policy/policy.service.abstraction"; diff --git a/apps/browser/src/popup/vault/ciphers.component.ts b/apps/browser/src/popup/vault/ciphers.component.ts index 4346ad7a66..60a92e238c 100644 --- a/apps/browser/src/popup/vault/ciphers.component.ts +++ b/apps/browser/src/popup/vault/ciphers.component.ts @@ -10,7 +10,7 @@ import { CipherService } from "@bitwarden/common/abstractions/cipher.service"; import { CollectionService } from "@bitwarden/common/abstractions/collection.service"; import { FolderService } from "@bitwarden/common/abstractions/folder/folder.service.abstraction"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; -import { OrganizationService } from "@bitwarden/common/abstractions/organization.service"; +import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction"; import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service"; import { SearchService } from "@bitwarden/common/abstractions/search.service"; import { CipherType } from "@bitwarden/common/enums/cipherType"; @@ -78,7 +78,7 @@ export class CiphersComponent extends BaseCiphersComponent implements OnInit, On async ngOnInit() { this.searchTypeSearch = !this.platformUtilsService.isSafari(); - this.showOrganizations = await this.organizationService.hasOrganizations(); + this.showOrganizations = this.organizationService.hasOrganizations(); this.vaultFilter = this.vaultFilterService.getVaultFilter(); // eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe this.route.queryParams.pipe(first()).subscribe(async (params) => { diff --git a/apps/browser/src/popup/vault/current-tab.component.ts b/apps/browser/src/popup/vault/current-tab.component.ts index 2f3569841f..f3e97dd233 100644 --- a/apps/browser/src/popup/vault/current-tab.component.ts +++ b/apps/browser/src/popup/vault/current-tab.component.ts @@ -4,7 +4,7 @@ import { Router } from "@angular/router"; import { BroadcasterService } from "@bitwarden/common/abstractions/broadcaster.service"; import { CipherService } from "@bitwarden/common/abstractions/cipher.service"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; -import { OrganizationService } from "@bitwarden/common/abstractions/organization.service"; +import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction"; import { PasswordRepromptService } from "@bitwarden/common/abstractions/passwordReprompt.service"; import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service"; import { SearchService } from "@bitwarden/common/abstractions/search.service"; @@ -219,7 +219,7 @@ export class CurrentTabComponent implements OnInit, OnDestroy { const otherTypes: CipherType[] = []; const dontShowCards = await this.stateService.getDontShowCardsCurrentTab(); const dontShowIdentities = await this.stateService.getDontShowIdentitiesCurrentTab(); - this.showOrganizations = await this.organizationService.hasOrganizations(); + this.showOrganizations = this.organizationService.hasOrganizations(); if (!dontShowCards) { otherTypes.push(CipherType.Card); } diff --git a/apps/browser/src/popup/vault/share.component.html b/apps/browser/src/popup/vault/share.component.html index ad1447f6f6..dcec42415c 100644 --- a/apps/browser/src/popup/vault/share.component.html +++ b/apps/browser/src/popup/vault/share.component.html @@ -1,70 +1,76 @@
-
-
- -
-

- {{ "moveToOrganization" | i18n }} -

-
- -
-
-
-
-
-
- {{ "noOrganizationsList" | i18n }} -
+ +
+
+
-
-
- - -
-
- -
-
-

- {{ "collections" | i18n }} -

-
-
- {{ "noCollectionsInList" | i18n }} -
-
-
-
+ {{ "moveToOrganization" | i18n }} + +
+ +
+ +
+
+
+
+ {{ "noOrganizationsList" | i18n }} +
+
+
+
+ + +
+
+
-
-
+
+

+ {{ "collections" | i18n }} +

+
+
+ {{ "noCollectionsInList" | i18n }} +
+
+
+
+ + +
+
+
+ +
diff --git a/apps/browser/src/popup/vault/share.component.ts b/apps/browser/src/popup/vault/share.component.ts index bfff215533..112b432c0e 100644 --- a/apps/browser/src/popup/vault/share.component.ts +++ b/apps/browser/src/popup/vault/share.component.ts @@ -7,7 +7,7 @@ import { CipherService } from "@bitwarden/common/abstractions/cipher.service"; import { CollectionService } from "@bitwarden/common/abstractions/collection.service"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/abstractions/log.service"; -import { OrganizationService } from "@bitwarden/common/abstractions/organization.service"; +import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction"; import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service"; @Component({ diff --git a/apps/browser/src/popup/vault/vault-select.component.html b/apps/browser/src/popup/vault/vault-select.component.html index d5698e7928..95d1effd7f 100644 --- a/apps/browser/src/popup/vault/vault-select.component.html +++ b/apps/browser/src/popup/vault/vault-select.component.html @@ -1,71 +1,70 @@ -
- - - + + + + +
+ diff --git a/apps/browser/src/popup/vault/vault-select.component.ts b/apps/browser/src/popup/vault/vault-select.component.ts index d12463f2c1..04ae04d0fa 100644 --- a/apps/browser/src/popup/vault/vault-select.component.ts +++ b/apps/browser/src/popup/vault/vault-select.component.ts @@ -5,19 +5,19 @@ import { Component, ElementRef, EventEmitter, - NgZone, OnInit, Output, TemplateRef, ViewChild, ViewContainerRef, HostListener, + OnDestroy, } from "@angular/core"; -import { merge } from "rxjs"; +import { BehaviorSubject, concatMap, map, merge, Observable, Subject, takeUntil } from "rxjs"; import { VaultFilter } from "@bitwarden/angular/vault/vault-filter/models/vault-filter.model"; -import { BroadcasterService } from "@bitwarden/common/abstractions/broadcaster.service"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; +import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction"; import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service"; import { Organization } from "@bitwarden/common/models/domain/organization"; @@ -47,20 +47,22 @@ import { VaultFilterService } from "../../services/vaultFilter.service"; ]), ], }) -// eslint-disable-next-line rxjs-angular/prefer-takeuntil -export class VaultSelectComponent implements OnInit { +export class VaultSelectComponent implements OnInit, OnDestroy { @Output() onVaultSelectionChanged = new EventEmitter(); @ViewChild("toggleVaults", { read: ElementRef }) buttonRef: ElementRef; @ViewChild("vaultSelectorTemplate", { read: TemplateRef }) templateRef: TemplateRef; + private _selectedVault = new BehaviorSubject(null); + isOpen = false; loaded = false; - organizations: Organization[]; + organizations$: Observable; + selectedVault$: Observable = this._selectedVault.asObservable(); + vaultFilter: VaultFilter = new VaultFilter(); - vaultFilterDisplay = ""; - enforcePersonalOwnwership = false; + enforcePersonalOwnership = false; overlayPostition: ConnectedPosition[] = [ { originX: "start", @@ -71,22 +73,22 @@ export class VaultSelectComponent implements OnInit { ]; private overlayRef: OverlayRef; + private _destroy = new Subject(); - get show() { + shouldShow(organizations: Organization[]): boolean { return ( - (this.organizations.length > 0 && !this.enforcePersonalOwnwership) || - (this.organizations.length > 1 && this.enforcePersonalOwnwership) + (organizations.length > 0 && !this.enforcePersonalOwnership) || + (organizations.length > 1 && this.enforcePersonalOwnership) ); } constructor( private vaultFilterService: VaultFilterService, private i18nService: I18nService, - private ngZone: NgZone, - private broadcasterService: BroadcasterService, private overlay: Overlay, private viewContainerRef: ViewContainerRef, - private platformUtilsService: PlatformUtilsService + private platformUtilsService: PlatformUtilsService, + private organizationService: OrganizationService ) {} @HostListener("document:keydown.escape", ["$event"]) @@ -98,46 +100,45 @@ export class VaultSelectComponent implements OnInit { } async ngOnInit() { - await this.load(); - this.broadcasterService.subscribe(this.constructor.name, (message: any) => { - this.ngZone.run(async () => { - switch (message.command) { - case "syncCompleted": - await this.load(); - break; - default: - break; - } - }); - }); + this.organizations$ = this.organizationService.organizations$ + .pipe(takeUntil(this._destroy)) + .pipe(map((orgs) => orgs.sort((a, b) => a.name.localeCompare(b.name)))); + + this.organizations$ + .pipe( + concatMap(async (organizations) => { + this.enforcePersonalOwnership = + await this.vaultFilterService.checkForPersonalOwnershipPolicy(); + + if (this.shouldShow(organizations)) { + if (this.enforcePersonalOwnership && !this.vaultFilter.myVaultOnly) { + const firstOrganization = organizations[0]; + this._selectedVault.next(firstOrganization.name); + this.vaultFilterService.setVaultFilter(firstOrganization.id); + this.vaultFilter.selectedOrganizationId = firstOrganization.id; + } else if (this.vaultFilter.myVaultOnly) { + this._selectedVault.next(this.i18nService.t(this.vaultFilterService.myVault)); + } else if (this.vaultFilter.selectedOrganizationId != null) { + const selectedOrganization = organizations.find( + (o) => o.id === this.vaultFilter.selectedOrganizationId + ); + this._selectedVault.next(selectedOrganization.name); + } else { + this._selectedVault.next(this.i18nService.t(this.vaultFilterService.allVaults)); + } + } + }) + ) + .pipe(takeUntil(this._destroy)) + .subscribe(); + + this.loaded = true; } - async load() { - this.vaultFilter = this.vaultFilterService.getVaultFilter(); - this.organizations = (await this.vaultFilterService.buildOrganizations()).sort((a, b) => - a.name.localeCompare(b.name) - ); - this.enforcePersonalOwnwership = - await this.vaultFilterService.checkForPersonalOwnershipPolicy(); - - if (this.show) { - if (this.enforcePersonalOwnwership && !this.vaultFilter.myVaultOnly) { - this.vaultFilterService.setVaultFilter(this.organizations[0].id); - this.vaultFilter.selectedOrganizationId = this.organizations[0].id; - this.vaultFilterDisplay = this.organizations.find( - (o) => o.id === this.vaultFilter.selectedOrganizationId - ).name; - } else if (this.vaultFilter.myVaultOnly) { - this.vaultFilterDisplay = this.i18nService.t(this.vaultFilterService.myVault); - } else if (this.vaultFilter.selectedOrganizationId != null) { - this.vaultFilterDisplay = this.organizations.find( - (o) => o.id === this.vaultFilter.selectedOrganizationId - ).name; - } else { - this.vaultFilterDisplay = this.i18nService.t(this.vaultFilterService.allVaults); - } - } - this.loaded = true; + ngOnDestroy(): void { + this._destroy.next(); + this._destroy.complete(); + this._selectedVault.complete(); } openOverlay() { @@ -191,20 +192,20 @@ export class VaultSelectComponent implements OnInit { this.i18nService.t("disabledOrganizationFilterError") ); } else { - this.vaultFilterDisplay = organization.name; + this._selectedVault.next(organization.name); this.vaultFilterService.setVaultFilter(organization.id); this.onVaultSelectionChanged.emit(); this.close(); } } selectAllVaults() { - this.vaultFilterDisplay = this.i18nService.t(this.vaultFilterService.allVaults); + this._selectedVault.next(this.i18nService.t(this.vaultFilterService.allVaults)); this.vaultFilterService.setVaultFilter(this.vaultFilterService.allVaults); this.onVaultSelectionChanged.emit(); this.close(); } selectMyVault() { - this.vaultFilterDisplay = this.i18nService.t(this.vaultFilterService.myVault); + this._selectedVault.next(this.i18nService.t(this.vaultFilterService.myVault)); this.vaultFilterService.setVaultFilter(this.vaultFilterService.myVault); this.onVaultSelectionChanged.emit(); this.close(); diff --git a/apps/browser/src/services/vaultFilter.service.ts b/apps/browser/src/services/vaultFilter.service.ts index b921a21292..77016638d8 100644 --- a/apps/browser/src/services/vaultFilter.service.ts +++ b/apps/browser/src/services/vaultFilter.service.ts @@ -3,7 +3,7 @@ import { VaultFilterService as BaseVaultFilterService } from "@bitwarden/angular import { CipherService } from "@bitwarden/common/abstractions/cipher.service"; import { CollectionService } from "@bitwarden/common/abstractions/collection.service"; import { FolderService } from "@bitwarden/common/abstractions/folder/folder.service.abstraction"; -import { OrganizationService } from "@bitwarden/common/abstractions/organization.service"; +import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction"; import { PolicyService } from "@bitwarden/common/abstractions/policy/policy.service.abstraction"; import { StateService } from "@bitwarden/common/abstractions/state.service"; import { CipherView } from "@bitwarden/common/models/view/cipherView"; diff --git a/apps/cli/src/bw.ts b/apps/cli/src/bw.ts index 734a030943..489f92fac9 100644 --- a/apps/cli/src/bw.ts +++ b/apps/cli/src/bw.ts @@ -30,8 +30,8 @@ import { ImportService } from "@bitwarden/common/services/import.service"; import { KeyConnectorService } from "@bitwarden/common/services/keyConnector.service"; import { MemoryStorageService } from "@bitwarden/common/services/memoryStorage.service"; import { NoopMessagingService } from "@bitwarden/common/services/noopMessaging.service"; -import { OrganizationService } from "@bitwarden/common/services/organization.service"; import { OrganizationApiService } from "@bitwarden/common/services/organization/organization-api.service"; +import { OrganizationService } from "@bitwarden/common/services/organization/organization.service"; import { PasswordGenerationService } from "@bitwarden/common/services/passwordGeneration.service"; import { PolicyService } from "@bitwarden/common/services/policy/policy.service"; import { ProviderService } from "@bitwarden/common/services/provider.service"; @@ -41,6 +41,7 @@ import { SettingsService } from "@bitwarden/common/services/settings.service"; import { StateService } from "@bitwarden/common/services/state.service"; import { StateMigrationService } from "@bitwarden/common/services/stateMigration.service"; import { SyncService } from "@bitwarden/common/services/sync/sync.service"; +import { SyncNotifierService } from "@bitwarden/common/services/sync/syncNotifier.service"; import { TokenService } from "@bitwarden/common/services/token.service"; import { TotpService } from "@bitwarden/common/services/totp.service"; import { TwoFactorService } from "@bitwarden/common/services/twoFactor.service"; @@ -113,6 +114,7 @@ export class Main { folderApiService: FolderApiService; userVerificationApiService: UserVerificationApiService; organizationApiService: OrganizationApiServiceAbstraction; + syncNotifierService: SyncNotifierService; constructor() { let p = null; @@ -191,7 +193,9 @@ export class Main { customUserAgent ); - this.organizationApiService = new OrganizationApiService(this.apiService); + this.syncNotifierService = new SyncNotifierService(); + + this.organizationApiService = new OrganizationApiService(this.apiService, this.syncService); this.containerService = new ContainerService(this.cryptoService, this.encryptService); @@ -231,7 +235,7 @@ export class Main { this.providerService = new ProviderService(this.stateService); - this.organizationService = new OrganizationService(this.stateService); + this.organizationService = new OrganizationService(this.stateService, this.syncNotifierService); this.policyService = new PolicyService(this.stateService, this.organizationService); @@ -311,9 +315,9 @@ export class Main { this.logService, this.keyConnectorService, this.stateService, - this.organizationService, this.providerService, this.folderApiService, + this.syncNotifierService, async (expired: boolean) => await this.logout() ); diff --git a/apps/cli/src/commands/convertToKeyConnector.command.ts b/apps/cli/src/commands/convertToKeyConnector.command.ts index 6339fa9b9a..00fb2f7291 100644 --- a/apps/cli/src/commands/convertToKeyConnector.command.ts +++ b/apps/cli/src/commands/convertToKeyConnector.command.ts @@ -74,7 +74,6 @@ export class ConvertToKeyConnectorCommand { } else if (answer.convert === "leave") { await this.organizationApiService.leave(organization.id); await this.keyConnectorService.removeConvertAccountRequired(); - await this.syncService.fullSync(true); return Response.success(); } else { await this.logout(); diff --git a/apps/cli/src/commands/get.command.ts b/apps/cli/src/commands/get.command.ts index 7cfcd9fb6e..510cb10da3 100644 --- a/apps/cli/src/commands/get.command.ts +++ b/apps/cli/src/commands/get.command.ts @@ -4,7 +4,7 @@ import { CipherService } from "@bitwarden/common/abstractions/cipher.service"; import { CollectionService } from "@bitwarden/common/abstractions/collection.service"; import { CryptoService } from "@bitwarden/common/abstractions/crypto.service"; import { FolderService } from "@bitwarden/common/abstractions/folder/folder.service.abstraction"; -import { OrganizationService } from "@bitwarden/common/abstractions/organization.service"; +import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction"; import { SearchService } from "@bitwarden/common/abstractions/search.service"; import { StateService } from "@bitwarden/common/abstractions/state.service"; import { TotpService } from "@bitwarden/common/abstractions/totp.service"; diff --git a/apps/cli/src/commands/import.command.ts b/apps/cli/src/commands/import.command.ts index f3b04a5f56..6fb17fa2cd 100644 --- a/apps/cli/src/commands/import.command.ts +++ b/apps/cli/src/commands/import.command.ts @@ -2,7 +2,7 @@ import * as program from "commander"; import * as inquirer from "inquirer"; import { ImportService } from "@bitwarden/common/abstractions/import.service"; -import { OrganizationService } from "@bitwarden/common/abstractions/organization.service"; +import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction"; import { ImportType } from "@bitwarden/common/enums/importOptions"; import { Importer } from "@bitwarden/common/importers/importer"; import { Response } from "@bitwarden/node/cli/models/response"; diff --git a/apps/cli/src/commands/list.command.ts b/apps/cli/src/commands/list.command.ts index 4e2d7cb02e..dd779ec057 100644 --- a/apps/cli/src/commands/list.command.ts +++ b/apps/cli/src/commands/list.command.ts @@ -2,7 +2,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { CipherService } from "@bitwarden/common/abstractions/cipher.service"; import { CollectionService } from "@bitwarden/common/abstractions/collection.service"; import { FolderService } from "@bitwarden/common/abstractions/folder/folder.service.abstraction"; -import { OrganizationService } from "@bitwarden/common/abstractions/organization.service"; +import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction"; import { SearchService } from "@bitwarden/common/abstractions/search.service"; import { Utils } from "@bitwarden/common/misc/utils"; import { CollectionData } from "@bitwarden/common/models/data/collectionData"; diff --git a/apps/desktop/src/app/vault/add-edit.component.ts b/apps/desktop/src/app/vault/add-edit.component.ts index aa76d2ba7d..5a2153fadc 100644 --- a/apps/desktop/src/app/vault/add-edit.component.ts +++ b/apps/desktop/src/app/vault/add-edit.component.ts @@ -11,7 +11,7 @@ import { FolderService } from "@bitwarden/common/abstractions/folder/folder.serv import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/abstractions/log.service"; import { MessagingService } from "@bitwarden/common/abstractions/messaging.service"; -import { OrganizationService } from "@bitwarden/common/abstractions/organization.service"; +import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction"; import { PasswordRepromptService } from "@bitwarden/common/abstractions/passwordReprompt.service"; import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service"; import { PolicyService } from "@bitwarden/common/abstractions/policy/policy.service.abstraction"; diff --git a/apps/desktop/src/app/vault/share.component.html b/apps/desktop/src/app/vault/share.component.html index f80c3b4829..f460703d5d 100644 --- a/apps/desktop/src/app/vault/share.component.html +++ b/apps/desktop/src/app/vault/share.component.html @@ -1,78 +1,80 @@