Skip to content
Open
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
e5a5a87
Try to modify MSC4311 test to meet new proposal
turt2live Aug 15, 2025
d98aae0
Merge branch 'main' into travis/msc4311-v2
kegsay Oct 1, 2025
1faef0d
Merge branch 'main' into travis/msc4311-v2
MadLittleMods Apr 30, 2026
35dcccf
More robust test
MadLittleMods May 1, 2026
96b8d49
Add TODO about testing `knock_room_state`
MadLittleMods May 2, 2026
795a951
Fix raw bytes being encoded as `event` instead of actual JSON
MadLittleMods May 2, 2026
47474a0
Use more specific type
MadLittleMods May 4, 2026
25ced8b
WIP: Add `TestMSC4311CreateEventInStrippedStateClientApi`
MadLittleMods May 4, 2026
3256657
Use more robust `MustSyncUntil`
MadLittleMods May 4, 2026
cabb542
WIP: Add test for `invite_room_state` in client API
MadLittleMods May 4, 2026
7171d67
Remove `invite_room_state` client test
MadLittleMods May 4, 2026
18d6da2
Remove stray parallel
MadLittleMods May 4, 2026
5d61d01
Better casing
MadLittleMods May 4, 2026
9f29477
Merge branch 'main' into travis/msc4311-v2
MadLittleMods May 22, 2026
633c1a2
Add client `knock_state` test
MadLittleMods May 22, 2026
55df04e
Add `knock_room_state` test (`MustKnockRoom` not implemented)
MadLittleMods May 22, 2026
92cdd79
Implement `srv.MustKnockRoom`
MadLittleMods May 22, 2026
2523631
We're doing the TODO now
MadLittleMods May 22, 2026
b4ab892
Split up tests
MadLittleMods May 23, 2026
07c60fc
Add `TestMSC4311RejectInvalidStrippedStateFederation`
MadLittleMods May 26, 2026
4b044a1
Add note about this applying to other room versions
MadLittleMods May 27, 2026
9b3b3da
`satisfied` typo
MadLittleMods May 28, 2026
f3134ad
Fix `JSONArraySome` logic
MadLittleMods May 28, 2026
9f339a8
Merge branch 'main' into travis/msc4311-v2
MadLittleMods Jul 9, 2026
9500eb0
Fix `serverNames` arg docstring typo
MadLittleMods Jul 9, 2026
d9972aa
Fix markdown syntax typo in comment
MadLittleMods Jul 9, 2026
15d86d1
Fix `room` plural typo
MadLittleMods Jul 9, 2026
8e23350
Clarify why run later "to allow some time for the ecosystem to adapt …
MadLittleMods Jul 9, 2026
f011b88
Cross-link https://github.com/element-hq/synapse/issues/19943
MadLittleMods Jul 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 40 additions & 25 deletions tests/v12_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1357,39 +1357,54 @@ func asEventIDs(pdus []gomatrixserverlib.PDU) []string {
return eventIDs
}

