diff --git a/app/lib/main.dart b/app/lib/main.dart index c0de2b7..e1a0827 100644 --- a/app/lib/main.dart +++ b/app/lib/main.dart @@ -2944,6 +2944,9 @@ class MeshNode { } } +/// The protocol identifier sent to the API to filter results to Meshtastic only. +const String _kProtocolFilter = 'meshtastic'; + /// Build a messages API URI for a given domain or absolute URL. Uri _buildMessagesUri(String domain, {int since = 0, int limit = 1000}) { final trimmed = domain.trim(); @@ -2951,6 +2954,7 @@ Uri _buildMessagesUri(String domain, {int since = 0, int limit = 1000}) { 'limit': limit.toString(), 'encrypted': 'false', 'since': since.toString(), + 'protocol': _kProtocolFilter, }; if (trimmed.isEmpty) { return Uri.https('potatomesh.net', '/api/messages', params); @@ -2988,7 +2992,7 @@ Uri _buildNodeUri(String domain, String nodeId) { /// Build the bulk nodes API URI for fetching recent nodes. Uri _buildNodesUri(String domain, {int limit = 1000}) { final trimmedDomain = domain.trim(); - final params = {'limit': limit.toString()}; + final params = {'limit': limit.toString(), 'protocol': _kProtocolFilter}; if (trimmedDomain.isEmpty) { return Uri.https('potatomesh.net', '/api/nodes', params); diff --git a/app/test/mesh_message_test.dart b/app/test/mesh_message_test.dart index cd5cd75..9b86b34 100644 --- a/app/test/mesh_message_test.dart +++ b/app/test/mesh_message_test.dart @@ -206,8 +206,10 @@ void main() { expect(calls[0].host, 'mesh.example.org'); expect(calls[0].path, '/api/messages'); + expect(calls[0].queryParameters['protocol'], 'meshtastic'); expect(calls[1].scheme, 'https'); expect(calls[1].path, '/api/messages'); + expect(calls[1].queryParameters['protocol'], 'meshtastic'); }); }); diff --git a/app/test/mesh_repository_test.dart b/app/test/mesh_repository_test.dart index ca702da..14a3f16 100644 --- a/app/test/mesh_repository_test.dart +++ b/app/test/mesh_repository_test.dart @@ -145,6 +145,7 @@ void main() { if (request.url.path == '/api/messages') { sinces.add(request.url.queryParameters['since'] ?? ''); expect(request.url.queryParameters['limit'], '1000'); + expect(request.url.queryParameters['protocol'], 'meshtastic'); if (sinces.length == 1) { return http.Response( jsonEncode([ diff --git a/matrix/src/potatomesh.rs b/matrix/src/potatomesh.rs index fc55cbe..c815680 100644 --- a/matrix/src/potatomesh.rs +++ b/matrix/src/potatomesh.rs @@ -19,6 +19,11 @@ use tokio::sync::RwLock; use crate::config::PotatomeshConfig; +/// Protocol identifier sent as a query parameter to restrict API results to +/// Meshtastic data only. Other protocols (e.g. MeshCore) are excluded until +/// the clients are updated to support them. +const PROTOCOL_FILTER: &str = "meshtastic"; + #[allow(dead_code)] #[derive(Debug, Deserialize, Clone)] pub struct PotatoMessage { @@ -131,7 +136,10 @@ impl PotatoClient { } pub async fn fetch_messages(&self, params: FetchParams) -> anyhow::Result> { - let mut req = self.http.get(self.messages_url()); + let mut req = self + .http + .get(self.messages_url()) + .query(&[("protocol", PROTOCOL_FILTER)]); if let Some(limit) = params.limit { req = req.query(&[("limit", limit)]); } @@ -336,7 +344,10 @@ mod tests { let mut server = mockito::Server::new_async().await; let mock = server .mock("GET", "/api/messages") - .match_query(mockito::Matcher::Any) // allow optional query params + .match_query(mockito::Matcher::UrlEncoded( + "protocol".into(), + "meshtastic".into(), + )) .with_status(200) .with_header("content-type", "application/json") .with_body( @@ -427,7 +438,10 @@ mod tests { let mut server = mockito::Server::new_async().await; let mock = server .mock("GET", "/api/messages") - .match_query(mockito::Matcher::Any) + .match_query(mockito::Matcher::UrlEncoded( + "protocol".into(), + PROTOCOL_FILTER.into(), + )) .with_status(500) .create(); @@ -448,7 +462,11 @@ mod tests { let mut server = mockito::Server::new_async().await; let mock = server .mock("GET", "/api/messages") - .match_query("limit=10&since=123") + .match_query(mockito::Matcher::AllOf(vec![ + mockito::Matcher::UrlEncoded("protocol".into(), PROTOCOL_FILTER.into()), + mockito::Matcher::UrlEncoded("limit".into(), "10".into()), + mockito::Matcher::UrlEncoded("since".into(), "123".into()), + ])) .with_status(200) .with_header("content-type", "application/json") .with_body("[]")