Compare commits

..

11 Commits

Author SHA1 Message Date
Renovate Bot 1c4020b346 chore(deps): update rust crate rand_core to 0.10.0 2026-05-04 05:04:10 +00:00
Renovate Bot 81c5c6b2bc chore(deps): update sentry-rust monorepo to 0.48.0 2026-05-03 14:41:05 +00:00
Renovate Bot 73d8462ace chore(deps): update rust crate askama to 0.16.0 2026-05-03 14:40:44 +00:00
Renovate Bot 8b5fda1fb5 chore(deps): lock file maintenance 2026-05-03 14:40:16 +00:00
Ginger 6f9b4a989e fix: Update ctor macro arguments 2026-05-03 14:39:30 +00:00
Renovate Bot fe0d83d447 chore(deps): update rust crate ctor to 0.13.0 2026-05-03 14:39:30 +00:00
Renovate Bot 37dccdbeb0 chore(deps): update https://github.com/taiki-e/install-action digest to b5fddbb 2026-05-03 12:30:32 +00:00
Renovate Bot 1060adc670 chore(deps): update dependency cargo-bins/cargo-binstall to v1.19.0 2026-05-03 05:04:01 +00:00
Renovate Bot d963b89a07 chore(deps): update rust-zerover-patch-updates 2026-05-01 17:40:13 +00:00
Ginger 680c972b44 chore: News fragment 2026-05-01 13:17:00 -04:00
Ginger 88b59eb053 fix: Include target user's membership when building stripped state 2026-05-01 13:15:55 -04:00
40 changed files with 329 additions and 536 deletions
+1 -1
View File
@@ -71,7 +71,7 @@ runs:
- name: Install timelord-cli and git-warp-time
if: steps.check-binaries.outputs.need-install == 'true'
uses: https://github.com/taiki-e/install-action@787505cde8a44ea468a00478fe52baf23b15bccd # v2
uses: https://github.com/taiki-e/install-action@b5fddbb5361bce8a06fb168c9d403a6cc552b084 # v2
with:
tool: git-warp-time,timelord-cli@3.0.1
Generated
+208 -218
View File
File diff suppressed because it is too large Load Diff
+8 -5
View File
@@ -39,7 +39,10 @@ features = ["ffi", "std", "union"]
version = "1.1.0"
[workspace.dependencies.ctor]
version = "0.10.0"
version = "0.13.0"
[workspace.dependencies.dtor]
version = "0.13.0"
[workspace.dependencies.cargo_toml]
version = "0.22"
@@ -430,7 +433,7 @@ features = ["http", "grpc-tonic", "trace", "logs", "metrics"]
# optional sentry metrics for crash/panic reporting
[workspace.dependencies.sentry]
version = "0.47.0"
version = "0.48.0"
default-features = false
features = [
"backtrace",
@@ -445,9 +448,9 @@ features = [
]
[workspace.dependencies.sentry-tracing]
version = "0.47.0"
version = "0.48.0"
[workspace.dependencies.sentry-tower]
version = "0.47.0"
version = "0.48.0"
# jemalloc usage
[workspace.dependencies.tikv-jemalloc-sys]
@@ -555,7 +558,7 @@ features = ["sync", "tls-rustls", "rustls-provider"]
version = "1.0.1"
[workspace.dependencies.askama]
version = "0.15.0"
version = "0.16.0"
[workspace.dependencies.lettre]
version = "0.11.19"
+1
View File
@@ -0,0 +1 @@
The invite recipient's membership event is now included in invite stripped state, which should fix flaky invite display in some clients. Contributed by @ginger
+1 -1
View File
@@ -50,7 +50,7 @@ EOF
# Developer tool versions
# renovate: datasource=github-releases depName=cargo-bins/cargo-binstall
ENV BINSTALL_VERSION=1.18.1
ENV BINSTALL_VERSION=1.19.0
# renovate: datasource=github-releases depName=psastras/sbom-rs
ENV CARGO_SBOM_VERSION=0.9.1
# renovate: datasource=crate depName=lddtree
+1 -1
View File
@@ -18,7 +18,7 @@ RUN --mount=type=cache,target=/etc/apk/cache apk add \
# Developer tool versions
# renovate: datasource=github-releases depName=cargo-bins/cargo-binstall
ENV BINSTALL_VERSION=1.18.1
ENV BINSTALL_VERSION=1.19.0
# renovate: datasource=github-releases depName=psastras/sbom-rs
ENV CARGO_SBOM_VERSION=0.9.1
# renovate: datasource=crate depName=lddtree
Generated
+15 -15
View File
@@ -3,11 +3,11 @@
"advisory-db": {
"flake": false,
"locked": {
"lastModified": 1775907537,
"narHash": "sha256-vbeLNgmsx1Z6TwnlDV0dKyeBCcon3UpkV9yLr/yc6HM=",
"lastModified": 1777645914,
"narHash": "sha256-P1T7QVQS13OvkXEuEhI91CLaQfyv6iqV9vW8IBLLDYg=",
"owner": "rustsec",
"repo": "advisory-db",
"rev": "d99f7b9eb81731bddebf80a355f8be7b2f8b1b28",
"rev": "d6ba1f7070ba91f45efe372d68eb648be67d0417",
"type": "github"
},
"original": {
@@ -18,11 +18,11 @@
},
"crane": {
"locked": {
"lastModified": 1775839657,
"narHash": "sha256-SPm9ck7jh3Un9nwPuMGbRU04UroFmOHjLP56T10MOeM=",
"lastModified": 1777335812,
"narHash": "sha256-bEg5xoAxAwsyfnGhkEX7RJViTIBIYPd8ISg4O1c0HFc=",
"owner": "ipetkov",
"repo": "crane",
"rev": "7cf72d978629469c4bd4206b95c402514c1f6000",
"rev": "5e0fb2f64edff2822249f21293b8304dedaaf676",
"type": "github"
},
"original": {
@@ -39,11 +39,11 @@
"rust-analyzer-src": "rust-analyzer-src"
},
"locked": {
"lastModified": 1775891769,
"narHash": "sha256-EOfVlTKw2n8w1uhfh46GS4hEGnQ7oWrIWQfIY6utIkI=",
"lastModified": 1777624102,
"narHash": "sha256-thSyElkje577x/kAbP72nHlfiFc1a+tCudskLPHXe9s=",
"owner": "nix-community",
"repo": "fenix",
"rev": "6fbc54dde15aee725bdc7aae5e478849685d5f56",
"rev": "4d81601e0b73f20d81d066754ad0e7d1e7f75a06",
"type": "github"
},
"original": {
@@ -89,11 +89,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1775710090,
"narHash": "sha256-ar3rofg+awPB8QXDaFJhJ2jJhu+KqN/PRCXeyuXR76E=",
"lastModified": 1777268161,
"narHash": "sha256-bxrdOn8SCOv8tN4JbTF/TXq7kjo9ag4M+C8yzzIRYbE=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "4c1018dae018162ec878d42fec712642d214fdfa",
"rev": "1c3fe55ad329cbcb28471bb30f05c9827f724c76",
"type": "github"
},
"original": {
@@ -132,11 +132,11 @@
"rust-analyzer-src": {
"flake": false,
"locked": {
"lastModified": 1775843361,
"narHash": "sha256-j53ZgyDvmYf3Sjh1IPvvTjqa614qUfVQSzj59+MpzkY=",
"lastModified": 1777583169,
"narHash": "sha256-dVJ4+wrRKc8oIgp3rLOFSq1obt/sCKlXy3h47qof/w0=",
"owner": "rust-lang",
"repo": "rust-analyzer",
"rev": "9eb97ea96d8400e8957ddd56702e962614296583",
"rev": "aa64e4828a2bbba44463c1229a81c748d3cce583",
"type": "github"
},
"original": {
+17 -17
View File
@@ -1399,9 +1399,9 @@
}
},
"node_modules/hookable": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/hookable/-/hookable-6.1.0.tgz",
"integrity": "sha512-ZoKZSJgu8voGK2geJS+6YtYjvIzu9AOM/KZXsBxr83uhLL++e9pEv/dlgwgy3dvHg06kTz6JOh1hk3C8Ceiymw==",
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/hookable/-/hookable-6.1.1.tgz",
"integrity": "sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==",
"dev": true,
"license": "MIT"
},
@@ -2683,20 +2683,20 @@
"license": "MIT"
},
"node_modules/oniguruma-parser": {
"version": "0.12.1",
"resolved": "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.1.tgz",
"integrity": "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==",
"version": "0.12.2",
"resolved": "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.2.tgz",
"integrity": "sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==",
"dev": true,
"license": "MIT"
},
"node_modules/oniguruma-to-es": {
"version": "4.3.5",
"resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-4.3.5.tgz",
"integrity": "sha512-Zjygswjpsewa0NLTsiizVuMQZbp0MDyM6lIt66OxsF21npUDlzpHi1Mgb/qhQdkb+dWFTzJmFbEWdvZgRho8eQ==",
"version": "4.3.6",
"resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-4.3.6.tgz",
"integrity": "sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==",
"dev": true,
"license": "MIT",
"dependencies": {
"oniguruma-parser": "^0.12.1",
"oniguruma-parser": "^0.12.2",
"regex": "^6.1.0",
"regex-recursion": "^6.0.2"
}
@@ -2822,9 +2822,9 @@
}
},
"node_modules/react-router": {
"version": "7.14.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.14.0.tgz",
"integrity": "sha512-m/xR9N4LQLmAS0ZhkY2nkPA1N7gQ5TUVa5n8TgANuDTARbn1gt+zLPXEm7W0XDTbrQ2AJSJKhoa6yx1D8BcpxQ==",
"version": "7.14.2",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.14.2.tgz",
"integrity": "sha512-yCqNne6I8IB6rVCH7XUvlBK7/QKyqypBFGv+8dj4QBFJiiRX+FG7/nkdAvGElyvVZ/HQP5N19wzteuTARXi5Gw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2845,13 +2845,13 @@
}
},
"node_modules/react-router-dom": {
"version": "7.14.0",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.14.0.tgz",
"integrity": "sha512-2G3ajSVSZMEtmTjIklRWlNvo8wICEpLihfD/0YMDxbWK2UyP5EGfnoIn9AIQGnF3G/FX0MRbHXdFcD+rL1ZreQ==",
"version": "7.14.2",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.14.2.tgz",
"integrity": "sha512-YZcM5ES8jJSM+KrJ9BdvHHqlnGTg5tH3sC5ChFRj4inosKctdyzBDhOyyHdGk597q2OT6NTrCA1OvB/YDwfekQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"react-router": "7.14.0"
"react-router": "7.14.2"
},
"engines": {
"node": ">=20.0.0"
+1
View File
@@ -81,6 +81,7 @@ conduwuit-macros.workspace = true
conduwuit-service.workspace = true
const-str.workspace = true
ctor.workspace = true
dtor.workspace = true
futures.workspace = true
lettre.workspace = true
log.workspace = true
+3 -68
View File
@@ -1,9 +1,9 @@
use api::client::leave_room;
use clap::Subcommand;
use conduwuit::{
debug, info, utils::{IterStream, ReadyExt}, warn,
Err,
Result,
Err, Result, debug, info,
utils::{IterStream, ReadyExt},
warn,
};
use futures::{FutureExt, StreamExt};
use ruma::{OwnedRoomId, OwnedRoomOrAliasId, RoomAliasId, RoomId, RoomOrAliasId};
@@ -43,12 +43,6 @@ pub enum RoomModerationCommand {
/// information
no_details: bool,
},
/// Deletes a room
Delete {
/// The room ID
room_id: OwnedRoomId,
},
}
#[admin_command]
@@ -458,62 +452,3 @@ async fn list_banned_rooms(&self, no_details: bool) -> Result {
self.write_str(&format!("Rooms Banned ({num}):\n```\n{body}\n```"))
.await
}
#[admin_command]
async fn delete(&self, room_id: OwnedRoomId) -> Result {
let is_banned = self.services.rooms.metadata.is_banned(&room_id).await;
let is_disabled = self.services.rooms.metadata.is_disabled(&room_id).await;
// Temporarily forcefully ban the room to prevent people trying to join while
// deletion is ongoing.
self.services.rooms.metadata.disable_room(&room_id, true);
self.services.rooms.metadata.ban_room(&room_id, true);
let mut users = self
.services
.rooms
.state_cache
.room_members(&room_id)
.ready_filter(|user| self.services.globals.user_is_local(user))
.boxed();
while let Some(ref user_id) = users.next().await {
info!("Removing {user_id} from {room_id}",);
if let Err(e) = leave_room(self.services, user_id, &room_id, None)
.boxed()
.await
{
warn!("Failed to remove {user_id} from {room_id}: {e}");
}
self.services.rooms.state_cache.forget(&room_id, user_id);
}
self.services
.rooms
.alias
.local_aliases_for_room(&room_id)
.for_each(|local_alias| async move {
info!("Removing alias {local_alias}");
self.services
.rooms
.alias
.remove_alias(&local_alias, &self.services.globals.server_user)
.await
.ok();
})
.await;
info!("Removing the room from the directory if it is present");
self.services.rooms.directory.set_not_public(&room_id);
info!("Removing lazy-loading metadata");
self.services.rooms.lazy_loading.purge(&room_id).await;
info!("Removing PDU metadata");
self.services.rooms.pdu_metadata.purge(&room_id).await;
info!("Removing state cache");
self.services.rooms.state_cache.purge(&room_id).await;
info!("Removing room state");
self.services.rooms.state.purge(&room_id).await;
Ok(())
}
+1
View File
@@ -77,6 +77,7 @@ conduwuit-macros.workspace = true
conduwuit-service.workspace = true
const-str.workspace = true
ctor.workspace = true
dtor.workspace = true
futures.workspace = true
hmac.workspace = true
http.workspace = true
+2 -3
View File
@@ -118,9 +118,8 @@ pub(crate) async fn get_content_thumbnail_route(
} = match fetch_thumbnail_meta(&services, &mxc, user, body.timeout_ms, &dim).await {
| Ok(meta) => meta,
| Err(conduwuit::Error::Io(e)) => match e.kind() {
| std::io::ErrorKind::NotFound => {
return Err!(Request(NotFound("Thumbnail not found.")));
},
| std::io::ErrorKind::NotFound =>
return Err!(Request(NotFound("Thumbnail not found."))),
| std::io::ErrorKind::PermissionDenied => {
error!("Permission denied when trying to read file: {e:?}");
return Err!(Request(Unknown("Unknown error when fetching thumbnail.")));
+5 -1
View File
@@ -163,7 +163,11 @@ pub(crate) async fn invite_helper(
)
.await?;
let invite_room_state = services.rooms.state.summary_stripped(&pdu, room_id).await;
let invite_room_state = services
.rooms
.state
.summary_stripped(&pdu, room_id, recipient_user)
.await;
drop(state_lock);
+2 -3
View File
@@ -375,7 +375,7 @@ async fn allowed_to_send_state_event(
},
}
},
| StateEventType::RoomMember => {
| StateEventType::RoomMember =>
match json.deserialize_as_unchecked::<RoomMemberEventContent>() {
| Ok(mut membership_content) => {
let Ok(state_key) = UserId::parse(state_key) else {
@@ -434,8 +434,7 @@ async fn allowed_to_send_state_event(
membership state: {e}"
)));
},
}
},
},
| _ => (),
}
+2 -3
View File
@@ -19,11 +19,10 @@ pub(crate) async fn well_known_client(
) -> Result<discover_homeserver::Response> {
let client_url = match services.config.well_known.client.as_ref() {
| Some(url) => url.to_string(),
| None => {
| None =>
return Err!(Request(NotFound(
"This server is not configured to serve well-known client information."
)));
},
))),
};
Ok(assign!(discover_homeserver::Response::new(HomeserverInfo::new(client_url)), {
+2 -3
View File
@@ -89,9 +89,8 @@ impl CheckAuth for ServerSignatures {
origin: Some(output.origin.clone()),
..Default::default()
}),
| Err(err) => {
Err!(Request(Unauthorized(warn!("Failed to verify X-Matrix header: {err}"))))
},
| Err(err) =>
Err!(Request(Unauthorized(warn!("Failed to verify X-Matrix header: {err}")))),
}
}
}
+2 -3
View File
@@ -252,7 +252,7 @@ pub(crate) async fn user_can_perform_restricted_join(
return Ok(true);
}
},
| other if other.rule_type() == "fi.mau.spam_checker" => {
| other if other.rule_type() == "fi.mau.spam_checker" =>
return match services
.antispam
.meowlnir_accept_make_join(room_id.to_owned(), user_id.to_owned())
@@ -260,8 +260,7 @@ pub(crate) async fn user_can_perform_restricted_join(
{
| Ok(()) => Ok(true),
| Err(_) => Err!(Request(Forbidden("Antispam rejected join request."))),
};
},
},
| _ => {
// We don't recognise this join rule, so we cannot satisfy the request.
could_satisfy = false;
+1 -1
View File
@@ -183,7 +183,7 @@ pub(crate) async fn create_knock_event_v1_route(
let knock_room_state = services
.rooms
.state
.summary_stripped(&pdu, &body.room_id)
.summary_stripped(&pdu, &body.room_id, &sender)
.await;
Ok(create_knock_event::v1::Response::new(knock_room_state))
+2 -1
View File
@@ -70,6 +70,7 @@ conduwuit-build-metadata.workspace = true
const-str.workspace = true
core_affinity.workspace = true
ctor.workspace = true
dtor.workspace = true
cyborgtime.workspace = true
either.workspace = true
figment.workspace = true
@@ -86,7 +87,7 @@ lettre.workspace = true
num-traits.workspace = true
rand.workspace = true
# tied to passwordhash 0.5.0
rand_core = { version = "0.6.4", features = ["getrandom"] }
rand_core = { version = "0.10.0", features = ["getrandom"] }
regex.workspace = true
reqwest.workspace = true
sha2.workspace = true
+1 -1
View File
@@ -47,7 +47,7 @@ type Key = ArrayVec<usize, KEY_SEGS>;
const NAME_MAX: usize = 128;
const KEY_SEGS: usize = 8;
#[ctor::ctor]
#[ctor::ctor(unsafe)]
fn _static_initialization() {
acq_epoch().expect("pre-initialization of jemalloc failed");
acq_epoch().expect("pre-initialization of jemalloc failed");
+1 -1
View File
@@ -62,7 +62,7 @@ pub const INFO_SPAN_LEVEL: Level = if cfg!(debug_assertions) {
pub static DEBUGGER: LazyLock<bool> =
LazyLock::new(|| env::var("_").unwrap_or_default().ends_with("gdb"));
#[cfg_attr(debug_assertions, ctor::ctor)]
#[cfg_attr(debug_assertions, ctor::ctor(unsafe))]
#[cfg_attr(not(debug_assertions), allow(dead_code))]
fn set_panic_trap() {
if !*DEBUGGER {
+1
View File
@@ -58,6 +58,7 @@ conduwuit-core.workspace = true
conduwuit-macros.workspace = true
const-str.workspace = true
ctor.workspace = true
dtor.workspace = true
futures.workspace = true
log.workspace = true
minicbor.workspace = true
+2 -2
View File
@@ -32,11 +32,11 @@ pub(super) fn introspect(_args: TokenStream) -> Result<TokenStream> {
const CRATE_NAME: &str = #crate_name;
/// Register this crate's features with the global registry during static initialization
#[::ctor::ctor]
#[::ctor::ctor(unsafe)]
fn register() {
conduwuit_core::info::introspection::ENABLED_FEATURES.lock().unwrap().insert(#crate_name, &ENABLED);
}
#[::ctor::dtor]
#[::dtor::dtor(unsafe)]
fn unregister() {
conduwuit_core::info::introspection::ENABLED_FEATURES.lock().unwrap().remove(#crate_name);
}
+1
View File
@@ -217,6 +217,7 @@ conduwuit-macros.workspace = true
clap.workspace = true
ctor.workspace = true
dtor.workspace = true
console-subscriber.optional = true
console-subscriber.workspace = true
const-str.workspace = true
+1
View File
@@ -105,6 +105,7 @@ conduwuit-service.workspace = true
conduwuit-web.workspace = true
const-str.workspace = true
ctor.workspace = true
dtor.workspace = true
futures.workspace = true
http.workspace = true
http-body-util.workspace = true
+1
View File
@@ -89,6 +89,7 @@ conduwuit-database.workspace = true
conduwuit-macros.workspace = true
const-str.workspace = true
ctor.workspace = true
dtor.workspace = true
either.workspace = true
futures.workspace = true
governor.workspace = true
+1 -4
View File
@@ -160,10 +160,7 @@ pub async fn create_admin_room(services: &Services) -> Result {
.boxed()
.await?;
let room_topic = format!(
"Manage {} | Run commands prefixed with `!admin` | Run `!admin -h` for help | Documentation: https://continuwuity.org/",
services.config.server_name
);
let room_topic = format!("Manage {} | Run commands prefixed with `!admin` | Run `!admin -h` for help | Documentation: https://continuwuity.org/", services.config.server_name);
services
.rooms
.timeline
+1 -3
View File
@@ -312,9 +312,7 @@ impl Service {
to open the console."
);
}
eprintln!(
"If you need assistance setting up your homeserver, make a Matrix account on another homeserver and join our chatroom: https://matrix.to/#/#continuwuity:continuwuity.org"
);
eprintln!("If you need assistance setting up your homeserver, make a Matrix account on another homeserver and join our chatroom: https://matrix.to/#/#continuwuity:continuwuity.org");
eprintln!("{}", "============".bold());
}
+1 -1
View File
@@ -802,7 +802,7 @@ async fn fix_local_invite_state(services: &Services) -> Result {
&& services.globals.user_is_local(&membership_event.sender) {
// build and save stripped state for their invite in the database
let stripped_state = services.rooms.state.summary_stripped(&membership_event, &room_id).await;
let stripped_state = services.rooms.state.summary_stripped(&membership_event, &room_id, &user_id).await;
userroomid_invitestate.put((&user_id, &room_id), Json(stripped_state));
fixed = fixed.saturating_add(1);
}
-11
View File
@@ -67,17 +67,6 @@ pub async fn reset(&self, ctx: &Context<'_>) {
.await;
}
#[implement(Service)]
pub async fn purge(&self, room_id: &RoomId) {
let prefix = (Interfix, Interfix, room_id, Interfix);
self.db
.lazyloadedids
.keys_prefix_raw(&prefix)
.ignore_err()
.ready_for_each(|key| self.db.lazyloadedids.remove(key))
.await;
}
/// Returns only the subset of `senders` which should be sent to the client
/// according to the provided lazy loading context.
#[implement(Service)]
+1 -15
View File
@@ -9,7 +9,7 @@ use conduwuit::{
u64_from_u8,
},
};
use database::{Interfix, Map};
use database::Map;
use futures::{Stream, StreamExt};
use ruma::{EventId, RoomId, UserId, api::Direction};
@@ -46,16 +46,6 @@ impl Data {
}
}
pub(super) async fn purge(&self, room_id: &RoomId) {
// NOTE: This does not remove soft-failed event references, that must be done
// somewhere else.
self.referencedevents
.keys_prefix_raw(&(room_id, Interfix))
.ignore_err()
.ready_for_each(|key| self.referencedevents.remove(key))
.await;
}
pub(super) fn add_relation(&self, from: u64, to: u64) {
const BUFSIZE: usize = size_of::<u64>() * 2;
@@ -131,8 +121,4 @@ impl Data {
pub(super) async fn is_event_soft_failed(&self, event_id: &EventId) -> bool {
self.softfailedeventids.get(event_id).await.is_ok()
}
pub(super) async fn remove_soft_fail_marker(&self, event_id: &EventId) {
self.softfailedeventids.remove(event_id);
}
}
-6
View File
@@ -140,10 +140,4 @@ impl Service {
pub async fn is_event_soft_failed(&self, event_id: &EventId) -> bool {
self.db.is_event_soft_failed(event_id).await
}
pub async fn purge(&self, room_id: &RoomId) { self.db.purge(room_id).await; }
pub async fn remove_soft_fail_marker(&self, event_id: &EventId) {
self.db.remove_soft_fail_marker(event_id).await;
}
}
-8
View File
@@ -115,12 +115,4 @@ impl Data {
.deserialized()
.unwrap_or(0)
}
pub(super) async fn purge(&self, room_id: &RoomId) {
self.readreceiptid_readreceipt
.keys_prefix_raw(room_id)
.ignore_err()
.ready_for_each(|key| self.readreceiptid_readreceipt.remove(key))
.await;
}
}
-2
View File
@@ -142,8 +142,6 @@ impl Service {
pub async fn last_privateread_update(&self, user_id: &UserId, room_id: &RoomId) -> u64 {
self.db.last_privateread_update(user_id, room_id).await
}
pub async fn purge(&self, room_id: &RoomId) { self.db.purge(room_id).await }
}
#[must_use]
+23 -36
View File
@@ -3,32 +3,32 @@ use std::{collections::HashMap, fmt::Write, sync::Arc};
use async_trait::async_trait;
use conduwuit::debug;
use conduwuit_core::{
err, result::FlatOk, state_res::{self, StateMap}, utils::{
calculate_hash, stream::{BroadbandExt, TryIgnore}, IterStream, MutexMap, MutexMapGuard,
ReadyExt,
Event, PduEvent, Result, err,
result::FlatOk,
state_res::{self, StateMap},
utils::{
IterStream, MutexMap, MutexMapGuard, ReadyExt, calculate_hash,
stream::{BroadbandExt, TryIgnore},
},
warn,
Event,
PduEvent,
Result,
};
use conduwuit_database::{Deserialized, Ignore, Interfix, Map};
use futures::{
future::join_all, pin_mut, FutureExt, Stream, StreamExt, TryFutureExt, TryStreamExt,
FutureExt, Stream, StreamExt, TryFutureExt, TryStreamExt, future::join_all, pin_mut,
};
use ruma::{
api::federation::membership::RawStrippedState, events::{room::create::RoomCreateEventContent, StateEventType, TimelineEventType}, room_version_rules::RoomVersionRules, EventId, OwnedEventId, OwnedRoomId,
RoomId,
RoomVersionId,
UserId,
EventId, OwnedEventId, OwnedRoomId, RoomId, RoomVersionId, UserId,
api::federation::membership::RawStrippedState,
events::{StateEventType, TimelineEventType, room::create::RoomCreateEventContent},
room_version_rules::RoomVersionRules,
};
use crate::{
globals, rooms, rooms::{
Dep, globals, rooms,
rooms::{
short::{ShortEventId, ShortStateHash},
state_compressor::{parse_compressed_state_event, CompressedState},
state_compressor::{CompressedState, parse_compressed_state_event},
},
Dep,
};
pub struct Service {
@@ -89,25 +89,6 @@ impl crate::Service for Service {
}
impl Service {
pub async fn purge(&self, room_id: &RoomId) {
self.db.roomid_pduleaves
.keys_prefix_raw(room_id)
.ignore_err()
.ready_for_each(|k| self.db.roomid_pduleaves.remove(k))
.await;
let mut shortstatehashes = self.db.roomid_shortstatehash
.keys_prefix_raw(room_id)
.ignore_err();
while let Some(key) = shortstatehashes.next().await {
self.db.shorteventid_shortstatehash
.keys_prefix_raw(&(Interfix, key))
.ignore_err()
.ready_for_each(|key| self.db.shorteventid_shortstatehash.remove(key))
.await;
self.db.roomid_shortstatehash.remove(key);
};
}
/// Set the room to the given statehash and update caches.
pub async fn force_state(
&self,
@@ -319,12 +300,13 @@ impl Service {
&self,
event: &'a E,
room_id: &RoomId,
target_user: &UserId,
) -> Vec<RawStrippedState>
where
E: Event + Send + Sync,
&'a E: Event + Send,
{
let cells = [
let mut state_events = [
(&StateEventType::RoomCreate, ""),
(&StateEventType::RoomJoinRules, ""),
(&StateEventType::RoomCanonicalAlias, ""),
@@ -333,9 +315,14 @@ impl Service {
(&StateEventType::RoomMember, event.sender().as_str()), // Add recommended events
(&StateEventType::RoomEncryption, ""),
(&StateEventType::RoomTopic, ""),
];
]
.to_vec();
let fetches = cells.into_iter().map(|(event_type, state_key)| {
if target_user != event.sender() {
state_events.push((&StateEventType::RoomMember, target_user.as_str()));
}
let fetches = state_events.into_iter().map(|(event_type, state_key)| {
self.services
.state_accessor
.room_state_get(room_id, event_type, state_key)
+9 -94
View File
@@ -4,21 +4,20 @@ mod via;
use std::{collections::HashMap, sync::Arc};
use conduwuit::{
implement, result::LogErr, utils::{stream::TryIgnore, ReadyExt}, warn,
Pdu,
Result,
SyncRwLock,
Pdu, Result, SyncRwLock, implement,
result::LogErr,
utils::{ReadyExt, stream::TryIgnore},
warn,
};
use database::{Deserialized, Ignore, Interfix, Map};
use futures::{future::join5, pin_mut, Stream, StreamExt};
use futures::{Stream, StreamExt, future::join5, pin_mut};
use ruma::{
events::{room::member::MembershipState, AnyStrippedStateEvent}, serde::Raw, OwnedRoomId, OwnedServerName, OwnedUserId, RoomId,
ServerName,
UserId,
OwnedRoomId, OwnedServerName, OwnedUserId, RoomId, ServerName, UserId,
events::{AnyStrippedStateEvent, room::member::MembershipState},
serde::Raw,
};
use tokio::join;
use crate::{account_data, appservice::RegistrationInfo, config, globals, rooms, users, Dep};
use crate::{Dep, account_data, appservice::RegistrationInfo, config, globals, rooms, users};
pub struct Service {
appservice_in_room_cache: AppServiceInRoomCache,
@@ -94,90 +93,6 @@ impl crate::Service for Service {
fn name(&self) -> &str { crate::service::make_name(std::module_path!()) }
}
#[implement(Service)]
#[tracing::instrument(skip(self))]
pub async fn purge(&self, room_id: &RoomId) {
let roomuser_key = (room_id, Interfix);
let userroom_key = (Interfix, room_id);
join!(
self.db
.roomid_invitedcount
.keys_prefix_raw(room_id)
.ignore_err()
.ready_for_each(|key| self.db.roomid_invitedcount.remove(key)),
self.db
.roomid_inviteviaservers
.keys_prefix_raw(room_id)
.ignore_err()
.ready_for_each(|key| self.db.roomid_inviteviaservers.remove(key)),
self.db
.roomid_joinedcount
.keys_prefix_raw(room_id)
.ignore_err()
.ready_for_each(|key| self.db.roomid_joinedcount.remove(key)),
self.db
.roomserverids
.keys_prefix_raw(room_id)
.ignore_err()
.ready_for_each(|key| self.db.roomserverids.remove(key)),
self.db
.roomuserid_invitecount
.keys_prefix_raw(&roomuser_key)
.ignore_err()
.ready_for_each(|key| self.db.roomuserid_invitecount.remove(key)),
self.db
.roomuserid_joined
.keys_prefix_raw(&roomuser_key)
.ignore_err()
.ready_for_each(|key| self.db.roomuserid_joined.remove(key)),
self.db
.roomuserid_leftcount
.keys_prefix_raw(&roomuser_key)
.ignore_err()
.ready_for_each(|key| self.db.roomuserid_leftcount.remove(key)),
self.db
.roomuserid_knockedcount
.keys_prefix_raw(&roomuser_key)
.ignore_err()
.ready_for_each(|key| self.db.roomuserid_knockedcount.remove(key)),
self.db
.roomuseroncejoinedids
.keys_prefix_raw(room_id)
.ignore_err()
.ready_for_each(|key| self.db.roomuseroncejoinedids.remove(key)),
self.db
.userroomid_invitestate
.keys_prefix_raw(&userroom_key)
.ignore_err()
.ready_for_each(|key| self.db.userroomid_invitestate.remove(key)),
self.db
.userroomid_joined
.keys_prefix_raw(&userroom_key)
.ignore_err()
.ready_for_each(|key| self.db.userroomid_joined.remove(key)),
self.db
.userroomid_leftstate
.keys_prefix_raw(&userroom_key)
.ignore_err()
.ready_for_each(|key| self.db.userroomid_leftstate.remove(key)),
self.db
.userroomid_knockedstate
.keys_prefix_raw(&userroom_key)
.ignore_err()
.ready_for_each(|key| self.db.userroomid_knockedstate.remove(key)),
self.db
.userroomid_invitesender
.keys_prefix_raw(&userroom_key)
.ignore_err()
.ready_for_each(|key| self.db.userroomid_invitesender.remove(key)),
self.db
.serverroomids
.keys_prefix_raw(&(Interfix, room_id))
.ignore_err()
.ready_for_each(|key| self.db.serverroomids.remove(key)),
);
}
#[implement(Service)]
#[tracing::instrument(level = "trace", skip_all)]
pub async fn appservice_in_room(&self, room_id: &RoomId, appservice: &RegistrationInfo) -> bool {
+5 -1
View File
@@ -119,7 +119,11 @@ pub async fn update_membership(
self.mark_as_joined(user_id, room_id);
},
| MembershipState::Invite => {
let last_state = self.services.state.summary_stripped(pdu, room_id).await;
let last_state = self
.services
.state
.summary_stripped(pdu, room_id, user_id)
.await;
self.mark_as_invited(user_id, room_id, pdu.sender(), last_state, None)
.await?;
+2 -3
View File
@@ -54,9 +54,8 @@ where
if !status.is_success() {
debug_error!("Antispam response bytes: {:?}", utils::string_from_bytes(&body));
return match status {
| http::StatusCode::FORBIDDEN => {
Err!(Request(Forbidden("Request was rejected by antispam service.",)))
},
| http::StatusCode::FORBIDDEN =>
Err!(Request(Forbidden("Request was rejected by antispam service.",))),
| _ => Err!(BadServerResponse(warn!(
"Antispam returned unsuccessful HTTP response {status}",
))),
+2 -3
View File
@@ -360,12 +360,11 @@ impl Service {
));
}
},
| _ => {
| _ =>
return Err(StandardErrorBody::new(
ErrorKind::Unrecognized,
"Identifier type not recognized".to_owned(),
));
},
)),
};
let Ok(user_id) = UserId::parse_with_server_name(
+1 -1
View File
@@ -14,7 +14,7 @@ conduwuit-admin.workspace = true
conduwuit.workspace = true
clap.workspace = true
askama = "0.15.1"
askama = "0.16.0"
cargo_metadata = "0.23.1"
[lints]