Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
640e3c8
feat(billing): add provided as a required property to premium response
sbrown-livefront Nov 13, 2025
630a3c1
fix(billing): replace hard coded storage variables with retrieved plan
sbrown-livefront Nov 13, 2025
c21f28a
tests(billing): add tests to pricing-summary service
sbrown-livefront Nov 13, 2025
93dc312
feat(billing): add optional property.
sbrown-livefront Nov 14, 2025
05dde04
Merge branch 'main' into billing/pm-27600/replace-hard-coded-pricing-โ€ฆ
sbrown-livefront Nov 14, 2025
0e6b5bf
Merge branch 'main' into billing/pm-27600/replace-hard-coded-pricing-โ€ฆ
sbrown-livefront Nov 14, 2025
1ea8144
fix(billing): update storage logic
sbrown-livefront Nov 14, 2025
1a71cb4
Merge branch 'main' into billing/pm-27600/replace-hard-coded-pricing-โ€ฆ
sbrown-livefront Nov 14, 2025
507525b
fix(billing): remove optional check
sbrown-livefront Nov 14, 2025
ee2b2ef
fix(billing): remove optionality
sbrown-livefront Nov 14, 2025
380d8ef
fix(billing): remove optionality
sbrown-livefront Nov 14, 2025
02dbda2
fix(billing): refactored storage calculation logic
sbrown-livefront Nov 19, 2025
9937eef
feat(billing): add provided amounts to subscription-pricing-service
sbrown-livefront Nov 19, 2025
629d107
fix(billing): update cloud premium component
sbrown-livefront Nov 19, 2025
2afc885
fix(billing): update desktop premium component
sbrown-livefront Nov 19, 2025
f45d803
fix(billing): update org plans component
sbrown-livefront Nov 19, 2025
c72b8e4
Merge branch 'main' into billing/pm-27600/replace-hard-coded-pricing-โ€ฆ
sbrown-livefront Nov 20, 2025
dfcd18c
Merge branch 'main' into billing/pm-27600/replace-hard-coded-pricing-โ€ฆ
sbrown-livefront Nov 20, 2025
125f30d
fix(billing) update stories and tests
sbrown-livefront Nov 20, 2025
2353da4
fix(billing): update messages
sbrown-livefront Nov 20, 2025
26b15ed
fix(billing): replace storage sizes
sbrown-livefront Nov 20, 2025
aae8c9c
Merge branch 'main' into billing/pm-27600/replace-hard-coded-pricing-โ€ฆ
sbrown-livefront Nov 20, 2025
0bd479b
fix(billing): update messages
sbrown-livefront Nov 21, 2025
1d9f87d
fix(billing): update components
sbrown-livefront Nov 21, 2025
f10776e
Merge branch 'main' into billing/pm-27600/replace-hard-coded-pricing-โ€ฆ
sbrown-livefront Nov 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions apps/browser/src/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1469,6 +1469,15 @@
"ppremiumSignUpStorage": {
"message": "1 GB encrypted storage for file attachments."
},
"premiumSignUpStorageV2": {
"message": "$SIZE$ encrypted storage for file attachments.",
"placeholders": {
"size": {
"content": "$1",
"example": "1 GB"
}
}
},
"premiumSignUpEmergency": {
"message": "Emergency access."
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ <h2 class="tw-font-medium">{{ "premiumFeatures" | i18n }}</h2>
<div class="tw-flex tw-flex-col tw-p-2">
<ul class="tw-list-disc tw-pl-5 tw-space-y-2 tw-break-words tw-mb-0">
<li>
{{ "ppremiumSignUpStorage" | i18n }}
{{ "premiumSignUpStorageV2" | i18n: `${storageProvidedGb} GB` }}
</li>
<li>
{{ "premiumSignUpTwoStepOptions" | i18n }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { PremiumComponent as BasePremiumComponent } from "@bitwarden/angular/bil
import { JslibModule } from "@bitwarden/angular/jslib.module";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions";
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";
Expand Down Expand Up @@ -59,6 +60,7 @@ export class PremiumV2Component extends BasePremiumComponent {
billingAccountProfileStateService: BillingAccountProfileStateService,
toastService: ToastService,
accountService: AccountService,
billingApiService: BillingApiServiceAbstraction,
) {
super(
i18nService,
Expand All @@ -70,6 +72,7 @@ export class PremiumV2Component extends BasePremiumComponent {
billingAccountProfileStateService,
toastService,
accountService,
billingApiService,
);

// Support old price string. Can be removed in future once all translations are properly updated.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ <h1 class="box-header" id="premiumTitle">
<ul class="bwi-ul">
<li>
<i class="bwi bwi-li bwi-check text-success" aria-hidden="true"></i>
{{ "premiumSignUpStorage" | i18n }}
{{ "premiumSignUpStorageV2" | i18n: `${storageProvidedGb} GB` }}
</li>
<li>
<i class="bwi bwi-li bwi-check text-success" aria-hidden="true"></i>
Expand Down
3 changes: 3 additions & 0 deletions apps/desktop/src/billing/app/accounts/premium.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Component } from "@angular/core";
import { PremiumComponent as BasePremiumComponent } from "@bitwarden/angular/billing/components/premium.component";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions";
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";
Expand All @@ -28,6 +29,7 @@ export class PremiumComponent extends BasePremiumComponent {
billingAccountProfileStateService: BillingAccountProfileStateService,
toastService: ToastService,
accountService: AccountService,
billingApiService: BillingApiServiceAbstraction,
) {
super(
i18nService,
Expand All @@ -39,6 +41,7 @@ export class PremiumComponent extends BasePremiumComponent {
billingAccountProfileStateService,
toastService,
accountService,
billingApiService,
);
}
}
9 changes: 9 additions & 0 deletions apps/desktop/src/locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1490,6 +1490,15 @@
"premiumSignUpStorage": {
"message": "1 GB encrypted storage for file attachments."
},
"premiumSignUpStorageV2": {
"message": "$SIZE$ encrypted storage for file attachments.",
"placeholders": {
"size": {
"content": "$1",
"example": "1 GB"
}
}
},
"premiumSignUpTwoStepOptions": {
"message": "Proprietary two-step login options such as YubiKey and Duo."
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ <h2 bitTypography="h2">{{ "goPremium" | i18n }}</h2>
<ul class="bwi-ul">
<li>
<i class="bwi bwi-check tw-text-success bwi-li" aria-hidden="true"></i>
{{ "premiumSignUpStorage" | i18n }}
{{ "premiumSignUpStorageV2" | i18n: `${(providedStorageGb$ | async)} GB` }}
</li>
<li>
<i class="bwi bwi-check tw-text-success bwi-li" aria-hidden="true"></i>
Expand Down Expand Up @@ -82,7 +82,10 @@ <h2 bitTypography="h2">{{ "addons" | i18n }}</h2>
/>
<bit-hint>{{
"additionalStorageIntervalDesc"
| i18n: "1 GB" : (storagePrice$ | async | currency: "$") : ("year" | i18n)
| i18n
: `${(providedStorageGb$ | async)} GB`
: (storagePrice$ | async | currency: "$")
: ("year" | i18n)
}}</bit-hint>
</bit-form-field>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ import { debounceTime } from "rxjs/operators";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions";
import { SubscriptionPricingServiceAbstraction } from "@bitwarden/common/billing/abstractions/subscription-pricing.service.abstraction";
import { PaymentMethodType } from "@bitwarden/common/billing/enums";
import { DefaultSubscriptionPricingService } from "@bitwarden/common/billing/services/subscription-pricing.service";
import { PersonalSubscriptionPricingTierIds } from "@bitwarden/common/billing/types/subscription-pricing-tier";
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
Expand Down Expand Up @@ -75,6 +75,7 @@ export class CloudHostedPremiumComponent {
return {
seat: premiumPlan.passwordManager.annualPrice,
storage: premiumPlan.passwordManager.annualPricePerAdditionalStorageGB,
providedStorageGb: premiumPlan.passwordManager.providedStorageGB,
};
}),
shareReplay({ bufferSize: 1, refCount: true }),
Expand All @@ -84,6 +85,8 @@ export class CloudHostedPremiumComponent {

storagePrice$ = this.premiumPrices$.pipe(map((prices) => prices.storage));

providedStorageGb$ = this.premiumPrices$.pipe(map((prices) => prices.providedStorageGb));

protected isLoadingPrices$ = this.premiumPrices$.pipe(
map(() => false),
startWith(true),
Expand Down Expand Up @@ -134,7 +137,7 @@ export class CloudHostedPremiumComponent {
private accountService: AccountService,
private subscriberBillingClient: SubscriberBillingClient,
private taxClient: TaxClient,
private subscriptionPricingService: DefaultSubscriptionPricingService,
private subscriptionPricingService: SubscriptionPricingServiceAbstraction,
) {
this.hasPremiumFromAnyOrganization$ = this.accountService.activeAccount$.pipe(
switchMap((account) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<ul class="bwi-ul">
<li>
<i class="bwi bwi-check tw-text-success bwi-li" aria-hidden="true"></i>
{{ "premiumSignUpStorage" | i18n }}
{{ "premiumSignUpStorage" }}
</li>
<li>
<i class="bwi bwi-check tw-text-success bwi-li" aria-hidden="true"></i>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,10 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
}

get storageGb() {
return this.sub?.maxStorageGb ? this.sub?.maxStorageGb - 1 : 0;
return Math.max(
0,
(this.sub?.maxStorageGb ?? 0) - this.selectedPlan.PasswordManager.baseStorageGb,
);
}

passwordManagerSeatTotal(plan: PlanResponse): number {
Expand All @@ -644,12 +647,7 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
return 0;
}

return (
plan.PasswordManager.additionalStoragePricePerGb *
// TODO: Eslint upgrade. Please resolve this since the null check does nothing
// eslint-disable-next-line no-constant-binary-expression
Math.abs(this.sub?.maxStorageGb ? this.sub?.maxStorageGb - 1 : 0 || 0)
);
return plan.PasswordManager.additionalStoragePricePerGb * this.storageGb;
}

additionalStoragePriceMonthly(selectedPlan: PlanResponse) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ <h2 bitTypography="h2">{{ "chooseYourPlan" | i18n }}</h2>
<li *ngIf="selectableProduct.PasswordManager.baseStorageGb">
{{
"gbEncryptedFileStorage"
| i18n: selectableProduct.PasswordManager.baseStorageGb + "GB"
| i18n: selectableProduct.PasswordManager.baseStorageGb + " GB"
}}
</li>
<li *ngIf="selectableProduct.hasGroups">
Expand Down Expand Up @@ -239,7 +239,7 @@ <h2 bitTypography="h2">{{ "addons" | i18n }}</h2>
<bit-hint class="tw-text-sm">{{
"additionalStorageIntervalDesc"
| i18n
: "1 GB"
: `${selectedPlan.PasswordManager.baseStorageGb} GB`
: (additionalStoragePriceMonthly(selectedPlan) | currency: "$")
: ("month" | i18n)
}}</bit-hint>
Expand Down
Loading
Loading