Commit Graph
4132 Commits
Author SHA1 Message Date
Jason Robinson e68560a8a2 Don't dump to json string in tests 2026-07-02 22:21:00 +03:00
Jason Robinson 45e9a018af Don't unpact ProfileUpdateAction unnecessarily early 2026-07-01 17:32:08 +03:00
Jason Robinson e6aec556ab Merge remote-tracking branch 'origin/develop' into anoa/msc4429 2026-07-01 11:55:57 +03:00
Jason Robinson eb5aa2129a Ensure both initial and incremental syncs include our own profile and updates
Otherwise if the user has multiple clients doing incremental sync, they wont get their own profile updates to their other clients. For initial because it should probably match the incremental behaviour + it avoids clients needing to look up the profile separately potentially.
2026-07-01 11:22:57 +03:00
aa97687305 Change MSC3814 dehydrated device /events endpoint from POST to GET (#19896)
Change `/org.matrix.msc3814.v1/dehydrated_device/[device_id]/events` to
accept GET requests instead of POST.

The original version of
[MSC3814](https://github.com/matrix-org/matrix-spec-proposals/pull/3814)
said we should delete keys after returning them from this endpoint, but
it is being updated to say we should not delete them, and therefore the
appropriate verb is GET.

Synapse already doesn't delete anything, so we just need to change to a
GET with a `next_batch` query param. (Currently it is a POST with
`next_batch` in the JSON content.)

This code was initially written by @ara4n and Claude, but both he and I
have read it and think it makes sense. I am far from a Synapse expert,
so feel free to tell me it's all wrong and point me in the right
direction.

I don't know what system tests will be affected by this, but I guess we
will see when the CI runs (right?).

This is a change to an unstable endpoint so no need for notifications
about breaking changes or similar.

Part of https://github.com/element-hq/element-meta/issues/2704

### Pull Request Checklist

* [x] Pull request is based on the develop branch
* [x] Pull request includes a [changelog
file](https://element-hq.github.io/synapse/latest/development/contributing_guide.html#changelog).
The entry should:
* [x] [Code
style](https://element-hq.github.io/synapse/latest/code_style.html) is
correct (run the
[linters](https://element-hq.github.io/synapse/latest/development/contributing_guide.html#run-the-linters))

---------

Co-authored-by: Matthew Hodgson <matthew@matrix.org>
2026-06-30 21:20:26 +00:00
aa6e616470 Don't delete the dehydrated device when MAS syncs the device list (#19892)
`_synapse/mas/sync_devices` checks the device list against the set of
devices MAS knows about, but the dehydrated device (MSC3814) is
invisible to MAS, so it gets automatically deleted on each sync, which
prevents dehydrated devices from working.

This change excludes the dehydrated device from the check.

There is similar special case code in the admin devices API (which gives
it a special flag) and MAS's own legacy sync path (which filters it
out).

This code was initially written by @ara4n and Claude, but both he and I
have read it and think it makes sense. I am far from a Synapse expert,
so feel free to tell me it's all wrong and point me in the right
direction.

A system-level test for this bug is being written here:
https://github.com/element-hq/element-web/issues/34034 but if you think
we should have one somewhere else, please let me know.

Closes https://github.com/element-hq/synapse/issues/19889

### Pull Request Checklist

* [x] Pull request is based on the develop branch
* [x] Pull request includes a [changelog
file](https://element-hq.github.io/synapse/latest/development/contributing_guide.html#changelog).
The entry should:
* [x] [Code
style](https://element-hq.github.io/synapse/latest/code_style.html) is
correct (run the
[linters](https://element-hq.github.io/synapse/latest/development/contributing_guide.html#run-the-linters))

Co-authored-by: Matthew <matthew@element.io>
2026-06-30 15:24:42 +02:00
Andrew MorganandGitHub 1639c30281 Fix the cargo-test and cargo-bench CI jobs not running (#19883) 2026-06-30 11:46:47 +00:00
Jason Robinson a460c285a7 Merge remote-tracking branch 'origin/develop' into anoa/msc4429 2026-06-29 21:58:15 +03:00
Jason Robinson 496728df15 Add docstrings to tests
Plus make a few tests actually do something sane..
2026-06-29 21:48:11 +03:00
Jason Robinson 2377165ebd Add test to prove initial sync doesn't include users updates who don't share a room 2026-06-29 16:33:36 +03:00
5edcb0f542 MSC4143: Advertise org.matrix.msc4143 in /versions unstable_features (#19646)
Closes #19580

---------

Co-authored-by: toonbr1me <toonbr1me@users.noreply.github.com>
2026-06-29 14:07:43 +01:00
Jason Robinson 60ed1758dc When user has left all rooms shared with a user, clear any previous profile updates
This ensures we don't accidentally leak any profile updates to users no longer sharing rooms.
2026-06-29 16:00:00 +03:00
Jason Robinson b0950f98df Merge remote-tracking branch 'origin/develop' into anoa/msc4429 2026-06-29 12:57:21 +03:00
Jason Robinson b459512725 Use include_profile_updates_in_sync config item instead of an experimental flag + alias.
The requirement for this comes from a customer commitment.
2026-06-26 18:08:12 +03:00
Will HuntandGitHub 2bb3aac839 Add metric to count number of non-deactivated users. (#19848)
This reports the total count of users (split by appservice) which is
meant to be the monthless counterpart to the MAU metric.

Context:

> So this is largely for billing purposes and wanting to know the change
in the number of users. If a user is deactivated then we no longer want
to count them. Consumers *might* want to count appservice users, and
maybe count them based on the service (perhaps you change more for users
under bridge X or bridge Y).
>
> *-- https://github.com/element-hq/synapse/pull/19848#discussion_r3402216234*
2026-06-25 11:57:36 -05:00
Jason Robinson 5f761ab5b4 Use set for uniqueness 2026-06-25 17:39:42 +03:00
Jason Robinson b657d2f8db Add a prune job for the profile updates stream tables
Taken and adapted from https://github.com/element-hq/synapse/pull/19473

Didn't add the "safety" table due to afaik that has more relevance with the device updates, and not so much here for the profile updates.
2026-06-24 19:11:41 +03:00
Jason Robinson 7c728ec61c Optimize profile handler user_joined_room and user_left_room
Save a db query if there are no users to add profile updates for.
2026-06-24 13:45:13 +03:00
Jason Robinson d3aacee235 Fix test_update_profile_set_field_writes_to_per_user_profile_tracking_table test
And remove unused `get_profile_updates_per_user_for_user` function
2026-06-24 13:32:19 +03:00
Jason Robinson 9d58d19934 Merge remote-tracking branch 'origin/develop' into anoa/msc4429 2026-06-24 11:52:58 +03:00
Jason Robinson 8504386b1f Send down full profile of user if user has joined during incremental sync
Also refactor the "user left" to not listen to the "user_left_room" dispatch hook since we only want to do this once, thus call the profile handler immediately in the instance responsible for receiving the event.
2026-06-23 16:44:39 +03:00
16fe5fb462 Expose MSC4354 Sticky Events over MSC4186 (Simplified) Sliding Sync. (#19591)
Follows: #19487
Part of: MSC4354 whose experimental feature tracking issue is #19409

This PR implements the Sliding Sync (MSC4186) extension described in
MSC4354, allowing sliding sync clients
to receive sticky events in a reliable way.

The logic is much the same as for oldschool sync (implementation in
#19487),
although in the sliding sync extension, the client can choose their own
limit
and must control their own pagination through an extra token in the
extension request/response bodies.

Note this does not yet send down existing sticky events in the
room when the room has been newly-joined.
This newly-discovered gap is tracked at #19662 and will be addressed for
both current sync and MSC4186 SSS soon.

---------

Signed-off-by: Olivier 'reivilibre <oliverw@matrix.org>
Co-authored-by: Eric Eastwood <erice@element.io>
2026-06-23 13:04:36 +00:00
Jason Robinson 2dbaec329b Send down a null when user has left all shared rooms
Restore test and switch from {} to null.
2026-06-23 15:37:35 +03:00
Jason Robinson 09e212537e Fix incremental lazy sync to send down profiles for users without profile updates
Remove the checking of any stream token changes and ensure we always collect profiles for users even if they have not done profile updates, if they have events in the timeline. Also fix the cache.
2026-06-23 14:53:33 +03:00
Stefan CeriuandGitHub 6d289f7ce0 Fix permanent badge inflation from read receipts before first rotation (#19785) 2026-06-23 11:31:32 +00:00
Jason Robinson 5819dccd91 Use a cache to ensure we don't re-send the full profile fields of users in every incremental sync all the time when lazy loading 2026-06-23 13:10:21 +03:00
Jason Robinson daa8d7a28d Ensure lazy loaded profile updates in sync contain full profiles for users in timeline 2026-06-23 12:39:07 +03:00
Jason Robinson 874dc359ac Merge remote-tracking branch 'origin/develop' into anoa/msc4429 2026-06-22 22:54:16 +03:00
Andrew Morgan ab9c917ca2 Remove test_incremental_sync_sends_down_null_profile_if_user_no_longer_sharing_rooms
We might just have clients do this instead (based on leave membership events).
2026-06-21 23:02:04 +01:00
Andrew Morgan 4a3fc09856 fix the tests 2026-06-21 22:53:29 +01:00
d3fc81974a MSC1763: Implement /_matrix/client/unstable/org.matrix.msc1763/retention/configuration (#19853)
Implements https://github.com/matrix-org/matrix-spec-proposals/pull/1763
Tracking issue https://github.com/element-hq/synapse/issues/19852

This only implements the MSC's configuration endpoint and does not add
new configuration fields or options. The reason for including this is to
allow clients to run global retention against locally stored events, and
to be able to offer configuration UI.

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-18 17:37:02 +00:00
2487b31422 MSC4140: allow auth on management endpoints for delayed events (#19794)
Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-18 13:27:37 +00:00
FrenchGithubUserandGitHub 75ee23a16b feat: Include allowed_room_ids in the /summary client-server API response for rooms with restricted join rules, as required by Matrix 1.15. (#19762)
Currently the `/summary` endpoint on the client and federation APIs does
not include the allowed_room_ids field, that is present on the
/hierarchy API. This is required by the 1.15 spec and this is what this
PR does.

Complement test: https://github.com/matrix-org/complement/pull/873

Part of https://github.com/element-hq/synapse/issues/18731
2026-06-18 14:12:51 +01:00
Olivier 'reivilibreandGitHub 2d06667661 Fix local events being deleted despite delete_local_events=False in room versions other than 1 and 2. (#19850)
Not aware of an open ticket for this.

I came across it when I accidentally broke the feature even more (as
part of another piece of work),
then discovered there weren't tests for this.

So this is overall a low-priority drive-by fix.

Requires a fix to SyTest https://github.com/matrix-org/sytest/pull/1426
(as it depended on the bug).

<ol>
<li>

Add a test for purging rooms with `delete_local_events=False` \
Parameterised by room version, this test currently succeeds
on v2 but fails on v12.

This is because the condition checking for local events relies
on the old event ID format, which has not been used since v2.


</li>
<li>

Fix delete_local_events=False for room versions above v2 \
The event ID format changing means that we have to rely on `sender`
to know the origin of an event


</li>
</ol>

---------

Signed-off-by: Olivier 'reivilibre <oliverw@matrix.org>
2026-06-17 11:03:59 +01:00
1b7807ae6b Fix /sync caching transient errors for the sync_response_cache_duration. (#19845)
Fixes: #19844

Concretely, this changes `ResponseCache` to unset cache entries once
they resolve to a `Failure`.

---------

Signed-off-by: Olivier 'reivilibre <oliverw@matrix.org>
Co-authored-by: Eric Eastwood <erice@element.io>
2026-06-16 11:12:29 +01:00
d7e9a3ff83 Fix inflated notification counts after /purge_history (#19834)
The sytest `After /purge_history users still get pushed for new
messages` is flaky. The flakiness exposes a real bug rather than a
test-timing issue.

Notification counts are stored in two places: `event_push_actions` (one
row per unread event) and `event_push_summary` (aggregate counts
populated periodically by `_rotate_notifs`, which runs on a 30-second
timer). `_purge_history_txn` deletes the purged events' rows from
`event_push_actions` but never adjusts `event_push_summary` (only the
full-room `purge_room` drops that table).

So the result depends on a race: if rotation hasn't fired, counts come
live from `event_push_actions`, the purge removes the right rows, and
the count is correct. If rotation fires before the purge — more likely
under the slower
multi-postgres/workers/asyncio CI config — the events get folded into
`event_push_summary`, the purge then deletes the underlying
`event_push_actions` rows but leaves the summary untouched, and the
count comes out inflated.

### Fix

Before deleting the rotated rows from `event_push_actions`, decrement
`event_push_summary` by the amount attributable to the events being
deleted. The decrement mirrors the counting logic in
`_rotate_notifs_before_txn`: only rows that were already rotated
(`stream_ordering <= event_push_summary_stream_ordering`) and that fall
after the summary's receipt are subtracted, so it stays correct in the
presence of read receipts and unread/highlight rows. The SQL avoids
`UPDATE ... FROM` and CTEs so it works on both SQLite and Postgres.
End-of-purge cache invalidation already covers
`get_unread_event_push_actions_by_room_for_user`.

### Tests

Adds `test_count_aggregation_after_purge`, which forces a rotation
before purging and asserts the aggregate count reflects only the
surviving events, covering read receipts and a subsequent re-rotation.
It fails (`3 != 1`) without the fix.

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 16:31:26 +01:00
Eric EastwoodandGitHub d11b012a81 Force keyword-args for clear default_config(server_name="test") usage (#19849)
I.e. `default_config("test")` and `default_config("test", False)` are so
opaque and hard to connect the dots with.

Spawning from trying to figure out what the `server_name` is set as for
our `HomeserverTestCase` in order to reference it in
https://github.com/element-hq/synapse/pull/19848#discussion_r3397455309
2026-06-12 09:45:22 -05:00
ff034c1f62 Fix flakey test failing with "twisted.protocols.amp.TooLong" (#19832)
This was all done through claude.

## Fix flaky `test_edu_large_messages_not_splitting_one_user` (`TooLong`
under `trial -jN`)

  ### Problem

  The "Build .deb packages" CI step intermittently failed with:

  ```
  twisted.protocols.amp.TooLong
...in
tests.rest.client.test_sendtodevice.SendToDeviceTestCase.test_edu_large_messages_not_splitting_one_user
  ```

The deb build runs the suite with `twisted.trial -j2`. In that mode,
worker log events are shipped to the manager process over Twisted's AMP
protocol, which encodes each value with a 2-byte length prefix — so any
single log line of **64 KiB or more** raises `TooLong`.

  ### Root cause

Not a bug in the to-device/EDU logic, and **not** debug logging enabled
by the build (it runs at the default `ERROR` level). It's a **log-level
leak between tests sharing a `-j2` worker**:

- `tests/logging/test_loggers.py::ExplicitlyConfiguredLoggerTestCase`
calls `root_logger.setLevel(logging.DEBUG)` directly and never restores
it (no `setUp`/`tearDown`/`addCleanup`).
- When that test runs before
`test_edu_large_messages_not_splitting_one_user` **in the same worker
process**, the root logger is left at `DEBUG`.
- That test deliberately builds an EDU of exactly `SOFT_MAX_EDU_SIZE -
1` (65 535) bytes. Storing it triggers `synapse/storage/database.py`'s
`[SQL values]` DEBUG log, which dumps the full query params — producing
a **65 708-byte**
  line that overflows AMP's cap.
  
It looks "flaky" purely because of `-j2` scheduling: whether the two
tests land on the same worker, and in what order.
  
  ### Fix

  Three commits:

1. **Restore the root logger level in
`ExplicitlyConfiguredLoggerTestCase`** — `addCleanup` to put the level
back. Fixes the root cause.
2. **Truncate oversized log lines in the test log handler**
(`ToTwistedHandler.emit`) — caps lines at 1000 chars so no debug line
can break `trial -jN`, regardless of which query is logged (defense in
depth).
3. **Truncate values in `[SQL values]` debug logging** — caps the logged
param repr at 1000 chars (guarded by `isEnabledFor(DEBUG)` to keep the
hot path lazy). Keeps production debug logs sane too.

  ### Testing

- The reproduction (`trial -j2 tests.logging.test_loggers <the EDU
test>`) went from **~3/8 failing** to **10/10 passing**.
- Confirmed the root level is restored after the logging tests, and that
the `[SQL values]` line is now capped (~50 KB with a `[truncated]`
marker, was 65 708).
- `ruff` + `mypy` clean; `tests.logging.test_loggers` and
`tests.rest.client.test_sendtodevice` pass (14/14).

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Eric Eastwood <erice@element.io>
2026-06-10 17:33:21 +01:00
Erik JohnstonandGitHub ac21bf08f3 Port Requester class to Rust. (#19828)
This is in prep for converting the event serialization to Rust.

This is a fairly mechanical port, except that we store the appservice ID
rather than the appservice object. This avoids us having to store a
`Py<..>` (or port the appservice object over).
2026-06-09 10:26:04 +01:00
8c9b1ff877 Reintroduce #19714 - Send a SSS response immediately if the config has changed (#19792)
Reintroduces #19714, after being reverted in #19784.

Fix https://github.com/element-hq/synapse/issues/18844
Fix https://github.com/element-hq/synapse/issues/19783
Fix https://github.com/element-hq/synapse/issues/18880

This PR also adds a fix so that we don't always return immediately when
using the e2ee extension.

---------

Co-authored-by: Benjamin Bouvier <benjamin@bouvier.cc>
Co-authored-by: Eric Eastwood <madlittlemods@gmail.com>
Co-authored-by: Eric Eastwood <erice@element.io>
2026-06-08 11:42:57 +01:00
Jason Robinson e90096ef57 Use a "per user profile updates" tracking table
This makes writes heavier when profile updates happen, but reduces the effort to produce an incremental sync response by not needing to look whether users share rooms.
2026-06-05 19:17:12 +03:00
Jason Robinson 877074f38e Lint tests/handlers/test_sync.py 2026-06-05 15:30:23 +03:00
Jason Robinson 28587d7907 Fix the lazy loading test cases 2026-06-05 13:49:27 +03:00
Jason Robinson 2d9f943034 Collect lazy loaded members for profile updates in sync response from events 2026-06-04 22:04:41 +03:00
Jason Robinson 36f0f64f62 Add "action" to profile updates stream
This allows distinguishing between "a field was updated" or "something else happened". In this case, we want to know if the user left a room. Seeing this action while building the sync response we can then check if the user is still a member of the same rooms as the syncing user, and if not, we can tell the client to remove their profile.
2026-06-04 11:26:50 +03:00
Noah MarkertandGitHub 003febe399 Add tests to ensure that email notification links are sanitized (#19741)
Fix #2860

Also cleans up comments around plans to define `ALLOWED_SCHEMES` as we can rely on Bleach's `ALLOWED_PROTOCOLS` defaults (`http`, `https`  and `mailto`).
2026-06-03 17:36:58 -05:00
Jason Robinson b61f748928 Fix some broken tests due to sync token changes 2026-06-03 18:08:36 +03:00
Erik JohnstonandGitHub e8e5a42180 Fix parsing events that have large integers (#19819)
Follow on from https://github.com/element-hq/synapse/pull/19701.

Unfortunately serde has a bug when using `#[serde(flatten)]` with
`arbitrary-precision` feature when handling integers that fit in a i128
when doing `serde_json::from_value`. See
https://github.com/serde-rs/serde/issues/2230.

The `depythonize` hits the same issue. To fix this we make it so we only
parse events from strings and not values.
2026-06-03 14:52:05 +01:00
Jason Robinson bd40add5d5 Add some tests for profile handler updating profile_updates stream table and waking up notifiers 2026-06-03 13:55:22 +03:00
Jason Robinson e236ddb32b Add SyncProfileUpdatesTestCase
For initial sync
2026-06-02 21:35:34 +03:00