diff --git a/server/src/routes/nodeinfo.rs b/server/src/routes/nodeinfo.rs index 509e3404a..75568608e 100644 --- a/server/src/routes/nodeinfo.rs +++ b/server/src/routes/nodeinfo.rs @@ -1,3 +1,4 @@ +extern crate lazy_static; use crate::db::site_view::SiteView; use crate::version; use crate::Settings; @@ -6,7 +7,7 @@ use actix_web::web; use actix_web::HttpResponse; use diesel::r2d2::{ConnectionManager, Pool}; use diesel::PgConnection; -use serde_json::json; +use serde::Serialize; pub fn config(cfg: &mut web::ServiceConfig) { cfg @@ -15,14 +16,13 @@ pub fn config(cfg: &mut web::ServiceConfig) { } async fn node_info_well_known() -> HttpResponse { - let json = json!({ - "links": { - "rel": "http://nodeinfo.diaspora.software/ns/schema/2.0", - "href": format!("https://{}/nodeinfo/2.0.json", Settings::get().hostname), - } - }); - - HttpResponse::Ok().json(json) + let node_info = NodeInfoWellKnown { + links: NodeInfoWellKnownLinks { + rel: "http://nodeinfo.diaspora.software/ns/schema/2.0".to_string(), + href: format!("https://{}/nodeinfo/2.0.json", Settings::get().hostname), + }, + }; + HttpResponse::Ok().json(node_info) } async fn node_info( @@ -35,29 +35,68 @@ async fn node_info( Err(_) => return Err(format_err!("not_found")), }; let protocols = if Settings::get().federation_enabled { - vec!["activitypub"] + vec!["activitypub".to_string()] } else { vec![] }; - Ok(json!({ - "version": "2.0", - "software": { - "name": "lemmy", - "version": version::VERSION, + Ok(NodeInfo { + version: "2.0".to_string(), + software: NodeInfoSoftware { + name: "lemmy".to_string(), + version: version::VERSION.to_string(), }, - "protocols": protocols, - "usage": { - "users": { - "total": site_view.number_of_users + protocols, + usage: NodeInfoUsage { + users: NodeInfoUsers { + total: site_view.number_of_users, }, - "localPosts": site_view.number_of_posts, - "localComments": site_view.number_of_comments, - "openRegistrations": site_view.open_registration, - } - })) + local_posts: site_view.number_of_posts, + local_comments: site_view.number_of_comments, + open_registrations: site_view.open_registration, + }, + }) }) .await .map(|json| HttpResponse::Ok().json(json)) .map_err(|_| HttpResponse::InternalServerError())?; Ok(res) } + +#[derive(Serialize)] +struct NodeInfoWellKnown { + links: NodeInfoWellKnownLinks, +} + +#[derive(Serialize)] +struct NodeInfoWellKnownLinks { + rel: String, + href: String, +} + +#[derive(Serialize)] +struct NodeInfo { + version: String, + software: NodeInfoSoftware, + protocols: Vec, + usage: NodeInfoUsage, +} + +#[derive(Serialize)] +struct NodeInfoSoftware { + name: String, + version: String, +} + +#[derive(Serialize)] +#[serde(rename_all = "camelCase")] +struct NodeInfoUsage { + users: NodeInfoUsers, + local_posts: i64, + local_comments: i64, + open_registrations: bool, +} + +#[derive(Serialize)] +struct NodeInfoUsers { + total: i64, +}