mirror of
https://github.com/bitwarden/browser
synced 2026-01-04 01:23:57 +00:00
[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
This commit is contained in:
@@ -7,7 +7,7 @@ import {
|
||||
import { mock, MockProxy } from "jest-mock-extended";
|
||||
|
||||
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 { SyncService } from "@bitwarden/common/abstractions/sync/sync.service.abstraction";
|
||||
import { OrganizationUserType } from "@bitwarden/common/enums/organizationUserType";
|
||||
@@ -57,7 +57,7 @@ describe("Organization Permissions Guard", () => {
|
||||
});
|
||||
|
||||
it("blocks navigation if organization does not exist", async () => {
|
||||
organizationService.get.mockResolvedValue(null);
|
||||
organizationService.get.mockReturnValue(null);
|
||||
|
||||
const actual = await organizationPermissionsGuard.canActivate(route, state);
|
||||
|
||||
@@ -66,7 +66,7 @@ describe("Organization Permissions Guard", () => {
|
||||
|
||||
it("permits navigation if no permissions are specified", async () => {
|
||||
const org = orgFactory();
|
||||
organizationService.get.calledWith(org.id).mockResolvedValue(org);
|
||||
organizationService.get.calledWith(org.id).mockReturnValue(org);
|
||||
|
||||
const actual = await organizationPermissionsGuard.canActivate(route, state);
|
||||
|
||||
@@ -81,7 +81,7 @@ describe("Organization Permissions Guard", () => {
|
||||
};
|
||||
|
||||
const org = orgFactory();
|
||||
organizationService.get.calledWith(org.id).mockResolvedValue(org);
|
||||
organizationService.get.calledWith(org.id).mockReturnValue(org);
|
||||
|
||||
const actual = await organizationPermissionsGuard.canActivate(route, state);
|
||||
|
||||
@@ -104,7 +104,7 @@ describe("Organization Permissions Guard", () => {
|
||||
});
|
||||
|
||||
const org = orgFactory();
|
||||
organizationService.get.calledWith(org.id).mockResolvedValue(org);
|
||||
organizationService.get.calledWith(org.id).mockReturnValue(org);
|
||||
|
||||
const actual = await organizationPermissionsGuard.canActivate(route, state);
|
||||
|
||||
@@ -124,7 +124,7 @@ describe("Organization Permissions Guard", () => {
|
||||
}),
|
||||
});
|
||||
const org = orgFactory();
|
||||
organizationService.get.calledWith(org.id).mockResolvedValue(org);
|
||||
organizationService.get.calledWith(org.id).mockReturnValue(org);
|
||||
|
||||
const actual = await organizationPermissionsGuard.canActivate(route, state);
|
||||
|
||||
@@ -141,7 +141,7 @@ describe("Organization Permissions Guard", () => {
|
||||
type: OrganizationUserType.Admin,
|
||||
enabled: false,
|
||||
});
|
||||
organizationService.get.calledWith(org.id).mockResolvedValue(org);
|
||||
organizationService.get.calledWith(org.id).mockReturnValue(org);
|
||||
|
||||
const actual = await organizationPermissionsGuard.canActivate(route, state);
|
||||
|
||||
@@ -153,7 +153,7 @@ describe("Organization Permissions Guard", () => {
|
||||
type: OrganizationUserType.Owner,
|
||||
enabled: false,
|
||||
});
|
||||
organizationService.get.calledWith(org.id).mockResolvedValue(org);
|
||||
organizationService.get.calledWith(org.id).mockReturnValue(org);
|
||||
|
||||
const actual = await organizationPermissionsGuard.canActivate(route, state);
|
||||
|
||||
|
||||
@@ -2,13 +2,14 @@ import { Injectable } from "@angular/core";
|
||||
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from "@angular/router";
|
||||
|
||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
|
||||
import {
|
||||
canAccessOrgAdmin,
|
||||
OrganizationService,
|
||||
} from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||
import { SyncService } from "@bitwarden/common/abstractions/sync/sync.service.abstraction";
|
||||
import { Organization } from "@bitwarden/common/models/domain/organization";
|
||||
|
||||
import { canAccessOrgAdmin } from "../navigation-permissions";
|
||||
|
||||
@Injectable({
|
||||
providedIn: "root",
|
||||
})
|
||||
@@ -27,7 +28,7 @@ export class OrganizationPermissionsGuard implements CanActivate {
|
||||
await this.syncService.fullSync(false);
|
||||
}
|
||||
|
||||
const org = await this.organizationService.get(route.params.organizationId);
|
||||
const org = this.organizationService.get(route.params.organizationId);
|
||||
if (org == null) {
|
||||
return this.router.createUrlTree(["/"]);
|
||||
}
|
||||
|
||||
@@ -1,39 +1,49 @@
|
||||
<app-navbar></app-navbar>
|
||||
<div class="org-nav" *ngIf="organization">
|
||||
<div class="container d-flex">
|
||||
<div class="d-flex flex-column">
|
||||
<app-organization-switcher
|
||||
class="my-auto pl-1"
|
||||
[activeOrganization]="organization"
|
||||
></app-organization-switcher>
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" routerLink="vault" routerLinkActive="active">
|
||||
<i class="bwi bwi-lock" aria-hidden="true"></i>
|
||||
{{ "vault" | i18n }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item" *ngIf="showManageTab">
|
||||
<a class="nav-link" [routerLink]="manageRoute" routerLinkActive="active">
|
||||
<i class="bwi bwi-sliders" aria-hidden="true"></i>
|
||||
{{ "manage" | i18n }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item" *ngIf="showToolsTab">
|
||||
<a class="nav-link" [routerLink]="toolsRoute" routerLinkActive="active">
|
||||
<i class="bwi bwi-wrench" aria-hidden="true"></i>
|
||||
{{ "tools" | i18n }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item" *ngIf="showSettingsTab">
|
||||
<a class="nav-link" routerLink="settings" routerLinkActive="active">
|
||||
<i class="bwi bwi-cogs" aria-hidden="true"></i>
|
||||
{{ "settings" | i18n }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ng-container *ngIf="organization$ | async as organization">
|
||||
<div class="org-nav" *ngIf="organization">
|
||||
<div class="container d-flex">
|
||||
<div class="d-flex flex-column">
|
||||
<app-organization-switcher
|
||||
class="my-auto pl-1"
|
||||
[activeOrganization]="organization"
|
||||
></app-organization-switcher>
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" routerLink="vault" routerLinkActive="active">
|
||||
<i class="bwi bwi-lock" aria-hidden="true"></i>
|
||||
{{ "vault" | i18n }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item" *ngIf="canShowManageTab(organization)">
|
||||
<a
|
||||
class="nav-link"
|
||||
[routerLink]="getManageRoute(organization)"
|
||||
routerLinkActive="active"
|
||||
>
|
||||
<i class="bwi bwi-sliders" aria-hidden="true"></i>
|
||||
{{ "manage" | i18n }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item" *ngIf="canShowToolsTab(organization)">
|
||||
<a
|
||||
class="nav-link"
|
||||
[routerLink]="getToolsRoute(organization)"
|
||||
routerLinkActive="active"
|
||||
>
|
||||
<i class="bwi bwi-wrench" aria-hidden="true"></i>
|
||||
{{ "tools" | i18n }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item" *ngIf="canShowSettingsTab(organization)">
|
||||
<a class="nav-link" routerLink="settings" routerLinkActive="active">
|
||||
<i class="bwi bwi-cogs" aria-hidden="true"></i>
|
||||
{{ "settings" | i18n }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
<router-outlet></router-outlet>
|
||||
<app-footer></app-footer>
|
||||
|
||||
@@ -1,100 +1,86 @@
|
||||
import { Component, NgZone, OnDestroy, OnInit } from "@angular/core";
|
||||
import { Component, OnDestroy, OnInit } from "@angular/core";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
|
||||
import { BroadcasterService } from "@bitwarden/common/abstractions/broadcaster.service";
|
||||
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
|
||||
import { Organization } from "@bitwarden/common/models/domain/organization";
|
||||
import { map, mergeMap, Observable, Subject, takeUntil } from "rxjs";
|
||||
|
||||
import {
|
||||
OrganizationService,
|
||||
getOrganizationById,
|
||||
canAccessManageTab,
|
||||
canAccessSettingsTab,
|
||||
canAccessToolsTab,
|
||||
} from "../navigation-permissions";
|
||||
|
||||
const BroadcasterSubscriptionId = "OrganizationLayoutComponent";
|
||||
} from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
|
||||
import { Organization } from "@bitwarden/common/models/domain/organization";
|
||||
|
||||
@Component({
|
||||
selector: "app-organization-layout",
|
||||
templateUrl: "organization-layout.component.html",
|
||||
})
|
||||
export class OrganizationLayoutComponent implements OnInit, OnDestroy {
|
||||
organization: Organization;
|
||||
businessTokenPromise: Promise<any>;
|
||||
private organizationId: string;
|
||||
organization$: Observable<Organization>;
|
||||
businessTokenPromise: Promise<void>;
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private organizationService: OrganizationService,
|
||||
private broadcasterService: BroadcasterService,
|
||||
private ngZone: NgZone
|
||||
) {}
|
||||
private _destroy = new Subject<void>();
|
||||
|
||||
constructor(private route: ActivatedRoute, private organizationService: OrganizationService) {}
|
||||
|
||||
ngOnInit() {
|
||||
document.body.classList.remove("layout_frontend");
|
||||
// eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe
|
||||
this.route.params.subscribe(async (params: any) => {
|
||||
this.organizationId = params.organizationId;
|
||||
await this.load();
|
||||
});
|
||||
this.broadcasterService.subscribe(BroadcasterSubscriptionId, (message: any) => {
|
||||
this.ngZone.run(async () => {
|
||||
switch (message.command) {
|
||||
case "updatedOrgLicense":
|
||||
await this.load();
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.organization$ = this.route.params
|
||||
.pipe(takeUntil(this._destroy))
|
||||
.pipe<string>(map((p) => p.organizationId))
|
||||
.pipe(
|
||||
mergeMap((id) => {
|
||||
return this.organizationService.organizations$
|
||||
.pipe(takeUntil(this._destroy))
|
||||
.pipe(getOrganizationById(id));
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.broadcasterService.unsubscribe(BroadcasterSubscriptionId);
|
||||
this._destroy.next();
|
||||
this._destroy.complete();
|
||||
}
|
||||
|
||||
async load() {
|
||||
this.organization = await this.organizationService.get(this.organizationId);
|
||||
canShowManageTab(organization: Organization): boolean {
|
||||
return canAccessManageTab(organization);
|
||||
}
|
||||
|
||||
get showManageTab(): boolean {
|
||||
return canAccessManageTab(this.organization);
|
||||
canShowToolsTab(organization: Organization): boolean {
|
||||
return canAccessToolsTab(organization);
|
||||
}
|
||||
|
||||
get showToolsTab(): boolean {
|
||||
return canAccessToolsTab(this.organization);
|
||||
canShowSettingsTab(organization: Organization): boolean {
|
||||
return canAccessSettingsTab(organization);
|
||||
}
|
||||
|
||||
get showSettingsTab(): boolean {
|
||||
return canAccessSettingsTab(this.organization);
|
||||
getToolsRoute(organization: Organization): string {
|
||||
return organization.canAccessImportExport ? "tools/import" : "tools/exposed-passwords-report";
|
||||
}
|
||||
|
||||
get toolsRoute(): string {
|
||||
return this.organization.canAccessImportExport
|
||||
? "tools/import"
|
||||
: "tools/exposed-passwords-report";
|
||||
}
|
||||
|
||||
get manageRoute(): string {
|
||||
getManageRoute(organization: Organization): string {
|
||||
let route: string;
|
||||
switch (true) {
|
||||
case this.organization.canManageUsers:
|
||||
case organization.canManageUsers:
|
||||
route = "manage/people";
|
||||
break;
|
||||
case this.organization.canViewAssignedCollections || this.organization.canViewAllCollections:
|
||||
case organization.canViewAssignedCollections || organization.canViewAllCollections:
|
||||
route = "manage/collections";
|
||||
break;
|
||||
case this.organization.canManageGroups:
|
||||
case organization.canManageGroups:
|
||||
route = "manage/groups";
|
||||
break;
|
||||
case this.organization.canManagePolicies:
|
||||
case organization.canManagePolicies:
|
||||
route = "manage/policies";
|
||||
break;
|
||||
case this.organization.canManageSso:
|
||||
case organization.canManageSso:
|
||||
route = "manage/sso";
|
||||
break;
|
||||
case this.organization.canManageScim:
|
||||
case organization.canManageScim:
|
||||
route = "manage/scim";
|
||||
break;
|
||||
case this.organization.canAccessEventLogs:
|
||||
case organization.canAccessEventLogs:
|
||||
route = "manage/events";
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { CryptoService } from "@bitwarden/common/abstractions/crypto.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";
|
||||
import { Utils } from "@bitwarden/common/misc/utils";
|
||||
import { EncString } from "@bitwarden/common/models/domain/encString";
|
||||
|
||||
@@ -7,7 +7,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.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";
|
||||
import { SearchService } from "@bitwarden/common/abstractions/search.service";
|
||||
import { CollectionData } from "@bitwarden/common/models/data/collectionData";
|
||||
|
||||
@@ -7,7 +7,7 @@ import { ExportService } from "@bitwarden/common/abstractions/export.service";
|
||||
import { FileDownloadService } from "@bitwarden/common/abstractions/fileDownload/fileDownload.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";
|
||||
import { ProviderService } from "@bitwarden/common/abstractions/provider.service";
|
||||
import { Organization } from "@bitwarden/common/models/domain/organization";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
|
||||
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
|
||||
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
|
||||
import { Organization } from "@bitwarden/common/models/domain/organization";
|
||||
|
||||
@Component({
|
||||
|
||||
@@ -10,8 +10,8 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { CryptoService } from "@bitwarden/common/abstractions/crypto.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 { OrganizationApiServiceAbstraction } from "@bitwarden/common/abstractions/organization/organization-api.service.abstraction";
|
||||
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||
import { PolicyApiServiceAbstraction } from "@bitwarden/common/abstractions/policy/policy-api.service.abstraction";
|
||||
import { PolicyService } from "@bitwarden/common/abstractions/policy/policy.service.abstraction";
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ActivatedRoute, Router } from "@angular/router";
|
||||
import { first } from "rxjs/operators";
|
||||
|
||||
import { ModalService } from "@bitwarden/angular/services/modal.service";
|
||||
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
|
||||
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
|
||||
import { PolicyApiServiceAbstraction } from "@bitwarden/common/abstractions/policy/policy-api.service.abstraction";
|
||||
import { PolicyType } from "@bitwarden/common/enums/policyType";
|
||||
import { Organization } from "@bitwarden/common/models/domain/organization";
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
import { Organization } from "@bitwarden/common/models/domain/organization";
|
||||
|
||||
export function canAccessToolsTab(org: Organization): boolean {
|
||||
return org.canAccessImportExport || org.canAccessReports;
|
||||
}
|
||||
|
||||
export function canAccessSettingsTab(org: Organization): boolean {
|
||||
return org.isOwner;
|
||||
}
|
||||
|
||||
export function canAccessManageTab(org: Organization): boolean {
|
||||
return (
|
||||
org.canCreateNewCollections ||
|
||||
org.canEditAnyCollection ||
|
||||
org.canDeleteAnyCollection ||
|
||||
org.canEditAssignedCollections ||
|
||||
org.canDeleteAssignedCollections ||
|
||||
org.canAccessEventLogs ||
|
||||
org.canManageGroups ||
|
||||
org.canManageUsers ||
|
||||
org.canManagePolicies ||
|
||||
org.canManageSso ||
|
||||
org.canManageScim
|
||||
);
|
||||
}
|
||||
|
||||
export function canAccessOrgAdmin(org: Organization): boolean {
|
||||
return canAccessToolsTab(org) || canAccessSettingsTab(org) || canAccessManageTab(org);
|
||||
}
|
||||
@@ -2,6 +2,12 @@ import { NgModule } from "@angular/core";
|
||||
import { RouterModule, Routes } from "@angular/router";
|
||||
|
||||
import { AuthGuard } from "@bitwarden/angular/guards/auth.guard";
|
||||
import {
|
||||
canAccessOrgAdmin,
|
||||
canAccessManageTab,
|
||||
canAccessSettingsTab,
|
||||
canAccessToolsTab,
|
||||
} from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
|
||||
import { Organization } from "@bitwarden/common/models/domain/organization";
|
||||
|
||||
import { OrganizationPermissionsGuard } from "./guards/org-permissions.guard";
|
||||
@@ -12,12 +18,6 @@ import { GroupsComponent } from "./manage/groups.component";
|
||||
import { ManageComponent } from "./manage/manage.component";
|
||||
import { PeopleComponent } from "./manage/people.component";
|
||||
import { PoliciesComponent } from "./manage/policies.component";
|
||||
import {
|
||||
canAccessOrgAdmin,
|
||||
canAccessManageTab,
|
||||
canAccessSettingsTab,
|
||||
canAccessToolsTab,
|
||||
} from "./navigation-permissions";
|
||||
import { AccountComponent } from "./settings/account.component";
|
||||
import { OrganizationBillingComponent } from "./settings/organization-billing.component";
|
||||
import { OrganizationSubscriptionComponent } from "./settings/organization-subscription.component";
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Component } from "@angular/core";
|
||||
import { UntypedFormBuilder } from "@angular/forms";
|
||||
|
||||
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 { PolicyType } from "@bitwarden/common/enums/policyType";
|
||||
|
||||
import { BasePolicy, BasePolicyComponent } from "./base-policy.component";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Component } from "@angular/core";
|
||||
import { UntypedFormBuilder } from "@angular/forms";
|
||||
|
||||
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
|
||||
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
|
||||
import { PolicyType } from "@bitwarden/common/enums/policyType";
|
||||
import { Organization } from "@bitwarden/common/models/domain/organization";
|
||||
|
||||
|
||||
@@ -2,14 +2,12 @@ import { Component, ViewChild, ViewContainerRef } from "@angular/core";
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
|
||||
import { ModalService } from "@bitwarden/angular/services/modal.service";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { CryptoService } from "@bitwarden/common/abstractions/crypto.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 { OrganizationApiServiceAbstraction } from "@bitwarden/common/abstractions/organization/organization-api.service.abstraction";
|
||||
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||
import { SyncService } from "@bitwarden/common/abstractions/sync/sync.service.abstraction";
|
||||
import { OrganizationKeysRequest } from "@bitwarden/common/models/request/organizationKeysRequest";
|
||||
import { OrganizationUpdateRequest } from "@bitwarden/common/models/request/organizationUpdateRequest";
|
||||
import { OrganizationResponse } from "@bitwarden/common/models/response/organizationResponse";
|
||||
@@ -41,17 +39,15 @@ export class AccountComponent {
|
||||
loading = true;
|
||||
canUseApi = false;
|
||||
org: OrganizationResponse;
|
||||
formPromise: Promise<boolean>;
|
||||
formPromise: Promise<OrganizationResponse>;
|
||||
taxFormPromise: Promise<unknown>;
|
||||
|
||||
private organizationId: string;
|
||||
|
||||
constructor(
|
||||
private modalService: ModalService,
|
||||
private apiService: ApiService,
|
||||
private i18nService: I18nService,
|
||||
private route: ActivatedRoute,
|
||||
private syncService: SyncService,
|
||||
private platformUtilsService: PlatformUtilsService,
|
||||
private cryptoService: CryptoService,
|
||||
private logService: LogService,
|
||||
@@ -66,9 +62,7 @@ export class AccountComponent {
|
||||
// eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe
|
||||
this.route.parent.parent.params.subscribe(async (params) => {
|
||||
this.organizationId = params.organizationId;
|
||||
this.canManageBilling = (
|
||||
await this.organizationService.get(this.organizationId)
|
||||
).canManageBilling;
|
||||
this.canManageBilling = this.organizationService.get(this.organizationId).canManageBilling;
|
||||
try {
|
||||
this.org = await this.organizationApiService.get(this.organizationId);
|
||||
this.canUseApi = this.org.useApi;
|
||||
@@ -94,9 +88,7 @@ export class AccountComponent {
|
||||
request.keys = new OrganizationKeysRequest(orgKeys[0], orgKeys[1].encryptedString);
|
||||
}
|
||||
|
||||
this.formPromise = this.organizationApiService.save(this.organizationId, request).then(() => {
|
||||
return this.syncService.fullSync(true);
|
||||
});
|
||||
this.formPromise = this.organizationApiService.save(this.organizationId, request);
|
||||
await this.formPromise;
|
||||
this.platformUtilsService.showToast(
|
||||
"success",
|
||||
|
||||
@@ -3,8 +3,8 @@ import { Component, EventEmitter, OnInit, Output } from "@angular/core";
|
||||
import { CipherService } from "@bitwarden/common/abstractions/cipher.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 { OrganizationApiServiceAbstraction } from "@bitwarden/common/abstractions/organization/organization-api.service.abstraction";
|
||||
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||
import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification/userVerification.service.abstraction";
|
||||
import { CipherType } from "@bitwarden/common/enums/cipherType";
|
||||
|
||||
@@ -7,8 +7,8 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
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 { OrganizationApiServiceAbstraction } from "@bitwarden/common/abstractions/organization/organization-api.service.abstraction";
|
||||
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||
import { OrganizationApiKeyType } from "@bitwarden/common/enums/organizationApiKeyType";
|
||||
import { OrganizationConnectionType } from "@bitwarden/common/enums/organizationConnectionType";
|
||||
@@ -87,7 +87,7 @@ export class OrganizationSubscriptionComponent implements OnInit {
|
||||
}
|
||||
|
||||
this.loading = true;
|
||||
this.userOrg = await this.organizationService.get(this.organizationId);
|
||||
this.userOrg = this.organizationService.get(this.organizationId);
|
||||
if (this.userOrg.canManageBilling) {
|
||||
this.sub = await this.organizationApiService.getSubscription(this.organizationId);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Component } from "@angular/core";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
|
||||
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({
|
||||
|
||||
@@ -34,7 +34,9 @@
|
||||
>
|
||||
<option value="" disabled>-- {{ "select" | i18n }} --</option>
|
||||
<option value="createNew">{{ "newFamiliesOrganization" | i18n }}</option>
|
||||
<option *ngFor="let o of existingFamilyOrganizations" [ngValue]="o.id">{{ o.name }}</option>
|
||||
<option *ngFor="let o of existingFamilyOrganizations$ | async" [ngValue]="o.id">
|
||||
{{ o.name }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div *ngIf="showNewOrganization" class="col-12">
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { Component, OnInit, ViewChild, ViewContainerRef } from "@angular/core";
|
||||
import { Component, OnDestroy, OnInit, ViewChild, ViewContainerRef } from "@angular/core";
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
import { first } from "rxjs/operators";
|
||||
import { Observable, Subject } from "rxjs";
|
||||
import { first, map, takeUntil } from "rxjs/operators";
|
||||
|
||||
import { ModalService } from "@bitwarden/angular/services/modal.service";
|
||||
import { ValidationService } from "@bitwarden/angular/services/validation.service";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.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 { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||
import { SyncService } from "@bitwarden/common/abstractions/sync/sync.service.abstraction";
|
||||
import { PlanSponsorshipType } from "@bitwarden/common/enums/planSponsorshipType";
|
||||
@@ -22,8 +23,7 @@ import { DeleteOrganizationComponent } from "../settings/delete-organization.com
|
||||
selector: "families-for-enterprise-setup",
|
||||
templateUrl: "families-for-enterprise-setup.component.html",
|
||||
})
|
||||
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
|
||||
export class FamiliesForEnterpriseSetupComponent implements OnInit {
|
||||
export class FamiliesForEnterpriseSetupComponent implements OnInit, OnDestroy {
|
||||
@ViewChild(OrganizationPlansComponent, { static: false })
|
||||
set organizationPlansComponent(value: OrganizationPlansComponent) {
|
||||
if (!value) {
|
||||
@@ -46,11 +46,14 @@ export class FamiliesForEnterpriseSetupComponent implements OnInit {
|
||||
|
||||
token: string;
|
||||
existingFamilyOrganizations: Organization[];
|
||||
existingFamilyOrganizations$: Observable<Organization[]>;
|
||||
|
||||
showNewOrganization = false;
|
||||
_organizationPlansComponent: OrganizationPlansComponent;
|
||||
_selectedFamilyOrganizationId = "";
|
||||
|
||||
private _destroy = new Subject<void>();
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
private platformUtilsService: PlatformUtilsService,
|
||||
@@ -84,17 +87,24 @@ export class FamiliesForEnterpriseSetupComponent implements OnInit {
|
||||
await this.syncService.fullSync(true);
|
||||
this.badToken = !(await this.apiService.postPreValidateSponsorshipToken(this.token));
|
||||
this.loading = false;
|
||||
});
|
||||
|
||||
this.existingFamilyOrganizations = (await this.organizationService.getAll()).filter(
|
||||
(o) => o.planProductType === ProductType.Families
|
||||
);
|
||||
this.existingFamilyOrganizations$ = this.organizationService.organizations$.pipe(
|
||||
map((orgs) => orgs.filter((o) => o.planProductType === ProductType.Families))
|
||||
);
|
||||
|
||||
if (this.existingFamilyOrganizations.length === 0) {
|
||||
this.existingFamilyOrganizations$.pipe(takeUntil(this._destroy)).subscribe((orgs) => {
|
||||
if (orgs.length === 0) {
|
||||
this.selectedFamilyOrganizationId = "createNew";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this._destroy.next();
|
||||
this._destroy.complete();
|
||||
}
|
||||
|
||||
async submit() {
|
||||
this.formPromise = this.doSubmit(this._selectedFamilyOrganizationId);
|
||||
await this.formPromise;
|
||||
|
||||
@@ -5,7 +5,7 @@ import { ModalService } from "@bitwarden/angular/services/modal.service";
|
||||
import { AuditService } from "@bitwarden/common/abstractions/audit.service";
|
||||
import { CipherService } from "@bitwarden/common/abstractions/cipher.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 { StateService } from "@bitwarden/common/abstractions/state.service";
|
||||
import { Cipher } from "@bitwarden/common/models/domain/cipher";
|
||||
|
||||
@@ -5,7 +5,7 @@ import { ModalService } from "@bitwarden/angular/services/modal.service";
|
||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||
import { ImportService } from "@bitwarden/common/abstractions/import.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";
|
||||
import { PolicyService } from "@bitwarden/common/abstractions/policy/policy.service.abstraction";
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { ModalService } from "@bitwarden/angular/services/modal.service";
|
||||
import { CipherService } from "@bitwarden/common/abstractions/cipher.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 { StateService } from "@bitwarden/common/abstractions/state.service";
|
||||
import { CipherView } from "@bitwarden/common/models/view/cipherView";
|
||||
|
||||
@@ -4,7 +4,7 @@ import { ActivatedRoute } from "@angular/router";
|
||||
import { ModalService } from "@bitwarden/angular/services/modal.service";
|
||||
import { CipherService } from "@bitwarden/common/abstractions/cipher.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 { StateService } from "@bitwarden/common/abstractions/state.service";
|
||||
import { Cipher } from "@bitwarden/common/models/domain/cipher";
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Component } from "@angular/core";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
|
||||
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 { Organization } from "@bitwarden/common/models/domain/organization";
|
||||
|
||||
@Component({
|
||||
|
||||
@@ -4,7 +4,7 @@ import { ActivatedRoute } from "@angular/router";
|
||||
import { ModalService } from "@bitwarden/angular/services/modal.service";
|
||||
import { CipherService } from "@bitwarden/common/abstractions/cipher.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 { StateService } from "@bitwarden/common/abstractions/state.service";
|
||||
import { CipherView } from "@bitwarden/common/models/view/cipherView";
|
||||
|
||||
@@ -4,7 +4,7 @@ import { ActivatedRoute } from "@angular/router";
|
||||
import { ModalService } from "@bitwarden/angular/services/modal.service";
|
||||
import { CipherService } from "@bitwarden/common/abstractions/cipher.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 { PasswordGenerationService } from "@bitwarden/common/abstractions/passwordGeneration.service";
|
||||
import { PasswordRepromptService } from "@bitwarden/common/abstractions/passwordReprompt.service";
|
||||
import { StateService } from "@bitwarden/common/abstractions/state.service";
|
||||
|
||||
@@ -9,7 +9,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 { PasswordGenerationService } from "@bitwarden/common/abstractions/passwordGeneration.service";
|
||||
import { PasswordRepromptService } from "@bitwarden/common/abstractions/passwordReprompt.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||
|
||||
@@ -5,7 +5,7 @@ import { CipherService } from "@bitwarden/common/abstractions/cipher.service";
|
||||
import { EventService } from "@bitwarden/common/abstractions/event.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 { PasswordRepromptService } from "@bitwarden/common/abstractions/passwordReprompt.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||
import { SearchService } from "@bitwarden/common/abstractions/search.service";
|
||||
|
||||
@@ -16,7 +16,7 @@ import { BroadcasterService } from "@bitwarden/common/abstractions/broadcaster.s
|
||||
import { CipherService } from "@bitwarden/common/abstractions/cipher.service";
|
||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.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 { SyncService } from "@bitwarden/common/abstractions/sync/sync.service.abstraction";
|
||||
|
||||
Reference in New Issue
Block a user