summary refs log tree commit diff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--flake.lock92
-rwxr-xr-xflake.nix4
-rw-r--r--host/Rory-nginx/services/matrix/synapse/workers/event-creator.nix1
-rw-r--r--packages/overlays/matrix-synapse/patches/0001-Fast-auth-links.patch2
-rw-r--r--packages/overlays/matrix-synapse/patches/0002-Hotfix-ignore-rejected-events-in-delayed_events.patch2
-rw-r--r--packages/overlays/matrix-synapse/patches/0003-Add-too-much-logging-to-room-summary-over-federation.patch2
-rw-r--r--packages/overlays/matrix-synapse/patches/0004-Log-entire-room-if-accessibility-check-fails.patch2
-rw-r--r--packages/overlays/matrix-synapse/patches/0005-Log-policy-server-rejected-events.patch2
-rw-r--r--packages/overlays/matrix-synapse/patches/0006-Use-parse_boolean-for-unredacted-content.patch2
-rw-r--r--packages/overlays/matrix-synapse/patches/0007-Expose-tombstone-in-room-admin-api.patch2
-rw-r--r--packages/overlays/matrix-synapse/patches/0008-fix-Always-recheck-messages-pagination-data-if-a-bac.patch2
-rw-r--r--packages/overlays/matrix-synapse/patches/0009-Fix-pagination-with-large-gaps-of-rejected-events.patch2
-rw-r--r--packages/overlays/matrix-synapse/patches/0010-Fix-nix-flake.patch2
-rw-r--r--packages/overlays/matrix-synapse/patches/0011-Fix-gitignore-to-ignore-.venv.patch2
-rw-r--r--packages/overlays/matrix-synapse/patches/0012-Devenv-use-postgres-17.patch24
-rw-r--r--packages/overlays/matrix-synapse/patches/0013-RequestRatelimiter-expose-can_do_action.patch95
-rw-r--r--packages/overlays/matrix-synapse/patches/0014-Add-bulk-send-events-endpoint.patch187
17 files changed, 366 insertions, 59 deletions
diff --git a/flake.lock b/flake.lock

