feat: display when an api key was last used, in ACP, #10873

isekai-main
Julian Lam 2 years ago
parent 2614b95c40
commit 402229845c

@ -11,6 +11,9 @@
"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",
"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.",
"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'));
$('#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 }) => {
element.addEventListener('click', (ev) => {
if (ev.target.closest('input[readonly]')) {

@ -9,3 +9,5 @@ const utils = module.exports;
utils.log = async (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 navigationAdmin = require('../../navigation/admin');
const social = require('../../social');
const api = require('../../api');
const helpers = require('../helpers');
const translator = require('../../translator');
@ -108,3 +109,16 @@ settingsController.social = async function (req, res) {
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/homepage`, middlewares, controllers.admin.settings.homepage);
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}/appearance/:term?`, middlewares, controllers.admin.appearance.get);

@ -10,7 +10,7 @@
<em>[[admin/settings/api:no-description]]</em>
{{{ end }}}
<br />
<small>{timestampISO}</small>
<small class="text-info">{./lastSeen}</small>
</p>
</div>
<div class="col-3 text-end">

Loading…
Cancel
Save