952 Commits

Author SHA1 Message Date
callebtc
57bb99c170 Merge remote-tracking branch 'origin/main' into claude/ios-features-android-port-ebe483
# Conflicts:
#	app/src/main/java/com/bitchat/android/ui/ChatViewModel.kt
2026-10-26 12:40:40 +01:00
callebtc
c8b10c5e71
Merge pull request #997 from permissionlesstech/claude/geohash-chat-autoscroll-bug-bae434
Keep following new messages in full chat timelines
2026-10-26 12:39:15 +01:00
callebtc
405297fd70
Merge pull request #1003 from swedishfrenchpress/fix/verification-sheet-stacking
fix(ui): stack verify sheet over the network sheet
2026-10-26 12:38:48 +01:00
callebtc
c7db79fa37
Merge pull request #1008 from permissionlesstech/claude/wear-os-swipe-menu-d7f87d
feat(wear): add swipe-right app menu with quit option
2026-10-26 12:37:46 +01:00
callebtc
822213b551 fix(wear): hide page indicator on chat home pager 2026-10-26 12:36:55 +01:00
callebtc
404fe4a588 feat(wear): add swipe-right app menu with quit option
Swiping the public mesh chat to the right reveals an app menu page
(Wear HorizontalPagerScaffold). The menu shows mesh status and a
"Quit bitchat" button that, after confirmation, stops the mesh
foreground service and closes the task.

Swiping from the menu's left edge still falls through to system
swipe-to-dismiss. Page swipes are disabled while push-to-talk or the
full-screen image viewer owns the gesture.
2026-10-26 12:33:12 +01:00
callebtc
e4310e9df9
Merge pull request #1006 from permissionlesstech/fix/mesh-relay-concurrency
Fix concurrent security-cache cleanup and relay snapshots
2026-10-26 11:42:25 +01:00
callebtc
972bf44ee0 Merge remote-tracking branch 'origin/main' into claude/geohash-chat-autoscroll-bug-bae434
# Conflicts:
#	app/gradle.lockfile
2026-10-26 11:41:26 +01:00
callebtc
ac5d719a96
Merge pull request #984 from permissionlesstech/fix/play-release-crashes
Fix minified release QR scanner initialization
2026-10-26 11:36:28 +01:00
callebtc
f5419f0e90 Fix concurrent security cache and relay snapshots 2026-10-26 09:51:58 +01:00
callebtc
ec1a92fcfe Fix minified release scanner initialization 2026-10-26 09:50:36 +01:00
callebtc
79897d36ac
Merge pull request #1005 from permissionlesstech/fix/translation-lint
Complete missing locale resources
2026-10-26 09:41:01 +01:00
callebtc
ab57e209a1 Complete missing locale resources 2026-10-25 23:51:59 +01:00
callebtc
de26ef336b
Merge pull request #1004 from permissionlesstech/claude/bubble-audio-contrast-light-de2b64
Improve voice note waveform contrast in light mode
2026-10-25 23:01:59 +01:00
callebtc
1e121fafad
Merge pull request #999 from permissionlesstech/claude/bitcohat-spam-detection-20c908
Add spam filter for public mesh and geohash chats
2026-10-25 22:34:50 +01:00
callebtc
844239d384 See through disguised copies in repeat checks
A copy with a zero-width space between letters, an accent on every
letter, or math-bold or fullwidth letters looks the same to a reader
but defeated both the per-sender and cross-user repeat checks.

Normalize text for comparison by applying NFKD (which folds fullwidth
and styled letters to plain ones and splits off accents), dropping
combining marks and invisible characters, collapsing whitespace and
lowercasing. Displayed and stored text is unchanged. Input is capped
before normalizing to bound the work per message.
2026-10-25 21:25:17 +01:00
Erik
8a7718cc7e fix(ui): stack verify sheet over the network sheet
Tapping the QR action closed the network sheet, briefly showed the chat
screen, then opened the verify sheet; closing verify reopened the network
sheet through a reopenSidebarAfterVerification flag. Open the verify
sheet on top of the network sheet instead, the way the private chat sheet
already hosts security verification, so dismissing it (close button or
back) simply reveals the network sheet underneath. The reopen flag and the
fromSidebar parameter are no longer needed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 20:20:50 +01:00
callebtc
01294db3f0
Merge pull request #1002 from swedishfrenchpress/fix/network-sheet-scan-icon-consistency
fix(ui): match network sheet QR action to top bar chrome
2026-10-25 20:18:58 +01:00
callebtc
fb7ee683dc Wipe spam filter history on panic and add Mesh Lab spam scenario
The spam filter keeps recent message text and sender keys for its
repeat checks, and panic clear left them in memory. Reset the shared
filter as part of the panic wipe.