index a2d8e37..f0c3b8e 100644 --- a/flake.lock +++ b/flake.lock
@@ -20,11 +20,11 @@ ] }, "locked": { - "lastModified": 1742213273, - "narHash": "sha256-0l0vDb4anfsBu1rOs94bC73Hub+xEivgBAo6QXl2MmU=", + "lastModified": 1752936381, + "narHash": "sha256-b191B12GRfvOT3odGpx5IFyGRPZbBrvCLADZfFHoJFg=", "owner": "hyprwm", "repo": "aquamarine", - "rev": "484b732195cc53f4536ce4bd59a5c6402b1e7ccf", + "rev": "141a991678b34e768f09b3a670c61a4c1d5d7110", "type": "github" }, "original": { @@ -590,16 +590,16 @@ ] }, "locked": { - "lastModified": 1743128724, - "narHash": "sha256-CUlxc2u1Y8gpeAl7NKrZxxpeZjyU2DBxOYb8b0haM2M=", + "lastModified": 1752830283, + "narHash": "sha256-1BTJSqkj+lkIry27HuqA5UB7uRqAUvGT7LAUDQhKjU0=", "owner": "outfoxxed", "repo": "hy3", - "rev": "4014433d1c3d1bf36c6684cff14c23d538337070", + "rev": "d61a2eb9b9f22c6e46edad3e8f5fbd3578961b11", "type": "github" }, "original": { "owner": "outfoxxed", - "ref": "hl0.48.0", + "ref": "hl0.50.0", "repo": "hy3", "type": "github" } @@ -620,11 +620,11 @@ ] }, "locked": { - "lastModified": 1742215578, - "narHash": "sha256-zfs71PXVVPEe56WEyNi2TJQPs0wabU4WAlq0XV7GcdE=", + "lastModified": 1749155331, + "narHash": "sha256-XR9fsI0zwLiFWfqi/pdS/VD+YNorKb3XIykgTg4l1nA=", "owner": "hyprwm", "repo": "hyprcursor", - "rev": "2fd36421c21aa87e2fe3bee11067540ae612f719", + "rev": "45fcc10b4c282746d93ec406a740c43b48b4ef80", "type": "github" }, "original": { @@ -649,11 +649,11 @@ ] }, "locked": { - "lastModified": 1739049071, - "narHash": "sha256-3+7TpXMrbsUXSwgr5VAKAnmkzMb6JO+Rvc9XRb5NMg4=", + "lastModified": 1752149140, + "narHash": "sha256-gbh1HL98Fdqu0jJIWN4OJQN7Kkth7+rbkFpSZLm/62A=", "owner": "hyprwm", "repo": "hyprgraphics", - "rev": "175c6b29b6ff82100539e7c4363a35a02c74dd73", + "rev": "340494a38b5ec453dfc542c6226481f736cc8a9a", "type": "github" }, "original": { @@ -678,17 +678,17 @@ "xdph": "xdph" }, "locked": { - "lastModified": 1743178567, - "narHash": "sha256-skuJFly6LSFfyAVy2ByNolkEwIijsTu2TxzQ9ugWarI=", - "ref": "refs/tags/v0.48.1", - "rev": "29e2e59fdbab8ed2cc23a20e3c6043d5decb5cdc", - "revCount": 5937, + "lastModified": 1752961026, + "narHash": "sha256-ALp/WkfOfXMScwytTmjxpjRNmbezrgFQdEX6n3py7L8=", + "ref": "refs/tags/v0.50.1", + "rev": "4e242d086e20b32951fdc0ebcbfb4d41b5be8dcc", + "revCount": 6291, "submodules": true, "type": "git", "url": "https://github.com/hyprwm/Hyprland" }, "original": { - "ref": "refs/tags/v0.48.1", + "ref": "refs/tags/v0.50.1", "submodules": true, "type": "git", "url": "https://github.com/hyprwm/Hyprland" @@ -706,11 +706,11 @@ ] }, "locked": { - "lastModified": 1738422629, - "narHash": "sha256-5v+bv75wJWvahyM2xcMTSNNxmV8a7hb01Eey5zYnBJw=", + "lastModified": 1749046714, + "narHash": "sha256-kymV5FMnddYGI+UjwIw8ceDjdeg7ToDVjbHCvUlhn14=", "owner": "hyprwm", "repo": "hyprland-protocols", - "rev": "755aef8dab49d0fc4663c715fa4ad221b2aedaed", + "rev": "613878cb6f459c5e323aaafe1e6f388ac8a36330", "type": "github" }, "original": { @@ -738,11 +738,11 @@ ] }, "locked": { - "lastModified": 1737634706, - "narHash": "sha256-nGCibkfsXz7ARx5R+SnisRtMq21IQIhazp6viBU8I/A=", + "lastModified": 1749154592, + "narHash": "sha256-DO7z5CeT/ddSGDEnK9mAXm1qlGL47L3VAHLlLXoCjhE=", "owner": "hyprwm", "repo": "hyprland-qt-support", - "rev": "8810df502cdee755993cb803eba7b23f189db795", + "rev": "4c8053c3c888138a30c3a6c45c2e45f5484f2074", "type": "github" }, "original": { @@ -774,11 +774,11 @@ ] }, "locked": { - "lastModified": 1739048983, - "narHash": "sha256-REhTcXq4qs3B3cCDtLlYDz0GZvmsBSh947Ub6pQWGTQ=", + "lastModified": 1750371812, + "narHash": "sha256-D868K1dVEACw17elVxRgXC6hOxY+54wIEjURztDWLk8=", "owner": "hyprwm", "repo": "hyprland-qtutils", - "rev": "3504a293c8f8db4127cb0f7cfc1a318ffb4316f8", + "rev": "b13c7481e37856f322177010bdf75fccacd1adc8", "type": "github" }, "original": { @@ -803,11 +803,11 @@ ] }, "locked": { - "lastModified": 1741191527, - "narHash": "sha256-kM+11Nch47Xwfgtw2EpRitJuORy4miwoMuRi5tyMBDY=", + "lastModified": 1750371198, + "narHash": "sha256-/iuJ1paQOBoSLqHflRNNGyroqfF/yvPNurxzcCT0cAE=", "owner": "hyprwm", "repo": "hyprlang", - "rev": "72df3861f1197e41b078faa3e38eedd60e00018d", + "rev": "cee01452bca58d6cadb3224e21e370de8bc20f0b", "type": "github" }, "original": { @@ -828,11 +828,11 @@ ] }, "locked": { - "lastModified": 1741534688, - "narHash": "sha256-EV3945SnjOCuRVbGRghsWx/9D89FyshnSO1Q6/TuQ14=", + "lastModified": 1752252310, + "narHash": "sha256-06i1pIh6wb+sDeDmWlzuPwIdaFMxLlj1J9I5B9XqSeo=", "owner": "hyprwm", "repo": "hyprutils", - "rev": "dd1f720cbc2dbb3c71167c9598045dd3261d27b3", + "rev": "bcabcbada90ed2aacb435dc09b91001819a6dc82", "type": "github" }, "original": { @@ -853,11 +853,11 @@ ] }, "locked": { - "lastModified": 1739870480, - "narHash": "sha256-SiDN5BGxa/1hAsqhgJsS03C3t2QrLgBT8u+ENJ0Qzwc=", + "lastModified": 1751897909, + "narHash": "sha256-FnhBENxihITZldThvbO7883PdXC/2dzW4eiNvtoV5Ao=", "owner": "hyprwm", "repo": "hyprwayland-scanner", - "rev": "206367a08dc5ac4ba7ad31bdca391d098082e64b", + "rev": "fcca0c61f988a9d092cbb33e906775014c61579d", "type": "github" }, "original": { @@ -1207,11 +1207,11 @@ }, "nixpkgs_7": { "locked": { - "lastModified": 1742069588, - "narHash": "sha256-C7jVfohcGzdZRF6DO+ybyG/sqpo1h6bZi9T56sxLy+k=", + "lastModified": 1752687322, + "narHash": "sha256-RKwfXA4OZROjBTQAl9WOZQFm7L8Bo93FQwSJpAiSRvo=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "c80f6a7e10b39afcc1894e02ef785b1ad0b0d7e5", + "rev": "6e987485eb2c77e5dcc5af4e3c70843711ef9251", "type": "github" }, "original": { @@ -1281,11 +1281,11 @@ ] }, "locked": { - "lastModified": 1742058297, - "narHash": "sha256-b4SZc6TkKw8WQQssbN5O2DaCEzmFfvSTPYHlx/SFW9Y=", + "lastModified": 1750779888, + "narHash": "sha256-wibppH3g/E2lxU43ZQHC5yA/7kIKLGxVEnsnVK1BtRg=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "59f17850021620cd348ad2e9c0c64f4e6325ce2a", + "rev": "16ec914f6fb6f599ce988427d9d94efddf25fe6d", "type": "github" }, "original": { @@ -1545,11 +1545,11 @@ ] }, "locked": { - "lastModified": 1741934139, - "narHash": "sha256-ZhTcTH9FoeAtbPfWGrhkH7RjLJZ7GeF18nygLAMR+WE=", + "lastModified": 1751300244, + "narHash": "sha256-PFuv1TZVYvQhha0ac53E3YgdtmLShrN0t4T6xqHl0jE=", "owner": "hyprwm", "repo": "xdg-desktop-portal-hyprland", - "rev": "150b0b6f52bb422a1b232a53698606fe0320dde0", + "rev": "6115f3fdcb2c1a57b4a80a69f3c797e47607b90a", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix
index 675a614..d38e272 100755 --- a/flake.nix +++ b/flake.nix
@@ -102,9 +102,9 @@ flake = false; }; - hyprland.url = "git+https://github.com/hyprwm/Hyprland?submodules=1&ref=refs/tags/v0.48.1"; + hyprland.url = "git+https://github.com/hyprwm/Hyprland?submodules=1&ref=refs/tags/v0.50.1"; hy3 = { - url = "github:outfoxxed/hy3?ref=hl0.48.0"; + url = "github:outfoxxed/hy3?ref=hl0.50.0"; inputs.hyprland.follows = "hyprland"; }; diff --git a/host/Rory-nginx/services/matrix/synapse/workers/event-creator.nix b/host/Rory-nginx/services/matrix/synapse/workers/event-creator.nix
index 0966573..9534b62 100644 --- a/host/Rory-nginx/services/matrix/synapse/workers/event-creator.nix +++ b/host/Rory-nginx/services/matrix/synapse/workers/event-creator.nix
@@ -14,6 +14,7 @@ let "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/knock/" "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/profile/" "~ ^/_synapse/admin/v1/rooms" # We have a lot of them, so let's do a bunch of jobs at once! + "~ ^/_matrix/client/unstable/gay.rory.bulk_send_events/rooms/.*/bulk_send_events" ]; federation = [ ]; media = [ ]; diff --git a/packages/overlays/matrix-synapse/patches/0001-Fast-auth-links.patch b/packages/overlays/matrix-synapse/patches/0001-Fast-auth-links.patch
index 0d92e4e..7b91953 100644 --- a/packages/overlays/matrix-synapse/patches/0001-Fast-auth-links.patch +++ b/packages/overlays/matrix-synapse/patches/0001-Fast-auth-links.patch
@@ -1,7 +1,7 @@ From 1b82f35b613e96c56bf18015e33f34328ad73188 Mon Sep 17 00:00:00 2001 From: Rory& <root@rory.gay> Date: Tue, 22 Jul 2025 05:07:01 +0200 -Subject: [PATCH 01/11] Fast auth links +Subject: [PATCH 01/14] Fast auth links --- synapse/storage/database.py | 43 +++++++++++++++++++ diff --git a/packages/overlays/matrix-synapse/patches/0002-Hotfix-ignore-rejected-events-in-delayed_events.patch b/packages/overlays/matrix-synapse/patches/0002-Hotfix-ignore-rejected-events-in-delayed_events.patch
index 3d5ea60..adc1b50 100644 --- a/packages/overlays/matrix-synapse/patches/0002-Hotfix-ignore-rejected-events-in-delayed_events.patch +++ b/packages/overlays/matrix-synapse/patches/0002-Hotfix-ignore-rejected-events-in-delayed_events.patch
@@ -1,7 +1,7 @@ From 346fb5899fa42d4604b7bf0261c5e1774e6d2c04 Mon Sep 17 00:00:00 2001 From: Rory& <root@rory.gay> Date: Sun, 20 Apr 2025 00:30:29 +0200 -Subject: [PATCH 02/11] Hotfix: ignore rejected events in delayed_events +Subject: [PATCH 02/14] Hotfix: ignore rejected events in delayed_events --- synapse/handlers/delayed_events.py | 7 ++++++- diff --git a/packages/overlays/matrix-synapse/patches/0003-Add-too-much-logging-to-room-summary-over-federation.patch b/packages/overlays/matrix-synapse/patches/0003-Add-too-much-logging-to-room-summary-over-federation.patch
index 5f4e596..c5a71ec 100644 --- a/packages/overlays/matrix-synapse/patches/0003-Add-too-much-logging-to-room-summary-over-federation.patch +++ b/packages/overlays/matrix-synapse/patches/0003-Add-too-much-logging-to-room-summary-over-federation.patch
@@ -1,7 +1,7 @@ From 929d1e329ec26d2e351591206a82c6e235660437 Mon Sep 17 00:00:00 2001 From: Rory& <root@rory.gay> Date: Wed, 23 Apr 2025 17:53:52 +0200 -Subject: [PATCH 03/11] Add too much logging to room summary over federation +Subject: [PATCH 03/14] Add too much logging to room summary over federation Signed-off-by: Rory& <root@rory.gay> --- diff --git a/packages/overlays/matrix-synapse/patches/0004-Log-entire-room-if-accessibility-check-fails.patch b/packages/overlays/matrix-synapse/patches/0004-Log-entire-room-if-accessibility-check-fails.patch
index 290f0da..04c00c1 100644 --- a/packages/overlays/matrix-synapse/patches/0004-Log-entire-room-if-accessibility-check-fails.patch +++ b/packages/overlays/matrix-synapse/patches/0004-Log-entire-room-if-accessibility-check-fails.patch
@@ -1,7 +1,7 @@ From 0ce933278f77e272e2cc894229a1178e1b4fb552 Mon Sep 17 00:00:00 2001 From: Rory& <root@rory.gay> Date: Wed, 23 Apr 2025 18:24:57 +0200 -Subject: [PATCH 04/11] Log entire room if accessibility check fails +Subject: [PATCH 04/14] Log entire room if accessibility check fails Signed-off-by: Rory& <root@rory.gay> --- diff --git a/packages/overlays/matrix-synapse/patches/0005-Log-policy-server-rejected-events.patch b/packages/overlays/matrix-synapse/patches/0005-Log-policy-server-rejected-events.patch
index ae59e63..7c6b002 100644 --- a/packages/overlays/matrix-synapse/patches/0005-Log-policy-server-rejected-events.patch +++ b/packages/overlays/matrix-synapse/patches/0005-Log-policy-server-rejected-events.patch
@@ -1,7 +1,7 @@ From 0b5d4c8104bf25f7bbb4e4e7db229742f04199b6 Mon Sep 17 00:00:00 2001 From: Rory& <root@rory.gay> Date: Tue, 27 May 2025 05:21:46 +0200 -Subject: [PATCH 05/11] Log policy server rejected events +Subject: [PATCH 05/14] Log policy server rejected events --- synapse/handlers/room_policy.py | 7 +++++++ diff --git a/packages/overlays/matrix-synapse/patches/0006-Use-parse_boolean-for-unredacted-content.patch b/packages/overlays/matrix-synapse/patches/0006-Use-parse_boolean-for-unredacted-content.patch
index 1c2841c..45fbd2c 100644 --- a/packages/overlays/matrix-synapse/patches/0006-Use-parse_boolean-for-unredacted-content.patch +++ b/packages/overlays/matrix-synapse/patches/0006-Use-parse_boolean-for-unredacted-content.patch
@@ -1,7 +1,7 @@ From 07d72fd39ea3044577322647d5ed1dd8cb6f77d9 Mon Sep 17 00:00:00 2001 From: Rory& <root@rory.gay> Date: Tue, 27 May 2025 06:14:26 +0200 -Subject: [PATCH 06/11] Use parse_boolean for unredacted content +Subject: [PATCH 06/14] Use parse_boolean for unredacted content --- synapse/rest/client/room.py | 5 ++--- diff --git a/packages/overlays/matrix-synapse/patches/0007-Expose-tombstone-in-room-admin-api.patch b/packages/overlays/matrix-synapse/patches/0007-Expose-tombstone-in-room-admin-api.patch
index 719705e..f331512 100644 --- a/packages/overlays/matrix-synapse/patches/0007-Expose-tombstone-in-room-admin-api.patch +++ b/packages/overlays/matrix-synapse/patches/0007-Expose-tombstone-in-room-admin-api.patch
@@ -1,7 +1,7 @@ From d3edb4aa9a225f521fdbc406c187fd40343b3963 Mon Sep 17 00:00:00 2001 From: Rory& <root@rory.gay> Date: Tue, 27 May 2025 06:37:52 +0200 -Subject: [PATCH 07/11] Expose tombstone in room admin api +Subject: [PATCH 07/14] Expose tombstone in room admin api --- synapse/rest/admin/rooms.py | 5 ++++ diff --git a/packages/overlays/matrix-synapse/patches/0008-fix-Always-recheck-messages-pagination-data-if-a-bac.patch b/packages/overlays/matrix-synapse/patches/0008-fix-Always-recheck-messages-pagination-data-if-a-bac.patch
index 363204e..724c134 100644 --- a/packages/overlays/matrix-synapse/patches/0008-fix-Always-recheck-messages-pagination-data-if-a-bac.patch +++ b/packages/overlays/matrix-synapse/patches/0008-fix-Always-recheck-messages-pagination-data-if-a-bac.patch
@@ -1,7 +1,7 @@ From afecddceaa6ece4cf797ce27e226a99acb8e8a6d Mon Sep 17 00:00:00 2001 From: Jason Little <j.little@famedly.com> Date: Wed, 30 Apr 2025 09:29:42 -0500 -Subject: [PATCH 08/11] fix: Always recheck `/messages` pagination data if a +Subject: [PATCH 08/14] fix: Always recheck `/messages` pagination data if a backfill might have been needed (#28) --- diff --git a/packages/overlays/matrix-synapse/patches/0009-Fix-pagination-with-large-gaps-of-rejected-events.patch b/packages/overlays/matrix-synapse/patches/0009-Fix-pagination-with-large-gaps-of-rejected-events.patch
index ebed62e..e249252 100644 --- a/packages/overlays/matrix-synapse/patches/0009-Fix-pagination-with-large-gaps-of-rejected-events.patch +++ b/packages/overlays/matrix-synapse/patches/0009-Fix-pagination-with-large-gaps-of-rejected-events.patch
@@ -1,7 +1,7 @@ From 2f2dd65326b8a8dc6b7ac99dbe7476abb2163469 Mon Sep 17 00:00:00 2001 From: Nicolas Werner <nicolas.werner@hotmail.de> Date: Sun, 8 Jun 2025 23:14:31 +0200 -Subject: [PATCH 09/11] Fix pagination with large gaps of rejected events +Subject: [PATCH 09/14] Fix pagination with large gaps of rejected events --- synapse/handlers/pagination.py | 13 +++++++++++-- diff --git a/packages/overlays/matrix-synapse/patches/0010-Fix-nix-flake.patch b/packages/overlays/matrix-synapse/patches/0010-Fix-nix-flake.patch
index 4df6090..a2bb1ed 100644 --- a/packages/overlays/matrix-synapse/patches/0010-Fix-nix-flake.patch +++ b/packages/overlays/matrix-synapse/patches/0010-Fix-nix-flake.patch
@@ -1,7 +1,7 @@ From 448de6ea7bfe1c6073726f517988e5deeb510861 Mon Sep 17 00:00:00 2001 From: Rory& <root@rory.gay> Date: Mon, 9 Jun 2025 17:38:34 +0200 -Subject: [PATCH 10/11] Fix nix flake +Subject: [PATCH 10/14] Fix nix flake --- flake.lock | 58 +++++++++++++++++++----------------------------------- diff --git a/packages/overlays/matrix-synapse/patches/0011-Fix-gitignore-to-ignore-.venv.patch b/packages/overlays/matrix-synapse/patches/0011-Fix-gitignore-to-ignore-.venv.patch
index 82335db..f627abc 100644 --- a/packages/overlays/matrix-synapse/patches/0011-Fix-gitignore-to-ignore-.venv.patch +++ b/packages/overlays/matrix-synapse/patches/0011-Fix-gitignore-to-ignore-.venv.patch
@@ -1,7 +1,7 @@ From e1b50954048039a23c538cd260644ccc63d82941 Mon Sep 17 00:00:00 2001 From: Rory& <root@rory.gay> Date: Mon, 9 Jun 2025 17:46:10 +0200 -Subject: [PATCH 11/11] Fix gitignore to ignore .venv +Subject: [PATCH 11/14] Fix gitignore to ignore .venv --- .gitignore | 1 + diff --git a/packages/overlays/matrix-synapse/patches/0012-Devenv-use-postgres-17.patch b/packages/overlays/matrix-synapse/patches/0012-Devenv-use-postgres-17.patch new file mode 100644
index 0000000..0e78105 --- /dev/null +++ b/packages/overlays/matrix-synapse/patches/0012-Devenv-use-postgres-17.patch
@@ -0,0 +1,24 @@ +From 8fefc1ece0f73ab4e4867cbb4cc1511dc7faa56f Mon Sep 17 00:00:00 2001 +From: Rory& <root@rory.gay> +Date: Fri, 25 Jul 2025 08:25:28 +0200 +Subject: [PATCH 12/14] Devenv: use postgres 17 + +--- + flake.nix | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/flake.nix b/flake.nix +index 76b3c1a4b0..cc41490a41 100644 +--- a/flake.nix ++++ b/flake.nix +@@ -157,6 +157,7 @@ + # Postgres is needed to run Synapse with postgres support and + # to run certain unit tests that require postgres. + services.postgres.enable = true; ++ services.postgres.package = pkgs.postgresql_17; + + # On the first invocation of `devenv up`, create a database for + # Synapse to store data in. +-- +2.49.0 + diff --git a/packages/overlays/matrix-synapse/patches/0013-RequestRatelimiter-expose-can_do_action.patch b/packages/overlays/matrix-synapse/patches/0013-RequestRatelimiter-expose-can_do_action.patch new file mode 100644
index 0000000..2ad8e55 --- /dev/null +++ b/packages/overlays/matrix-synapse/patches/0013-RequestRatelimiter-expose-can_do_action.patch
@@ -0,0 +1,95 @@ +From 4b62d4e914d8ff7e21bcfbbc6572f1f2a363e066 Mon Sep 17 00:00:00 2001 +From: Rory& <root@rory.gay> +Date: Fri, 25 Jul 2025 08:26:15 +0200 +Subject: [PATCH 13/14] RequestRatelimiter: expose can_do_action + +--- + synapse/api/ratelimiting.py | 75 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 75 insertions(+) + +diff --git a/synapse/api/ratelimiting.py b/synapse/api/ratelimiting.py +index 509ef6b2c1..5f22089a6b 100644 +--- a/synapse/api/ratelimiting.py ++++ b/synapse/api/ratelimiting.py +@@ -435,3 +435,78 @@ class RequestRatelimiter: + update=update, + n_actions=n_actions, + ) ++ ++ async def can_do_action( ++ self, ++ requester: Optional[Requester], ++ burst_count: Optional[int] = None, ++ update: bool = True, ++ is_admin_redaction: bool = False, ++ n_actions: int = 1, ++ ) -> Tuple[bool, float]: ++ """Can the entity (e.g. user or IP address) perform the action? ++ ++ Checks if the user has ratelimiting disabled in the database by looking ++ for null/zero values in the `ratelimit_override` table. (Non-zero ++ values aren't honoured, as they're specific to the event sending ++ ratelimiter, rather than all ratelimiters) ++ ++ Args: ++ requester: The requester that is doing the action, if any. Used to check ++ if the user has ratelimits disabled in the database. ++ key: An arbitrary key used to classify an action. Defaults to the ++ requester's user ID. ++ rate_hz: The long term number of actions that can be performed in a second. ++ Overrides the value set during instantiation if set. ++ burst_count: How many actions that can be performed before being limited. ++ Overrides the value set during instantiation if set. ++ update: Whether to count this check as performing the action. If the action ++ cannot be performed, the user's action count is not incremented at all. ++ n_actions: The number of times the user wants to do this action. If the user ++ cannot do all of the actions, the user's action count is not incremented ++ at all. ++ _time_now_s: The current time. Optional, defaults to the current time according ++ to self.clock. Only used by tests. ++ ++ Returns: ++ A tuple containing: ++ * A bool indicating if they can perform the action now ++ * The reactor timestamp for when the action can be performed next. ++ -1 if rate_hz is less than or equal to zero ++ """ ++ user_id = requester.user.to_string() ++ ++ # The AS user itself is never rate limited. ++ app_service = self.store.get_app_service_by_user_id(user_id) ++ if app_service is not None: ++ return True, 0 # do not ratelimit app service senders ++ ++ messages_per_second = self._rc_message.per_second ++ burst_count = self._rc_message.burst_count ++ ++ # Check if there is a per user override in the DB. ++ override = await self.store.get_ratelimit_for_user(user_id) ++ if override: ++ # If overridden with a null Hz then ratelimiting has been entirely ++ # disabled for the user ++ if not override.messages_per_second: ++ return True, 0 ++ ++ messages_per_second = override.messages_per_second ++ burst_count = override.burst_count ++ ++ if is_admin_redaction and self.admin_redaction_ratelimiter: ++ # If we have separate config for admin redactions, use a separate ++ # ratelimiter as to not have user_ids clash ++ return await self.admin_redaction_ratelimiter.can_do_action( ++ requester, update=update, n_actions=n_actions ++ ) ++ else: ++ # Override rate and burst count per-user ++ return await self.request_ratelimiter.can_do_action( ++ requester, ++ rate_hz=messages_per_second, ++ burst_count=burst_count, ++ update=update, ++ n_actions=n_actions, ++ ) +-- +2.49.0 + diff --git a/packages/overlays/matrix-synapse/patches/0014-Add-bulk-send-events-endpoint.patch b/packages/overlays/matrix-synapse/patches/0014-Add-bulk-send-events-endpoint.patch new file mode 100644
index 0000000..fdd6030 --- /dev/null +++ b/packages/overlays/matrix-synapse/patches/0014-Add-bulk-send-events-endpoint.patch
@@ -0,0 +1,187 @@ +From 452f38800dd00b8686543099d6a085f9b4210687 Mon Sep 17 00:00:00 2001 +From: Rory& <root@rory.gay> +Date: Sat, 26 Jul 2025 09:50:56 +0200 +Subject: [PATCH 14/14] Add bulk send events endpoint + +--- + synapse/rest/client/capabilities.py | 3 + + synapse/rest/client/room.py | 117 +++++++++++++++++++++++++++- + 2 files changed, 119 insertions(+), 1 deletion(-) + +diff --git a/synapse/rest/client/capabilities.py b/synapse/rest/client/capabilities.py +index 8f3193fb47..7220b75006 100644 +--- a/synapse/rest/client/capabilities.py ++++ b/synapse/rest/client/capabilities.py +@@ -74,6 +74,9 @@ class CapabilitiesRestServlet(RestServlet): + "m.get_login_token": { + "enabled": self.config.auth.login_via_existing_enabled, + }, ++ "gay.rory.bulk_send_events": { ++ "enabled": True ++ } + } + } + +diff --git a/synapse/rest/client/room.py b/synapse/rest/client/room.py +index f61152c35b..19ba13dd64 100644 +--- a/synapse/rest/client/room.py ++++ b/synapse/rest/client/room.py +@@ -23,10 +23,12 @@ + + import logging + import re ++import ijson + from enum import Enum + from http import HTTPStatus + from typing import TYPE_CHECKING, Awaitable, Dict, List, Optional, Tuple + from urllib import parse as urlparse ++from twisted.internet import defer + + from prometheus_client.core import Histogram + +@@ -44,6 +46,7 @@ from synapse.api.errors import ( + UnredactedContentDeletedError, + ) + from synapse.api.filtering import Filter ++from synapse.events import EventBase + from synapse.events.utils import SerializeEventConfig, format_event_for_client_v2 + from synapse.http.server import HttpServer + from synapse.http.servlet import ( +@@ -469,7 +472,6 @@ class RoomSendEventRestServlet(TransactionRestServlet): + txn_id, + ) + +- + def _parse_request_delay( + request: SynapseRequest, + max_delay: Optional[int], +@@ -1610,6 +1612,118 @@ class RoomSummaryRestServlet(ResolveRoomIdMixin, RestServlet): + remote_room_hosts, + ) + ++class RoomBulkSendEventRestServlet(ResolveRoomIdMixin, RestServlet): ++ """ ++ Bulk send events to a room. ++ ++ This endpoint allows sending multiple events to a room in a single request, ++ avoiding event linearisation issues. ++ """ ++ ++ PATTERNS = ( ++ re.compile( ++ "^/_matrix/client/unstable/gay.rory.bulk_send_events" ++ "/rooms/(?P<room_identifier>[^/]*)/bulk_send_events$" ++ ), ++ ) ++ CATEGORY = "Event sending requests" ++ ++ def __init__(self, hs: "HomeServer"): ++ super().__init__(hs) ++ self._auth = hs.get_auth() ++ self._event_creation_handler = hs.get_event_creation_handler() ++ self._message_handler = hs.get_message_handler() ++ ++ async def on_POST( ++ self, request: SynapseRequest, room_identifier: str ++ ) -> Tuple[int, JsonDict]: ++ logger.warning("bulk_send_events: Got bulk send events request") ++ requester = await self._auth.get_user_by_req(request, allow_guest=False) ++ room_id, remote_room_hosts = await self.resolve_room_id(room_identifier) ++ ++ force_sync_interval = parse_integer(request, "force_sync_interval", default=250) ++ ++ current_state_events = await self._message_handler.get_state_events( ++ room_id=room_id, ++ requester=requester, ++ ) ++ ++ state_map = {(event["type"], event.get("state_key", "")): event.get("event_id") for event in current_state_events} ++ ++ events = ijson.items( ++ request.content, ++ "item" ++ ) ++ ++ i = 0 ++ unpersisted_events = [] ++ ++ for event_data in events: ++ current_index = i ++ i += 1 ++ logger.info("bulk_send_events: Processing event %d: %s", current_index, event_data) ++ ++ event_dict: JsonDict = { ++ "type": event_data.get("type"), ++ "content": event_data.get("content", {}), ++ "room_id": room_id, ++ "sender": requester.user.to_string(), ++ } ++ ++ if "state_key" in event_data: ++ event_dict["state_key"] = event_data["state_key"] ++ ++ # Explicitly handle rate limits in order to avoid compounding effects ++ awaiting_ratelimit = False ++ ratelimit_hit = False ++ while awaiting_ratelimit: ++ can_do_action, ratelimit_expiry = await self._event_creation_handler.request_ratelimiter.can_do_action(requester, update=False) ++ if not can_do_action: ++ # can_do_action returns an absolute timestamp, convert it to a relative time ++ time_to_sleep = ratelimit_expiry - self._event_creation_handler.request_ratelimiter.clock.time() ++ logger.warning("bulk_send_events: Got rate limited in bulk sending events, waiting %ds", time_to_sleep) ++ await self._event_creation_handler.request_ratelimiter.clock.sleep(time_to_sleep) ++ ratelimit_hit = True ++ else: ++ awaiting_ratelimit = False ++ await self._event_creation_handler.request_ratelimiter.can_do_action(requester, update=True) ++ ++ event, unpersisted_context = await self._event_creation_handler.create_event( ++ requester, ++ event_dict, ++ for_batch=True, ++ state_map=state_map, ++ ) ++ context = await unpersisted_context.persist(event) ++ ++ if event.is_state(): ++ prev_event = await self._event_creation_handler.deduplicate_state_event(event, context) ++ if prev_event is not None: ++ logger.info( ++ "Not bothering to persist state event %s duplicated by %s", ++ event.event_id, ++ prev_event.event_id, ++ ) ++ continue ++ else: ++ state_map[(event_dict["type"], event_dict["state_key"])] = event.event_id ++ logger.warning("bulk_send_events: Updated state_map!") ++ ++ unpersisted_events.append((event, context)) ++ logger.warning("bulk_send_events: Persisted event %d: %s", current_index, event) ++ ++ if ratelimit_hit or len(unpersisted_events) >= force_sync_interval: ++ logger.warning("bulk_send_events: Hit rate limit or max batch size, sending %d events", len(unpersisted_events)) ++ await self._event_creation_handler.handle_new_client_event(requester, unpersisted_events, ratelimit=False) ++ unpersisted_events = [] ++ ++ # Finalize any remaining unpersisted events ++ if(len(unpersisted_events) > 0): ++ await self._event_creation_handler.handle_new_client_event(requester, unpersisted_events, ratelimit=False) ++ unpersisted_events = [] ++ ++ return 200, {} ++ + + def register_servlets(hs: "HomeServer", http_server: HttpServer) -> None: + RoomStateEventRestServlet(hs).register(http_server) +@@ -1619,6 +1733,7 @@ def register_servlets(hs: "HomeServer", http_server: HttpServer) -> None: + JoinRoomAliasServlet(hs).register(http_server) + RoomMembershipRestServlet(hs).register(http_server) + RoomSendEventRestServlet(hs).register(http_server) ++ RoomBulkSendEventRestServlet(hs).register(http_server) + PublicRoomListRestServlet(hs).register(http_server) + RoomStateRestServlet(hs).register(http_server) + RoomRedactEventRestServlet(hs).register(http_server) +-- +2.49.0 +