Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
75 changes: 75 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# This file is adapted from the same file in element-hq/synapse:
# https://github.com/element-hq/synapse/blob/2e9b8202f0a1a8ceba9f02bb5ec227498d51dcbd/.github/dependabot.yml
# But updated to remove `pip` and `cargo` ecosystems, and introduce `gomod`.
version: 2
# As dependabot is currently only run on a weekly basis, we raise the
# open-pull-requests-limit to 10 (from the default of 5) to better ensure we
# don't continuously grow a backlog of updates.
updates:
- package-ecosystem: "gomod"
directory: "/"
open-pull-requests-limit: 10
schedule:
interval: "weekly"
# Group patch updates to packages together into a single PR, as they rarely
# if ever contain breaking changes that need to be reviewed separately.
#
# Less PRs means a streamlined review process.
#
# The Go ecosystem is special in that breaking changes are often introduced
# in minor version bumps, as packages typically stay pre-1.0 for a long time.
# Thus we specifically keep minor version bumps separate in their own PRs.
groups:
minor-and-patches:
applies-to: version-updates
patterns:
- "*"
update-types:
- "minor"
- "patch"
# Prevent pulling packages that were recently updated to help mitigate
# supply chain attacks. 14 days was taken from the recommendation at
# https://blog.yossarian.net/2025/11/21/We-should-all-be-using-dependency-cooldowns
# where the author noted that 9/10 attacks would have been mitigated by a
# two week cooldown.
#
# The cooldown only applies to general updates; security updates will still
# be pulled in as soon as possible.
cooldown:
default-days: 14

- package-ecosystem: "docker"
directory: "/complement/cmd/homerunner"
open-pull-requests-limit: 10
schedule:
interval: "weekly"
# For container versions, breaking changes are also typically only introduced in major
# package bumps.
groups:
minor-and-patches:
applies-to: version-updates
patterns:
- "*"
update-types:
- "minor"
- "patch"
cooldown:
default-days: 14

- package-ecosystem: "github-actions"
directory: "/"
open-pull-requests-limit: 10
schedule:
interval: "weekly"
# Similarly for GitHub Actions, breaking changes are typically only introduced in major
# package bumps.
groups:
minor-and-patches:
applies-to: version-updates
patterns:
- "*"
update-types:
- "minor"
- "patch"
cooldown:
default-days: 14
8 changes: 4 additions & 4 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ jobs:
complement-internal:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3 # Checkout complement
- uses: actions/setup-go@v4
- uses: actions/checkout@v6 # Checkout complement
- uses: actions/setup-go@v6
with:
go-version-file: go.mod
- name: "Run internal Complement tests"
Expand Down Expand Up @@ -50,9 +50,9 @@ jobs:
timeout: 10m

steps:
- uses: actions/checkout@v3 # Checkout complement
- uses: actions/checkout@v6 # Checkout complement

- uses: actions/setup-go@v4
- uses: actions/setup-go@v6
with:
go-version-file: go.mod

Expand Down
34 changes: 30 additions & 4 deletions client/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,11 @@ func SyncTimelineHasEventID(roomID string, eventID string) SyncCheckOpt {
})
}

