fix(appservice): Create appservice user on registration

Fixes #813 where appservice users were not being created when the
appservice was registered, causing bridges like mautrix-telegram
to fail on startup.

The fix creates the appservice's sender_localpart user if it doesn't
already exist during the registration process, matching the expected
Matrix appservice behaviour.
This commit is contained in:
Tom Foster 2025-08-04 19:33:02 +01:00
commit 15ee7559ea

View file

@ -11,7 +11,7 @@ use ruma::{RoomAliasId, RoomId, UserId, api::appservice::Registration};
use tokio::sync::{RwLock, RwLockReadGuard}; use tokio::sync::{RwLock, RwLockReadGuard};
pub use self::{namespace_regex::NamespaceRegex, registration_info::RegistrationInfo}; pub use self::{namespace_regex::NamespaceRegex, registration_info::RegistrationInfo};
use crate::{Dep, sending}; use crate::{Dep, globals, sending, users};
pub struct Service { pub struct Service {
registration_info: RwLock<Registrations>, registration_info: RwLock<Registrations>,
@ -20,7 +20,9 @@ pub struct Service {
} }
struct Services { struct Services {
globals: Dep<globals::Service>,
sending: Dep<sending::Service>, sending: Dep<sending::Service>,
users: Dep<users::Service>,
} }
struct Data { struct Data {
@ -35,7 +37,9 @@ impl crate::Service for Service {
Ok(Arc::new(Self { Ok(Arc::new(Self {
registration_info: RwLock::new(BTreeMap::new()), registration_info: RwLock::new(BTreeMap::new()),
services: Services { services: Services {
globals: args.depend::<globals::Service>("globals"),
sending: args.depend::<sending::Service>("sending"), sending: args.depend::<sending::Service>("sending"),
users: args.depend::<users::Service>("users"),
}, },
db: Data { db: Data {
id_appserviceregistrations: args.db["id_appserviceregistrations"].clone(), id_appserviceregistrations: args.db["id_appserviceregistrations"].clone(),
@ -68,6 +72,16 @@ impl Service {
appservice_config_body: &str, appservice_config_body: &str,
) -> Result { ) -> Result {
//TODO: Check for collisions between exclusive appservice namespaces //TODO: Check for collisions between exclusive appservice namespaces
let appservice_user_id = UserId::parse_with_server_name(
registration.sender_localpart.as_str(),
self.services.globals.server_name(),
)?;
if !self.services.users.exists(&appservice_user_id).await {
self.services.users.create(&appservice_user_id, None)?;
}
self.registration_info self.registration_info
.write() .write()
.await .await