mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-27 17:16:14 +01:00
feat: display when an api key was last used, in ACP, #10873
This commit is contained in:
@@ -11,6 +11,9 @@
|
|||||||
"uid": "User ID",
|
"uid": "User ID",
|
||||||
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is <code>0</code>, it will be considered a <em>master</em> token, which can assume the identity of other users based on the <code>_uid</code> parameter",
|
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is <code>0</code>, it will be considered a <em>master</em> token, which can assume the identity of other users based on the <code>_uid</code> parameter",
|
||||||
"description": "Description",
|
"description": "Description",
|
||||||
|
"last-seen-ago": "Last used <span class=\"timeago\" title=\"%1\"></span>.",
|
||||||
|
"last-seen-on": "Last used on <span class=\"timeago\" title=\"%1\"></span>.",
|
||||||
|
"last-seen-never": "This key has never been used.",
|
||||||
"no-description": "No description specified.",
|
"no-description": "No description specified.",
|
||||||
"token-on-save": "Token will be generated once form is saved"
|
"token-on-save": "Token will be generated once form is saved"
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,26 @@ define('admin/settings/api', ['settings', 'alerts', 'hooks'], function (settings
|
|||||||
settings.load('core.api', $('.core-api-settings'));
|
settings.load('core.api', $('.core-api-settings'));
|
||||||
$('#save').on('click', saveSettings);
|
$('#save').on('click', saveSettings);
|
||||||
|
|
||||||
|
hooks.on('filter:settings.sorted-list.loadItem', ({ item }) => {
|
||||||
|
if (!ajaxify.data.lastSeen[item.token]) {
|
||||||
|
item.lastSeen = '[[admin/settings/api:last-seen-never]]';
|
||||||
|
return { item };
|
||||||
|
}
|
||||||
|
|
||||||
|
const cutoffMs = 1000 * 60 * 60 * 24 * Math.max(0, parseInt(config.timeagoCutoff, 10));
|
||||||
|
let translationSuffix = 'ago';
|
||||||
|
if (cutoffMs > 0 && Date.now() - ajaxify.data.lastSeen[item.token] > cutoffMs) {
|
||||||
|
translationSuffix = 'on';
|
||||||
|
}
|
||||||
|
item.lastSeen = `[[admin/settings/api:last-seen-${translationSuffix}, ${ajaxify.data.lastSeenISO[item.token]}]]`;
|
||||||
|
|
||||||
|
return { item };
|
||||||
|
});
|
||||||
|
|
||||||
|
hooks.on('action:settings.sorted-list.loaded', ({ listEl }) => {
|
||||||
|
$(listEl).find('.timeago').timeago();
|
||||||
|
});
|
||||||
|
|
||||||
hooks.on('action:settings.sorted-list.itemLoaded', ({ element }) => {
|
hooks.on('action:settings.sorted-list.itemLoaded', ({ element }) => {
|
||||||
element.addEventListener('click', (ev) => {
|
element.addEventListener('click', (ev) => {
|
||||||
if (ev.target.closest('input[readonly]')) {
|
if (ev.target.closest('input[readonly]')) {
|
||||||
|
|||||||
@@ -9,3 +9,5 @@ const utils = module.exports;
|
|||||||
utils.log = async (token) => {
|
utils.log = async (token) => {
|
||||||
await db.sortedSetAdd('tokens:lastSeen', Date.now(), token);
|
await db.sortedSetAdd('tokens:lastSeen', Date.now(), token);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
utils.getLastSeen = async tokens => await db.sortedSetScores('tokens:lastSeen', tokens);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ const groups = require('../../groups');
|
|||||||
const languages = require('../../languages');
|
const languages = require('../../languages');
|
||||||
const navigationAdmin = require('../../navigation/admin');
|
const navigationAdmin = require('../../navigation/admin');
|
||||||
const social = require('../../social');
|
const social = require('../../social');
|
||||||
|
const api = require('../../api');
|
||||||
|
|
||||||
const helpers = require('../helpers');
|
const helpers = require('../helpers');
|
||||||
const translator = require('../../translator');
|
const translator = require('../../translator');
|
||||||
@@ -108,3 +109,16 @@ settingsController.social = async function (req, res) {
|
|||||||
posts: posts,
|
posts: posts,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
settingsController.api = async (req, res) => {
|
||||||
|
const { tokens } = await meta.settings.get('core.api');
|
||||||
|
const scores = await api.utils.getLastSeen(tokens.map(t => t.token));
|
||||||
|
|
||||||
|
const [lastSeen, lastSeenISO] = tokens.reduce((memo, cur, idx) => {
|
||||||
|
memo[0][cur.token] = scores[idx];
|
||||||
|
memo[1][cur.token] = new Date(scores[idx]).toISOString();
|
||||||
|
return memo;
|
||||||
|
}, [{}, {}]);
|
||||||
|
|
||||||
|
res.render('admin/settings/api', { lastSeen, lastSeenISO });
|
||||||
|
};
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ module.exports = function (app, name, middleware, controllers) {
|
|||||||
helpers.setupAdminPageRoute(app, `/${name}/settings/navigation`, middlewares, controllers.admin.settings.navigation);
|
helpers.setupAdminPageRoute(app, `/${name}/settings/navigation`, middlewares, controllers.admin.settings.navigation);
|
||||||
helpers.setupAdminPageRoute(app, `/${name}/settings/homepage`, middlewares, controllers.admin.settings.homepage);
|
helpers.setupAdminPageRoute(app, `/${name}/settings/homepage`, middlewares, controllers.admin.settings.homepage);
|
||||||
helpers.setupAdminPageRoute(app, `/${name}/settings/social`, middlewares, controllers.admin.settings.social);
|
helpers.setupAdminPageRoute(app, `/${name}/settings/social`, middlewares, controllers.admin.settings.social);
|
||||||
|
helpers.setupAdminPageRoute(app, `/${name}/settings/api`, middlewares, controllers.admin.settings.api);
|
||||||
helpers.setupAdminPageRoute(app, `/${name}/settings/:term?`, middlewares, controllers.admin.settings.get);
|
helpers.setupAdminPageRoute(app, `/${name}/settings/:term?`, middlewares, controllers.admin.settings.get);
|
||||||
|
|
||||||
helpers.setupAdminPageRoute(app, `/${name}/appearance/:term?`, middlewares, controllers.admin.appearance.get);
|
helpers.setupAdminPageRoute(app, `/${name}/appearance/:term?`, middlewares, controllers.admin.appearance.get);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<em>[[admin/settings/api:no-description]]</em>
|
<em>[[admin/settings/api:no-description]]</em>
|
||||||
{{{ end }}}
|
{{{ end }}}
|
||||||
<br />
|
<br />
|
||||||
<small>{timestampISO}</small>
|
<small class="text-info">{./lastSeen}</small>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-3 text-end">
|
<div class="col-3 text-end">
|
||||||
|
|||||||
Reference in New Issue
Block a user