Files
peardock/server/handlers/peers.js
T
snxraven 0ee9b67834
CI / test (push) Successful in 9m54s
Complete production roadmap: vault, peers, swarm, streams, ops
Ship remaining roadmap items: encrypted registry vault, peer invite/revoke,
Swarm/plugins behind flags, binary streams, engine create validation, deploy
rollback, schema validation, fleet/access UI, metrics, fuzz/load/soak tests,
systemd packaging, and release tooling. Mark ROADMAP fully complete.
2026-07-10 20:50:55 -04:00

91 lines
2.7 KiB
JavaScript

/**
* Peer invite / revoke / list ACL management (admin).
*/
import * as peerPolicy from '../core/peer-policy.js'
import { peers } from '../core/peer-registry.js'
import { Roles } from '../../shared/protocol.js'
import * as validation from '../utils/validation.js'
export function registerPeerHandlers(session) {
session.respond('listPeers', async () => {
const policy = peerPolicy.listPeers()
const live = []
for (const s of peers) {
live.push({
peerId: s.id,
role: s.role,
connected: !s.closed,
clientInfo: s.clientInfo || null,
})
}
return {
success: true,
type: 'peers',
...policy,
live,
}
})
session.respond('listInvites', async () => {
return {
success: true,
type: 'invites',
data: peerPolicy.listInvites(),
}
})
session.respond('invitePeer', async (args) => {
// Either create redeemable token OR register known peer key
if (args.peerId) {
const peerId = validation.sanitizeString(args.peerId, 64).toLowerCase()
if (!/^[0-9a-f]{64}$/.test(peerId)) throw new Error('peerId must be 64 hex characters')
const role = args.role || Roles.operator
const entry = peerPolicy.registerPeer(peerId, {
role,
alias: args.alias || null,
note: args.note || null,
})
return { success: true, type: 'peerRegistered', data: entry }
}
const invite = peerPolicy.createInvite({
role: args.role || Roles.operator,
ttlHours: args.ttlHours,
maxUses: args.maxUses,
note: args.note,
})
return { success: true, type: 'invite', data: invite }
})
session.respond('revokePeer', async (args) => {
const peerId = validation.sanitizeString(args.peerId || args.id, 64).toLowerCase()
if (!peerId) throw new Error('peerId required')
const result = peerPolicy.revokePeer(peerId)
// Drop live session if connected
const live = peers.get(peerId)
if (live) {
try {
live.destroy()
} catch {
// ignore
}
}
return { success: true, ...result }
})
session.respond('unrevokePeer', async (args) => {
const peerId = validation.sanitizeString(args.peerId || args.id, 64).toLowerCase()
if (!peerId) throw new Error('peerId required')
return { success: true, ...peerPolicy.unrevokePeer(peerId) }
})
session.respond('setPeerRole', async (args) => {
const peerId = validation.sanitizeString(args.peerId || args.id, 64).toLowerCase()
const role = args.role
if (!peerId || !role) throw new Error('peerId and role required')
const entry = peerPolicy.setPeerRole(peerId, role)
const live = peers.get(peerId)
if (live) live.role = role
return { success: true, data: entry }
})
}