diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-09-30 15:48:51 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-09-30 15:48:51 +0200 |
| commit | 8926f163dad9d32dc06c3a142658a4e11d9c12c1 (patch) | |
| tree | 4d36d1c18154cb46e6e80c59ef6c607972caa81e /packages/meshbay-hub/src/meshbay_hub/static/transport-devices.js | |
| parent | 8d96cf2314b45e0737f932998b5422c27a2ae72e (diff) | |
| download | meshbay-8926f163dad9d32dc06c3a142658a4e11d9c12c1.tar.gz | |
refactor(hub): the transport holds an identity, never a private key
Two public keys, sign() and shared(); the apps take transport.signFn. What
holds the keys (this page, or the desktop main process) is the identity's
business alone.
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.js | 26 |
1 files changed, 10 insertions, 16 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 199b6a2..f17b1b6 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/transport-devices.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/transport-devices.js @@ -94,7 +94,7 @@ extendTransport(class { * this node sees this account (and not at all in an open-join group). */ async joinGroup(userId, groupId, code) { - if (!this._sessionKeys || !this._sessionKeys.skEdB64 || !this._sessionKeys.skXB64) { + if (!this._identity) { throw new Error('Identity keys unavailable in this browser — sign in again'); } if (!this._nonceNode || !this.nodePk) { @@ -102,13 +102,12 @@ extendTransport(class { } const C = window.MeshBayCrypto; - const pkEdB64 = await _pkEdFromSk(this._sessionKeys.skEdB64); - const pkXB64 = await _pkFromSk(this._sessionKeys.skXB64); + const { pkEdB64, pkXB64 } = this._identity; const ts = Math.floor(Date.now() / 1000); const transcript = C.joinTranscript( this.nodePk, groupId || '', userId, pkEdB64, pkXB64, this._nonceNode, ts); - const sig = await window.MeshBayKeys.signBytes(this._sessionKeys.skEdB64, transcript); + const sig = await this._identity.sign(transcript); const resp = await this._sendAndWait({ type: 'join_request', @@ -133,9 +132,8 @@ extendTransport(class { // Unwrap with our own secret key — the node wrapped for the public key we // just proved we hold, so nobody else can open this. - const skXRaw = Uint8Array.from(atob(this._sessionKeys.skXB64), c => c.charCodeAt(0)); const myPkX = Uint8Array.from(atob(pkXB64), c => c.charCodeAt(0)); - const gekRaw = await C.unwrapGEK(resp, skXRaw, myPkX); + const gekRaw = await C.unwrapGEK(resp, (pk) => this._identity.shared(pk), myPkX); this._gekRaw = gekRaw; // What the node's roster says this identity is, which is not what the hub // says: `operator` here means this browser's key was paired with the node, @@ -154,15 +152,14 @@ extendTransport(class { * device cannot be handed a substituted key and sign for it by mistake. */ async requestDeviceAdd(userId) { - if (!this._sessionKeys || !this._sessionKeys.skEdB64) { + if (!this._identity) { throw new Error('Identity keys unavailable in this browser — sign in again'); } if (!this._nonceNode || !this.nodePk) { throw new Error('Handshake incomplete — reconnect and retry'); } const C = window.MeshBayCrypto; - const pkEdB64 = await _pkEdFromSk(this._sessionKeys.skEdB64); - const pkXB64 = await _pkFromSk(this._sessionKeys.skXB64); + const { pkEdB64, pkXB64 } = this._identity; // 40 bits from the platform CSPRNG, in the same alphabet as a pairing code // so it reads and types the same way. @@ -176,8 +173,7 @@ extendTransport(class { const ts = Math.floor(Date.now() / 1000); const transcript = C.deviceRequestTranscript( this.nodePk, userId, pkEdB64, pkXB64, codeHash, this._nonceNode, ts); - const sig = await window.MeshBayKeys.signBytes( - this._sessionKeys.skEdB64, transcript); + const sig = await this._identity.sign(transcript); const resp = await this._sendAndWait({ type: 'device_add_request', v: '0.1', @@ -196,7 +192,7 @@ extendTransport(class { * nothing to sign and nothing for a person to misread. */ async approveDevice(userId, code) { - if (!this._sessionKeys || !this._sessionKeys.skEdB64) { + if (!this._identity) { throw new Error('Identity keys unavailable in this browser — sign in again'); } if (!this._nonceNode || !this.nodePk) { @@ -231,8 +227,7 @@ extendTransport(class { const ts = Math.floor(Date.now() / 1000); const transcript = C.deviceAddTranscript( this.nodePk, userId, pkEdB64, pkXB64, this._nonceNode, ts); - const sig = await window.MeshBayKeys.signBytes( - this._sessionKeys.skEdB64, transcript); + const sig = await this._identity.sign(transcript); const resp = await this._sendAndWait({ type: 'device_add', v: '0.1', pk_ed25519: pkEdB64, pk_x25519: pkXB64, code_hash: codeHash, ts, sig, @@ -253,8 +248,7 @@ extendTransport(class { const ts = Math.floor(Date.now() / 1000); const transcript = C.deviceAddTranscript( this.nodePk, userId, pkEdB64, pkXB64, this._nonceNode, ts); - const sig = await window.MeshBayKeys.signBytes( - this._sessionKeys.skEdB64, transcript); + const sig = await this._identity.sign(transcript); const resp = await this._sendAndWait({ type: 'device_revoke', v: '0.1', pk_ed25519: pkEdB64, ts, sig, }); |