diff options
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/transport-admin.js')
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/static/transport-admin.js | 39 |
1 files changed, 24 insertions, 15 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/transport-admin.js b/packages/meshbay-hub/src/meshbay_hub/static/transport-admin.js index 03a0f33..1a5a4c0 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/transport-admin.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/transport-admin.js @@ -17,7 +17,7 @@ extendTransport(class { async pairOperator(userId, code) { if (!this._connected) throw new Error('Not connected to the node'); if (!userId) throw new Error('Missing user id'); - 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) { @@ -28,14 +28,14 @@ extendTransport(class { // Both public keys are derived from OUR OWN secret keys, never read back from // the hub: signing a public key the directory handed us would reintroduce the // substitution this whole mechanism exists to close. - 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); // group_id is empty: operator authority is node-wide, not per group. - const transcript = C.joinTranscript( - this.nodePk, '', userId, pkEdB64, pkXB64, this._nonceNode, ts); - const sig = await window.MeshBayKeys.signBytes(this._sessionKeys.skEdB64, transcript); + const sig = await this._identity.signAs('join', { + nodePk: this.nodePk, groupId: '', userId, + nonceNode: C.b64encode(this._nonceNode), ts, + }); const resp = await this._sendAndWait({ type: 'join_request', @@ -108,11 +108,12 @@ extendTransport(class { } if (!signFn) throw new Error('Admin challenge received but no signing key available'); - const transcript = window.MeshBayCrypto.adminTranscript( - challenge.op, challenge.node_pk, challenge.group_id, - challenge.subject, challenge.nonce, challenge.ts); - - const signature = await signFn(transcript); + // The fields, not the bytes: whatever holds the key builds the transcript + // from them (crypto.js, transcriptFor). + const signature = await signFn({ + op: challenge.op, nodePk: challenge.node_pk, groupId: challenge.group_id, + subject: challenge.subject, nonce: challenge.nonce, ts: challenge.ts, + }); console.log('[MeshBay] _authorizeAdminOp: signed', challenge.op, 'op_id=', challenge.op_id, '— sending admin_response'); const ack = await this._sendAndWait({ @@ -263,7 +264,10 @@ extendTransport(class { }); if (msg.type === 'error') throw new Error(msg.detail); if (msg.type === 'admin_challenge') { - return this._authorizeAdminOp(msg, 'root_add', path, signFn); + // Everything the node will act on is in the subject, `writable` included. + const subject = window.MeshBayCrypto.rootAddSubject( + path, name || '', kind || 'generic', !!writable, !!removable); + return this._authorizeAdminOp(msg, 'root_add', subject, signFn); } return msg; } @@ -369,11 +373,13 @@ extendTransport(class { async attachGroup(name, sharedDir, uploadDir, signFn) { const msg = await this._sendAndWait({ type: 'group_attach', v: '0.1', - name, shared_dir: sharedDir, upload_dir: uploadDir || '', + name, shared_dir: sharedDir, upload_dir: uploadDir || '', writable: true, }); if (msg.type === 'error') throw new Error(msg.detail); if (msg.type === 'admin_challenge') { - return this._authorizeAdminOp(msg, 'group_attach', name, signFn); + // The directory being exposed is signed, not only the group's name. + const subject = window.MeshBayCrypto.groupAttachSubject(name, sharedDir, true); + return this._authorizeAdminOp(msg, 'group_attach', subject, signFn); } return msg; } @@ -416,7 +422,10 @@ extendTransport(class { }); if (msg.type === 'error') throw new Error(msg.detail); if (msg.type === 'admin_challenge') { - return this._authorizeAdminOp(msg, 'invite_create', userId, signFn); + // The node keeps the first 64 code points of the name, as Python slices. + const name = Array.from(username || '').slice(0, 64).join(''); + const subject = window.MeshBayCrypto.inviteCreateSubject(userId, name); + return this._authorizeAdminOp(msg, 'invite_create', subject, signFn); } return msg; } |