fix(cli): no base64 fallback on direct-message decrypt failure

The push handler previously fell through to base64-decoding the
raw ciphertext whenever decryptDirect() returned null. For direct
(crypto_box) messages that produces garbage binary which surfaces
as garbled bytes in Claude's <channel> reminder. Limit the base64
fallback to legacy broadcast/channel messages (no senderPubkey),
and emit a clearer "⚠ message from <pubkey> failed to decrypt"
warning when direct decryption fails.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alejandro Gutiérrez
2026-04-05 22:22:33 +01:00
parent f8369a0e9b
commit f144e0485a
2 changed files with 16 additions and 7 deletions

View File

@@ -312,10 +312,14 @@ export class BrokerClient {
this.mesh.secretKey,
);
}
// If decryption failed, fall back to base64 UTF-8 unwrap —
// this covers the legacy plaintext path for broadcasts/channels
// until channel crypto lands.
if (plaintext === null && ciphertext) {
// Legacy/broadcast path: no senderPubkey means the message
// was not crypto_box'd, so base64 UTF-8 unwrap is correct.
// For direct messages (senderPubkey present) we MUST NOT
// base64-decode the ciphertext on decrypt failure — that
// produces garbage binary that surfaces as garbled bytes
// to Claude. Leave plaintext=null and let consumers emit
// a clear "failed to decrypt" warning.
if (plaintext === null && ciphertext && !senderPubkey) {
try {
plaintext = Buffer.from(ciphertext, "base64").toString("utf-8");
} catch {