1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-20 02:03:39 +00:00

[AC-2156] Billing State Provider Migration (#8133)

* Added billing account profile state service

* Update usages after removing state service functions

* Added migrator

* Updated bw.ts and main.background.ts

* Removed comment

* Updated state service dependencies to include billing service

* Added missing mv3 factory and updated MainContextMenuHandler

* updated autofill service and tests

* Updated the remaining extensions usages

* Updated desktop

* Removed subjects where they weren't needed

* Refactored billing service to have a single setter to avoid unecessary emissions

* Refactored has premium guard to return an observable

* Renamed services to match ADR

f633f2cdd8/docs/architecture/clients/presentation/angular.md (abstract--default-implementations)

* Updated property names to be a smidgen more descriptive and added jsdocs

* Updated setting of canAccessPremium to automatically update when the underlying observable emits

* Fixed build error after merge conflicts

* Another build error from conflict

* Removed autofill unit test changes from conflict

* Updated login strategy to not set premium field using state service

* Updated CLI to use billing state provider

* Shortened names a bit

* Fixed build
This commit is contained in:
Conner Turnbull
2024-03-15 15:53:05 -04:00
committed by GitHub
parent 65534a1323
commit b99153a016
85 changed files with 942 additions and 261 deletions

View File

@@ -4,6 +4,7 @@ import { FormBuilder } from "@angular/forms";
import { AddEditComponent as BaseAddEditComponent } from "@bitwarden/angular/tools/send/add-edit.component";
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
@@ -32,6 +33,7 @@ export class AddEditComponent extends BaseAddEditComponent {
sendApiService: SendApiService,
dialogService: DialogService,
formBuilder: FormBuilder,
billingAccountProfileStateService: BillingAccountProfileStateService,
) {
super(
i18nService,
@@ -46,6 +48,7 @@ export class AddEditComponent extends BaseAddEditComponent {
sendApiService,
dialogService,
formBuilder,
billingAccountProfileStateService,
);
}

View File

@@ -7,7 +7,7 @@
{{ "premiumMembership" | i18n }}
</h1>
<div class="box-content box-content-padded">
<div *ngIf="!isPremium">
<div *ngIf="!(isPremium$ | async)">
<p class="text-center lead">{{ "premiumNotCurrentMember" | i18n }}</p>
<p>{{ "premiumSignUpAndGet" | i18n }}</p>
<ul class="bwi-ul">
@@ -40,7 +40,7 @@
{{ "premiumPrice" | i18n: (price | currency: "$") }}
</p>
</div>
<div *ngIf="isPremium">
<div *ngIf="isPremium$ | async">
<p class="text-center lead">{{ "premiumCurrentMember" | i18n }}</p>
<p class="text-center">{{ "premiumCurrentMemberThanks" | i18n }}</p>
</div>
@@ -48,7 +48,7 @@
</div>
</div>
<div class="modal-footer">
<button type="button" class="primary" (click)="manage()" *ngIf="isPremium">
<button type="button" class="primary" (click)="manage()" *ngIf="isPremium$ | async">
<b>{{ "premiumManage" | i18n }}</b>
</button>
<button
@@ -56,13 +56,13 @@
type="button"
class="primary"
(click)="purchase()"
*ngIf="!isPremium"
*ngIf="!(isPremium$ | async)"
[disabled]="$any(purchaseBtn).loading"
>
<b>{{ "premiumPurchase" | i18n }}</b>
</button>
<button type="button" data-dismiss="modal">{{ "close" | i18n }}</button>
<div class="right" *ngIf="!isPremium">
<div class="right" *ngIf="!(isPremium$ | async)">
<button
#refreshBtn
type="button"

View File

@@ -2,6 +2,7 @@ import { Component } from "@angular/core";
import { PremiumComponent as BasePremiumComponent } from "@bitwarden/angular/vault/components/premium.component";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
@@ -22,6 +23,7 @@ export class PremiumComponent extends BasePremiumComponent {
stateService: StateService,
dialogService: DialogService,
environmentService: EnvironmentService,
billingAccountProfileStateService: BillingAccountProfileStateService,
) {
super(
i18nService,
@@ -31,6 +33,7 @@ export class PremiumComponent extends BasePremiumComponent {
stateService,
dialogService,
environmentService,
billingAccountProfileStateService,
);
}
}

View File

@@ -2,6 +2,7 @@ import { Component } from "@angular/core";
import { AttachmentsComponent as BaseAttachmentsComponent } from "@bitwarden/angular/vault/components/attachments.component";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
@@ -26,6 +27,7 @@ export class AttachmentsComponent extends BaseAttachmentsComponent {
stateService: StateService,
fileDownloadService: FileDownloadService,
dialogService: DialogService,
billingAccountProfileStateService: BillingAccountProfileStateService,
) {
super(
cipherService,
@@ -38,6 +40,7 @@ export class AttachmentsComponent extends BaseAttachmentsComponent {
stateService,
fileDownloadService,
dialogService,
billingAccountProfileStateService,
);
}
}

View File

@@ -8,6 +8,7 @@ import {
ViewContainerRef,
} from "@angular/core";
import { ActivatedRoute, Router } from "@angular/router";
import { Subject, takeUntil } from "rxjs";
import { first } from "rxjs/operators";
import { ModalRef } from "@bitwarden/angular/components/modal/modal.ref";
@@ -15,6 +16,7 @@ import { ModalService } from "@bitwarden/angular/services/modal.service";
import { VaultFilter } from "@bitwarden/angular/vault/vault-filter/models/vault-filter.model";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service";
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
import { EventType } from "@bitwarden/common/enums";
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
@@ -84,6 +86,7 @@ export class VaultComponent implements OnInit, OnDestroy {
activeFilter: VaultFilter = new VaultFilter();
private modal: ModalRef = null;
private componentIsDestroyed$ = new Subject<boolean>();
constructor(
private route: ActivatedRoute,
@@ -103,10 +106,16 @@ export class VaultComponent implements OnInit, OnDestroy {
private searchBarService: SearchBarService,
private apiService: ApiService,
private dialogService: DialogService,
private billingAccountProfileStateService: BillingAccountProfileStateService,
) {}
async ngOnInit() {
this.userHasPremiumAccess = await this.stateService.getCanAccessPremium();
this.billingAccountProfileStateService.hasPremiumFromAnySource$
.pipe(takeUntil(this.componentIsDestroyed$))
.subscribe((canAccessPremium: boolean) => {
this.userHasPremiumAccess = canAccessPremium;
});
this.broadcasterService.subscribe(BroadcasterSubscriptionId, (message: any) => {
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
@@ -229,6 +238,8 @@ export class VaultComponent implements OnInit, OnDestroy {
ngOnDestroy() {
this.searchBarService.setEnabled(false);
this.broadcasterService.unsubscribe(BroadcasterSubscriptionId);
this.componentIsDestroyed$.next(true);
this.componentIsDestroyed$.complete();
}
async load() {

View File

@@ -13,6 +13,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { AuditService } from "@bitwarden/common/abstractions/audit.service";
import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service";
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
@@ -58,6 +59,7 @@ export class ViewComponent extends BaseViewComponent implements OnChanges {
fileDownloadService: FileDownloadService,
dialogService: DialogService,
datePipe: DatePipe,
billingAccountProfileStateService: BillingAccountProfileStateService,
) {
super(
cipherService,
@@ -80,6 +82,7 @@ export class ViewComponent extends BaseViewComponent implements OnChanges {
fileDownloadService,
dialogService,
datePipe,
billingAccountProfileStateService,
);
}
ngOnInit() {