* Fix race between stopping and starting the receive thread
When the last receive handler was removed, receiveThread was cleared
before the thread had stopped. A handler added in that window, e.g. by
a client reconnecting to the daemon in on-connection receive mode,
started a second receive thread. While the stop request for the old
thread was still set, each new thread ended immediately and started the
next one. When the old thread ended, it cleared the reference to the
newer thread and started yet another one, leaving two receive loops on
the same websocket. The unreferenced loop was never stopped and kept
receiving and acknowledging messages after all clients had gone.
Keep receiveThread set until the receive thread has finished and only
let the thread itself clear it. Its end block already starts a new
receive thread if handlers were added in the meantime. Clear a stop
request right before a new receive loop is started instead of when a
loop ends, so it can neither be cleared by another loop nor stop a
later one.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Add test for adding a receive handler while the receive thread stops
The receive loop is replaced by a fake one that can be held while it
stops, so the test doesn't connect to the server.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: iddo <917594+iddo@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Fix voice calls from linked devices
(cherry picked from commit f3e22de14e4463adb785fb797791bc826b765a10)
* Verify primary and linked call configuration through account state
---------
Co-authored-by: Daniel <dan@gainengineering.com.au>
Each event of /api/v1/events now has an id. The last 1000 events are
kept in memory, and a client that reconnects with a Last-Event-ID header
first gets the events it missed. The keep-alive interval can be set with
the new daemon option --sse-keepalive-interval.
Closes#2132
Co-authored-by: Romain Boulay <169323+RomainBoulay@users.noreply.github.com>
* Support linking phone-numberless Signal accounts
* Align numberless account support with project style
* Support numberless accounts over D-Bus
* Keep superseded accounts out of numberless account discovery
Record numberless accounts explicitly instead of treating every retained ACI
as a discoverable account. Resolve older index entries against saved account
state, preserving ACI lookup and retrying unavailable state on later reads.
The optional index field remains compatible with version 2 readers. Update
native-image reflection metadata and cover replacement, legacy migration,
locked and missing state, and mismatched ACIs in regression tests.
* Address numberless linking review cleanup
Reuse AccountApiV2 through SignalDependencies and use the shared suspend response helper while preserving linking error handling. Remove the unused account-number accessor and unsupported D-Bus version fallback. Keep numberless linking documentation in the man page and point the README to the wiki.
Validate linking errors through HTTP response fixtures. All 196 tests pass on JDK 25 with an isolated D-Bus session; build and JSON schema generation also pass. Account-index classification is unchanged pending review discussion.
* Accept caller-supplied attachment dimensions
Forward positional WIDTHxHEIGHT metadata supplied by the caller. Validate dimensions before sending and retain automatic image detection for omitted entries.
* Accept caller-supplied attachment BlurHashes
Forward positional BlurHashes supplied by the caller alongside attachment dimensions. Reject BlurHashes whose length doesn't match their size digit.
* Skip image probing when dimensions are supplied
Caller-supplied dimensions replace the probed values, so don't buffer and decode the image to measure it.
Consume the duration text token by token instead of validating the
whole string with a nested-quantifier regex, which could backtrack
exponentially on crafted input.
New listNotificationProfiles command to show the notification profiles
of the account and the current manual override, and a new
setNotificationProfile command to manually turn a profile on for a
duration or until a point in time, turn it off, or clear the manual
override. The override is written to the account storage record and
synced to the other devices, the same way the official clients do it.
Durations accept compact forms (90m, 1h37m), words (2 hours 30 minutes),
h:mm and ISO-8601. End times accept times of day, dates, ISO timestamps,
unix timestamps and "forever".
Notification profiles are stored as their own record type in the
storage service. Until now they were treated as unknown records, which
also meant they were dropped from the manifest on every force push.
Store them locally in a new notification_profile table and handle them
like the other synced record types (sticker packs in particular), so
they survive force pushes and can be read locally.