Add a broadcast_spam Mesh Lab scenario so messaging validation covers
both admitted and filtered public messages: B must show two
near-copies from A, hide the third, and still show A's next ordinary
message. It runs phone-to-phone and phone-to-watch.
2026-10-25 20:16:09 +01:00
callebtc
a9c9638826 Harden spam filter exemptions and threading
A mesh peer could skip every spam rule by choosing the nickname
"system", since the exemption for local notices checked only the
peer-controlled display name. Exempt only messages without a sender
peer ID: every message read off the wire carries one, while local
notices such as "X favorited you" do not. Applies to the phone and
watch admission paths.

The foreground geohash handler runs on the main thread, so the spam
checks could stall the UI during a relay backfill. Run them on a
background dispatcher (the signature verification one by default).
2026-10-25 20:09:59 +01:00
Erik
d3b168f425 fix(ui): match network sheet QR action to top bar chrome
The QR action next to the network sheet's close button was the only
grey, oversized icon in any top bar, and sat 16dp away from the close
button. Align it with the conversation header's action pattern:

- tint with colorScheme.primary, like the close button beside it
- size to HeaderIconSize (19dp), like the private chat header actions
- space the close button 2dp from a preceding action; the 16dp end
  inset is unchanged, so the close button does not move on any sheet

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 20:06:41 +01:00
callebtc
78af907c69 Raise default character budget to 1200 per minute
600 characters per minute hid ordinary long messages too eagerly. The bucket now holds 1200 characters and refills 20 per second.
2026-10-25 20:04:46 +01:00
callebtc
4b7c034f43 Detect copied messages across users
Spammers can rotate through unlimited npubs, so per-sender repeat
limits miss a swarm posting the same text once each. Keep the last 200
messages of 16+ characters from all senders and hide a message once
more than 2 near-copies from other senders appeared within the repeat
window.

Plain cross-correlation keeps only the best shift, so one inserted or
deleted character split a copy in two (a "!!" insertion scored 54%).
Similarity now combines up to 3 correlation peaks, where the extra
peaks count only runs of 3+ matching characters and no character is
used twice; the same example scores 95% while unrelated text stays
under 40%. Comparisons cover the first 280 characters and skip pairs
sharing under 25% of their trigrams, bounding the cost per message.

Both cross-user limits are tunable in the debug Spam section.
2026-10-25 19:16:14 +01:00
callebtc
445650937c Add spam filter debug settings
Add a Spam filter section to debug settings with sliders for every
limit (message burst and refill, characters and links per minute,
repeat tolerance, similarity and window, repeated-character threshold
and minimum length) and a reset to defaults. Tuned values persist and
apply immediately; changing them gives every sender a full budget.

A debug bypass keeps spam in the chat instead of hiding it and marks
it with a red background and the reason it would have been hidden,
in both matrix and bubble mode. Transports now ask
SpamFilter.shouldHide, which records bypassed verdicts in a flow the
message list observes.
2026-10-25 15:24:54 +01:00
callebtc
5996eb84c7 Add spam filter for public mesh and geohash chats
Hide public messages from a sender who exceeds per-user token buckets
(6 messages with 1 refilled every 10 s, 600 characters per minute,
2 links per minute), posts a third near-copy of a recent message, or
sends a message that repeats a character or phrase (character
autocorrelation). Buckets run on message timestamps, clamped to the
last hour, so relay backfill and mesh sync bursts are not mistaken
for floods.

The filter applies to mesh public and channel messages at transport
admission, to geohash messages in GeohashMessageHandler, and to the
watch's mesh intake. Private messages are not filtered. All limits
live in SpamFilterConfig; a Settings toggle (on by default) disables
the filter.
2026-10-25 14:54:47 +01:00
callebtc
07d4c546ef Improve voice note waveform contrast in light mode
Draw unplayed waveform bars in the surface text colour and played bars in the theme accent, and give the duration label an explicit colour so it stays readable in dark mode.
2026-10-25 14:32:09 +01:00
GitHub Action
137ce6d01b Automated update of relay data - Sun Oct 25 06:16:38 UTC 2026 2026-10-25 06:16:38 +00:00
callebtc
d32cfad700 Merge remote-tracking branch 'origin/main' into claude/ios-features-android-port-ebe483
# Conflicts:
#	docs/client-rewrite-contracts.md
2026-10-25 01:42:19 +02:00
callebtc
0451f9921d Keep following new messages in full chat timelines
Public, channel and geohash timelines are capped at 1,000 messages, so once
full each arrival evicts the oldest and the list size stops changing. The
follow effect was keyed only on size, so it stopped auto-scrolling. Key it on
the newest message id and the conversation as well, and add a Robolectric
Compose regression test.
2026-10-25 01:25:18 +02:00
callebtc
95c0852c2b
Merge pull request #965 from Chessing234/codex/apk-response-byte-budget
Validate APK response sizes before appending download bytes
2026-10-25 01:14:41 +02:00
callebtc
a000ed448c
Merge pull request #910 from Chessing234/fix/qr-reject-future-dated-timestamp
fix: reject a future-dated verification QR
2026-10-25 01:14:31 +02:00
callebtc
f7dc80fb2b
Merge pull request #964 from Chessing234/codex/bech32-canonical-padding
Reject noncanonical Bech32 padding and invalid prefix lengths
2026-10-25 01:14:21 +02:00
callebtc
88b286b978
Merge pull request #928 from Chessing234/fix/hex-string-parity
Reject odd-length and 0x-prefixed hex the way iOS does
2026-10-25 01:14:11 +02:00
callebtc
1970e967bb
Merge pull request #894 from Chessing234/gcs-param-guard
fix(sync): reject out-of-range GCS parameters instead of decoding garbage
2026-10-25 01:14:02 +02:00
callebtc
3b9e6d3bbd
Merge pull request #880 from Chessing234/fix/fragment-injection-hardening
fix: stop an injected fragment from destroying or poisoning a reassembly
2026-10-25 01:13:53 +02:00
callebtc
adf6c68995
Merge pull request #887 from Chessing234/security/exclude-app-data-from-backup-and-transfer
fix: keep identity keys and message history out of backup and device transfer
2026-10-25 01:13:44 +02:00
callebtc
64be2b73ba
Merge pull request #995 from permissionlesstech/claude/geohash-chat-block-review-ae5033
Fix geohash block targeting and hide blocked messages
2026-10-25 01:06:34 +02:00
callebtc
df0b1389f1 Confirm every panic wipe stage; specify payload caps
- The panic wipe announces success only when every data-at-rest stage
  confirms: identity and signing-key prefs, Nostr keys, favorites, media,
  bookmarks, and the conversation database. Each stage now returns
  whether its wipe was committed instead of swallowing failures; any
  failure shows the incomplete message.
