Chat updates

This commit is contained in:
Raven Scott
2026-04-21 20:43:06 -04:00
parent 6158ac2aa7
commit 01e066d7cb
6 changed files with 128 additions and 33 deletions
-7
View File
@@ -9954,13 +9954,6 @@ async function main() {
const swarm = new Hyperswarm(swarmOpts)
bareOsRegisterCorestoreSuspendResumeHooks(store, swarm)
const disk = new SwarmDisk()
if (
swarm.keyPair &&
swarm.keyPair.publicKey &&
swarm.keyPair.publicKey.byteLength === 32
) {
disk.localSwarmPublicKey = b4a.from(swarm.keyPair.publicKey)
}
if (bareOsChatMuxEnabled(hostEnvMain)) {
disk.bareOsChatService = createBareOsChatService({
env: /** @type {Record<string, string | undefined>} */ (
@@ -238,16 +238,13 @@ export function createBareOsChatService(opts = {}) {
try {
const id16 = randomBytes(16)
let pk = b4a.alloc(32)
if (
disk.localSwarmPublicKey &&
disk.localSwarmPublicKey.byteLength === 32
) {
pk = disk.localSwarmPublicKey
} else if (
socket?.publicKey &&
socket.publicKey.byteLength === 32
) {
if (socket?.publicKey && socket.publicKey.byteLength === 32) {
pk = b4a.from(socket.publicKey)
} else if (
disk.localNoiseWirePk &&
disk.localNoiseWirePk.byteLength === 32
) {
pk = disk.localNoiseWirePk
}
chan.messages[2].send({
roomId: 'general',
@@ -294,19 +291,9 @@ export function createBareOsChatService(opts = {}) {
*/
broadcastLocal(disk, text, meta = {}) {
const evtId = randomBytes(16)
let pk = meta.senderPk
if (!pk || pk.byteLength !== 32) {
pk = null
}
if (!pk || pk.byteLength !== 32) {
if (
disk.localSwarmPublicKey &&
disk.localSwarmPublicKey.byteLength === 32
) {
pk = disk.localSwarmPublicKey
}
}
if (!pk || pk.byteLength !== 32) {
let pk =
meta.senderPk && meta.senderPk.byteLength === 32 ? meta.senderPk : null
if (!pk) {
for (const p of disk.peers) {
const sk = p.socket?.publicKey
if (sk && sk.byteLength === 32) {
@@ -315,6 +302,9 @@ export function createBareOsChatService(opts = {}) {
}
}
}
if (!pk && disk.localNoiseWirePk && disk.localNoiseWirePk.byteLength === 32) {
pk = disk.localNoiseWirePk
}
if (!pk || pk.byteLength !== 32) {
pk = b4a.alloc(32)
}
+17 -3
View File
@@ -172,8 +172,11 @@ export class SwarmDisk {
this.seedHttpDhtProxyRoutes = null
/** @type {string[]} MBR-derived drive key hex list (primary + failovers). */
this.mbrKeysHex = []
/** Host Hyperswarm/DHT public key (32 bytes); set by booter `main` for chat wire `senderPk`. */
this.localSwarmPublicKey = /** @type {Uint8Array | null} */ (null)
/**
* Local Noise wire static key (32 bytes), last seen from `Hyperswarm` socket `publicKey`.
* Peers validate chat `senderPk` against `socket.remotePublicKey`, which matches **this** — not `swarm.keyPair.publicKey`.
*/
this.localNoiseWirePk = /** @type {Uint8Array | null} */ (null)
}
/**
@@ -479,6 +482,14 @@ export class SwarmDisk {
this.bareOsChatService.pairOnMux(this, mux, socket, peer)
}
/** Sync local Noise static key once the secret stream exposes `publicKey` (may follow handshake). */
const cacheLocalNoiseWirePk = () => {
if (socket.publicKey && socket.publicKey.byteLength === 32) {
disk.localNoiseWirePk = b4a.from(socket.publicKey)
}
}
cacheLocalNoiseWirePk()
this.peers.add(peer)
const collabNd =
@@ -508,7 +519,10 @@ export class SwarmDisk {
return false
}
socket.on('handshake', setPeerId)
socket.on('handshake', () => {
setPeerId()
cacheLocalNoiseWirePk()
})
if (!setPeerId()) {
let attempts = 0
const tryAgain = () => {
+1 -1
View File
@@ -8,7 +8,7 @@
"start": "node ../../scripts/ensure-pear-node-modules.mjs packages/bare-os-booter && bare index.js",
"dev": "node ../../scripts/ensure-pear-node-modules.mjs packages/bare-os-booter && bare index.js",
"pear:dev": "node ../../scripts/ensure-pear-node-modules.mjs packages/bare-os-booter && pear run --dev .",
"test": "../../node_modules/.bin/brittle-bare test.identity.js && node --require ./scripts/bare-node-test-shim.cjs ../../node_modules/.bin/brittle-node test.js test.bare-os-chat-service.js test.bare-holesail.js test.bare-holesail-managed.js test.bare-openssh-pty.js test.bare-openssh-sftp.js test.hrpc-allowlist.js test.socket-scm-rights.js",
"test": "../../node_modules/.bin/brittle-bare test.identity.js && node --require ./scripts/bare-node-test-shim.cjs ../../node_modules/.bin/brittle-node test.js test.bare-os-chat-service.js test.bare-os-chat-wire.js test.bare-holesail.js test.bare-holesail-managed.js test.bare-openssh-pty.js test.bare-openssh-sftp.js test.hrpc-allowlist.js test.socket-scm-rights.js",
"test:bare": "../../node_modules/.bin/brittle-bare test.identity.js test.bare-smoke.js"
},
"dependencies": {
@@ -0,0 +1,64 @@
/**
* Proves chat `senderPk` must be the **Noise** `socket.publicKey` (32 B), not
* `swarm.keyPair.publicKey` — the peer's `remotePublicKey` matches the other
* side's `publicKey` on the same connection, not the DHT key pair.
*/
import Hyperswarm from 'hyperswarm'
import b4a from 'b4a'
import { topicKey } from 'bare-os-protocol/constants.js'
const topic = topicKey()
const a = new Hyperswarm()
const b = new Hyperswarm()
const aKey = a.keyPair.publicKey
const bKey = b.keyPair.publicKey
let aSock = null
let bSock = null
a.on('connection', (s) => {
aSock = s
check()
})
b.on('connection', (s) => {
bSock = s
check()
})
function check() {
if (!aSock || !bSock) return
const remoteB = b4a.equals(aSock.remotePublicKey, bKey)
const remoteA = b4a.equals(bSock.remotePublicKey, aKey)
console.log(
'DHT keyPair.pub === peer remotePk ?',
' A.remote vs B.dht:',
remoteB,
' B.remote vs A.dht:',
remoteA
)
console.log(
'Noise wire identity (correct for chat senderPk):'
)
console.log(
' B.remotePk === A.socket.publicKey',
b4a.equals(bSock.remotePublicKey, aSock.publicKey)
)
console.log(
' A.remotePk === B.socket.publicKey',
b4a.equals(aSock.remotePublicKey, bSock.publicKey)
)
}
b.join(topic)
await new Promise((r) => setTimeout(r, 400))
a.join(topic)
await new Promise((r) => setTimeout(r, 12000))
if (!aSock || !bSock) {
console.error('FAIL: missing connection within timeout (NAT/firewall?)')
process.exitCode = 1
}
await a.destroy()
await b.destroy()
@@ -0,0 +1,34 @@
import test from 'brittle'
import b4a from 'b4a'
import { createBareOsChatService } from './lib/bare-os-chat-service.js'
test('broadcastLocal senderPk equals Noise socket.publicKey', async (t) => {
const wirePk = b4a.alloc(32)
wirePk[7] = 42
/** @type {{ sent?: Uint8Array }} */
const cap = {}
const disk = {
localNoiseWirePk: wirePk,
peers: new Set([
{
socket: { publicKey: wirePk },
chatChan: {
messages: [, , , , { send(evt) {
cap.sent = /** @type {Uint8Array} */ (evt.senderPk)
} }]
}
}
]),
protomuxChatChannelRxTotal: 0
}
const svc = createBareOsChatService({ env: {} })
svc.broadcastLocal(disk, 'hello', { displayName: 'x' })
t.ok(cap.sent && b4a.equals(cap.sent, wirePk), 'multiplex frame carries Noise static pk')
const hist = svc.history()
const last = hist[hist.length - 1]
t.ok(last && b4a.equals(/** @type {Uint8Array} */ (last.senderPk), wirePk))
})