diff --git a/public/language/en-GB/admin/settings/api.json b/public/language/en-GB/admin/settings/api.json index 50892925f3..746b99068b 100644 --- a/public/language/en-GB/admin/settings/api.json +++ b/public/language/en-GB/admin/settings/api.json @@ -11,6 +11,9 @@ "uid": "User ID", "uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0, it will be considered a master token, which can assume the identity of other users based on the _uid parameter", "description": "Description", + "last-seen-ago": "Last used .", + "last-seen-on": "Last used on .", + "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" } \ No newline at end of file diff --git a/public/src/admin/settings/api.js b/public/src/admin/settings/api.js index 52734bdaef..ba3667e40e 100644 --- a/public/src/admin/settings/api.js +++ b/public/src/admin/settings/api.js @@ -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]')) { diff --git a/src/api/utils.js b/src/api/utils.js index ca10069703..63d5473e12 100644 --- a/src/api/utils.js +++ b/src/api/utils.js @@ -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); diff --git a/src/controllers/admin/settings.js b/src/controllers/admin/settings.js index ca0765cc02..3255680a1e 100644 --- a/src/controllers/admin/settings.js +++ b/src/controllers/admin/settings.js @@ -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 }); +}; diff --git a/src/routes/admin.js b/src/routes/admin.js index aac0e5dfb0..c7e9c5f060 100644 --- a/src/routes/admin.js +++ b/src/routes/admin.js @@ -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); diff --git a/src/views/admin/partials/api/sorted-list/item.tpl b/src/views/admin/partials/api/sorted-list/item.tpl index 41cbaa3a82..c34836e758 100644 --- a/src/views/admin/partials/api/sorted-list/item.tpl +++ b/src/views/admin/partials/api/sorted-list/item.tpl @@ -10,7 +10,7 @@ [[admin/settings/api:no-description]] {{{ end }}}
- {timestampISO} + {./lastSeen}