mirror of
https://github.com/bitwarden/browser
synced 2026-01-02 08:33:43 +00:00
[PM-15506] Implement vNextOrganizationService (#12839)
* [PM-15506] Wire up vNextOrganizationService for libs/common and libs/angular (#12683) * Wire up vNextOrganizationService in PolicyService * Wire vNextOrganizationService in SyncService * wire vNextOrganizationService for EventCollectionService * wire vNextOrganizationService for KeyConnectorService * wire up vNextOrganizationService for CipherAuthorizationService * Wire up vNextOrganizationService in PolicyService * Wire vNextOrganizationService in SyncService * wire vNextOrganizationService for EventCollectionService * wire vNextOrganizationService for KeyConnectorService * wire up vNextOrganizationService for CipherAuthorizationService * wire vNextOrganizationService for share.component * wire vNextOrganizationService for collections.component * wire vNextOrganizationServcie for add-account-credit-dialog * wire vNextOrganizationService for vault-filter.service * fix browser errors for vNextOrganizationService implementation in libs * fix desktop errors for vNextOrganizationService implementation for libs * fix linter errors * fix CLI errors on vNextOrganizationServcie implementations for libs * [PM-15506] Wire up vNextOrganizationService for web client (#12810) PR to a feature branch, no need to review until this goes to main. * implement vNextOrganization service for browser client (#12844) PR to feature branch, no need for review yet. * wire vNextOrganizationService for licence and some web router guards * wire vNextOrganizationService in tests * remove vNext notation for OrganizationService and related * Merge branch 'main' into ac/pm-15506-vNextOrganizationService * fix tsstrict error * fix test, fix ts strict error
This commit is contained in:
@@ -8,7 +8,7 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { OrganizationUserStatusType, PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { CipherId } from "@bitwarden/common/types/guid";
|
||||
import { CipherId, UserId } from "@bitwarden/common/types/guid";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
|
||||
import { CipherType } from "@bitwarden/common/vault/enums";
|
||||
@@ -46,7 +46,7 @@ export class DefaultCipherFormConfigService implements CipherFormConfigService {
|
||||
const [organizations, collections, allowPersonalOwnership, folders, cipher] =
|
||||
await firstValueFrom(
|
||||
combineLatest([
|
||||
this.organizations$,
|
||||
this.organizations$(activeUserId),
|
||||
this.collectionService.encryptedCollections$.pipe(
|
||||
switchMap((c) =>
|
||||
this.collectionService.decryptedCollections$.pipe(
|
||||
@@ -78,13 +78,17 @@ export class DefaultCipherFormConfigService implements CipherFormConfigService {
|
||||
};
|
||||
}
|
||||
|
||||
private organizations$ = this.organizationService.organizations$.pipe(
|
||||
map((orgs) =>
|
||||
orgs.filter(
|
||||
(o) => o.isMember && o.enabled && o.status === OrganizationUserStatusType.Confirmed,
|
||||
),
|
||||
),
|
||||
);
|
||||
organizations$(userId: UserId) {
|
||||
return this.organizationService
|
||||
.organizations$(userId)
|
||||
.pipe(
|
||||
map((orgs) =>
|
||||
orgs.filter(
|
||||
(o) => o.isMember && o.enabled && o.status === OrganizationUserStatusType.Confirmed,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
private allowPersonalOwnership$ = this.policyService
|
||||
.policyAppliesToActiveUser$(PolicyType.PersonalOwnership)
|
||||
|
||||
@@ -4,9 +4,13 @@ import { firstValueFrom, map, Observable, Subject, takeUntil } from "rxjs";
|
||||
|
||||
import { CollectionService, CollectionView } from "@bitwarden/admin-console/common";
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
import {
|
||||
getOrganizationById,
|
||||
OrganizationService,
|
||||
} from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { isCardExpired } from "@bitwarden/common/autofill/utils";
|
||||
import { CollectionId } from "@bitwarden/common/types/guid";
|
||||
import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
|
||||
@@ -133,9 +137,12 @@ export class CipherViewComponent implements OnChanges, OnDestroy {
|
||||
);
|
||||
}
|
||||
|
||||
if (this.cipher.organizationId) {
|
||||
const userId = await firstValueFrom(getUserId(this.accountService.activeAccount$));
|
||||
|
||||
if (this.cipher.organizationId && userId) {
|
||||
this.organization$ = this.organizationService
|
||||
.get$(this.cipher.organizationId)
|
||||
.organizations$(userId)
|
||||
.pipe(getOrganizationById(this.cipher.organizationId))
|
||||
.pipe(takeUntil(this.destroyed$));
|
||||
}
|
||||
|
||||
|
||||
@@ -26,10 +26,14 @@ import {
|
||||
|
||||
import { CollectionService, CollectionView } from "@bitwarden/admin-console/common";
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
import {
|
||||
getOrganizationById,
|
||||
OrganizationService,
|
||||
} from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
import { OrganizationUserStatusType } from "@bitwarden/common/admin-console/enums";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { CipherId, CollectionId, OrganizationId, UserId } from "@bitwarden/common/types/guid";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
@@ -128,28 +132,31 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI
|
||||
protected orgName: string;
|
||||
protected showOrgSelector: boolean = false;
|
||||
|
||||
protected organizations$: Observable<Organization[]> =
|
||||
this.organizationService.organizations$.pipe(
|
||||
map((orgs) =>
|
||||
orgs
|
||||
.filter((o) => o.enabled && o.status === OrganizationUserStatusType.Confirmed)
|
||||
.sort((a, b) => a.name.localeCompare(b.name)),
|
||||
),
|
||||
tap((orgs) => {
|
||||
if (orgs.length > 0 && this.showOrgSelector) {
|
||||
// Using setTimeout to defer the patchValue call until the next event loop cycle
|
||||
setTimeout(() => {
|
||||
this.formGroup.patchValue({ selectedOrg: orgs[0].id });
|
||||
this.setFormValidators();
|
||||
protected organizations$: Observable<Organization[]> = this.accountService.activeAccount$.pipe(
|
||||
switchMap((account) =>
|
||||
this.organizationService.organizations$(account?.id).pipe(
|
||||
map((orgs) =>
|
||||
orgs
|
||||
.filter((o) => o.enabled && o.status === OrganizationUserStatusType.Confirmed)
|
||||
.sort((a, b) => a.name.localeCompare(b.name)),
|
||||
),
|
||||
tap((orgs) => {
|
||||
if (orgs.length > 0 && this.showOrgSelector) {
|
||||
// Using setTimeout to defer the patchValue call until the next event loop cycle
|
||||
setTimeout(() => {
|
||||
this.formGroup.patchValue({ selectedOrg: orgs[0].id });
|
||||
this.setFormValidators();
|
||||
|
||||
// Disable the org selector if there is only one organization
|
||||
if (orgs.length === 1) {
|
||||
this.formGroup.controls.selectedOrg.disable();
|
||||
}
|
||||
});
|
||||
}
|
||||
}),
|
||||
);
|
||||
// Disable the org selector if there is only one organization
|
||||
if (orgs.length === 1) {
|
||||
this.formGroup.controls.selectedOrg.disable();
|
||||
}
|
||||
});
|
||||
}
|
||||
}),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
protected transferWarningText = (orgName: string, itemsCount: number) => {
|
||||
const haveOrgName = !!orgName;
|
||||
@@ -354,7 +361,10 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI
|
||||
return;
|
||||
}
|
||||
|
||||
const org = await this.organizationService.get(organizationId);
|
||||
const userId = await firstValueFrom(getUserId(this.accountService.activeAccount$));
|
||||
const org = await firstValueFrom(
|
||||
this.organizationService.organizations$(userId).pipe(getOrganizationById(organizationId)),
|
||||
);
|
||||
this.orgName = org.name;
|
||||
|
||||
this.editableItems = org.canEditAllCiphers
|
||||
@@ -408,7 +418,9 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI
|
||||
private getCollectionsForOrganization(orgId: OrganizationId): Observable<CollectionView[]> {
|
||||
return combineLatest([
|
||||
this.collectionService.decryptedCollections$,
|
||||
this.organizationService.organizations$,
|
||||
this.accountService.activeAccount$.pipe(
|
||||
switchMap((account) => this.organizationService.organizations$(account?.id)),
|
||||
),
|
||||
]).pipe(
|
||||
map(([collections, organizations]) => {
|
||||
const org = organizations.find((o) => o.id === orgId);
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { DialogRef } from "@angular/cdk/dialog";
|
||||
import { Component } from "@angular/core";
|
||||
import { FormBuilder, ReactiveFormsModule, Validators } from "@angular/forms";
|
||||
import { firstValueFrom, map } from "rxjs";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import {
|
||||
@@ -57,7 +58,7 @@ export class PasswordRepromptComponent {
|
||||
return;
|
||||
}
|
||||
|
||||
const userId = await firstValueFrom(this.accountService.activeAccount$.pipe(map((a) => a?.id)));
|
||||
const userId = await firstValueFrom(getUserId(this.accountService.activeAccount$));
|
||||
|
||||
if (userId == null) {
|
||||
throw new Error("An active user is expected while doing password reprompt.");
|
||||
|
||||
@@ -43,7 +43,7 @@ describe("Default task service", () => {
|
||||
{
|
||||
provide: OrganizationService,
|
||||
useValue: {
|
||||
getAll$: mockGetAllOrgs$,
|
||||
organizations$: mockGetAllOrgs$,
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
@@ -23,7 +23,7 @@ export class DefaultTaskService implements TaskService {
|
||||
|
||||
tasksEnabled$ = perUserCache$((userId) => {
|
||||
return this.organizationService
|
||||
.getAll$(userId)
|
||||
.organizations$(userId)
|
||||
.pipe(map((orgs) => orgs.some((o) => o.useRiskInsights)));
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user