2026-05-18 18:27:41 +00:00
|
|
|
function parsePeers(peerMap) {
|
|
|
|
|
if (!peerMap) return []
|
|
|
|
|
return Object.keys(peerMap).map(function (key) {
|
|
|
|
|
var p = peerMap[key]
|
|
|
|
|
return {
|
|
|
|
|
hostname: p.HostName || key,
|
|
|
|
|
ip: (p.TailscaleIPs && p.TailscaleIPs.length) ? p.TailscaleIPs[0] : "",
|
|
|
|
|
online: p.Online || false,
|
|
|
|
|
exitNode: p.ExitNodeOption || false
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function makeExitNodeCommand(hostname) {
|
|
|
|
|
return ["tailscale", "set", "--exit-node=" + hostname]
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-18 22:10:37 +00:00
|
|
|
function findActiveExitNode(peerMap) {
|
|
|
|
|
if (!peerMap) return ""
|
|
|
|
|
for (const key in peerMap) {
|
|
|
|
|
const p = peerMap[key]
|
|
|
|
|
if (p.ExitNode) {
|
|
|
|
|
return p.HostName || key
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-18 20:53:32 +00:00
|
|
|
function errorMessage(cmd) {
|
|
|
|
|
var messages = {
|
|
|
|
|
"up": "Failed to connect to Tailscale",
|
|
|
|
|
"connect": "Failed to connect to Tailscale",
|
|
|
|
|
"down": "Failed to disconnect from Tailscale",
|
|
|
|
|
"disconnect": "Failed to disconnect from Tailscale",
|
|
|
|
|
"set": "Failed to set exit node",
|
|
|
|
|
"status": "Failed to read Tailscale status"
|
|
|
|
|
}
|
|
|
|
|
return messages[cmd] || "Tailscale command failed"
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-18 18:39:39 +00:00
|
|
|
// CommonJS export for Node.js tests (ignored by QML)
|
|
|
|
|
if (typeof module !== "undefined" && module.exports) {
|
2026-05-18 22:10:37 +00:00
|
|
|
module.exports = { parsePeers, makeExitNodeCommand, findActiveExitNode, errorMessage }
|
2026-05-18 18:39:39 +00:00
|
|
|
}
|