2024-02-25 22:16:08 -05:00
use std ::collections ::BTreeMap ;
2022-01-13 12:06:20 +01:00
2024-07-16 08:05:25 +00:00
use axum ::{ extract ::State , response ::IntoResponse , Json } ;
2024-08-08 17:18:30 +00:00
use futures ::StreamExt ;
2024-04-06 18:42:00 -04:00
use ruma ::api ::client ::{
discovery ::{
2024-04-11 20:17:30 -04:00
discover_homeserver ::{ self , HomeserverInfo , SlidingSyncProxyInfo } ,
2024-04-06 18:42:00 -04:00
discover_support ::{ self , Contact } ,
get_supported_versions ,
} ,
error ::ErrorKind ,
} ;
2022-04-06 21:31:29 +02:00
2024-07-16 08:05:25 +00:00
use crate ::{ Error , Result , Ruma } ;
2020-07-30 18:14:47 +02:00
2020-07-31 14:40:28 +02:00
/// # `GET /_matrix/client/versions`
///
/// Get the versions of the specification and unstable features supported by
/// this server.
///
/// - Versions take the form MAJOR.MINOR.PATCH
/// - Only the latest PATCH release will be reported for each MAJOR.MINOR value
2021-08-31 19:14:37 +02:00
/// - Unstable features are namespaced and may include version information in
/// their name
2020-07-31 14:40:28 +02:00
///
/// Note: Unstable features are used while developing new features. Clients
/// should avoid using unstable features in their stable releases
2024-04-22 23:48:57 -04:00
pub ( crate ) async fn get_supported_versions_route (
2022-12-14 13:09:10 +01:00
_body : Ruma < get_supported_versions ::Request > ,
2022-01-22 16:58:32 +01:00
) -> Result < get_supported_versions ::Response > {
2022-01-13 11:48:18 +01:00
let resp = get_supported_versions ::Response {
2022-05-30 12:58:43 +02:00
versions : vec ! [
2024-01-07 17:20:44 -05:00
" r0.0.1 " . to_owned ( ) ,
" r0.1.0 " . to_owned ( ) ,
" r0.2.0 " . to_owned ( ) ,
" r0.3.0 " . to_owned ( ) ,
" r0.4.0 " . to_owned ( ) ,
2022-05-30 12:58:43 +02:00
" r0.5.0 " . to_owned ( ) ,
" r0.6.0 " . to_owned ( ) ,
2024-01-07 17:20:44 -05:00
" r0.6.1 " . to_owned ( ) ,
2022-05-30 12:58:43 +02:00
" v1.1 " . to_owned ( ) ,
" v1.2 " . to_owned ( ) ,
2023-06-25 19:31:40 +02:00
" v1.3 " . to_owned ( ) ,
" v1.4 " . to_owned ( ) ,
2024-01-07 17:20:44 -05:00
" v1.5 " . to_owned ( ) ,
2024-08-27 11:19:57 +00:00
" v1.11 " . to_owned ( ) ,
2022-05-30 12:58:43 +02:00
] ,
2024-01-07 17:20:44 -05:00
unstable_features : BTreeMap ::from_iter ( [
( " org.matrix.e2e_cross_signing " . to_owned ( ) , true ) ,
2024-05-22 03:34:40 -04:00
( " org.matrix.msc2285.stable " . to_owned ( ) , true ) , /* private read receipts (https: / / github.com / matrix-org / matrix-spec-proposals / pull / 2285) */
( " uk.half-shot.msc2666.query_mutual_rooms " . to_owned ( ) , true ) , /* query mutual rooms (https: / / github.com / matrix-org / matrix-spec-proposals / pull / 2666) */
( " org.matrix.msc2836 " . to_owned ( ) , true ) , /* threading / threads (https: / / github.com / matrix-org / matrix-spec-proposals / pull / 2836) */
( " org.matrix.msc2946 " . to_owned ( ) , true ) , /* spaces / hierarchy summaries (https: / / github.com / matrix-org / matrix-spec-proposals / pull / 2946) */
( " org.matrix.msc3026.busy_presence " . to_owned ( ) , true ) , /* busy presence status (https: / / github.com / matrix-org / matrix-spec-proposals / pull / 3026) */
( " org.matrix.msc3827 " . to_owned ( ) , true ) , /* filtering of / publicRooms by room type (https: / / github.com / matrix-org / matrix-spec-proposals / pull / 3827) */
2024-11-13 20:06:25 -05:00
( " org.matrix.msc3952_intentional_mentions " . to_owned ( ) , true ) , /* intentional mentions (https: / / github.com / matrix-org / matrix-spec-proposals / pull / 3952) */
2024-05-22 03:34:40 -04:00
( " org.matrix.msc3575 " . to_owned ( ) , true ) , /* sliding sync (https: / / github.com / matrix-org / matrix-spec-proposals / pull / 3575 / files#r1588877046) */
2024-08-29 19:17:33 +00:00
( " org.matrix.msc3916.stable " . to_owned ( ) , true ) , /* authenticated media (https: / / github.com / matrix-org / matrix-spec-proposals / pull / 3916) */
( " org.matrix.msc4180 " . to_owned ( ) , true ) , /* stable flag for 3916 (https: / / github.com / matrix-org / matrix-spec-proposals / pull / 4180) */
2024-09-08 19:53:33 -04:00
( " uk.tcpip.msc4133 " . to_owned ( ) , true ) , /* Extending User Profile API with Key:Value Pairs (https: / / github.com / matrix-org / matrix-spec-proposals / pull / 4133) */
( " us.cloke.msc4175 " . to_owned ( ) , true ) , /* Profile field for user time zone (https: / / github.com / matrix-org / matrix-spec-proposals / pull / 4175) */
2024-01-07 17:20:44 -05:00
] ) ,
2022-01-13 11:48:18 +01:00
} ;
2020-07-30 18:14:47 +02:00
2022-01-22 16:58:32 +01:00
Ok ( resp )
2020-07-30 18:14:47 +02:00
}
2023-07-06 10:32:25 +02:00
/// # `GET /.well-known/matrix/client`
2024-04-11 20:17:30 -04:00
///
/// Returns the .well-known URL if it is configured, otherwise returns 404.
2024-04-22 23:48:57 -04:00
pub ( crate ) async fn well_known_client (
2024-07-16 08:05:25 +00:00
State ( services ) : State < crate ::State > , _body : Ruma < discover_homeserver ::Request > ,
2024-04-22 23:48:57 -04:00
) -> Result < discover_homeserver ::Response > {
2024-07-16 08:05:25 +00:00
let client_url = match services . globals . well_known_client ( ) {
2024-04-11 20:17:30 -04:00
Some ( url ) = > url . to_string ( ) ,
2023-07-06 10:32:25 +02:00
None = > return Err ( Error ::BadRequest ( ErrorKind ::NotFound , " Not found. " ) ) ,
} ;
2024-04-11 20:17:30 -04:00
Ok ( discover_homeserver ::Response {
homeserver : HomeserverInfo {
base_url : client_url . clone ( ) ,
} ,
identity_server : None ,
sliding_sync_proxy : Some ( SlidingSyncProxyInfo {
url : client_url ,
} ) ,
tile_server : None ,
} )
2023-07-06 10:32:25 +02:00
}
2024-01-07 21:24:55 -05:00
2024-04-06 18:42:00 -04:00
/// # `GET /.well-known/matrix/support`
///
/// Server support contact and support page of a homeserver's domain.
2024-07-16 08:05:25 +00:00
pub ( crate ) async fn well_known_support (
State ( services ) : State < crate ::State > , _body : Ruma < discover_support ::Request > ,
) -> Result < discover_support ::Response > {
let support_page = services
2024-04-11 20:17:30 -04:00
. globals
. well_known_support_page ( )
. as_ref ( )
. map ( ToString ::to_string ) ;
2024-04-06 18:42:00 -04:00
2024-07-16 08:05:25 +00:00
let role = services . globals . well_known_support_role ( ) . clone ( ) ;
2024-04-06 18:42:00 -04:00
// support page or role must be either defined for this to be valid
if support_page . is_none ( ) & & role . is_none ( ) {
return Err ( Error ::BadRequest ( ErrorKind ::NotFound , " Not found. " ) ) ;
}
2024-07-16 08:05:25 +00:00
let email_address = services . globals . well_known_support_email ( ) . clone ( ) ;
let matrix_id = services . globals . well_known_support_mxid ( ) . clone ( ) ;
2024-04-06 18:42:00 -04:00
// if a role is specified, an email address or matrix id is required
if role . is_some ( ) & & ( email_address . is_none ( ) & & matrix_id . is_none ( ) ) {
return Err ( Error ::BadRequest ( ErrorKind ::NotFound , " Not found. " ) ) ;
}
// TOOD: support defining multiple contacts in the config
let mut contacts : Vec < Contact > = vec! [ ] ;
if let Some ( role ) = role {
let contact = Contact {
role ,
email_address ,
matrix_id ,
} ;
contacts . push ( contact ) ;
}
// support page or role+contacts must be either defined for this to be valid
if contacts . is_empty ( ) & & support_page . is_none ( ) {
return Err ( Error ::BadRequest ( ErrorKind ::NotFound , " Not found. " ) ) ;
}
Ok ( discover_support ::Response {
contacts ,
support_page ,
} )
}
2024-01-07 21:24:55 -05:00
/// # `GET /client/server.json`
///
/// Endpoint provided by sliding sync proxy used by some clients such as Element
/// Web as a non-standard health check.
2024-07-16 08:05:25 +00:00
pub ( crate ) async fn syncv3_client_server_json ( State ( services ) : State < crate ::State > ) -> Result < impl IntoResponse > {
let server_url = match services . globals . well_known_client ( ) {
2024-04-11 20:17:30 -04:00
Some ( url ) = > url . to_string ( ) ,
2024-07-16 08:05:25 +00:00
None = > match services . globals . well_known_server ( ) {
2024-04-11 20:17:30 -04:00
Some ( url ) = > url . to_string ( ) ,
2024-01-07 21:24:55 -05:00
None = > return Err ( Error ::BadRequest ( ErrorKind ::NotFound , " Not found. " ) ) ,
} ,
} ;
Ok ( Json ( serde_json ::json! ( {
" server " : server_url ,
2024-06-24 22:06:20 +00:00
" version " : conduit ::version ( ) ,
2024-03-27 10:17:11 -04:00
} ) ) )
}
/// # `GET /_conduwuit/server_version`
///
/// Conduwuit-specific API to get the server version, results akin to
/// `/_matrix/federation/v1/version`
2024-04-22 23:48:57 -04:00
pub ( crate ) async fn conduwuit_server_version ( ) -> Result < impl IntoResponse > {
2024-03-27 10:17:11 -04:00
Ok ( Json ( serde_json ::json! ( {
2024-06-24 22:06:20 +00:00
" name " : conduit ::version ::name ( ) ,
" version " : conduit ::version ::version ( ) ,
2024-01-07 21:24:55 -05:00
} ) ) )
}
2024-05-23 11:26:27 -04:00
/// # `GET /_conduwuit/local_user_count`
///
/// conduwuit-specific API to return the amount of users registered on this
/// homeserver. Endpoint is disabled if federation is disabled for privacy. This
/// only includes active users (not deactivated, no guests, etc)
2024-07-16 08:05:25 +00:00
pub ( crate ) async fn conduwuit_local_user_count ( State ( services ) : State < crate ::State > ) -> Result < impl IntoResponse > {
2024-08-08 17:18:30 +00:00
let user_count = services . users . list_local_users ( ) . count ( ) . await ;
2024-05-23 11:26:27 -04:00
Ok ( Json ( serde_json ::json! ( {
" count " : user_count
} ) ) )
}