feat(mesh): GET /api/mesh/self for local bootstrap self-IP discovery
A no-inbound spoke's join script (theta-suite's bootstrap/site-join.js) needs its own gateway's mesh IP to hand to sso-manager-node's /api/site/join, but the only existing read (GET /api/mesh/gateways) requires a full jump-admin session -- unusable from an unattended bootstrap script. Add a narrower read gated only by a valid jmp_ API token (any self-service token, same as theta-proxy's prx_ tokens for proxy_client.js), exposing just this gateway's own mesh IP.
This commit is contained in:
@@ -154,6 +154,24 @@ router.post('/join', middleware.auth, middleware.requireJumpAdmin, async (req, r
|
||||
} catch (e) { next(e); }
|
||||
});
|
||||
|
||||
// This gateway's own mesh address, for a LOCAL bootstrap script to discover
|
||||
// (e.g. theta-suite's site-join, running on the same host as this gateway)
|
||||
// without needing full jump-admin session auth -- any valid jmp_ API token
|
||||
// (middleware.auth, no requireJumpAdmin) is enough, same service-to-service
|
||||
// pattern as theta-proxy's prx_ tokens for proxy_client.js. Not a peer
|
||||
// listing, so no admin-only audit/config data is exposed here.
|
||||
router.get('/self', middleware.auth, async (req, res, next) => {
|
||||
try {
|
||||
const self = conf.wireguard || {};
|
||||
let meshIp = null;
|
||||
if (self.serverPublicKey) {
|
||||
const entry = await meshGateway.findByPublicKey(self.serverPublicKey);
|
||||
if (entry) meshIp = meshCidrFor(entry.meshIndex).split('/')[0];
|
||||
}
|
||||
res.json({ status: 'ok', meshIp, joined: !!meshIp, iface: IFACE });
|
||||
} catch (e) { next(e); }
|
||||
});
|
||||
|
||||
router.get('/gateways', middleware.auth, middleware.requireJumpAdmin, async (req, res, next) => {
|
||||
try {
|
||||
const gateways = await meshGateway.list();
|
||||
|
||||
Reference in New Issue
Block a user