support application lock
This commit is contained in:
Generated
+20
@@ -3896,6 +3896,11 @@
|
||||
"randomfill": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"crypto-js": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.0.0.tgz",
|
||||
"integrity": "sha512-bzHZN8Pn+gS7DQA6n+iUmBfl0hO5DJq++QP3U6uTucDtk/0iGpXd/Gg7CGR0p8tJhofJyaKoWBuJI4eAO00BBg=="
|
||||
},
|
||||
"css-color-names": {
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
|
||||
@@ -11218,6 +11223,21 @@
|
||||
"moment": "^2.19.2"
|
||||
}
|
||||
},
|
||||
"vue-pincode-input": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/vue-pincode-input/-/vue-pincode-input-0.4.0.tgz",
|
||||
"integrity": "sha512-A1DtG9J+o5AhdxRcgmuW8xxh7w5+GGVd6Di1J3n12xI99qSyKm9kBNJx4AzrNDgzr2TwUbleAdw7YTy3B68ohQ==",
|
||||
"requires": {
|
||||
"core-js": "^2.6.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"core-js": {
|
||||
"version": "2.6.11",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz",
|
||||
"integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"vue-style-loader": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.2.tgz",
|
||||
|
||||
+3
-1
@@ -10,6 +10,7 @@
|
||||
"dependencies": {
|
||||
"axios": "^0.21.0",
|
||||
"core-js": "^3.6.5",
|
||||
"crypto-js": "^4.0.0",
|
||||
"framework7": "^5.7.14",
|
||||
"framework7-icons": "^3.0.1",
|
||||
"framework7-vue": "^5.7.14",
|
||||
@@ -20,7 +21,8 @@
|
||||
"vue-clipboard2": "^0.3.1",
|
||||
"vue-i18n": "^8.22.1",
|
||||
"vue-i18n-filter": "^0.1.6",
|
||||
"vue-moment": "^4.1.0"
|
||||
"vue-moment": "^4.1.0",
|
||||
"vue-pincode-input": "^0.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "~4.5.0",
|
||||
|
||||
@@ -57,6 +57,16 @@ body {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.vue-pincode-input {
|
||||
margin: 3px !important;
|
||||
padding: 5px !important;
|
||||
box-shadow: 0 0 3px rgba(0,0,0,.5) !important;
|
||||
}
|
||||
|
||||
.list-item-pincode-input .item-inner {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.work-break-all {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
@@ -117,6 +117,12 @@ const licenses = [
|
||||
url: 'https://github.com/Inndy/vue-clipboard2',
|
||||
licenseUrl: 'https://github.com/Inndy/vue-clipboard2/blob/master/LICENSE'
|
||||
},
|
||||
{
|
||||
name: 'vue-pincode-input',
|
||||
copyright: 'Copyright (c) 2019 Maxim Noverin',
|
||||
url: 'https://github.com/Seokky/vue-pincode-input',
|
||||
licenseUrl: 'https://github.com/Seokky/vue-pincode-input/blob/master/LICENSE'
|
||||
},
|
||||
{
|
||||
name: 'core-js',
|
||||
copyright: 'Copyright (c) 2014-2020 Denis Pushkarev',
|
||||
@@ -153,6 +159,12 @@ const licenses = [
|
||||
url: 'https://momentjs.com',
|
||||
licenseUrl: 'https://github.com/moment/moment/blob/develop/LICENSE'
|
||||
},
|
||||
{
|
||||
name: 'crypto-js',
|
||||
copyright: 'Copyright (c) 2009-2013 Jeff Mott, Copyright (c) 2013-2016 Evan Vosberg',
|
||||
url: 'https://github.com/brix/crypto-js',
|
||||
licenseUrl: 'https://github.com/brix/crypto-js/blob/develop/LICENSE'
|
||||
},
|
||||
{
|
||||
name: 'js-cookie',
|
||||
copyright: 'Copyright (c) 2018 Copyright 2018 Klaus Hartl, Fagner Brack, GitHub Contributors',
|
||||
|
||||
@@ -5,6 +5,7 @@ const serverSettingsCookieKey = 'ACP_SETTINGS';
|
||||
|
||||
const defaultSettings = {
|
||||
lang: 'en',
|
||||
applicationLock: false,
|
||||
autoUpdateExchangeRatesData: true,
|
||||
thousandsSeparator: true,
|
||||
currencyDisplayMode: 'code', // or 'none' or 'name'
|
||||
@@ -73,6 +74,8 @@ function clearSettings() {
|
||||
export default {
|
||||
getLanguage: () => getOriginalOption('lang'),
|
||||
setLanguage: value => setOption('lang', value),
|
||||
isEnableApplicationLock: () => getOption('applicationLock'),
|
||||
setEnableApplicationLock: value => setOption('applicationLock', value),
|
||||
isAutoUpdateExchangeRatesData: () => getOption('autoUpdateExchangeRatesData'),
|
||||
setAutoUpdateExchangeRatesData: value => setOption('autoUpdateExchangeRatesData', value),
|
||||
isEnableThousandsSeparator: () => getOption('thousandsSeparator'),
|
||||
|
||||
+80
-4
@@ -1,10 +1,34 @@
|
||||
import utils from './utils.js'
|
||||
import CryptoJS from 'crypto-js';
|
||||
|
||||
import settings from './settings.js';
|
||||
import utils from './utils.js';
|
||||
|
||||
const APP_LOCK_SECRET_BASE_STRING_PREFIX = 'LAB_LOCK_SECRET_';
|
||||
|
||||
const tokenLocalStorageKey = 'lab_user_token';
|
||||
const userInfoLocalStorageKey = 'lab_user_info';
|
||||
const tokenSessionStorageKey = 'lab_user_session_token';
|
||||
const appLockSecretSessionStorageKey = 'lab_user_app_lock_secret';
|
||||
|
||||
function getAppLockSecret(pinCode) {
|
||||
return CryptoJS.SHA256(APP_LOCK_SECRET_BASE_STRING_PREFIX + pinCode).toString();
|
||||
}
|
||||
|
||||
function getEncryptedToken(token, secret) {
|
||||
return CryptoJS.AES.encrypt(token, secret).toString();
|
||||
}
|
||||
|
||||
function getDecryptedToken(encryptedToken, secret) {
|
||||
const bytes = CryptoJS.AES.decrypt(encryptedToken, secret);
|
||||
return bytes.toString(CryptoJS.enc.Utf8);
|
||||
}
|
||||
|
||||
function getToken() {
|
||||
return localStorage.getItem(tokenLocalStorageKey);
|
||||
if (settings.isEnableApplicationLock()) {
|
||||
return sessionStorage.getItem(tokenSessionStorageKey);
|
||||
} else {
|
||||
return localStorage.getItem(tokenLocalStorageKey);
|
||||
}
|
||||
}
|
||||
|
||||
function getUserInfo() {
|
||||
@@ -13,12 +37,58 @@ function getUserInfo() {
|
||||
}
|
||||
|
||||
function isUserLogined() {
|
||||
return !!getToken();
|
||||
return !!localStorage.getItem(tokenLocalStorageKey);
|
||||
}
|
||||
|
||||
function isUserUnlocked() {
|
||||
if (!isUserLogined()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!settings.isEnableApplicationLock()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !!sessionStorage.getItem(appLockSecretSessionStorageKey) && !!sessionStorage.getItem(tokenSessionStorageKey);
|
||||
}
|
||||
|
||||
function unlockToken(pinCode) {
|
||||
const encryptedToken = localStorage.getItem(tokenLocalStorageKey);
|
||||
const secret = getAppLockSecret(pinCode);
|
||||
const token = getDecryptedToken(encryptedToken, secret);
|
||||
|
||||
sessionStorage.setItem(appLockSecretSessionStorageKey, secret);
|
||||
sessionStorage.setItem(tokenSessionStorageKey, token);
|
||||
}
|
||||
|
||||
function encryptToken(pinCode) {
|
||||
const token = localStorage.getItem(tokenLocalStorageKey);
|
||||
const secret = getAppLockSecret(pinCode);
|
||||
const encryptedToken = getEncryptedToken(token, secret);
|
||||
|
||||
sessionStorage.setItem(appLockSecretSessionStorageKey, secret);
|
||||
sessionStorage.setItem(tokenSessionStorageKey, token);
|
||||
localStorage.setItem(tokenLocalStorageKey, encryptedToken);
|
||||
}
|
||||
|
||||
function decryptToken() {
|
||||
const token = sessionStorage.getItem(tokenSessionStorageKey);
|
||||
|
||||
localStorage.setItem(tokenLocalStorageKey, token);
|
||||
sessionStorage.removeItem(tokenSessionStorageKey);
|
||||
sessionStorage.removeItem(appLockSecretSessionStorageKey);
|
||||
}
|
||||
|
||||
function updateToken(token) {
|
||||
if (utils.isString(token)) {
|
||||
localStorage.setItem(tokenLocalStorageKey, token);
|
||||
if (settings.isEnableApplicationLock()) {
|
||||
sessionStorage.setItem(tokenSessionStorageKey, token);
|
||||
|
||||
const secret = sessionStorage.getItem(appLockSecretSessionStorageKey);
|
||||
localStorage.setItem(tokenLocalStorageKey, getEncryptedToken(token, secret));
|
||||
} else {
|
||||
localStorage.setItem(tokenLocalStorageKey, token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +111,8 @@ function updateTokenAndUserInfo(item) {
|
||||
}
|
||||
|
||||
function clearTokenAndUserInfo() {
|
||||
sessionStorage.removeItem(tokenSessionStorageKey);
|
||||
sessionStorage.removeItem(appLockSecretSessionStorageKey);
|
||||
localStorage.removeItem(tokenLocalStorageKey);
|
||||
localStorage.removeItem(userInfoLocalStorageKey);
|
||||
}
|
||||
@@ -49,6 +121,10 @@ export default {
|
||||
getToken,
|
||||
getUserInfo,
|
||||
isUserLogined,
|
||||
isUserUnlocked,
|
||||
unlockToken,
|
||||
encryptToken,
|
||||
decryptToken,
|
||||
updateToken,
|
||||
updateUserInfo,
|
||||
updateTokenAndUserInfo,
|
||||
|
||||
@@ -275,6 +275,8 @@ export default {
|
||||
'Statistics': 'Statistics',
|
||||
'Settings': 'Settings',
|
||||
'Back': 'Back',
|
||||
'Unlock': 'Unlock',
|
||||
'Re-login': 'Re-login',
|
||||
'Username': 'Username',
|
||||
'Your username': 'Your username',
|
||||
'Your username or email': 'Your username or email',
|
||||
@@ -309,6 +311,7 @@ export default {
|
||||
'Unable to verify': 'Unable to verify',
|
||||
'Use a backup code': 'Use a backup code',
|
||||
'Use a passcode': 'Use a passcode',
|
||||
'PIN code is wrong': 'PIN code is wrong',
|
||||
'Sign Up': 'Sign Up',
|
||||
'Transaction Details': 'Transaction Details',
|
||||
'Account List': 'Account List',
|
||||
@@ -405,6 +408,9 @@ export default {
|
||||
'Log Out': 'Log Out',
|
||||
'Are you sure you want to log out?': 'Are you sure you want to log out?',
|
||||
'Unable to logout': 'Unable to logout',
|
||||
'Application Lock': 'Application Lock',
|
||||
'PIN Code': 'PIN Code',
|
||||
'Please input a new PIN code. PIN code would encrypt your local data, so you need input this PIN code when you launch this app. If this PIN code is lost, you should re-login.': 'Please input a new PIN code. PIN code would encrypt your local data, so you need input this PIN code when you launch this app. If this PIN code is lost, you should re-login.',
|
||||
'Exchange Rates Data': 'Exchange Rates Data',
|
||||
'Base Currency': 'Base Currency',
|
||||
'Last Updated': 'Last Updated',
|
||||
|
||||
@@ -275,6 +275,8 @@ export default {
|
||||
'Statistics': '统计',
|
||||
'Settings': '设置',
|
||||
'Back': '返回',
|
||||
'Unlock': '解锁',
|
||||
'Re-login': '重新登陆',
|
||||
'Username': '用户名',
|
||||
'Your username': '你的用户名',
|
||||
'Your username or email': '你的用户名或注册邮箱',
|
||||
@@ -309,6 +311,7 @@ export default {
|
||||
'Unable to verify': '无法验证',
|
||||
'Use a backup code': '使用备用码',
|
||||
'Use a passcode': '使用验证码',
|
||||
'PIN code is wrong': 'PIN码错误',
|
||||
'Sign Up': '注册',
|
||||
'Transaction Details': '交易详情',
|
||||
'Account List': '账户列表',
|
||||
@@ -405,6 +408,9 @@ export default {
|
||||
'Log Out': '退出登录',
|
||||
'Are you sure you want to log out?': '您确定是否要退出登录?',
|
||||
'Unable to logout': '无法退出登录',
|
||||
'Application Lock': '应用锁',
|
||||
'PIN Code': 'PIN码',
|
||||
'Please input a new PIN code. PIN code would encrypt your local data, so you need input this PIN code when you launch this app. If this PIN code is lost, you should re-login.': '请输入一个新的PIN码,PIN码会加密你的本地数据,所以您每次打开应用时都需要输入PIN码。如果您忘记了PIN码,您需要重新登录。',
|
||||
'Exchange Rates Data': '汇率数据',
|
||||
'Base Currency': '基准货币',
|
||||
'Last Updated': '最后更新',
|
||||
|
||||
+11
-7
@@ -3,6 +3,7 @@ import VueI18n from 'vue-i18n';
|
||||
import VueI18nFilter from 'vue-i18n-filter'
|
||||
import Framework7 from 'framework7/framework7.esm.bundle.js';
|
||||
import Framework7Vue from 'framework7-vue/framework7-vue.esm.bundle.js';
|
||||
import PincodeInput from 'vue-pincode-input';
|
||||
import VueMoment from 'vue-moment';
|
||||
import VueClipboard from 'vue-clipboard2';
|
||||
|
||||
@@ -34,6 +35,7 @@ Vue.use(VueI18n);
|
||||
Vue.use(VueI18nFilter);
|
||||
Vue.use(VueMoment, { moment });
|
||||
Vue.use(VueClipboard);
|
||||
Vue.component('PincodeInput', PincodeInput);
|
||||
Framework7.use(Framework7Vue);
|
||||
|
||||
const i18n = new VueI18n(getI18nOptions());
|
||||
@@ -161,14 +163,16 @@ Vue.filter('tokenIcon', (value) => tokenIconFilter(value));
|
||||
|
||||
Vue.prototype.$setLanguage(settings.getLanguage() || getDefaultLanguage());
|
||||
|
||||
// refresh token if user is logined
|
||||
if (userstate.isUserLogined()) {
|
||||
services.refreshToken();
|
||||
}
|
||||
if (!settings.isEnableApplicationLock()) {
|
||||
// refresh token if user is logined
|
||||
if (userstate.isUserLogined()) {
|
||||
services.refreshToken();
|
||||
}
|
||||
|
||||
// auto refresh exchange rates data
|
||||
if (settings.isAutoUpdateExchangeRatesData()) {
|
||||
services.autoRefreshLatestExchangeRates();
|
||||
// auto refresh exchange rates data
|
||||
if (settings.isAutoUpdateExchangeRatesData()) {
|
||||
services.autoRefreshLatestExchangeRates();
|
||||
}
|
||||
}
|
||||
|
||||
new Vue({
|
||||
|
||||
+68
-8
@@ -3,6 +3,7 @@ import userState from "../lib/userstate.js";
|
||||
import HomePage from '../views/mobile/Home.vue';
|
||||
import LoginPage from '../views/mobile/Login.vue';
|
||||
import SignUpPage from '../views/mobile/Signup.vue';
|
||||
import UnlockPage from '../views/mobile/Unlock.vue';
|
||||
|
||||
import TransactionDetailPage from '../views/mobile/transactions/Detail.vue';
|
||||
import TransactionNewPage from '../views/mobile/transactions/New.vue';
|
||||
@@ -13,6 +14,7 @@ import AccountEditPage from '../views/mobile/accounts/AccountEdit.vue';
|
||||
import StatisticsOverviewPage from '../views/mobile/statistics/Overview.vue';
|
||||
|
||||
import SettingsPage from '../views/mobile/Settings.vue';
|
||||
import ApplicationLockPage from '../views/mobile/ApplicationLock.vue';
|
||||
import ExchangeRatesPage from "../views/mobile/ExchangeRates.vue";
|
||||
import AboutPage from "../views/mobile/About.vue";
|
||||
import UserProfilePage from "../views/mobile/users/UserProfile.vue";
|
||||
@@ -22,25 +24,73 @@ import SessionListPage from "../views/mobile/users/SessionList.vue";
|
||||
function checkLogin(to, from, resolve, reject) {
|
||||
const router = this;
|
||||
|
||||
if (userState.isUserLogined()) {
|
||||
resolve();
|
||||
if (!userState.isUserLogined()) {
|
||||
reject();
|
||||
router.navigate('/login', {
|
||||
clearPreviousHistory: true,
|
||||
pushState: false
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
reject();
|
||||
router.navigate('/login');
|
||||
if (!userState.isUserUnlocked()) {
|
||||
reject();
|
||||
router.navigate('/unlock', {
|
||||
clearPreviousHistory: true,
|
||||
pushState: false
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
resolve();
|
||||
}
|
||||
|
||||
function checkLocked(to, from, resolve, reject) {
|
||||
const router = this;
|
||||
|
||||
if (!userState.isUserLogined()) {
|
||||
reject();
|
||||
router.navigate('/login', {
|
||||
clearPreviousHistory: true,
|
||||
pushState: false
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (userState.isUserUnlocked()) {
|
||||
reject();
|
||||
router.navigate('/', {
|
||||
clearPreviousHistory: true,
|
||||
pushState: false
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
resolve();
|
||||
}
|
||||
|
||||
function checkNotLogin(to, from, resolve, reject) {
|
||||
const router = this;
|
||||
|
||||
if (!userState.isUserLogined()) {
|
||||
resolve();
|
||||
if (userState.isUserLogined() && !userState.isUserUnlocked()) {
|
||||
reject();
|
||||
router.navigate('/unlock', {
|
||||
clearPreviousHistory: true,
|
||||
pushState: false
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
reject();
|
||||
router.navigate('/');
|
||||
if (userState.isUserLogined()) {
|
||||
reject();
|
||||
router.navigate('/', {
|
||||
clearPreviousHistory: true,
|
||||
pushState: false
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
resolve();
|
||||
}
|
||||
|
||||
const routes = [
|
||||
@@ -59,6 +109,11 @@ const routes = [
|
||||
component: SignUpPage,
|
||||
beforeEnter: checkNotLogin
|
||||
},
|
||||
{
|
||||
path: '/unlock',
|
||||
component: UnlockPage,
|
||||
beforeEnter: checkLocked
|
||||
},
|
||||
{
|
||||
path: '/transaction/details',
|
||||
component: TransactionDetailPage,
|
||||
@@ -94,6 +149,11 @@ const routes = [
|
||||
component: SettingsPage,
|
||||
beforeEnter: checkLogin
|
||||
},
|
||||
{
|
||||
path: '/app_lock',
|
||||
component: ApplicationLockPage,
|
||||
beforeEnter: checkLogin
|
||||
},
|
||||
{
|
||||
path: '/exchange_rates',
|
||||
component: ExchangeRatesPage,
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<f7-page>
|
||||
<f7-navbar>
|
||||
<f7-nav-left back-link-force :back-link="$t('Back')"></f7-nav-left>
|
||||
<f7-nav-title :title="$t('Application Lock')"></f7-nav-title>
|
||||
</f7-navbar>
|
||||
|
||||
<f7-card v-if="isEnableApplicationLock">
|
||||
<f7-card-content :padding="false">
|
||||
<f7-list>
|
||||
<f7-list-item :title="$t('Status')" :after="$t('Enabled')"></f7-list-item>
|
||||
<f7-list-button @click="disable">{{ $t('Disable') }}</f7-list-button>
|
||||
</f7-list>
|
||||
</f7-card-content>
|
||||
</f7-card>
|
||||
|
||||
<f7-card v-else-if="!isEnableApplicationLock">
|
||||
<f7-card-content :padding="false">
|
||||
<f7-list>
|
||||
<f7-list-item :title="$t('Status')" :after="$t('Disabled')"></f7-list-item>
|
||||
<f7-list-button @click="enable(null)">{{ $t('Enable') }}</f7-list-button>
|
||||
</f7-list>
|
||||
</f7-card-content>
|
||||
</f7-card>
|
||||
|
||||
<f7-sheet
|
||||
style="height:auto;"
|
||||
:opened="showInputPinCodeSheetForEnable" @sheet:closed="showInputPinCodeSheetForEnable = false; currentPinCodeForEnable = ''"
|
||||
>
|
||||
<f7-page-content>
|
||||
<div class="display-flex padding justify-content-space-between align-items-center">
|
||||
<div style="font-size: 18px"><b>{{ $t('PIN Code') }}</b></div>
|
||||
</div>
|
||||
<div class="padding-horizontal padding-bottom">
|
||||
<p class="no-margin-top margin-bottom-half">{{ $t('Please input a new PIN code. PIN code would encrypt your local data, so you need input this PIN code when you launch this app. If this PIN code is lost, you should re-login.') }}</p>
|
||||
<f7-list no-hairlines class="no-margin-top margin-bottom">
|
||||
<f7-list-item class="list-item-pincode-input">
|
||||
<PincodeInput secure :length="6" v-model="currentPinCodeForEnable" />
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
<f7-button large fill :class="{ 'disabled': !currentPinCodeForEnable }" :text="$t('Continue')" @click="enable(currentPinCodeForEnable)"></f7-button>
|
||||
<div class="margin-top text-align-center">
|
||||
<f7-link @click="showInputPinCodeSheetForEnable = false" :text="$t('Cancel')"></f7-link>
|
||||
</div>
|
||||
</div>
|
||||
</f7-page-content>
|
||||
</f7-sheet>
|
||||
</f7-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
isEnableApplicationLock: this.$settings.isEnableApplicationLock(),
|
||||
currentPinCodeForEnable: '',
|
||||
showInputPinCodeSheetForEnable: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
enable(pinCode) {
|
||||
if (!pinCode) {
|
||||
this.showInputPinCodeSheetForEnable = true;
|
||||
return;
|
||||
}
|
||||
|
||||
this.$user.encryptToken(pinCode);
|
||||
this.$settings.setEnableApplicationLock(true);
|
||||
this.isEnableApplicationLock = true;
|
||||
|
||||
this.showInputPinCodeSheetForEnable = false;
|
||||
},
|
||||
disable() {
|
||||
this.$user.decryptToken();
|
||||
this.$settings.setEnableApplicationLock(false);
|
||||
this.isEnableApplicationLock = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -185,13 +185,14 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
self.$settings.setEnableApplicationLock(false);
|
||||
self.$user.updateTokenAndUserInfo(data.result);
|
||||
|
||||
if (self.$settings.isAutoUpdateExchangeRatesData()) {
|
||||
self.$services.autoRefreshLatestExchangeRates();
|
||||
}
|
||||
|
||||
router.navigate('/');
|
||||
router.refreshPage();
|
||||
}).catch(error => {
|
||||
self.logining = false;
|
||||
self.$hideLoading();
|
||||
@@ -256,6 +257,7 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
self.$settings.setEnableApplicationLock(false);
|
||||
self.$user.updateTokenAndUserInfo(data.result);
|
||||
|
||||
if (self.$settings.isAutoUpdateExchangeRatesData()) {
|
||||
@@ -263,7 +265,7 @@ export default {
|
||||
}
|
||||
|
||||
self.show2faSheet = false;
|
||||
router.navigate('/');
|
||||
router.refreshPage();
|
||||
}).catch(error => {
|
||||
self.verifying = false;
|
||||
self.$hideLoading();
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
</select>
|
||||
</f7-list-item>
|
||||
|
||||
<f7-list-item :title="$t('Application Lock')" :after="isEnableApplicationLock ? $t('Enabled') : $t('Disabled')" link="/app_lock"></f7-list-item>
|
||||
|
||||
<f7-list-item :title="$t('Exchange Rates Data')" :after="exchangeRatesLastUpdateDate" link="/exchange_rates"></f7-list-item>
|
||||
|
||||
<f7-list-item>
|
||||
@@ -100,6 +102,9 @@ export default {
|
||||
this.$setLanguage(value);
|
||||
}
|
||||
},
|
||||
isEnableApplicationLock() {
|
||||
return this.$settings.isEnableApplicationLock();
|
||||
},
|
||||
exchangeRatesLastUpdateDate() {
|
||||
const exchangeRates = this.$exchangeRates.getExchangeRates();
|
||||
return exchangeRates && exchangeRates.date ? this.$moment(exchangeRates.date).format(this.$t('format.date.long')) : '';
|
||||
|
||||
@@ -157,6 +157,8 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
self.$settings.setEnableApplicationLock(false);
|
||||
|
||||
if (self.$utilities.isString(data.result.token)) {
|
||||
self.$user.updateTokenAndUserInfo(data.result);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
<template>
|
||||
<f7-page no-toolbar no-navbar no-swipeback login-screen>
|
||||
<f7-login-screen-title>{{ $t('PIN Code') }}</f7-login-screen-title>
|
||||
<f7-list>
|
||||
<f7-list-item class="list-item-pincode-input">
|
||||
<PincodeInput secure :length="6" v-model="pinCode" @keyup.native="unlock" />
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
<f7-list>
|
||||
<f7-list-button :class="{ 'disabled': !pinCodeValid }" :text="$t('Unlock')" @click="unlock"></f7-list-button>
|
||||
<f7-block-footer>
|
||||
<f7-link :text="$t('Re-login')" @click="relogin"></f7-link>
|
||||
</f7-block-footer>
|
||||
</f7-list>
|
||||
</f7-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
pinCode: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pinCodeValid() {
|
||||
return this.pinCode && this.pinCode.length === 6;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
unlock() {
|
||||
if (!this.pinCodeValid) {
|
||||
return;
|
||||
}
|
||||
|
||||
const router = this.$f7router;
|
||||
|
||||
try {
|
||||
this.$user.unlockToken(this.pinCode);
|
||||
this.$services.refreshToken();
|
||||
|
||||
if (this.$settings.isAutoUpdateExchangeRatesData()) {
|
||||
this.$services.autoRefreshLatestExchangeRates();
|
||||
}
|
||||
|
||||
router.refreshPage();
|
||||
} catch (ex) {
|
||||
this.$alert('PIN code is wrong');
|
||||
}
|
||||
},
|
||||
relogin() {
|
||||
const router = this.$f7router;
|
||||
|
||||
this.$user.clearTokenAndUserInfo();
|
||||
this.$settings.clearSettings();
|
||||
this.$exchangeRates.clearExchangeRates();
|
||||
|
||||
router.navigate('/login', {
|
||||
clearPreviousHistory: true
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user