mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-19 17:24:26 +08:00
show device icon and name in session list
This commit is contained in:
Generated
+5
@@ -10705,6 +10705,11 @@
|
|||||||
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
|
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"ua-parser-js": {
|
||||||
|
"version": "0.7.22",
|
||||||
|
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.22.tgz",
|
||||||
|
"integrity": "sha512-YUxzMjJ5T71w6a8WWVcMGM6YWOTX27rCoIQgLXiWaxqXSx9D7DNjiGWn1aJIRSQ5qr0xuhra77bSIh6voR/46Q=="
|
||||||
|
},
|
||||||
"uglify-js": {
|
"uglify-js": {
|
||||||
"version": "3.4.10",
|
"version": "3.4.10",
|
||||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz",
|
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz",
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
"framework7-vue": "^5.7.14",
|
"framework7-vue": "^5.7.14",
|
||||||
"js-cookie": "^2.2.1",
|
"js-cookie": "^2.2.1",
|
||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
|
"ua-parser-js": "^0.7.22",
|
||||||
"vue": "^2.6.12",
|
"vue": "^2.6.12",
|
||||||
"vue-clipboard2": "^0.3.1",
|
"vue-clipboard2": "^0.3.1",
|
||||||
"vue-i18n": "^8.22.1",
|
"vue-i18n": "^8.22.1",
|
||||||
|
|||||||
@@ -107,6 +107,10 @@ body {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.list-item-media-valign-middle .item-media {
|
||||||
|
align-self: normal !important;
|
||||||
|
}
|
||||||
|
|
||||||
.lab-list-item-error-info div.item-footer {
|
.lab-list-item-error-info div.item-footer {
|
||||||
color: var(--f7-input-error-text-color)
|
color: var(--f7-input-error-text-color)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,10 +65,28 @@ const allAccountIcons = {
|
|||||||
f7Icon: 'bitcoin'
|
f7Icon: 'bitcoin'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const deviceIcons = {
|
||||||
|
mobile: {
|
||||||
|
f7Icon: 'device_phone_portrait'
|
||||||
|
},
|
||||||
|
tablet: {
|
||||||
|
f7Icon: 'device_tablet_portrait'
|
||||||
|
},
|
||||||
|
wearable: {
|
||||||
|
f7Icon: 'device_phone_portrait'
|
||||||
|
},
|
||||||
|
desktop: {
|
||||||
|
f7Icon: 'device_desktop'
|
||||||
|
},
|
||||||
|
tv: {
|
||||||
|
f7Icon: 'tv'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
allAccountIcons: allAccountIcons,
|
allAccountIcons: allAccountIcons,
|
||||||
defaultAccountIconId: defaultAccountIconId,
|
defaultAccountIconId: defaultAccountIconId,
|
||||||
defaultAccountIcon: allAccountIcons[defaultAccountIconId],
|
defaultAccountIcon: allAccountIcons[defaultAccountIconId],
|
||||||
totalAccountIconCount: totalAccountIconCount,
|
totalAccountIconCount: totalAccountIconCount,
|
||||||
|
deviceIcons: deviceIcons,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -152,6 +152,12 @@ const licenses = [
|
|||||||
copyright: 'Copyright (c) 2018 Copyright 2018 Klaus Hartl, Fagner Brack, GitHub Contributors',
|
copyright: 'Copyright (c) 2018 Copyright 2018 Klaus Hartl, Fagner Brack, GitHub Contributors',
|
||||||
url: 'https://github.com/js-cookie/js-cookie',
|
url: 'https://github.com/js-cookie/js-cookie',
|
||||||
licenseUrl: 'https://github.com/js-cookie/js-cookie/blob/master/LICENSE'
|
licenseUrl: 'https://github.com/js-cookie/js-cookie/blob/master/LICENSE'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'UAParser.js',
|
||||||
|
copyright: 'Copyright (c) 2012-2019 Faisal Salman <f@faisalman.com>',
|
||||||
|
url: 'https://github.com/faisalman/ua-parser-js',
|
||||||
|
licenseUrl: 'https://github.com/faisalman/ua-parser-js/blob/master/license.md'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import utils from "../lib/utils.js";
|
||||||
|
|
||||||
|
export default function (token) {
|
||||||
|
const ua = utils.parseUserAgent(token.userAgent);
|
||||||
|
let result = '';
|
||||||
|
|
||||||
|
if (ua.device.model) {
|
||||||
|
result = ua.device.model;
|
||||||
|
} else if (ua.os.name) {
|
||||||
|
result = ua.os.name;
|
||||||
|
|
||||||
|
if (ua.os.version) {
|
||||||
|
result += ' ' + ua.os.version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ua.browser.name) {
|
||||||
|
let browserInfo = ua.browser.name;
|
||||||
|
|
||||||
|
if (ua.browser.version) {
|
||||||
|
browserInfo += ' ' + ua.browser.version;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
result += ' (' + browserInfo + ')';
|
||||||
|
} else {
|
||||||
|
result = browserInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return 'Unknown Device';
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import icons from "../consts/icon.js";
|
||||||
|
import utils from "../lib/utils.js";
|
||||||
|
|
||||||
|
export default function (token) {
|
||||||
|
const ua = utils.parseUserAgent(token.userAgent);
|
||||||
|
|
||||||
|
if (!ua || !ua.device) {
|
||||||
|
return icons.deviceIcons.desktop.f7Icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ua.device.type === 'mobile') {
|
||||||
|
return icons.deviceIcons.mobile.f7Icon;
|
||||||
|
} else if (ua.device.type === 'wearable') {
|
||||||
|
return icons.deviceIcons.wearable.f7Icon;
|
||||||
|
} else if (ua.device.type === 'tablet') {
|
||||||
|
return icons.deviceIcons.tablet.f7Icon;
|
||||||
|
} else if (ua.device.type === 'smarttv') {
|
||||||
|
return icons.deviceIcons.tv.f7Icon;
|
||||||
|
} else {
|
||||||
|
return icons.deviceIcons.desktop.f7Icon;
|
||||||
|
}
|
||||||
|
}
|
||||||
+23
-1
@@ -1,4 +1,5 @@
|
|||||||
import accountConstants from '../consts/account.js'
|
import uaParser from 'ua-parser-js';
|
||||||
|
import accountConstants from '../consts/account.js';
|
||||||
|
|
||||||
function isFunction(val) {
|
function isFunction(val) {
|
||||||
return typeof(val) === 'function';
|
return typeof(val) === 'function';
|
||||||
@@ -28,6 +29,26 @@ function isBoolean(val) {
|
|||||||
return typeof(val) === 'boolean';
|
return typeof(val) === 'boolean';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parseUserAgent(ua) {
|
||||||
|
const uaParseRet = uaParser(ua);
|
||||||
|
|
||||||
|
return {
|
||||||
|
device: {
|
||||||
|
vendor: uaParseRet.device.vendor,
|
||||||
|
model: uaParseRet.device.model,
|
||||||
|
type: uaParseRet.device.type
|
||||||
|
},
|
||||||
|
os: {
|
||||||
|
name: uaParseRet.os.name,
|
||||||
|
version: uaParseRet.os.version
|
||||||
|
},
|
||||||
|
browser: {
|
||||||
|
name: uaParseRet.browser.name,
|
||||||
|
version: uaParseRet.browser.version
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function getCategorizedAccounts(allAccounts) {
|
function getCategorizedAccounts(allAccounts) {
|
||||||
const ret = {};
|
const ret = {};
|
||||||
|
|
||||||
@@ -104,6 +125,7 @@ export default {
|
|||||||
isString,
|
isString,
|
||||||
isNumber,
|
isNumber,
|
||||||
isBoolean,
|
isBoolean,
|
||||||
|
parseUserAgent,
|
||||||
getCategorizedAccounts,
|
getCategorizedAccounts,
|
||||||
getAccountByAccountId,
|
getAccountByAccountId,
|
||||||
getAllFilteredAccountsBalance,
|
getAllFilteredAccountsBalance,
|
||||||
|
|||||||
@@ -380,6 +380,7 @@ export default {
|
|||||||
'Unable to get session list': 'Unable to get session list',
|
'Unable to get session list': 'Unable to get session list',
|
||||||
'Current': 'Current',
|
'Current': 'Current',
|
||||||
'Other Device': 'Other Device',
|
'Other Device': 'Other Device',
|
||||||
|
'Unknown Device': 'Unknown Device',
|
||||||
'Are you sure you want to logout from this session?': 'Are you sure you want to logout from this session?',
|
'Are you sure you want to logout from this session?': 'Are you sure you want to logout from this session?',
|
||||||
'Unable to logout from this session': 'Unable to logout from this session',
|
'Unable to logout from this session': 'Unable to logout from this session',
|
||||||
'Are you sure you want to logout all other sessions?': 'Are you sure you want to logout all other sessions?',
|
'Are you sure you want to logout all other sessions?': 'Are you sure you want to logout all other sessions?',
|
||||||
|
|||||||
@@ -380,6 +380,7 @@ export default {
|
|||||||
'Unable to get session list': '无法获取会话列表',
|
'Unable to get session list': '无法获取会话列表',
|
||||||
'Current': '当前',
|
'Current': '当前',
|
||||||
'Other Device': '其他设备',
|
'Other Device': '其他设备',
|
||||||
|
'Unknown Device': '未知设备',
|
||||||
'Are you sure you want to logout from this session?': '您确定是否要退出该会话?',
|
'Are you sure you want to logout from this session?': '您确定是否要退出该会话?',
|
||||||
'Unable to logout from this session': '无法退出该会话',
|
'Unable to logout from this session': '无法退出该会话',
|
||||||
'Are you sure you want to logout all other sessions?': '您确定是否要退出其他所有会话?',
|
'Are you sure you want to logout all other sessions?': '您确定是否要退出其他所有会话?',
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ import userstate from './lib/userstate.js';
|
|||||||
import utils from './lib/utils.js';
|
import utils from './lib/utils.js';
|
||||||
import currencyFilter from './filters/currency.js';
|
import currencyFilter from './filters/currency.js';
|
||||||
import accountIconFilter from './filters/accountIcon.js';
|
import accountIconFilter from './filters/accountIcon.js';
|
||||||
|
import tokenDeviceFilter from './filters/tokenDevice.js';
|
||||||
|
import tokenIconFilter from './filters/tokenIcon.js';
|
||||||
import App from './Mobile.vue';
|
import App from './Mobile.vue';
|
||||||
|
|
||||||
Vue.use(VueI18n);
|
Vue.use(VueI18n);
|
||||||
@@ -151,6 +153,8 @@ Vue.prototype.$user = userstate;
|
|||||||
|
|
||||||
Vue.filter('currency', (value, currencyCode) => currencyFilter({ i18n }, value, currencyCode));
|
Vue.filter('currency', (value, currencyCode) => currencyFilter({ i18n }, value, currencyCode));
|
||||||
Vue.filter('accountIcon', (value) => accountIconFilter(value));
|
Vue.filter('accountIcon', (value) => accountIconFilter(value));
|
||||||
|
Vue.filter('tokenDevice', (value) => tokenDeviceFilter(value));
|
||||||
|
Vue.filter('tokenIcon', (value) => tokenIconFilter(value));
|
||||||
|
|
||||||
Vue.prototype.$setLanguage(settings.getLanguage() || getDefaultLanguage());
|
Vue.prototype.$setLanguage(settings.getLanguage() || getDefaultLanguage());
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,12 @@
|
|||||||
<f7-card class="skeleton-text" v-if="loading">
|
<f7-card class="skeleton-text" v-if="loading">
|
||||||
<f7-card-content :padding="false">
|
<f7-card-content :padding="false">
|
||||||
<f7-list media-list>
|
<f7-list media-list>
|
||||||
<f7-list-item title="Token Name" after="MM/DD/YYYY HH:mm:ss"
|
<f7-list-item class="list-item-media-valign-middle"
|
||||||
text="Mozilla/5.0 (OS Name & Version or Device Name; CPU Architecture ...) AppleWebKit/Version (KHTML, like Gecko) Software Name/Version Software Name/Version ..."></f7-list-item>
|
title="Current"
|
||||||
|
text="Device Name (Browser xx.x.xxxx.xx)">
|
||||||
|
<f7-icon slot="media" f7="device_phone_portrait"></f7-icon>
|
||||||
|
<small slot="after">MM/DD/YYYY HH:mm:ss</small>
|
||||||
|
</f7-list-item>
|
||||||
</f7-list>
|
</f7-list>
|
||||||
</f7-card-content>
|
</f7-card-content>
|
||||||
</f7-card>
|
</f7-card>
|
||||||
@@ -20,7 +24,14 @@
|
|||||||
<f7-card v-else-if="!loading">
|
<f7-card v-else-if="!loading">
|
||||||
<f7-card-content :padding="false">
|
<f7-card-content :padding="false">
|
||||||
<f7-list media-list>
|
<f7-list media-list>
|
||||||
<f7-list-item swipeout v-for="token in tokens" :key="token.tokenId" :id="token | tokenDomId" :title="token | tokenTitle | t" :after="token.createdAt | moment($t('format.datetime.long'))" :text="token.userAgent">
|
<f7-list-item class="list-item-media-valign-middle" swipeout
|
||||||
|
v-for="token in tokens"
|
||||||
|
:key="token.tokenId"
|
||||||
|
:id="token | tokenDomId"
|
||||||
|
:title="token | tokenTitle | t"
|
||||||
|
:text="token | tokenDevice | t">
|
||||||
|
<f7-icon slot="media" :f7="token | tokenIcon"></f7-icon>
|
||||||
|
<small slot="after">{{ token.createdAt | moment($t('format.datetime.long')) }}</small>
|
||||||
<f7-swipeout-actions right v-if="!token.isCurrent">
|
<f7-swipeout-actions right v-if="!token.isCurrent">
|
||||||
<f7-swipeout-button color="red" :text="$t('Log Out')" @click="revoke(token)"></f7-swipeout-button>
|
<f7-swipeout-button color="red" :text="$t('Log Out')" @click="revoke(token)"></f7-swipeout-button>
|
||||||
</f7-swipeout-actions>
|
</f7-swipeout-actions>
|
||||||
|
|||||||
Reference in New Issue
Block a user