diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-09-30 16:58:31 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-09-30 16:58:31 +0200 |
| commit | 6d167392f6f8ede37e2794a68a3738f8ba03131d (patch) | |
| tree | 9caacef15dd034c6425f4bb623e0cd50a28ec52a /packages/meshbay-hub/src/meshbay_hub/static/hub-client.js | |
| parent | 8926f163dad9d32dc06c3a142658a4e11d9c12c1 (diff) | |
| download | meshbay-6d167392f6f8ede37e2794a68a3738f8ba03131d.tar.gz | |
feat(client): the desktop application keeps M and every node identity in its main process
keyring.js derives, opens, mints, seals, signs and agrees there; the page gets
public keys and a handle. Argon2 comes from the page's own WebAssembly build
(Electron's crypto has none). Without OS key storage the page keeps its keys as
a browser does. A node's bundle is settled after connecting, re-sealed when the
key changed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/hub-client.js')
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/static/hub-client.js | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/hub-client.js b/packages/meshbay-hub/src/meshbay_hub/static/hub-client.js index 3081ad8..18db1ba 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/hub-client.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/hub-client.js @@ -158,10 +158,19 @@ async function _loadKey(slot) { // in a *later* session still get a recovery-wrapped identity copy, instead of // only groups joined in the unbroken session that generated it. Cleared with // everything else on sign-out. -const _storeBundleKey = (key) => _storeKey('bk', key); +// In the desktop application the key is not here at all: its main process +// keeps it (platform.keys), and this page holds a handle. Nothing is written to +// this database for it, and a handle is only returned while the application +// really holds a key for the signed-in account. +const _storeBundleKey = (key) => (key && key.native ? Promise.resolve() : _storeKey('bk', key)); // A key stored before the pepper (`{v2, v1, …}`) opens nothing any more: it is // no key at all, and the group page asks for the passphrase again. const _loadBundleKey = async () => { + if (await platform.nativeKeys()) { + const auth = loadAuth(); + return auth && await platform.keys.hasSession(auth.userId) + ? { native: true, userId: auth.userId, pepperVersion: 1 } : null; + } const k = await _loadKey('bk'); return k && k.v3 ? k : null; }; @@ -201,10 +210,19 @@ function saveAuth(auth) { if (auth) { localStorage.setItem(AUTH_KEY, JSON.stringify(auth)); } else { + // The account signing out, read before its record goes: the application + // drops that account's bundle key (the node identities stay — they are + // this device's, and dropping them would strand it on every node). + const leaving = loadAuth(); localStorage.removeItem(AUTH_KEY); session.bundleKey = null; session.recoveryKey = null; _clearKeyDB(); + if (leaving && platform.keys) { + platform.nativeKeys() + .then((native) => native && platform.keys.forgetSession(leaving.userId)) + .catch(() => { /* nothing held */ }); + } } } |