// Check that the state section for `roomID` has an event which passes the check function.
// Note that the state section of a sync response only contains the change in state up to the start
// of the timeline and will not contain the entire state of the room for incremental or
// `lazy_load_members` syncs.
// Check that the `state` section for `roomID` has an event which passes the check function.
//
// Note that the `state` section of a sync response only contains the change in state up
// to the start of the `timeline` and will not contain the entire state of the room for
// incremental or `lazy_load_members` syncs.
func SyncStateHas(roomID string, check func(gjson.Result) bool) SyncCheckOpt {
return func(clientUserID string, topLevelSyncJSON gjson.Result) error {
err := checkArrayElements(
Expand All @@ -231,6 +232,31 @@ func SyncStateHas(roomID string, check func(gjson.Result) bool) SyncCheckOpt {
}
}

// Check that the `state_after` section for `roomID` has an event which passes the check function.
//
// Note that the `state_after` section of a sync response will not contain the entire
// state of the room for incremental or `lazy_load_members` syncs.
func SyncStateAfterHas(roomID string, check func(gjson.Result) bool) SyncCheckOpt {
return func(clientUserID string, topLevelSyncJSON gjson.Result) error {
// Check the stable field
errStable := checkArrayElements(
topLevelSyncJSON, "rooms.join."+GjsonEscape(roomID)+".state_after.events", check,
)
// Check the unstable field
//
// FIXME: Some implementations haven't stabilized yet (Synapse) so we'll keep this
// here until then.
errUnstable := checkArrayElements(
topLevelSyncJSON, "rooms.join."+GjsonEscape(roomID)+"."+GjsonEscape("org.matrix.msc4222.state_after")+".events", check,
)
// Valid to find it in either place
if errStable == nil || errUnstable == nil {
return nil
}
return fmt.Errorf("SyncStateAfterHas(%s): Tried to check in the stable field: %s - and unstable field: %s", roomID, errStable, errUnstable)
}
}

func SyncEphemeralHas(roomID string, check func(gjson.Result) bool) SyncCheckOpt {
return func(clientUserID string, topLevelSyncJSON gjson.Result) error {
err := checkArrayElements(
Expand Down
23 changes: 14 additions & 9 deletions federation/server_room.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,15 +333,20 @@ func InitialRoomEvents(roomVer gomatrixserverlib.RoomVersion, creator string) []
Type: "m.room.create",
StateKey: b.Ptr(""),
Sender: creator,
Content: map[string]interface{}{
"creator": creator,
"room_version": roomVer,
// We have to add randomness to the create event, else if you create 2x v12+ rooms in the same millisecond
// they will get the same room ID, clobbering internal data structures and causing extremely confusing
// behaviour. By adding this entropy, we ensure that even if rooms are created in the same millisecond, their
// hashes will not be the same.
"complement_entropy": util.RandomString(18),
},
Content: func() map[string]interface{} {
content := map[string]interface{}{
"room_version": roomVer,
// We have to add randomness to the create event, else if you create 2x v12+ rooms in the same millisecond
// they will get the same room ID, clobbering internal data structures and causing extremely confusing
// behaviour. By adding this entropy, we ensure that even if rooms are created in the same millisecond, their
// hashes will not be the same.
"complement_entropy": util.RandomString(18),
}
if gomatrixserverlib.MustGetRoomVersion(gomatrixserverlib.RoomVersion(roomVer)).CreatorInCreateEvent() {
content["creator"] = creator
}
return content
}(),
},
{
Type: "m.room.member",
Expand Down
39 changes: 20 additions & 19 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,49 +1,51 @@
module github.com/matrix-org/complement

go 1.24.0

toolchain go1.24.3
go 1.25.0

require (
github.com/docker/docker v28.0.4+incompatible
github.com/docker/go-connections v0.4.0
github.com/gorilla/mux v1.8.0
github.com/docker/docker v28.5.2+incompatible
github.com/docker/go-connections v0.6.0
github.com/gorilla/mux v1.8.1
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530
github.com/matrix-org/gomatrixserverlib v0.0.0-20250813150445-9f5070a65744
github.com/matrix-org/gomatrixserverlib v0.0.0-20260506075950-c9c468727353
github.com/matrix-org/util v0.0.0-20221111132719-399730281e66
github.com/sirupsen/logrus v1.9.3
github.com/sirupsen/logrus v1.9.4
github.com/tidwall/gjson v1.18.0
github.com/tidwall/sjson v1.2.5
golang.org/x/crypto v0.45.0
golang.org/x/crypto v0.49.0
golang.org/x/exp v0.0.0-20230905200255-921286631fa9
gonum.org/v1/plot v0.11.0
gonum.org/v1/plot v0.16.0
)

require (
git.sr.ht/~sbinet/gg v0.3.1 // indirect
codeberg.org/go-fonts/liberation v0.5.0 // indirect
codeberg.org/go-latex/latex v0.1.0 // indirect
codeberg.org/go-pdf/fpdf v0.10.0 // indirect
git.sr.ht/~sbinet/gg v0.6.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/Microsoft/go-winio v0.5.2 // indirect
github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b // indirect
github.com/campoy/embedmd v1.0.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/containerd/errdefs v1.0.0 // indirect
github.com/containerd/errdefs/pkg v0.3.0 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/distribution/reference v0.6.0 // indirect
github.com/docker/go-units v0.4.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/go-fonts/liberation v0.2.0 // indirect
github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-pdf/fpdf v0.6.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/hashicorp/go-set/v3 v3.0.0 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/sys/atomicwriter v0.1.0 // indirect
github.com/moby/term v0.0.0-20210610120745-9d4ed1856297 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/oleiade/lane/v2 v2.0.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
Expand All @@ -53,10 +55,9 @@ require (
go.opentelemetry.io/otel/metric v1.40.0 // indirect
go.opentelemetry.io/otel/sdk v1.40.0 // indirect
go.opentelemetry.io/otel/trace v1.40.0 // indirect
golang.org/x/image v0.18.0 // indirect
golang.org/x/net v0.47.0 // indirect
golang.org/x/sys v0.40.0 // indirect
golang.org/x/text v0.31.0 // indirect
golang.org/x/image v0.25.0 // indirect
golang.org/x/sys v0.42.0 // indirect
golang.org/x/text v0.35.0 // indirect
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
gotest.tools/v3 v3.0.3 // indirect
)
Loading
Loading