mirror of
https://github.com/bitwarden/browser.git
synced 2024-09-14 02:08:50 +02:00
Prevent Provider from viewing client organization payment method and billing history (#9442)
This commit is contained in:
parent
28de91888a
commit
010b55d39d
@ -52,7 +52,7 @@
|
|||||||
*ngIf="canShowBillingTab(organization)"
|
*ngIf="canShowBillingTab(organization)"
|
||||||
>
|
>
|
||||||
<bit-nav-item [text]="'subscription' | i18n" route="billing/subscription"></bit-nav-item>
|
<bit-nav-item [text]="'subscription' | i18n" route="billing/subscription"></bit-nav-item>
|
||||||
<ng-container *ngIf="showPaymentAndHistory$ | async">
|
<ng-container *ngIf="(showPaymentAndHistory$ | async) && (organizationIsUnmanaged$ | async)">
|
||||||
<bit-nav-item [text]="'paymentMethod' | i18n" route="billing/payment-method"></bit-nav-item>
|
<bit-nav-item [text]="'paymentMethod' | i18n" route="billing/payment-method"></bit-nav-item>
|
||||||
<bit-nav-item [text]="'billingHistory' | i18n" route="billing/history"></bit-nav-item>
|
<bit-nav-item [text]="'billingHistory' | i18n" route="billing/history"></bit-nav-item>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { CommonModule } from "@angular/common";
|
import { CommonModule } from "@angular/common";
|
||||||
import { Component, OnDestroy, OnInit } from "@angular/core";
|
import { Component, OnDestroy, OnInit } from "@angular/core";
|
||||||
import { ActivatedRoute, RouterModule } from "@angular/router";
|
import { ActivatedRoute, RouterModule } from "@angular/router";
|
||||||
import { map, mergeMap, Observable, Subject, takeUntil } from "rxjs";
|
import { combineLatest, map, mergeMap, Observable, Subject, switchMap, takeUntil } from "rxjs";
|
||||||
|
|
||||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
import {
|
import {
|
||||||
@ -16,7 +16,8 @@ import {
|
|||||||
OrganizationService,
|
OrganizationService,
|
||||||
} from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
} from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
import { ProviderService } from "@bitwarden/common/admin-console/abstractions/provider.service";
|
||||||
|
import { PolicyType, ProviderStatusType } from "@bitwarden/common/admin-console/enums";
|
||||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
@ -55,9 +56,14 @@ export class OrganizationLayoutComponent implements OnInit, OnDestroy {
|
|||||||
organization$: Observable<Organization>;
|
organization$: Observable<Organization>;
|
||||||
showPaymentAndHistory$: Observable<boolean>;
|
showPaymentAndHistory$: Observable<boolean>;
|
||||||
hideNewOrgButton$: Observable<boolean>;
|
hideNewOrgButton$: Observable<boolean>;
|
||||||
|
organizationIsUnmanaged$: Observable<boolean>;
|
||||||
|
|
||||||
private _destroy = new Subject<void>();
|
private _destroy = new Subject<void>();
|
||||||
|
|
||||||
|
protected consolidatedBillingEnabled$ = this.configService.getFeatureFlag$(
|
||||||
|
FeatureFlag.EnableConsolidatedBilling,
|
||||||
|
);
|
||||||
|
|
||||||
protected showPaymentMethodWarningBanners$ = this.configService.getFeatureFlag$(
|
protected showPaymentMethodWarningBanners$ = this.configService.getFeatureFlag$(
|
||||||
FeatureFlag.ShowPaymentMethodWarningBanners,
|
FeatureFlag.ShowPaymentMethodWarningBanners,
|
||||||
);
|
);
|
||||||
@ -68,6 +74,7 @@ export class OrganizationLayoutComponent implements OnInit, OnDestroy {
|
|||||||
private platformUtilsService: PlatformUtilsService,
|
private platformUtilsService: PlatformUtilsService,
|
||||||
private configService: ConfigService,
|
private configService: ConfigService,
|
||||||
private policyService: PolicyService,
|
private policyService: PolicyService,
|
||||||
|
private providerService: ProviderService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
@ -94,6 +101,24 @@ export class OrganizationLayoutComponent implements OnInit, OnDestroy {
|
|||||||
);
|
);
|
||||||
|
|
||||||
this.hideNewOrgButton$ = this.policyService.policyAppliesToActiveUser$(PolicyType.SingleOrg);
|
this.hideNewOrgButton$ = this.policyService.policyAppliesToActiveUser$(PolicyType.SingleOrg);
|
||||||
|
|
||||||
|
const provider$ = this.organization$.pipe(
|
||||||
|
switchMap((organization) => this.providerService.get$(organization.providerId)),
|
||||||
|
);
|
||||||
|
|
||||||
|
this.organizationIsUnmanaged$ = combineLatest([
|
||||||
|
this.consolidatedBillingEnabled$,
|
||||||
|
this.organization$,
|
||||||
|
provider$,
|
||||||
|
]).pipe(
|
||||||
|
map(
|
||||||
|
([consolidatedBillingEnabled, organization, provider]) =>
|
||||||
|
!consolidatedBillingEnabled ||
|
||||||
|
!organization.hasProvider ||
|
||||||
|
!provider ||
|
||||||
|
provider.providerStatus !== ProviderStatusType.Billable,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
import { inject } from "@angular/core";
|
||||||
|
import { ActivatedRouteSnapshot, CanActivateFn } from "@angular/router";
|
||||||
|
|
||||||
|
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||||
|
import { ProviderService } from "@bitwarden/common/admin-console/abstractions/provider.service";
|
||||||
|
import { ProviderStatusType } from "@bitwarden/common/admin-console/enums";
|
||||||
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
|
|
||||||
|
export const organizationIsUnmanaged: CanActivateFn = async (route: ActivatedRouteSnapshot) => {
|
||||||
|
const configService = inject(ConfigService);
|
||||||
|
const organizationService = inject(OrganizationService);
|
||||||
|
const providerService = inject(ProviderService);
|
||||||
|
|
||||||
|
const consolidatedBillingEnabled = await configService.getFeatureFlag(
|
||||||
|
FeatureFlag.EnableConsolidatedBilling,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!consolidatedBillingEnabled) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const organization = await organizationService.get(route.params.organizationId);
|
||||||
|
|
||||||
|
if (!organization.hasProvider) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const provider = await providerService.get(organization.providerId);
|
||||||
|
|
||||||
|
if (!provider) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return provider.providerStatus !== ProviderStatusType.Billable;
|
||||||
|
};
|
@ -5,6 +5,7 @@ import { canAccessBillingTab } from "@bitwarden/common/admin-console/abstraction
|
|||||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||||
|
|
||||||
import { OrganizationPermissionsGuard } from "../../admin-console/organizations/guards/org-permissions.guard";
|
import { OrganizationPermissionsGuard } from "../../admin-console/organizations/guards/org-permissions.guard";
|
||||||
|
import { organizationIsUnmanaged } from "../../billing/guards/organization-is-unmanaged.guard";
|
||||||
import { WebPlatformUtilsService } from "../../core/web-platform-utils.service";
|
import { WebPlatformUtilsService } from "../../core/web-platform-utils.service";
|
||||||
import { PaymentMethodComponent } from "../shared";
|
import { PaymentMethodComponent } from "../shared";
|
||||||
|
|
||||||
@ -29,7 +30,7 @@ const routes: Routes = [
|
|||||||
{
|
{
|
||||||
path: "payment-method",
|
path: "payment-method",
|
||||||
component: PaymentMethodComponent,
|
component: PaymentMethodComponent,
|
||||||
canActivate: [OrganizationPermissionsGuard],
|
canActivate: [OrganizationPermissionsGuard, organizationIsUnmanaged],
|
||||||
data: {
|
data: {
|
||||||
titleId: "paymentMethod",
|
titleId: "paymentMethod",
|
||||||
organizationPermissions: (org: Organization) => org.canEditPaymentMethods,
|
organizationPermissions: (org: Organization) => org.canEditPaymentMethods,
|
||||||
@ -38,7 +39,7 @@ const routes: Routes = [
|
|||||||
{
|
{
|
||||||
path: "history",
|
path: "history",
|
||||||
component: OrgBillingHistoryViewComponent,
|
component: OrgBillingHistoryViewComponent,
|
||||||
canActivate: [OrganizationPermissionsGuard],
|
canActivate: [OrganizationPermissionsGuard, organizationIsUnmanaged],
|
||||||
data: {
|
data: {
|
||||||
titleId: "billingHistory",
|
titleId: "billingHistory",
|
||||||
organizationPermissions: (org: Organization) => org.canViewBillingHistory,
|
organizationPermissions: (org: Organization) => org.canViewBillingHistory,
|
||||||
|
Loading…
Reference in New Issue
Block a user