4326d5588e
jump-host had zero API-token support: no model, no route, no UI, and Auth.checkApiToken was explicitly absent from the createOidcClient() call (per the comment it left behind). proxy and sso-manager-node both have this; jump-host didn't. Ports proxy's models/api_token.js + routes/api_token.js pattern (jmp_ prefix instead of prx_), wires checkApiToken into createOidcClient(), adds Bearer-token support to middleware/auth.js, and adds a token management card to dashboard.ejs (create/list/rotate/revoke) using app.modal/ app.messages. Scope note: a jump-host token carries no group claims (unlike proxy's, which snapshots the creator's groups), so it authenticates as its creator for non-admin routes (e.g. GET /api/user/hosts) but can never pass requireAdmin — a deliberate, conservative default rather than recomputing live admin status per-request. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
32 lines
1.4 KiB
JavaScript
32 lines
1.4 KiB
JavaScript
'use strict';
|
|
|
|
// Jump-host page controllers. app.api / app.auth come from app-base.js (the
|
|
// shared client framework); this adds the jump-host data calls and the small
|
|
// render helpers each page uses.
|
|
|
|
app.jump = (function(app){
|
|
function metrics(cb){ app.api.get('metrics', cb); }
|
|
function sessions(cb){ app.api.get('sessions', cb); }
|
|
function audit(query, cb){
|
|
var qs = $.param(query || {});
|
|
app.api.get('audit' + (qs ? '?' + qs : ''), cb);
|
|
}
|
|
function hosts(cb){ app.api.get('user/hosts', cb); }
|
|
return {metrics: metrics, sessions: sessions, audit: audit, hosts: hosts};
|
|
})(app);
|
|
|
|
// Self-service API token (PAT) management.
|
|
app.apiToken = (function(app){
|
|
function list(cb){ app.api.get('api-token/', cb); }
|
|
function add(args, cb){ app.api.post('api-token/', args, cb); }
|
|
function remove(id, cb){ app.api.delete('api-token/' + id, cb); }
|
|
function rotate(id, cb){ app.api.post('api-token/' + id + '/rotate', {}, cb); }
|
|
return {list: list, add: add, remove: remove, rotate: rotate};
|
|
})(app);
|
|
|
|
// Shared render helpers.
|
|
app.jump.fmtTime = function(ts){ return ts ? moment(Number(ts)).format('YYYY-MM-DD HH:mm:ss') : '—'; };
|
|
app.jump.esc = function(s){ return $('<div>').text(s == null ? '' : String(s)).html(); };
|
|
app.jump.result = function(e){ return e.success ? '<span class="badge bg-success">ok</span>'
|
|
: '<span class="badge bg-danger">' + app.jump.esc(e.failReason || 'fail') + '</span>'; };
|