summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--packages/meshbay-client/src/main.js25
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/index-dock.js10
2 files changed, 24 insertions, 11 deletions
diff --git a/packages/meshbay-client/src/main.js b/packages/meshbay-client/src/main.js
index a2a7a86..f582b57 100644
--- a/packages/meshbay-client/src/main.js
+++ b/packages/meshbay-client/src/main.js
@@ -1269,11 +1269,11 @@ function registerBridge() {
//
// The renderer never sees the session token. It names an operation and this
// process executes it — the same pattern as hub:fetch. The token is read
- // from the daemon's data directory, cached for the lifetime of this process,
- // and never exposed through the preload.
+ // from the daemon's data directory on every call and never exposed through
+ // the preload. Not cached: the daemon writes a new one each run and deletes
+ // it on stop, so a cached copy answered 401 after every node restart, and an
+ // operation asked before any page had called detect() had none at all.
- let _nodeToken = null;
- let _nodePort = 18000;
let _nodePairingCode = null;
function nodeConfigPath() {
@@ -1305,16 +1305,20 @@ function registerBridge() {
}
}
+ function nodeEndpoint() {
+ const nc = readNodeConfig();
+ const token = readNodeToken(nc ? nc.dataDir : meshbayDataDir());
+ return token ? { token, port: nc ? nc.uiPort : 18000 } : null;
+ }
+
handle('node:detect', async () => {
const nc = readNodeConfig();
if (!nc) return { detected: false, configured: false };
const token = readNodeToken(nc.dataDir);
if (!token) return { detected: false, configured: true };
- _nodeToken = token;
- _nodePort = nc.uiPort;
try {
const r = await fetch(
- `http://127.0.0.1:${_nodePort}/api/status?t=${_nodeToken}`,
+ `http://127.0.0.1:${nc.uiPort}/api/status?t=${token}`,
{ signal: AbortSignal.timeout(3000) });
if (!r.ok) return { detected: false, configured: true };
const status = await r.json();
@@ -1889,8 +1893,6 @@ function registerBridge() {
const READY = ['running', 'waiting_for_node_key', 'waiting_for_account',
'waiting_for_hub', 'starting'];
if (!READY.includes(status.status)) return null;
- _nodeToken = token;
- _nodePort = port;
return { pk_node_ed25519: status.pk_node_ed25519 || '', status: status.status,
version: status.version || '' };
} catch { return null; }
@@ -2235,10 +2237,11 @@ function registerBridge() {
handle('node:op', async (_e, name, args) => {
const op = Object.hasOwn(NODE_OPS, String(name)) ? NODE_OPS[String(name)] : null;
if (!op) throw new Error(`Refused: unknown node operation ${String(name)}`);
- if (!_nodeToken) throw new Error('Node not detected');
+ const endpoint = nodeEndpoint();
+ if (!endpoint) throw new Error('Node not detected');
const [method, apiPath, body] = await op(anObject(args));
const sep = apiPath.includes('?') ? '&' : '?';
- const url = `http://127.0.0.1:${_nodePort}${apiPath}${sep}t=${_nodeToken}`;
+ const url = `http://127.0.0.1:${endpoint.port}${apiPath}${sep}t=${endpoint.token}`;
const init = { method };
if (body !== undefined && body !== null) {
init.headers = { 'Content-Type': 'application/json' };
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/index-dock.js b/packages/meshbay-hub/src/meshbay_hub/static/index-dock.js
index 6730e60..6c89eb6 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/index-dock.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/index-dock.js
@@ -51,9 +51,18 @@ function useLoopbackActivity() {
let stopped = false;
let timer = null;
let last = '';
+ // Asked before the first operation and again after any failure: detect()
+ // answers "no node" as a value, where an operation on an absent node is a
+ // rejected IPC call that Electron prints to its terminal on every poll.
+ let present = false;
const poll = async () => {
let delay = IDLE_POLL_MS;
try {
+ if (!present) {
+ const found = await platform.node.detect();
+ if (!found || !found.detected) throw new Error('no node');
+ present = true;
+ }
const data = await platform.node.op('indexStatus');
const next = {};
for (const g of (data && data.groups) || []) next[g.group_id] = fromLoopback(g);
@@ -64,6 +73,7 @@ function useLoopbackActivity() {
if (!stopped && text !== last) { last = text; setLocal(next); }
} catch {
// No node on this machine, or one older than the route.
+ present = false;
if (!stopped && last !== '{}') { last = '{}'; setLocal({}); }
delay = ABSENT_POLL_MS;
}