mirror of
https://github.com/bitwarden/browser
synced 2025-12-22 11:13:46 +00:00
PM-2593 Update Premium Urls to target cloudWebVaultUrl (#5861)
* updated urls in premium web component and premium libs to use the cloudwebvaulturl * moved premium.component in web from base settings to a new settings folder inside vault
This commit is contained in:
@@ -1,129 +0,0 @@
|
||||
<div *ngIf="selfHosted" class="page-header">
|
||||
<h1>{{ "subscription" | i18n }}</h1>
|
||||
</div>
|
||||
<div *ngIf="!selfHosted" class="tabbed-header">
|
||||
<h1>{{ "goPremium" | i18n }}</h1>
|
||||
</div>
|
||||
<bit-callout
|
||||
type="info"
|
||||
*ngIf="canAccessPremium"
|
||||
title="{{ 'youHavePremiumAccess' | i18n }}"
|
||||
icon="bwi bwi-star-f"
|
||||
>
|
||||
{{ "alreadyPremiumFromOrg" | i18n }}
|
||||
</bit-callout>
|
||||
<bit-callout type="success">
|
||||
<p>{{ "premiumUpgradeUnlockFeatures" | i18n }}</p>
|
||||
<ul class="bwi-ul">
|
||||
<li>
|
||||
<i class="bwi bwi-check text-success bwi-li" aria-hidden="true"></i>
|
||||
{{ "premiumSignUpStorage" | i18n }}
|
||||
</li>
|
||||
<li>
|
||||
<i class="bwi bwi-check text-success bwi-li" aria-hidden="true"></i>
|
||||
{{ "premiumSignUpTwoStep" | i18n }}
|
||||
</li>
|
||||
<li>
|
||||
<i class="bwi bwi-check text-success bwi-li" aria-hidden="true"></i>
|
||||
{{ "premiumSignUpEmergency" | i18n }}
|
||||
</li>
|
||||
<li>
|
||||
<i class="bwi bwi-check text-success bwi-li" aria-hidden="true"></i>
|
||||
{{ "premiumSignUpReports" | i18n }}
|
||||
</li>
|
||||
<li>
|
||||
<i class="bwi bwi-check text-success bwi-li" aria-hidden="true"></i>
|
||||
{{ "premiumSignUpTotp" | i18n }}
|
||||
</li>
|
||||
<li>
|
||||
<i class="bwi bwi-check text-success bwi-li" aria-hidden="true"></i>
|
||||
{{ "premiumSignUpSupport" | i18n }}
|
||||
</li>
|
||||
<li>
|
||||
<i class="bwi bwi-check text-success bwi-li" aria-hidden="true"></i>
|
||||
{{ "premiumSignUpFuture" | i18n }}
|
||||
</li>
|
||||
</ul>
|
||||
<p class="text-lg" [ngClass]="{ 'mb-0': !selfHosted }">
|
||||
{{
|
||||
"premiumPriceWithFamilyPlan" | i18n : (premiumPrice | currency : "$") : familyPlanMaxUserCount
|
||||
}}
|
||||
<a routerLink="/create-organization" [queryParams]="{ plan: 'families' }">{{
|
||||
"bitwardenFamiliesPlan" | i18n
|
||||
}}</a>
|
||||
</p>
|
||||
<a
|
||||
bitButton
|
||||
href="https://vault.bitwarden.com/#/settings/premium"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
buttonType="secondary"
|
||||
*ngIf="selfHosted"
|
||||
>
|
||||
{{ "purchasePremium" | i18n }}
|
||||
</a>
|
||||
</bit-callout>
|
||||
<ng-container *ngIf="selfHosted">
|
||||
<p>{{ "uploadLicenseFilePremium" | i18n }}</p>
|
||||
<form #form (ngSubmit)="submit()" [appApiAction]="formPromise" ngNativeValidate>
|
||||
<div class="form-group">
|
||||
<label for="file">{{ "licenseFile" | i18n }}</label>
|
||||
<input type="file" id="file" class="form-control-file" name="file" required />
|
||||
<small class="form-text text-muted">{{
|
||||
"licenseFileDesc" | i18n : "bitwarden_premium_license.json"
|
||||
}}</small>
|
||||
</div>
|
||||
<button type="submit" buttonType="primary" bitButton [loading]="form.loading">
|
||||
{{ "submit" | i18n }}
|
||||
</button>
|
||||
</form>
|
||||
</ng-container>
|
||||
<form #form (ngSubmit)="submit()" [appApiAction]="formPromise" ngNativeValidate *ngIf="!selfHosted">
|
||||
<h2 class="mt-5">{{ "addons" | i18n }}</h2>
|
||||
<div class="row">
|
||||
<div class="form-group col-6">
|
||||
<label for="additionalStorage">{{ "additionalStorageGb" | i18n }}</label>
|
||||
<input
|
||||
id="additionalStorage"
|
||||
class="form-control"
|
||||
type="number"
|
||||
name="AdditionalStorageGb"
|
||||
[(ngModel)]="additionalStorage"
|
||||
min="0"
|
||||
max="99"
|
||||
step="1"
|
||||
placeholder="{{ 'additionalStorageGbDesc' | i18n }}"
|
||||
/>
|
||||
<small class="text-muted form-text">{{
|
||||
"additionalStorageIntervalDesc"
|
||||
| i18n : "1 GB" : (storageGbPrice | currency : "$") : ("year" | i18n)
|
||||
}}</small>
|
||||
</div>
|
||||
</div>
|
||||
<h2 class="spaced-header">{{ "summary" | i18n }}</h2>
|
||||
{{ "premiumMembership" | i18n }}: {{ premiumPrice | currency : "$" }} <br />
|
||||
{{ "additionalStorageGb" | i18n }}: {{ additionalStorage || 0 }} GB ×
|
||||
{{ storageGbPrice | currency : "$" }} =
|
||||
{{ additionalStorageTotal | currency : "$" }}
|
||||
<hr class="my-3" />
|
||||
<h2 class="spaced-header mb-4">{{ "paymentInformation" | i18n }}</h2>
|
||||
<app-payment [hideBank]="true"></app-payment>
|
||||
<app-tax-info></app-tax-info>
|
||||
<div id="price" class="my-4">
|
||||
<div class="text-muted text-sm">
|
||||
{{ "planPrice" | i18n }}: {{ subtotal | currency : "USD $" }}
|
||||
<br />
|
||||
<ng-container>
|
||||
{{ "estimatedTax" | i18n }}: {{ taxCharges | currency : "USD $" }}
|
||||
</ng-container>
|
||||
</div>
|
||||
<hr class="my-1 col-3 ml-0" />
|
||||
<p class="text-lg">
|
||||
<strong>{{ "total" | i18n }}:</strong> {{ total | currency : "USD $" }}/{{ "year" | i18n }}
|
||||
</p>
|
||||
</div>
|
||||
<small class="text-muted font-italic">{{ "paymentChargedAnnually" | i18n }}</small>
|
||||
<button type="submit" bitButton [loading]="form.loading">
|
||||
{{ "submit" | i18n }}
|
||||
</button>
|
||||
</form>
|
||||
@@ -1,143 +0,0 @@
|
||||
import { Component, OnInit, ViewChild } from "@angular/core";
|
||||
import { Router } from "@angular/router";
|
||||
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
||||
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
||||
|
||||
import { PaymentComponent } from "../billing/settings/payment.component";
|
||||
import { TaxInfoComponent } from "../billing/settings/tax-info.component";
|
||||
|
||||
@Component({
|
||||
selector: "app-premium",
|
||||
templateUrl: "premium.component.html",
|
||||
})
|
||||
export class PremiumComponent implements OnInit {
|
||||
@ViewChild(PaymentComponent) paymentComponent: PaymentComponent;
|
||||
@ViewChild(TaxInfoComponent) taxInfoComponent: TaxInfoComponent;
|
||||
|
||||
canAccessPremium = false;
|
||||
selfHosted = false;
|
||||
premiumPrice = 10;
|
||||
familyPlanMaxUserCount = 6;
|
||||
storageGbPrice = 4;
|
||||
additionalStorage = 0;
|
||||
|
||||
formPromise: Promise<any>;
|
||||
|
||||
constructor(
|
||||
private apiService: ApiService,
|
||||
private i18nService: I18nService,
|
||||
private platformUtilsService: PlatformUtilsService,
|
||||
private tokenService: TokenService,
|
||||
private router: Router,
|
||||
private messagingService: MessagingService,
|
||||
private syncService: SyncService,
|
||||
private logService: LogService,
|
||||
private stateService: StateService
|
||||
) {
|
||||
this.selfHosted = platformUtilsService.isSelfHost();
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
this.canAccessPremium = await this.stateService.getCanAccessPremium();
|
||||
const premiumPersonally = await this.stateService.getHasPremiumPersonally();
|
||||
if (premiumPersonally) {
|
||||
this.router.navigate(["/settings/subscription/user-subscription"]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
async submit() {
|
||||
let files: FileList = null;
|
||||
if (this.selfHosted) {
|
||||
const fileEl = document.getElementById("file") as HTMLInputElement;
|
||||
files = fileEl.files;
|
||||
if (files == null || files.length === 0) {
|
||||
this.platformUtilsService.showToast(
|
||||
"error",
|
||||
this.i18nService.t("errorOccurred"),
|
||||
this.i18nService.t("selectFile")
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (this.selfHosted) {
|
||||
if (!this.tokenService.getEmailVerified()) {
|
||||
this.platformUtilsService.showToast(
|
||||
"error",
|
||||
this.i18nService.t("errorOccurred"),
|
||||
this.i18nService.t("verifyEmailFirst")
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const fd = new FormData();
|
||||
fd.append("license", files[0]);
|
||||
this.formPromise = this.apiService.postAccountLicense(fd).then(() => {
|
||||
return this.finalizePremium();
|
||||
});
|
||||
} else {
|
||||
this.formPromise = this.paymentComponent
|
||||
.createPaymentToken()
|
||||
.then((result) => {
|
||||
const fd = new FormData();
|
||||
fd.append("paymentMethodType", result[1].toString());
|
||||
if (result[0] != null) {
|
||||
fd.append("paymentToken", result[0]);
|
||||
}
|
||||
fd.append("additionalStorageGb", (this.additionalStorage || 0).toString());
|
||||
fd.append("country", this.taxInfoComponent.taxInfo.country);
|
||||
fd.append("postalCode", this.taxInfoComponent.taxInfo.postalCode);
|
||||
return this.apiService.postPremium(fd);
|
||||
})
|
||||
.then((paymentResponse) => {
|
||||
if (!paymentResponse.success && paymentResponse.paymentIntentClientSecret != null) {
|
||||
return this.paymentComponent.handleStripeCardPayment(
|
||||
paymentResponse.paymentIntentClientSecret,
|
||||
() => this.finalizePremium()
|
||||
);
|
||||
} else {
|
||||
return this.finalizePremium();
|
||||
}
|
||||
});
|
||||
}
|
||||
await this.formPromise;
|
||||
} catch (e) {
|
||||
this.logService.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
async finalizePremium() {
|
||||
await this.apiService.refreshIdentityToken();
|
||||
await this.syncService.fullSync(true);
|
||||
this.platformUtilsService.showToast("success", null, this.i18nService.t("premiumUpdated"));
|
||||
this.messagingService.send("purchasedPremium");
|
||||
this.router.navigate(["/settings/subscription/user-subscription"]);
|
||||
}
|
||||
|
||||
get additionalStorageTotal(): number {
|
||||
return this.storageGbPrice * Math.abs(this.additionalStorage || 0);
|
||||
}
|
||||
|
||||
get subtotal(): number {
|
||||
return this.premiumPrice + this.additionalStorageTotal;
|
||||
}
|
||||
|
||||
get taxCharges(): number {
|
||||
return this.taxInfoComponent != null && this.taxInfoComponent.taxRate != null
|
||||
? (this.taxInfoComponent.taxRate / 100) * this.subtotal
|
||||
: 0;
|
||||
}
|
||||
|
||||
get total(): number {
|
||||
return this.subtotal + this.taxCharges || 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user