openclaw-navigator 5.7.3 → 5.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/cli.mjs +29 -7
  2. package/package.json +1 -1
package/cli.mjs CHANGED
@@ -1703,6 +1703,23 @@ async function registerWithRelay(code, url, token, name) {
1703
1703
  });
1704
1704
  clearTimeout(timeout);
1705
1705
  const data = await res.json();
1706
+
1707
+ // Also register with token as the lookup key — so Navigator can
1708
+ // resolve by saved token even after the pairing code rotates.
1709
+ // Uses first 8 chars of token as a "token code" (avoids relay key limits).
1710
+ const tokenCode = `T${token.substring(0, 7)}`;
1711
+ try {
1712
+ const c2 = new AbortController();
1713
+ const t2 = setTimeout(() => c2.abort(), 5000);
1714
+ await fetch(`${RELAY_URL}/register`, {
1715
+ method: "POST",
1716
+ headers: { "Content-Type": "application/json" },
1717
+ body: JSON.stringify({ code: tokenCode, url, token, name }),
1718
+ signal: c2.signal,
1719
+ });
1720
+ clearTimeout(t2);
1721
+ } catch { /* non-critical */ }
1722
+
1706
1723
  return data.ok === true;
1707
1724
  } catch {
1708
1725
  return false;
@@ -1927,25 +1944,30 @@ module.exports = {
1927
1944
  await killPort(ocUIPort);
1928
1945
  startWebUI();
1929
1946
 
1930
- // ── Step 2: Persistent identity ─────────────────────────────────────
1931
- // Reuse the same pairing code + token across restarts so Navigator
1932
- // doesn't need to re-pair. The code resolves to the NEW tunnel URL
1933
- // via the relay, so everything reconnects automatically.
1947
+ // ── Step 2: Identity persistent token, rotating code ──────────────
1948
+ // Token is persistent: Navigator stores it after first pairing and uses
1949
+ // it for all future requests. This is the real auth credential.
1950
+ // Pairing code rotates every startup: it's a one-time handshake to
1951
+ // exchange the token. A new code every time means nobody can reuse
1952
+ // an old code to hijack the connection.
1934
1953
  const displayName = hostname().replace(/\.local$/, "");
1935
1954
  let token;
1936
1955
 
1937
1956
  const savedIdentity = freshIdentity ? null : loadBridgeIdentity();
1938
1957
  if (savedIdentity) {
1939
- pairingCode = savedIdentity.pairingCode;
1958
+ // Keep the token (Navigator already has it) but rotate the code
1940
1959
  token = savedIdentity.token;
1941
1960
  validTokens.add(token);
1942
- ok(`Restored pairing code: ${BOLD}${GREEN}${pairingCode}${RESET} (same as last session)`);
1961
+ pairingCode = generatePairingCode(); // fresh code every startup
1962
+ saveBridgeIdentity(pairingCode, token, displayName);
1963
+ ok(`Token restored (Navigator will auto-reconnect)`);
1964
+ ok(`New pairing code: ${BOLD}${GREEN}${pairingCode}${RESET} (rotated for security)`);
1943
1965
  } else {
1944
1966
  token = randomUUID().replace(/-/g, "");
1945
1967
  validTokens.add(token);
1946
1968
  pairingCode = generatePairingCode();
1947
1969
  saveBridgeIdentity(pairingCode, token, displayName);
1948
- ok(`New pairing code generated: ${BOLD}${GREEN}${pairingCode}${RESET}`);
1970
+ ok(`New pairing code: ${BOLD}${GREEN}${pairingCode}${RESET}`);
1949
1971
  }
1950
1972
 
1951
1973
  let gatewayURL = `http://localhost:${port}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclaw-navigator",
3
- "version": "5.7.3",
3
+ "version": "5.7.4",
4
4
  "description": "One-command bridge + tunnel for the Navigator browser — works on any machine, any OS",
5
5
  "keywords": [
6
6
  "browser",