aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-client
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-client')
-rw-r--r--packages/meshbay-client/src/main.js52
1 files changed, 51 insertions, 1 deletions
diff --git a/packages/meshbay-client/src/main.js b/packages/meshbay-client/src/main.js
index 74c8203..de8de8f 100644
--- a/packages/meshbay-client/src/main.js
+++ b/packages/meshbay-client/src/main.js
@@ -1091,6 +1091,43 @@ function registerBridge() {
return null;
}
+ // The daemon is reachable but sitting at 'waiting_for_node_key' /
+ // 'waiting_for_account': its Ed25519 key is not linked to the hub account it
+ // runs as (a fresh node, or that account still carries a previous machine's
+ // node key). Link it with the signed-in user's token, then wait out the
+ // daemon's own 5s hub-auth retry until it reports 'running'. `PUT
+ // /me/node_key` overwrites unconditionally, so this also recovers an account
+ // whose linked key belongs to a node that is gone.
+ //
+ // The Linux branch of `node:start` does the same thing inline; Windows went
+ // without it, so the daemon never left 'waiting_for_account' and the Create
+ // Group wizard spun on "Detecting local node…" for ever.
+ async function linkNodeKeyAndAwaitRunning(opts, deadline) {
+ let linked = false;
+ let last = null;
+ while (Date.now() < deadline) {
+ last = await probeNode();
+ if (last && last.status === 'running') return last;
+ if (last && !linked && opts && opts.token && opts.hubUrl
+ && last.pk_node_ed25519
+ && (last.status === 'waiting_for_node_key'
+ || last.status === 'waiting_for_account')) {
+ try {
+ const r = await fetch(`${opts.hubUrl}/v1/users/me/node_key`, {
+ method: 'PUT',
+ headers: { 'Content-Type': 'application/json',
+ 'Authorization': `Bearer ${opts.token}` },
+ body: JSON.stringify({ pk_node_ed25519: last.pk_node_ed25519 }),
+ signal: AbortSignal.timeout(5000),
+ });
+ if (r.ok) linked = true;
+ } catch { /* transient — retried on the next tick */ }
+ }
+ await new Promise((r) => setTimeout(r, 500));
+ }
+ return last;
+ }
+
ipcMain.handle('node:installed', async () => {
if (process.platform === 'win32') {
const [bin, svc] = await Promise.all([findNodeBinary(), winServiceTaskStatus()]);
@@ -1350,7 +1387,20 @@ function registerBridge() {
const p = await waitForNode(Date.now() + 60000);
if (!p) throw new Error('the node did not start within 60s — run it from a '
+ 'terminal (`meshbay-node`) to see why');
- return { started: true, ...p };
+ // Up, but almost never 'running' on a first launch: link the node key to
+ // the hub account and wait for the daemon to authenticate. Without this
+ // it stays at 'waiting_for_account' and nothing here ever tells the hub
+ // about the node.
+ const ready = p.status === 'running'
+ ? p
+ : await linkNodeKeyAndAwaitRunning(opts, Date.now() + 45000);
+ if (!ready || ready.status !== 'running') {
+ throw new Error(
+ 'the node started but could not link to your hub account. Open the '
+ + 'Node page and use "Link this node", or check you are signed in to '
+ + 'the hub this node is configured for.');
+ }
+ return { started: true, ...ready };
}
if (process.platform !== 'linux') {