mirror of
https://github.com/bitwarden/browser
synced 2025-12-17 16:53:34 +00:00
licensing options when self hosted
This commit is contained in:
@@ -241,6 +241,7 @@ function config() {
|
||||
createModule: false,
|
||||
constants: _.merge({}, {
|
||||
appSettings: {
|
||||
selfHosted: false,
|
||||
version: project.version,
|
||||
environment: project.env
|
||||
}
|
||||
|
||||
@@ -127,12 +127,16 @@
|
||||
putKey: { url: _apiUri + '/accounts/key', method: 'POST', params: {} },
|
||||
'import': { url: _apiUri + '/accounts/import', method: 'POST', params: {} },
|
||||
postDelete: { url: _apiUri + '/accounts/delete', method: 'POST', params: {} },
|
||||
postPremium: { url: _apiUri + '/accounts/premium', method: 'POST', params: {} },
|
||||
putStorage: { url: _apiUri + '/accounts/storage', method: 'POST', params: {} },
|
||||
putPayment: { url: _apiUri + '/accounts/payment', method: 'POST', params: {} },
|
||||
putCancelPremium: { url: _apiUri + '/accounts/cancel-premium', method: 'POST', params: {} },
|
||||
putReinstatePremium: { url: _apiUri + '/accounts/reinstate-premium', method: 'POST', params: {} },
|
||||
getBilling: { url: _apiUri + '/accounts/billing', method: 'GET', params: {} }
|
||||
getBilling: { url: _apiUri + '/accounts/billing', method: 'GET', params: {} },
|
||||
postPremium: {
|
||||
url: _apiUri + '/accounts/premium',
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': undefined }
|
||||
}
|
||||
});
|
||||
|
||||
_service.twoFactor = $resource(_apiUri + '/two-factor', {}, {
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
angular.module("bit")
|
||||
.constant("appSettings", {"apiUri":"https://api.bitwarden.com","identityUri":"https://identity.bitwarden.com","stripeKey":"pk_live_bpN0P37nMxrMQkcaHXtAybJk","braintreeKey":"production_qfbsv8kc_njj2zjtyngtjmbjd","whitelistDomains":["api.bitwarden.com"],"version":"1.14.3","environment":"Production"});
|
||||
.constant("appSettings", {"apiUri":"https://api.bitwarden.com","identityUri":"https://identity.bitwarden.com","stripeKey":"pk_live_bpN0P37nMxrMQkcaHXtAybJk","braintreeKey":"production_qfbsv8kc_njj2zjtyngtjmbjd","whitelistDomains":["api.bitwarden.com"],"selfHosted":false,"version":"1.14.3","environment":"Production"});
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
$scope.paymentSource = null;
|
||||
$scope.subscription = null;
|
||||
$scope.loading = true;
|
||||
var license = null;
|
||||
|
||||
$scope.$on('$viewContentLoaded', function () {
|
||||
load();
|
||||
@@ -72,6 +73,26 @@
|
||||
});
|
||||
};
|
||||
|
||||
$scope.license = function () {
|
||||
var licenseString = JSON.stringify(license, null, 2);
|
||||
var licenseBlob = new Blob([licenseString]);
|
||||
|
||||
// IE hack. ref http://msdn.microsoft.com/en-us/library/ie/hh779016.aspx
|
||||
if (window.navigator.msSaveOrOpenBlob) {
|
||||
window.navigator.msSaveBlob(licenseBlob, 'bitwarden_premium_license.json');
|
||||
}
|
||||
else {
|
||||
var a = window.document.createElement('a');
|
||||
a.href = window.URL.createObjectURL(licenseBlob, { type: 'text/plain' });
|
||||
a.download = 'bitwarden_premium_license.json';
|
||||
document.body.appendChild(a);
|
||||
// IE: "Access is denied".
|
||||
// ref: https://connect.microsoft.com/IE/feedback/details/797361/ie-10-treats-blob-url-as-cross-origin-and-denies-access
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
}
|
||||
};
|
||||
|
||||
function load() {
|
||||
authService.getUserProfile().then(function (profile) {
|
||||
$scope.premium = profile.premium;
|
||||
@@ -87,6 +108,8 @@
|
||||
|
||||
var i = 0;
|
||||
|
||||
license = billing.License;
|
||||
|
||||
$scope.storage = null;
|
||||
if (billing && billing.MaxStorageGb) {
|
||||
$scope.storage = {
|
||||
|
||||
@@ -2,13 +2,15 @@
|
||||
.module('bit.settings')
|
||||
|
||||
.controller('settingsPremiumController', function ($scope, $state, apiService, toastr, $analytics, authService, stripe,
|
||||
constants, $timeout, appSettings) {
|
||||
constants, $timeout, appSettings, validationService) {
|
||||
authService.getUserProfile().then(function (profile) {
|
||||
if (profile.premium) {
|
||||
return $state.go('backend.user.settingsBilling');
|
||||
}
|
||||
});
|
||||
|
||||
$scope.selfHosted = appSettings.selfHosted;
|
||||
|
||||
var btInstance = null;
|
||||
$scope.storageGbPrice = constants.storageGb.yearlyPrice;
|
||||
$scope.premiumPrice = constants.premium.price;
|
||||
@@ -54,23 +56,43 @@
|
||||
return $scope.premiumPrice + (($scope.model.additionalStorageGb || 0) * $scope.storageGbPrice);
|
||||
};
|
||||
|
||||
$scope.submit = function (model) {
|
||||
$scope.submit = function (model, form) {
|
||||
if ($scope.selfHosted) {
|
||||
var fileEl = document.getElementById('file');
|
||||
var files = fileEl.files;
|
||||
if (!files || !files.length) {
|
||||
validationService.addError(form, 'file', 'Select a license file.', true);
|
||||
return;
|
||||
}
|
||||
|
||||
var fd = new FormData();
|
||||
fd.append('license', files[0]);
|
||||
|
||||
$scope.submitPromise = apiService.accounts.postPremium(fd).$promise.then(function (result) {
|
||||
return finalizePremium();
|
||||
});
|
||||
}
|
||||
else {
|
||||
$scope.submitPromise = getPaymentToken(model).then(function (token) {
|
||||
if (!token) {
|
||||
throw 'No payment token.';
|
||||
}
|
||||
|
||||
var request = {
|
||||
paymentToken: token,
|
||||
additionalStorageGb: model.additionalStorageGb
|
||||
};
|
||||
var fd = new FormData();
|
||||
fd.append('paymentToken', token);
|
||||
fd.append('additionalStorageGb', model.additionalStorageGb || 0);
|
||||
|
||||
return apiService.accounts.postPremium(request).$promise;
|
||||
return apiService.accounts.postPremium(fd).$promise;
|
||||
}, function (err) {
|
||||
throw err;
|
||||
}).then(function (result) {
|
||||
return authService.updateProfilePremium(true);
|
||||
}).then(function () {
|
||||
return finalizePremium();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function finalizePremium() {
|
||||
return authService.updateProfilePremium(true).then(function () {
|
||||
$analytics.eventTrack('Signed Up Premium');
|
||||
return authService.refreshAccessToken();
|
||||
}).then(function () {
|
||||
@@ -78,7 +100,7 @@
|
||||
}).then(function () {
|
||||
toastr.success('Premium upgrade complete.', 'Success');
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function getPaymentToken(model) {
|
||||
if ($scope.paymentMethod === 'paypal') {
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer" ng-if="!subscription.cancelled || subscription.markedForCancel">
|
||||
<div class="box-footer" ng-if="!loading && subscription && (!subscription.cancelled || subscription.markedForCancel)">
|
||||
<button type="button" class="btn btn-default btn-flat" ng-click="cancel()"
|
||||
ng-if="!subscription.cancelled && !subscription.markedForCancel">
|
||||
Cancel
|
||||
@@ -63,6 +63,10 @@
|
||||
ng-if="subscription.markedForCancel">
|
||||
Reinstate
|
||||
</button>
|
||||
<button type="button" class="btn btn-default btn-flat" ng-click="license()"
|
||||
ng-if="!subscription.cancelled">
|
||||
Download License
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box box-default" ng-if="storage">
|
||||
@@ -82,7 +86,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer" ng-if="!subscription.cancelled">
|
||||
<div class="box-footer" ng-if="subscription && paymentSource && !subscription.cancelled">
|
||||
<button type="button" class="btn btn-default btn-flat" ng-click="adjustStorage(true)">
|
||||
Add Storage
|
||||
</button>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<h1>Premium<span class="hidden-xs"> Membership</span><small>get started today!</small></h1>
|
||||
</section>
|
||||
<section class="content">
|
||||
<form name="form" ng-submit="form.$valid && submit(model)" api-form="submitPromise">
|
||||
<form name="form" ng-submit="form.$valid && submit(model, form)" api-form="submitPromise">
|
||||
<div class="callout callout-danger validation-errors" ng-show="form.$errors">
|
||||
<h4>Errors have occurred</h4>
|
||||
<ul>
|
||||
@@ -44,6 +44,29 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-if="selfHosted">
|
||||
<div class="box box-default">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">License</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<p>Unlock premium with your license.</p>
|
||||
<div class="form-group" show-error>
|
||||
<label for="file" class="sr-only">License</label>
|
||||
<input type="file" id="file" name="file" accept=".json" />
|
||||
<p class="help-block">
|
||||
Your license file will be named something like <code>bitwarden_premium_license.json</code>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary btn-flat" ng-disabled="form.$loading">
|
||||
<i class="fa fa-refresh fa-spin loading-icon" ng-show="form.$loading"></i>Submit
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-if="!selfHosted">
|
||||
<div class="box box-default">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">Addons</h3>
|
||||
@@ -454,5 +477,6 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
Reference in New Issue
Block a user