add log in frontend

This commit is contained in:
MaysWind
2020-11-22 11:01:06 +08:00
parent 801ceeaa2d
commit 800e922aec
15 changed files with 129 additions and 9 deletions
+42
View File
@@ -0,0 +1,42 @@
import settings from './settings.js';
function logDebug(msg, obj) {
if (settings.isEnableDebug()) {
if (obj) {
console.debug('[lab Debug] ' + msg, obj);
} else {
console.debug('[lab Debug] ' + msg);
}
}
}
function logInfo(msg, obj) {
if (obj) {
console.info('[lab Info] ' + msg, obj);
} else {
console.info('[lab Info] ' + msg);
}
}
function logWarn(msg, obj) {
if (obj) {
console.warn('[lab Warn] ' + msg, obj);
} else {
console.warn('[lab Warn] ' + msg);
}
}
function logError(msg, obj) {
if (obj) {
console.error('[lab Error] ' + msg, obj);
} else {
console.error('[lab Error] ' + msg);
}
}
export default {
debug: logDebug,
info: logInfo,
warn: logWarn,
error: logError
};
+3
View File
@@ -5,6 +5,7 @@ const serverSettingsCookieKey = 'ACP_SETTINGS';
const defaultSettings = {
lang: 'en',
debug: false,
applicationLock: false,
applicationLockWebAuthn: false,
autoUpdateExchangeRatesData: true,
@@ -75,6 +76,8 @@ function clearSettings() {
export default {
getLanguage: () => getOriginalOption('lang'),
setLanguage: value => setOption('lang', value),
isEnableDebug: () => getOption('debug'),
setEnableDebug: value => setOption('debug', value),
isEnableApplicationLock: () => getOption('applicationLock'),
setEnableApplicationLock: value => setOption('applicationLock', value),
isEnableApplicationLockWebAuthn: () => getOption('applicationLockWebAuthn'),
+19 -3
View File
@@ -1,4 +1,5 @@
import CBOR from 'cbor-js';
import logger from './logger.js';
import utils from './utils.js';
const PUBLIC_KEY_CREDENTIAL_CREATION_OPTIONS_TEMPLATE = {
@@ -72,6 +73,8 @@ function registerCredential({ username, nickname }, userSecret) {
}
});
logger.debug('webauthn create options', publicKeyCredentialCreationOptions);
return navigator.credentials.create({
publicKey: publicKeyCredentialCreationOptions
}).then(rawCredential => {
@@ -80,15 +83,20 @@ function registerCredential({ username, nickname }, userSecret) {
const challengeFromClientData = clientData && clientData.challenge ? atob(clientData.challenge) : null;
logger.debug('webauthn create raw response', rawCredential);
if (rawCredential && rawCredential.rawId &&
clientData && clientData.type === 'webauthn.create' && challengeFromClientData === challenge) {
return {
const ret = {
id: utils.base64encode(rawCredential.rawId),
clientData: clientData,
publicKey: publicKey,
rawCredential: rawCredential
};
logger.debug('webauthn create response', ret);
return ret;
} else {
return Promise.reject({
invalid: true
@@ -137,22 +145,30 @@ function verifyCredential(credentialId) {
});
publicKeyCredentialRequestOptions.allowCredentials[0].id = Uint8Array.from(atob(credentialId), c=>c.charCodeAt(0)).buffer;
logger.debug('webauthn get options', publicKeyCredentialRequestOptions);
return navigator.credentials.get({
publicKey: publicKeyCredentialRequestOptions
}).then(rawCredential => {
const clientData = rawCredential ? parseClientData(rawCredential) : null;
const challengeFromClientData = clientData && clientData.challenge ? atob(clientData.challenge) : null;
logger.debug('webauthn get raw response', rawCredential);
if (rawCredential && rawCredential.rawId &&
rawCredential.response && rawCredential.response.userHandle &&
clientData && clientData.type === 'webauthn.get' && challengeFromClientData === challenge) {
return {
const ret = {
id: utils.base64encode(rawCredential.rawId),
userSecret: utils.arrayBufferToString(rawCredential.response.userHandle),
clientData: clientData,
rawCredential: rawCredential
};
logger.debug('webauthn get response', ret);
return ret;
} else {
return Promise.reject({
invalid: true
+8
View File
@@ -20,6 +20,7 @@ import icons from './consts/icon.js';
import account from './consts/account.js';
import licenses from './consts/licenses.js';
import version from './lib/version.js';
import logger from './lib/logger.js';
import settings from './lib/settings.js';
import services from './lib/services.js';
import userstate from './lib/userstate.js';
@@ -51,6 +52,7 @@ Vue.prototype.$constants = {
account: account,
};
Vue.prototype.$utilities = utils;
Vue.prototype.$logger = logger;
Vue.prototype.$webauthn = webauthn;
Vue.prototype.$settings = settings;
Vue.prototype.$getDefaultLanguage = getDefaultLanguage;
@@ -163,6 +165,12 @@ Vue.filter('accountIcon', (value) => accountIconFilter(value));
Vue.filter('tokenDevice', (value) => tokenDeviceFilter(value));
Vue.filter('tokenIcon', (value) => tokenIconFilter(value));
if (settings.getLanguage()) {
logger.info(`Current language is ${settings.getLanguage()}`);
} else {
logger.info(`No language is set, use browser default ${getDefaultLanguage()}`);
}
Vue.prototype.$setLanguage(settings.getLanguage() || getDefaultLanguage());
if (userstate.isUserLogined()) {
+5 -3
View File
@@ -112,12 +112,14 @@ export default {
self.$user.saveWebAuthnConfig(id);
self.$settings.setEnableApplicationLockWebAuthn(true);
self.$toast('You have enabled Face ID/Touch ID successfully');
}).catch(({ notSupported, invalid }) => {
}).catch(error => {
self.$logger.error('failed to enable FaceID/Touch ID', error);
self.$hideLoading();
if (notSupported) {
if (error.notSupported) {
self.$toast('This device does not support Face ID/Touch ID');
} else if (invalid) {
} else if (error.invalid) {
self.$toast('Failed to enable Face ID/Touch ID');
} else {
self.$toast('User has canceled or this device does not support Face ID/Touch ID');
+2
View File
@@ -137,6 +137,8 @@ export default {
self.$toast('Exchange rates data has been updated');
}).catch(error => {
self.$logger.error('failed to get latest exchange rates data', error);
if (done) {
done();
}
+4
View File
@@ -194,6 +194,8 @@ export default {
router.refreshPage();
}).catch(error => {
self.$logger.error('failed to login', error);
self.logining = false;
self.$hideLoading();
@@ -267,6 +269,8 @@ export default {
self.show2faSheet = false;
router.refreshPage();
}).catch(error => {
self.$logger.error('failed to verify 2fa', error);
self.verifying = false;
self.$hideLoading();
+2
View File
@@ -188,6 +188,8 @@ export default {
self.$exchangeRates.clearExchangeRates();
router.navigate('/');
}).catch(error => {
self.$logger.error('failed to log out', error);
self.logouting = false;
self.$hideLoading();
+2
View File
@@ -166,6 +166,8 @@ export default {
self.$toast('You have been successfully registered');
router.navigate('/');
}).catch(error => {
self.$logger.error('failed to sign up', error);
self.submitting = false;
self.$hideLoading();
+6 -3
View File
@@ -43,10 +43,12 @@ export default {
}
router.refreshPage();
}).catch(({ notSupported, invalid }) => {
if (notSupported) {
}).catch(error => {
self.$logger.error('failed to use webauthn to verify', error);
if (error.notSupported) {
self.$toast('This device does not support Face ID/Touch ID');
} else if (invalid) {
} else if (error.invalid) {
self.$toast('Failed to authenticate by Face ID/Touch ID');
} else {
self.$toast('User has canceled or this device does not support Face ID/Touch ID');
@@ -72,6 +74,7 @@ export default {
router.refreshPage();
} catch (ex) {
this.$logger.error('failed to unlock by pin code', ex);
this.$alert('PIN code is wrong');
}
},
@@ -394,6 +394,8 @@ export default {
self.loading = false;
}).catch(error => {
self.$logger.error('failed to load account info', error);
if (error.response && error.response.data && error.response.data.errorMessage) {
self.$alert({ error: error.response.data }, () => {
router.back();
@@ -548,6 +550,8 @@ export default {
router.back('/account/list', { force: true });
}).catch(error => {
self.$logger.error('failed to save account', error);
self.submitting = false;
self.$hideLoading();
+10
View File
@@ -305,6 +305,8 @@ export default {
self.accounts = self.$utilities.getCategorizedAccounts(data.result);
self.loading = false;
}).catch(error => {
self.$logger.error('failed to load account list', error);
if (error.response && error.response.data && error.response.data.errorMessage) {
self.$alert({ error: error.response.data }, () => {
router.back();
@@ -332,6 +334,8 @@ export default {
self.accounts = self.$utilities.getCategorizedAccounts(data.result);
}).catch(error => {
self.$logger.error('failed to reload account list', error);
done();
if (error.response && error.response.data && error.response.data.errorMessage) {
@@ -477,6 +481,8 @@ export default {
self.sortable = false;
self.displayOrderModified = false;
}).catch(error => {
self.$logger.error('failed to save accounts display order', error);
self.displayOrderSaving = false;
self.$hideLoading();
@@ -514,6 +520,8 @@ export default {
account.hidden = hidden;
}).catch(error => {
self.$logger.error('failed to change account visibility', error);
self.$hideLoading();
if (error.response && error.response.data && error.response.data.errorMessage) {
@@ -555,6 +563,8 @@ export default {
}
});
}).catch(error => {
self.$logger.error('failed to delete account', error);
self.$hideLoading();
if (error.response && error.response.data && error.response.data.errorMessage) {
+8
View File
@@ -69,6 +69,8 @@ export default {
self.tokens = data.result;
self.loading = false;
}).catch(error => {
self.$logger.error('failed to load token list', error);
if (error.response && error.response.data && error.response.data.errorMessage) {
self.$alert({ error: error.response.data }, () => {
router.back();
@@ -96,6 +98,8 @@ export default {
self.tokens = data.result;
}).catch(error => {
self.$logger.error('failed to reload token list', error);
done();
if (error.response && error.response.data && error.response.data.errorMessage) {
@@ -132,6 +136,8 @@ export default {
}
});
}).catch(error => {
self.$logger.error('failed to revoke token', error);
self.$hideLoading();
if (error.response && error.response.data && error.response.data.errorMessage) {
@@ -169,6 +175,8 @@ export default {
self.$toast('You have logged out all other sessions');
}).catch(error => {
self.$logger.error('failed to revoke all tokens', error);
self.$hideLoading();
if (error.response && error.response.data && error.response.data.errorMessage) {
+10
View File
@@ -184,6 +184,8 @@ export default {
self.status = data.result.enable;
self.loading = false;
}).catch(error => {
self.$logger.error('failed to get 2fa status', error);
if (error.response && error.response.data && error.response.data.errorMessage) {
self.$alert({ error: error.response.data }, () => {
router.back();
@@ -220,6 +222,8 @@ export default {
self.showInputPasscodeSheetForEnable = true;
}).catch(error => {
self.$logger.error('failed to request to enable 2fa', error);
self.enabling = false;
self.$hideLoading();
@@ -262,6 +266,8 @@ export default {
self.showBackupCodeSheet = true;
}
}).catch(error => {
self.$logger.error('failed to confirm to enable 2fa', error);
self.enableConfirming = false;
self.$hideLoading();
@@ -300,6 +306,8 @@ export default {
self.showInputPasswordSheetForDisable = false;
self.$toast('Two factor authentication has been disabled');
}).catch(error => {
self.$logger.error('failed to disable 2fa', error);
self.disabling = false;
self.$hideLoading();
@@ -339,6 +347,8 @@ export default {
self.currentBackupCode = data.result.recoveryCodes.join('\n');
self.showBackupCodeSheet = true;
}).catch(error => {
self.$logger.error('failed to regenerate 2fa recovery code', error);
self.regenerating = false;
self.$hideLoading();
+4
View File
@@ -189,6 +189,8 @@ export default {
self.newProfile.defaultCurrency = self.oldProfile.defaultCurrency;
self.loading = false;
}).catch(error => {
self.$logger.error('failed to get user profile', error);
if (error.response && error.response.data && error.response.data.errorMessage) {
self.$alert({ error: error.response.data }, () => {
router.back();
@@ -251,6 +253,8 @@ export default {
self.$toast('Your profile has been successfully updated');
router.back('/settings', { force: true });
}).catch(error => {
self.$logger.error('failed to save user profile', error);
self.saving = false;
self.$hideLoading();
self.currentPassword = '';