#996

Port iOS geohash DM, payload cap, and panic confirm fixes

Opencallebtcwants to merge intofrom

Ports three security/privacy fixes from bitchat iOS and pins a fourth that Android already handles.

Changes

Geohash DMs no longer carry the mesh peer ID (jackjackbits/bitchat#1718) The recipient-less encoders used for geohash DMs and their acks wrote our mesh peer ID into the embedded packet's sender field. That ID is the stable Noise fingerprint prefix, so anyone who DMs a geohash identity (and gets the automatic DELIVERED ack) could link that persona to the device. Each envelope now gets fresh random bytes. No iOS or Android receiver reads this field; favorites (recipient-addressed) envelopes are unchanged.

Per-type payload caps at decode (decoder part of jackjackbits/bitchat#1719) New PacketPayloadLimits with the same per-type caps as iOS (public message 128 KiB, request sync 8 KiB, announce/leave/handshake/voice 4 KiB, fragment 1,280 B, unknown types 128 KiB). FILE_TRANSFER and NOISE_ENCRYPTED keep the existing MAX_PAYLOAD_LENGTH. Enforced on compressed and uncompressed payloads before allocation. The 50,000:1 compression-ratio guard becomes DEFLATE's 1032:1 bound. Not ported here: the iOS reassembly bound by claimed type and byte budgets for sync stores.

Panic wipe asks first (jackjackbits/bitchat#1588) Triple-tapping the logo now opens a "Wipe all data?" dialog instead of wiping immediately. A completed wipe posts "all data wiped — new identity created"; a wipe whose conversation-database erase fails now says so in the chat instead of failing silently. New strings are English-only (tools:ignore="MissingTranslation"), following recent precedent.

Ack only after the block check Already correct on Android (the block check runs right after decryption). Added a regression test.

Risk

  • Payload caps are receive-side only and sized at ≥2× the largest payload current iOS/Android encoders produce, but an oversized legitimate packet of a capped type would now be dropped at decode.
  • The sender-ID change touches the geohash DM wire content; receivers key these conversations on the Nostr pubkey, so interop should be unaffected.
  • Panic flow gains one extra tap.

Testing

  • ./gradlew testDebugUnitTest lintDebug passes (app 659 tests, Wear 231 tests); no new lint findings in changed code.
  • New tests: PacketPayloadLimitsTest, NostrEmbeddedBitChatTest, blocked-sender case in NostrDirectMessageHandlerTest; existing BinaryProtocolTest fixtures updated for the new bounds.
  • Not yet done: Mesh Lab validation on physical devices (iOS↔Android geohash DMs, large public messages and file transfers), and before/after screenshots of the panic confirmation dialog.

Activity

5
chatgpt-codex-connector[bot]6d ago

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

ReviewStatusCommitReview trigger
📝 Code Review✅ Completed 2026-10-24T23:07:20.089843Zdf0b138Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

chatgpt-codex-connector[bot]reviewed6d ago
chatgpt-codex-connector[bot]6d ago

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 30f911f947

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

callebtc6d ago

Addressed the Codex review in df0b1389:

Verify all wipe stages before announcing success — fixed. Each data-at-rest wipe stage now reports whether its wipe was committed instead of swallowing failures: identity prefs (clearIdentityData), the Noise identity and Ed25519 signing key (clearPersistentIdentity / clearAllEncryptionData, now Boolean through MeshService), Nostr keys (clearAllAssociations, now a synchronous commit), favorites secure values, media (clearAllMedia checks every deleteRecursively), bookmarks and the persisted channel. "all data wiped — new identity created" is shown only when every stage succeeded; otherwise the incomplete message is shown. Added FileUtilsClearAllMediaTest.

Document and pin the protocol acceptance contract — fixed. Added docs/PACKET_PAYLOAD_LIMITS.md (rules, per-type table, what is not ported yet) and linked it from docs/client-rewrite-contracts.md, which now also documents the random sender ID in geohash envelopes. Added PacketPayloadLimitsWireContractTest: literal frames with real raw-DEFLATE bodies decoded through the production decompressor — announce at 4,096 B (accepted) and 4,097 B (rejected), public message at 128 KiB (accepted, ~917:1) and one byte past (rejected), the same body as FILE_TRANSFER (accepted), and a 1032:1 overrun that never reaches the decompressor.

Physical Mesh Lab validation — agreed it is required, not done yet. No devices were attached in this environment, so the PR still needs a Mesh Lab run (BLE receive/relay/transfer scenarios, plus an iOS↔Android geohash DM and ack exchange) before merge.

./gradlew testDebugUnitTest lintDebug: app 667 tests, Wear 231 tests, 0 failures; no new lint errors (one new UseKtx warning where the KTX edit {} form can't return the commit result the wipe check needs).

callebtc6d ago

@codex review

chatgpt-codex-connector[bot]6d ago

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: df0b1389f1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".