mirror of
https://github.com/bitwarden/desktop.git
synced 2024-09-07 00:38:13 +02:00
premium membership page
This commit is contained in:
parent
1c693a45b3
commit
3a8f149008
@ -762,5 +762,73 @@
|
||||
"updateKey": {
|
||||
"message": "You cannot use this feature until you update your encryption key.",
|
||||
"description": "You cannot use this feature until you update your encryption key."
|
||||
},
|
||||
"premiumMembership": {
|
||||
"message": "Premium Membership",
|
||||
"description": "Premium Membership"
|
||||
},
|
||||
"premiumManage": {
|
||||
"message": "Manage Membership",
|
||||
"description": "Manage Membership"
|
||||
},
|
||||
"premiumManageAlert": {
|
||||
"message": "You can manage your membership on the bitwarden.com web vault. Do you want to visit the website now?",
|
||||
"description": "You can manage your membership on the bitwarden.com web vault. Do you want to visit the website now?"
|
||||
},
|
||||
"premiumRefresh": {
|
||||
"message": "Refresh Membership",
|
||||
"description": "Refresh Membership"
|
||||
},
|
||||
"premiumNotCurrentMember": {
|
||||
"message": "You are not currently a premium member.",
|
||||
"description": "You are not currently a premium member."
|
||||
},
|
||||
"premiumSignUpAndGet": {
|
||||
"message": "Sign up for a premium membership and get:",
|
||||
"description": "Sign up for a premium membership and get:"
|
||||
},
|
||||
"ppremiumSignUpStorage": {
|
||||
"message": "1 GB of encrypted file storage.",
|
||||
"description": "1 GB of encrypted file storage."
|
||||
},
|
||||
"ppremiumSignUpTwoStep": {
|
||||
"message": "Additional two-step login options such as YubiKey, FIDO U2F, and Duo.",
|
||||
"description": "Additional two-step login options such as YubiKey, FIDO U2F, and Duo."
|
||||
},
|
||||
"ppremiumSignUpTotp": {
|
||||
"message": "TOTP verification code (2FA) generator for logins in your vault.",
|
||||
"description": "TOTP verification code (2FA) generator for logins in your vault."
|
||||
},
|
||||
"ppremiumSignUpSupport": {
|
||||
"message": "Priority customer support.",
|
||||
"description": "Priority customer support."
|
||||
},
|
||||
"ppremiumSignUpFuture": {
|
||||
"message": "All future premium features. More coming soon!",
|
||||
"description": "All future premium features. More coming soon!"
|
||||
},
|
||||
"premiumPurchase": {
|
||||
"message": "Purchase Premium",
|
||||
"description": "Purchase Premium"
|
||||
},
|
||||
"premiumPurchaseAlert": {
|
||||
"message": "You can purchase premium membership on the bitwarden.com web vault. Do you want to visit the website now?",
|
||||
"description": "You can purchase premium membership on the bitwarden.com web vault. Do you want to visit the website now?"
|
||||
},
|
||||
"premiumCurrentMember": {
|
||||
"message": "You are a premium member!",
|
||||
"description": "You are a premium member!"
|
||||
},
|
||||
"premiumCurrentMemberThanks": {
|
||||
"message": "Thank you for supporting bitwarden.",
|
||||
"description": "Thank you for supporting bitwarden."
|
||||
},
|
||||
"premiumPrice": {
|
||||
"message": "All for just %price% /year!",
|
||||
"description": "All for just %price% /year!"
|
||||
},
|
||||
"refreshComplete": {
|
||||
"message": "Refresh complete",
|
||||
"description": "Refresh complete"
|
||||
}
|
||||
}
|
||||
|
@ -198,6 +198,13 @@
|
||||
data: { authorize: true },
|
||||
params: { animation: null }
|
||||
})
|
||||
.state('premium', {
|
||||
url: '/premium',
|
||||
templateUrl: 'app/settings/views/settingsPremium.html',
|
||||
controller: 'settingsPremiumController',
|
||||
data: { authorize: true },
|
||||
params: { animation: null }
|
||||
})
|
||||
|
||||
.state('folders', {
|
||||
url: '/folders',
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div class="home-page">
|
||||
<img src="../../../../images/logo@3x.png" alt="bitwarden" />
|
||||
<p>{{i18n.loginOrCreateNewAccount}}</p>
|
||||
<div class="buttons">
|
||||
<div class="bottom-buttons">
|
||||
<a class="btn btn-lg btn-primary btn-block" ui-sref="register({animation: 'in-slide-up'})"
|
||||
analytics-on="click" analytics-event="Clicked Create Account">
|
||||
<b>{{i18n.createAccount}}</b>
|
||||
|
50
src/popup/app/settings/settingsPremiumController.js
Normal file
50
src/popup/app/settings/settingsPremiumController.js
Normal file
@ -0,0 +1,50 @@
|
||||
angular
|
||||
.module('bit.settings')
|
||||
|
||||
.controller('settingsPremiumController', function ($scope, i18nService, tokenService, apiService, toastr, SweetAlert,
|
||||
$analytics, $timeout) {
|
||||
$scope.i18n = i18nService;
|
||||
$scope.isPremium = tokenService.getPremium();
|
||||
$scope.price = '$10';
|
||||
|
||||
$scope.refresh = function () {
|
||||
apiService.refreshIdentityToken(function () {
|
||||
toastr.success(i18nService.refreshComplete);
|
||||
$timeout(function () {
|
||||
$scope.isPremium = tokenService.getPremium();
|
||||
});
|
||||
}, function (err) {
|
||||
toastr.error(i18nService.errorsOccurred);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.purchase = function () {
|
||||
SweetAlert.swal({
|
||||
title: i18nService.premiumPurchase,
|
||||
text: i18nService.premiumPurchaseAlert,
|
||||
showCancelButton: true,
|
||||
confirmButtonText: i18nService.yes,
|
||||
cancelButtonText: i18nService.cancel
|
||||
}, function (confirmed) {
|
||||
$analytics.eventTrack('Clicked Purchase Premium');
|
||||
if (confirmed) {
|
||||
chrome.tabs.create({ url: 'https://vault.bitwarden.com/#/?premium=purchase' });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$scope.manage = function () {
|
||||
SweetAlert.swal({
|
||||
title: i18nService.premiumManage,
|
||||
text: i18nService.premiumManageAlert,
|
||||
showCancelButton: true,
|
||||
confirmButtonText: i18nService.yes,
|
||||
cancelButtonText: i18nService.cancel
|
||||
}, function (confirmed) {
|
||||
$analytics.eventTrack('Clicked Manage Membership');
|
||||
if (confirmed) {
|
||||
chrome.tabs.create({ url: 'https://vault.bitwarden.com/#/?premium=manage' });
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
@ -38,6 +38,10 @@
|
||||
{{i18n.account}}
|
||||
</div>
|
||||
<div class="list-section-items">
|
||||
<a class="list-section-item text-primary" ui-sref="premium({animation: 'in-slide-left'})">
|
||||
<i class="fa fa-star fa-fw"></i> <b>{{i18n.premiumMembership}}</b>
|
||||
<i class="fa fa-chevron-right fa-lg"></i>
|
||||
</a>
|
||||
<a class="list-section-item" href="" ng-click="changePassword()">
|
||||
{{i18n.changeMasterPassword}}
|
||||
<i class="fa fa-chevron-right fa-lg"></i>
|
||||
|
54
src/popup/app/settings/views/settingsPremium.html
Normal file
54
src/popup/app/settings/views/settingsPremium.html
Normal file
@ -0,0 +1,54 @@
|
||||
<div class="header">
|
||||
<div class="left">
|
||||
<a ui-sref="tabs.settings({animation: 'out-slide-right'})"><i class="fa fa-chevron-left"></i> {{i18n.settings}}</a>
|
||||
</div>
|
||||
<div class="title">{{i18n.premiumMembership}}</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="premium-page">
|
||||
<div ng-if="!isPremium">
|
||||
<p class="text-center lead">{{i18n.premiumNotCurrentMember}}</p>
|
||||
<p>{{i18n.premiumSignUpAndGet}}</p>
|
||||
<ul class="fa-ul">
|
||||
<li>
|
||||
<i class="fa-li fa fa-check text-success"></i>
|
||||
{{i18n.ppremiumSignUpStorage}}
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa-li fa fa-check text-success"></i>
|
||||
{{i18n.ppremiumSignUpTwoStep}}
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa-li fa fa-check text-success"></i>
|
||||
T{{i18n.ppremiumSignUpTotp}}
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa-li fa fa-check text-success"></i>
|
||||
{{i18n.ppremiumSignUpSupport}}
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa-li fa fa-check text-success"></i>
|
||||
{{i18n.ppremiumSignUpFuture}}
|
||||
</li>
|
||||
</ul>
|
||||
<p class="text-center lead">{{i18n.premiumPrice.replace('%price%', price)}}</p>
|
||||
<div class="bottom-buttons">
|
||||
<a class="btn btn-lg btn-primary btn-block" href="#" stop-click ng-click="purchase()">
|
||||
<b>{{i18n.premiumPurchase}}</b>
|
||||
</a>
|
||||
<a class="btn btn-lg btn-link btn-block" href="#" stop-click ng-click="refresh()">
|
||||
{{i18n.premiumRefresh}}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-if="isPremium">
|
||||
<p class="text-center lead">{{i18n.premiumCurrentMember}}</p>
|
||||
<p class="text-center">{{i18n.premiumCurrentMemberThanks}}</p>
|
||||
<div class="bottom-buttons">
|
||||
<a class="btn btn-lg btn-primary btn-block" href="#" stop-click ng-click="manage()">
|
||||
<b>{{i18n.premiumManage}}</b>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -84,6 +84,7 @@
|
||||
<script src="app/settings/settingsFoldersController.js"></script>
|
||||
<script src="app/settings/settingsAddFolderController.js"></script>
|
||||
<script src="app/settings/settingsEditFolderController.js"></script>
|
||||
<script src="app/settings/settingsPremiumController.js"></script>
|
||||
|
||||
<script src="app/tools/toolsModule.js"></script>
|
||||
<script src="app/tools/toolsController.js"></script>
|
||||
|
@ -37,22 +37,6 @@
|
||||
p {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.buttons {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
padding: 20px;
|
||||
|
||||
.btn {
|
||||
font-size: @font-size-base;
|
||||
}
|
||||
|
||||
.btn-link {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.splash-page {
|
||||
@ -74,4 +58,36 @@
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-buttons {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
padding: 20px;
|
||||
|
||||
.btn {
|
||||
font-size: @font-size-base;
|
||||
}
|
||||
|
||||
.btn-link {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.premium-page {
|
||||
padding: 60px 20px 20px;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
|
||||
p.lead {
|
||||
font-weight: normal;
|
||||
font-size: 18px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
}
|
||||
|
@ -56,6 +56,18 @@ function initApiService() {
|
||||
});
|
||||
};
|
||||
|
||||
ApiService.prototype.refreshIdentityToken = function (success, error) {
|
||||
refreshToken(this, function () {
|
||||
success();
|
||||
}, function (jqXHR) {
|
||||
if (jqXHR) {
|
||||
handleError(error, jqXHR, false, self);
|
||||
return;
|
||||
}
|
||||
error();
|
||||
});
|
||||
};
|
||||
|
||||
// Two Factor APIs
|
||||
|
||||
ApiService.prototype.postTwoFactorEmail = function (request, success, error) {
|
||||
@ -511,23 +523,10 @@ function initApiService() {
|
||||
});
|
||||
} // handle token refresh
|
||||
else if (self.tokenService.tokenNeedsRefresh()) {
|
||||
self.tokenService.getRefreshToken(function (refreshToken) {
|
||||
if (!refreshToken || refreshToken === '') {
|
||||
deferred.reject();
|
||||
return;
|
||||
}
|
||||
|
||||
postConnectToken(self, {
|
||||
grant_type: 'refresh_token',
|
||||
client_id: 'browser',
|
||||
refresh_token: refreshToken
|
||||
}, function (token) {
|
||||
self.tokenService.setTokens(token.accessToken, token.refreshToken, function () {
|
||||
resolveTokenQs(token.accessToken, self, deferred);
|
||||
});
|
||||
}, function (jqXHR) {
|
||||
deferred.reject(jqXHR);
|
||||
});
|
||||
refreshToken(self, function (accessToken) {
|
||||
resolveTokenQs(accessToken, self, deferred);
|
||||
}, function (err) {
|
||||
deferred.reject(err);
|
||||
});
|
||||
}
|
||||
else {
|
||||
@ -543,6 +542,27 @@ function initApiService() {
|
||||
return deferred.promise
|
||||
}
|
||||
|
||||
function refreshToken(self, success, error) {
|
||||
self.tokenService.getRefreshToken(function (refreshToken) {
|
||||
if (!refreshToken || refreshToken === '') {
|
||||
error();
|
||||
return;
|
||||
}
|
||||
|
||||
postConnectToken(self, {
|
||||
grant_type: 'refresh_token',
|
||||
client_id: 'browser',
|
||||
refresh_token: refreshToken
|
||||
}, function (token) {
|
||||
self.tokenService.setTokens(token.accessToken, token.refreshToken, function () {
|
||||
success(token.accessToken);
|
||||
});
|
||||
}, function (jqXHR) {
|
||||
error(jqXHR);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function resolveTokenQs(token, self, deferred) {
|
||||
var issuer = self.tokenService.getIssuer();
|
||||
if (issuer === self.baseUrl) {
|
||||
|
Loading…
Reference in New Issue
Block a user