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>
This commit is contained in:
Andy Balaam
2026-06-30 21:20:26 +00:00
committed by GitHub
co-authored by Matthew Hodgson
parent fd8f0e53a3
commit aa97687305
3 changed files with 38 additions and 8 deletions
+1
View File
@@ -0,0 +1 @@
Change the [MSC3814](https://github.com/matrix-org/matrix-spec-proposals/pull/3814) dehydrated device `/events` endpoint from `POST` to `GET`.
+33
View File
@@ -33,6 +33,7 @@ from synapse.http.servlet import (
RestServlet,
parse_and_validate_json_object_from_request,
parse_integer,
parse_string,
)
from synapse.http.site import SynapseRequest
from synapse.rest.client._base import client_patterns, interactive_auth_handler
@@ -249,17 +250,49 @@ class DehydratedDeviceEventsServlet(RestServlet):
self.auth = hs.get_auth()
self.store = hs.get_datastores().main
async def on_GET(
self, request: SynapseRequest, device_id: str
) -> tuple[int, JsonDict]:
requester = await self.auth.get_user_by_req(request)
next_batch = parse_string(request, "next_batch")
limit = parse_integer(request, "limit", 100)
msgs = await self.message_handler.get_events_for_dehydrated_device(
requester=requester,
device_id=device_id,
since_token=next_batch,
limit=limit,
)
return 200, msgs
class PostBody(RequestBodyModel):
"""
This is deprecated: you should use GET instead.
The POST version is provided temporarily for backwards compatibility
with a previous unstable draft of MSC3814.
"""
next_batch: StrictStr | None = None
async def on_POST(
self, request: SynapseRequest, device_id: str
) -> tuple[int, JsonDict]:
"""
This is deprecated: you should use GET instead.
The POST version is provided temporarily for backwards compatibility
with a previous unstable draft of MSC3814.
"""
requester = await self.auth.get_user_by_req(request)
next_batch = parse_and_validate_json_object_from_request(
request, self.PostBody
).next_batch
limit = parse_integer(request, "limit", 100)
msgs = await self.message_handler.get_events_for_dehydrated_device(
+4 -8
View File
@@ -224,9 +224,8 @@ class DehydratedDeviceTestCase(unittest.HomeserverTestCase):
# make sure we can fetch the message with our dehydrated device id
channel = self.make_request(
"POST",
"GET",
f"_matrix/client/unstable/org.matrix.msc3814.v1/dehydrated_device/{device_id}/events",
content={},
access_token=token,
shorthand=False,
)
@@ -236,9 +235,8 @@ class DehydratedDeviceTestCase(unittest.HomeserverTestCase):
# fetch messages again and make sure that the message was not deleted
channel = self.make_request(
"POST",
"GET",
f"_matrix/client/unstable/org.matrix.msc3814.v1/dehydrated_device/{device_id}/events",
content={},
access_token=token,
shorthand=False,
)
@@ -248,11 +246,9 @@ class DehydratedDeviceTestCase(unittest.HomeserverTestCase):
# make sure fetching messages with next batch token works - there are no unfetched
# messages so we should receive an empty array
content = {"next_batch": next_batch_token}
channel = self.make_request(
"POST",
f"_matrix/client/unstable/org.matrix.msc3814.v1/dehydrated_device/{device_id}/events",
content=content,
"GET",
f"_matrix/client/unstable/org.matrix.msc3814.v1/dehydrated_device/{device_id}/events?next_batch={next_batch_token}",
access_token=token,
shorthand=False,
)