Add super/jump admin, per-host connection tracking; move stats to Audit
- app_super_admin (cross-app, also recognized by sso-manager-node/proxy) and a new app_jump_admin group are added to conf.auth: super admins are full admins here same as app_sso_admin; jump admins get audit page/data access without other admin rights (isJumpAdmin/requireJumpAdmin in middleware/auth.js, wired into routes/api.js's audit-data gate and the /audit page's client-side forceLogin -- previously the page shell rendered for any logged-in user, only the data was gated). - Dashboard: moved the stat boxes and Top hosts/Top users cards to the Audit page (audit is now the admin-facing metrics home; dashboard stays focused on "hosts I can reach"). Renamed "All hosts" to "My hosts". - Host list now shows Last connection/Last failed connection columns and highlights rows green (live session, from session_registry) or yellow (most recent attempt failed) -- backed by new per-host last-success/ last-fail timestamps in models/metrics.js, populated by ssh_server.js (which now attributes grammar/TUI connect failures to the resolved host when one was found, not just aggregate counters) and surfaced through GET /api/user/hosts (routes/user.js).
This commit is contained in:
@@ -13,10 +13,34 @@ async function bump({ uid, hostSlug, success }) {
|
||||
const ops = [redis.incr(`${P()}total`), redis.incr(`${P()}day_${day}`)];
|
||||
if (!success) ops.push(redis.incr(`${P()}fail`));
|
||||
if (uid) ops.push(redis.incr(`${P()}user_${uid}`));
|
||||
if (hostSlug) ops.push(redis.incr(`${P()}host_${hostSlug}`));
|
||||
if (hostSlug) {
|
||||
ops.push(redis.incr(`${P()}host_${hostSlug}`));
|
||||
// Last-attempt timestamp per host, split by outcome -- drives the
|
||||
// dashboard's "Last connection"/"Last failed connection" columns and
|
||||
// row highlighting (see lastForHosts below).
|
||||
ops.push(redis.set(`${P()}host_last_${success ? 'success' : 'fail'}_${hostSlug}`, Date.now()));
|
||||
}
|
||||
await Promise.all(ops);
|
||||
}
|
||||
|
||||
// Per-host last-success/last-fail timestamps for a given list of slugs (e.g.
|
||||
// the hosts a session can reach), for the dashboard's host list.
|
||||
async function lastForHosts(slugs) {
|
||||
const redis = await getRedis();
|
||||
const result = {};
|
||||
await Promise.all((slugs || []).map(async (slug) => {
|
||||
const [lastSuccess, lastFail] = await Promise.all([
|
||||
redis.get(`${P()}host_last_success_${slug}`),
|
||||
redis.get(`${P()}host_last_fail_${slug}`),
|
||||
]);
|
||||
result[slug] = {
|
||||
lastConnected: lastSuccess ? Number(lastSuccess) : null,
|
||||
lastFailed: lastFail ? Number(lastFail) : null,
|
||||
};
|
||||
}));
|
||||
return result;
|
||||
}
|
||||
|
||||
async function summary() {
|
||||
const redis = await getRedis();
|
||||
const [total, fail] = await Promise.all([
|
||||
@@ -37,4 +61,4 @@ async function summary() {
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = { bump, summary };
|
||||
module.exports = { bump, summary, lastForHosts };
|
||||
|
||||
Reference in New Issue
Block a user