aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/static/transport-devices.js
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-30 16:58:31 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-30 16:58:31 +0200
commit6d167392f6f8ede37e2794a68a3738f8ba03131d (patch)
tree9caacef15dd034c6425f4bb623e0cd50a28ec52a /packages/meshbay-hub/src/meshbay_hub/static/transport-devices.js
parent8926f163dad9d32dc06c3a142658a4e11d9c12c1 (diff)
downloadmeshbay-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/transport-devices.js')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/transport-devices.js51
1 files changed, 44 insertions, 7 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/transport-devices.js b/packages/meshbay-hub/src/meshbay_hub/static/transport-devices.js
index f17b1b6..1cb248a 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/transport-devices.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/transport-devices.js
@@ -259,13 +259,11 @@ extendTransport(class {
/**
* Withdraw our key backup from this node.
*
- * The counterpart of storeKeypairBundle: turning the setting off has to remove
- * what is already stored, not merely stop adding to it — otherwise the blob
- * stays on every node the account has ever joined (C4).
- *
- * Nothing calls this yet, on purpose: it is reserved for `device_policy`
- * (docs/MESHBAY_DESIGN.md §3.7, O3). Offered alone, it would strand the next
- * browser that signs in to this node.
+ * The counterpart of storeKeypairBundle: turning browser access off has to
+ * remove what is already stored, not merely stop adding to it — otherwise
+ * the blob stays on every node the account has ever joined (C4). Called by
+ * `settleNodeBundle` only, for an account whose identities the desktop
+ * application holds.
*/
async deleteKeypairBundle() {
const msg = await this._sendAndWait({
@@ -275,6 +273,45 @@ extendTransport(class {
return msg;
}
+ /**
+ * Leave on this node what should be there, once the connection is made.
+ *
+ * In a browser: the bundle of an identity just created, as always — it is
+ * how the next browser becomes the same person here. In the desktop
+ * application, which keeps the identity itself: nothing when the account
+ * has no browser access (and whatever was left before is withdrawn), or the
+ * identity sealed under the current key when it has — sealed again whenever
+ * the key changed since, which is what carries a passphrase change to nodes
+ * that were offline when it happened.
+ */
+ async settleNodeBundle() {
+ const id = this._identity;
+ if (!id) return;
+ if (!id.native) {
+ if (this._newNodeBundle) {
+ await this.storeKeypairBundle(this._newNodeBundle, this._newNodeBundleRecovery);
+ this._newNodeBundle = null;
+ this._newNodeBundleRecovery = null;
+ }
+ return;
+ }
+ const P = window.MeshBayPlatform.keys;
+ const uid = this._userId;
+ if (!await P.browserAccess(uid)) {
+ if (this._nodeHasBundle) {
+ await this.deleteKeypairBundle();
+ this._nodeHasBundle = false;
+ }
+ return;
+ }
+ if (this._nodeHasBundle && id.sealedWith && id.sealedWith === await P.fingerprint(uid)) return;
+ const sealed = await P.sealBundle(uid, this.nodePk);
+ await this.storeKeypairBundle(sealed.bundle, null);
+ await P.markSealed(uid, this.nodePk, sealed.fingerprint);
+ id.sealedWith = sealed.fingerprint;
+ this._nodeHasBundle = true;
+ }
+
async storeKeypairBundle(bundleEnc, recoveryEnc) {
const msg = await this._sendAndWait({
type: 'keypair_bundle_store',