Communicate the upcoming client vault privacy changes to MSPs (#9994)

* Add a banner notification to the provider portal

* Feature flag the banner

* Move banner copy to messages.json

* Allow for dismissing the banner
This commit is contained in:
Addison Beck 2024-07-08 10:16:29 -04:00 committed by GitHub
parent d92e1b3eca
commit 52207b7620
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 81 additions and 3 deletions

View File

@ -8523,6 +8523,14 @@
},
"noInvoicesToList": {
"message": "There are no invoices to list",
"description": "A paragraph on the Billing History page of the Provider Portal letting users know they can download a CSV report for their invoices that does not include prorations."
"description": "A paragraph on the Billing History page of the Provider Portal letting users know they can download a CSV report for their invoices that does not include prorations."
},
"providerClientVaultPrivacyNotification": {
"message": "Notice: Later this month, client vault privacy will be improved and provider members will no longer have direct access to client vault items. For questions,",
"description": "This will be displayed as part of a larger sentence. The whole sentence reads: 'Notice: Later this month, client vault privacy will be improved and provider members will no longer have direct access to client vault items. For questions, please contact Bitwarden support'."
},
"contactBitwardenSupport": {
"message": "contact Bitwarden support.",
"description": "This will be displayed as part of a larger sentence. The whole sentence reads: 'Notice: Later this month, client vault privacy will be improved and provider members will no longer have direct access to client vault items. For questions, please contact Bitwarden support'. 'Bitwarden' should not be translated"
}
}

View File

@ -45,7 +45,26 @@
<app-toggle-width></app-toggle-width>
</ng-container>
</bit-side-nav>
<bit-banner
class="-tw-m-6 tw-flex tw-flex-col tw-pb-6"
(onClose)="(true)"
*ngIf="
(showProviderClientVaultPrivacyWarningBanner$ | async) &&
(providerClientVaultPrivacyBannerService.showBanner$ | async) != false
"
(onClose)="providerClientVaultPrivacyBannerService.hideBanner()"
>
{{ "providerClientVaultPrivacyNotification" | i18n }}
<a
href="https://bitwarden.com/contact/"
bitLink
linkType="contrast"
target="_blank"
rel="noreferrer"
>
{{ "contactBitwardenSupport" | i18n }} </a
>.
</bit-banner>
<app-payment-method-warnings
*ngIf="showPaymentMethodWarningBanners$ | async"
></app-payment-method-warnings>

View File

@ -10,12 +10,20 @@ import { Provider } from "@bitwarden/common/admin-console/models/domain/provider
import { hasConsolidatedBilling } from "@bitwarden/common/billing/abstractions/provider-billing.service.abstraction";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { IconModule, LayoutComponent, NavigationModule } from "@bitwarden/components";
import {
BannerModule,
IconModule,
LayoutComponent,
LinkModule,
NavigationModule,
} from "@bitwarden/components";
import { ProviderPortalLogo } from "@bitwarden/web-vault/app/admin-console/icons/provider-portal-logo";
import { PaymentMethodWarningsModule } from "@bitwarden/web-vault/app/billing/shared";
import { ProductSwitcherModule } from "@bitwarden/web-vault/app/layouts/product-switcher/product-switcher.module";
import { ToggleWidthComponent } from "@bitwarden/web-vault/app/layouts/toggle-width.component";
import { ProviderClientVaultPrivacyBannerService } from "./services/provider-client-vault-privacy-banner.service";
@Component({
selector: "providers-layout",
templateUrl: "providers-layout.component.html",
@ -30,6 +38,8 @@ import { ToggleWidthComponent } from "@bitwarden/web-vault/app/layouts/toggle-wi
PaymentMethodWarningsModule,
ToggleWidthComponent,
ProductSwitcherModule,
BannerModule,
LinkModule,
],
})
export class ProvidersLayoutComponent implements OnInit, OnDestroy {
@ -45,10 +55,15 @@ export class ProvidersLayoutComponent implements OnInit, OnDestroy {
FeatureFlag.ShowPaymentMethodWarningBanners,
);
protected showProviderClientVaultPrivacyWarningBanner$ = this.configService.getFeatureFlag$(
FeatureFlag.ProviderClientVaultPrivacyBanner,
);
constructor(
private route: ActivatedRoute,
private providerService: ProviderService,
private configService: ConfigService,
protected providerClientVaultPrivacyBannerService: ProviderClientVaultPrivacyBannerService,
) {}
ngOnInit() {

View File

@ -0,0 +1,31 @@
import { Injectable } from "@angular/core";
import {
StateProvider,
AC_BANNERS_DISMISSED_DISK,
UserKeyDefinition,
} from "@bitwarden/common/platform/state";
export const SHOW_BANNER_KEY = new UserKeyDefinition<boolean>(
AC_BANNERS_DISMISSED_DISK,
"showProviderClientVaultPrivacyBanner",
{
deserializer: (b) => b,
clearOn: [],
},
);
/** Displays a banner warning provider users that client organization vaults
* will soon become inaccessible directly. */
@Injectable({ providedIn: "root" })
export class ProviderClientVaultPrivacyBannerService {
private _showBanner = this.stateProvider.getActive(SHOW_BANNER_KEY);
showBanner$ = this._showBanner.state$;
constructor(private stateProvider: StateProvider) {}
async hideBanner() {
await this._showBanner.update(() => false);
}
}

View File

@ -22,6 +22,7 @@ export enum FeatureFlag {
MemberAccessReport = "ac-2059-member-access-report",
EnableTimeThreshold = "PM-5864-dollar-threshold",
GroupsComponentRefactor = "groups-component-refactor",
ProviderClientVaultPrivacyBanner = "ac-2833-provider-client-vault-privacy-banner",
}
export type AllowedFeatureFlagTypes = boolean | number | string;
@ -54,6 +55,7 @@ export const DefaultFeatureFlagValue = {
[FeatureFlag.MemberAccessReport]: FALSE,
[FeatureFlag.EnableTimeThreshold]: FALSE,
[FeatureFlag.GroupsComponentRefactor]: FALSE,
[FeatureFlag.ProviderClientVaultPrivacyBanner]: FALSE,
} satisfies Record<FeatureFlag, AllowedFeatureFlagTypes>;
export type DefaultFeatureFlagValueType = typeof DefaultFeatureFlagValue;

View File

@ -29,6 +29,9 @@ export const ORGANIZATION_MANAGEMENT_PREFERENCES_DISK = new StateDefinition(
web: "disk-local",
},
);
export const AC_BANNERS_DISMISSED_DISK = new StateDefinition("acBannersDismissed", "disk", {
web: "disk-local",
});
// Billing
export const BILLING_DISK = new StateDefinition("billing", "disk");