func TestMSC4311FullCreateEventOnStrippedState(t *testing.T) {
func TestMSC4311FullEventsOnStrippedStateFederation(t *testing.T) {
Comment thread
MadLittleMods marked this conversation as resolved.
runtime.SkipIf(t, runtime.Dendrite) // does not implement it yet
deployment := complement.Deploy(t, 2)
deployment := complement.Deploy(t, 1)
defer deployment.Destroy(t)
srv := federation.NewServer(t, deployment,
federation.HandleKeyRequests(),
federation.HandleMakeSendJoinRequests(),
federation.HandleTransactionRequests(nil, nil),
federation.HandleEventRequests(),
)
srv.UnexpectedRequestsAreErrors = false
cancel := srv.Listen()
defer cancel()

// Alice will invite Bob. Bob's server should receive full PDUs in `invite_room_state`.
alice := deployment.Register(t, "hs1", helpers.RegistrationOpts{LocalpartSuffix: "alice"})
local := deployment.Register(t, "hs1", helpers.RegistrationOpts{LocalpartSuffix: "local"})
remote := deployment.Register(t, "hs2", helpers.RegistrationOpts{LocalpartSuffix: "remote"})
bob := srv.UserID("bob")

roomID := alice.MustCreateRoom(t, map[string]interface{}{
"room_version": roomVersion12,
"preset": "public_chat",
})
for _, target := range []*client.CSAPI{local, remote} {
t.Logf("checking %s", target.UserID)
alice.MustInviteRoom(t, roomID, target.UserID)
resp, _ := target.MustSync(t, client.SyncReq{})
inviteState := resp.Get(
fmt.Sprintf("rooms.invite.%s.invite_state.events", client.GjsonEscape(roomID)),
)
must.NotEqual(t, len(inviteState.Array()), 0, "no events in invite_state")
// find the create event
found := false
for _, ev := range inviteState.Array() {
if ev.Get("type").Str == spec.MRoomCreate {
found = true
// we should have extra fields
must.MatchGJSON(t, ev,
match.JSONKeyPresent("origin_server_ts"),
)
srv.Mux().HandleFunc("/_matrix/federation/v2/invite/{roomID}/{eventID}", srv.ValidFederationRequest(t, func(fr *fclient.FederationRequest, pathParams map[string]string) util.JSONResponse {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should be able to alternatively use:

	srv := federation.NewServer(t, deployment,
		federation.HandleInviteRequests(func(p gomatrixserverlib.PDU) {
			// checks here
		}),
		federation.HandleKeyRequests(),
		federation.HandleMakeSendJoinRequests(),
		federation.HandleTransactionRequests(nil, nil),
	)

@MadLittleMods MadLittleMods May 1, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went down this route but the problem is that federation.HandleInviteRequests(...) doesn't allow you to inspect the invite_room_state yet. It would have to be updated to pass in the full invite request to the callback.

And gomatrixserverlib needs to be updated to handle the new world where invite_room_state can be stripped state or full PDUs.

We could have an infallible InviteV2Request.StrippedInviteRoomState() that would give a view of stripped state regardless of whether we were passed stripped or full PDU's (we can derive stripped state from the full PDU's). And then a fallible InviteV2Request.FullInviteRoomState() that would return an error if the homeserver didn't pass us full PDUs.

We would also need to update IRoomVersion to add new fields like CreateEventRequiredInInviteRoomState and FullPDUInviteRoomState (full PDU's can happen in any room version) so we can conditionally apply this behavior. Or maybe the flags could be combined as MSC4311InviteRoomState

If any of the events are not a PDU, not for the room ID specified, or fail signature checks, or the m.room.create event is missing, the receiving server MAY respond to invites with a 400 M_MISSING_PARAM standard Matrix error (new to the endpoint). For invites to room version 12+ rooms, servers SHOULD rather than MAY respond to such requests with 400 M_MISSING_PARAM.

-- matrix-org/matrix-spec-proposals#4311

if pathParams["roomID"] != roomID {
t.Errorf("Received /invite_room_state for the wrong room: %s", roomID)
return util.JSONResponse{
Code: 400,
JSON: "wrong room",
}
}
if !found {
ct.Errorf(t, "failed to find create event in invite_state")
inviteRoomState := gjson.ParseBytes(fr.Content()).Get("invite_room_state").Array()
for _, ev := range inviteRoomState {
// should have extra fields
must.MatchGJSON(t, ev, match.JSONKeyPresent("origin_server_ts"))
}
}

invite := []byte(gjson.ParseBytes(fr.Content()).Get("event").Raw)
signed, err := gomatrixserverlib.SignJSON(string(srv.ServerName()), srv.KeyID, srv.Priv, invite)
if err != nil {
t.Fatalf("failed to sign invite: %s", err)
}
return util.JSONResponse{
Code: 200,
JSON: struct {
Event any `json:"event"`
}{
Event: signed,
},
}
}))
alice.MustInviteRoom(t, roomID, bob)
}
Loading