- Add docs/PACKET_PAYLOAD_LIMITS.md for the per-type admission rules and
  literal wire vectors with real DEFLATE bodies at and past the caps.
- Document the random sender ID in geohash envelopes.
2026-10-25 01:05:43 +02:00
callebtc
30f911f947 Port iOS geohash DM, payload cap, and panic confirm fixes
- Geohash DMs and their acks embed a random sender ID per envelope
  instead of the mesh peer ID, which linked geohash personas to the
  device (iOS #1718). Favorites envelopes are unchanged.
- Decode enforces per-type payload caps on compressed and uncompressed
  payloads, matching iOS PacketPayloadLimits; media types keep the
  existing ceiling. The compression-ratio guard becomes DEFLATE's
  1032:1 bound (iOS #1719, decoder part only).
- Triple-tapping the logo asks for confirmation before a panic wipe,
  and the outcome (wiped, or incomplete) is posted to the chat
  (iOS #1588).
- Pin that a blocked geohash sender gets no delivery ack.
2026-10-25 00:53:53 +02:00
callebtc
534770516c Fix geohash block targeting and hide blocked messages
Block the long-pressed message's Nostr pubkey instead of resolving a
suffix-stripped nickname, which picked an arbitrary user when nicknames
collided and failed for anon senders. Nickname lookup now honors the
#suffix and returns nothing when ambiguous. Blocking also removes the
sender's existing messages from geohash timelines.
2026-10-25 00:35:37 +02:00
callebtc
d1da97160a
Merge pull request #985 from jmartinn/fix/cashu-display-amount
Fix Cashu token amounts displaying 100× too low
2026-10-24 16:49:39 +02:00
callebtc
497ccb2130
Merge pull request #986 from permissionlesstech/fix/geohash-participants
Fix missing geohash channel participants
2026-10-24 16:47:52 +02:00
callebtc
b30565f42f
Merge pull request #989 from swedishfrenchpress/ui/onboarding-cleanup
Align onboarding screen margins
2026-10-24 16:44:36 +02:00
callebtc
3209993dc3
Merge pull request #991 from ederto1987/basque-translation
Add Basque (eu) translation
2026-10-24 16:43:33 +02:00
Eder Etxebarria
cba0219ca6
Update locales_config.xml 2026-10-23 23:25:54 +02:00
Eder Etxebarria
bfb7a1fb7f
Create strings.xml 2026-10-23 23:18:31 +02:00
Erik
99ebd011b2 Use theme primary on Bluetooth and location check screens
Replace the hardcoded #00C851 and #4CAF50 greens with colorScheme.primary
and drop the extra label padding, so these primary buttons match the
other onboarding screens in color and height (40dp). In light theme this
also raises button label contrast from about 2.2:1 to 4.4:1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 18:54:50 +02:00
Erik
565e49ed36 Keep scrolling onboarding content clear of pinned buttons
Apply the content column's bottom padding outside the scroll container
on the permission, background location, and battery optimization
screens. At large font sizes the clipped edge now stops 16dp above the
buttons instead of running into them. Layout at default sizes is
unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 18:54:50 +02:00
Erik
f6c720005d Align onboarding screen margins
Use the same 24dp outer padding on every onboarding screen. The
permission explanation screen now follows the background location and
battery optimization layout: no extra top spacer, the primary button
sits inside the screen padding instead of a separate elevated bar, and
permission rows share the privacy card's icon and text inset.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 18:30:41 +02:00
a1denvalu3
6630705c23 Fix missing geohash channel participants 2026-10-23 14:15:42 +02:00