From 93918a20d109947ca486f23f26eb30a9c3b97fe5 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Thu, 19 Mar 2026 10:54:38 +0100 Subject: [PATCH] feat: Display incoming reports (XEP-0377) Servers might forward incoming reports to admins. So we need to display them so they can react upon it. --- src/xmpp/blocking.c | 62 +++++++++++++++++++++++++++++++++++++++++++++ src/xmpp/blocking.h | 1 + src/xmpp/iq.c | 5 ++++ 3 files changed, 68 insertions(+) diff --git a/src/xmpp/blocking.c b/src/xmpp/blocking.c index 1d16fd8c..955f69cd 100644 --- a/src/xmpp/blocking.c +++ b/src/xmpp/blocking.c @@ -319,3 +319,65 @@ _blocklist_result_handler(xmpp_stanza_t* const stanza, void* const userdata) return 0; } + +int +reporting_set_handler(xmpp_stanza_t* stanza) +{ + const char* from = xmpp_stanza_get_from(stanza); + xmpp_stanza_t* report = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_REPORTING); + if (!report) { + return 1; + } + + const char* reason = xmpp_stanza_get_attribute(report, STANZA_ATTR_REASON); + const char* display_reason = "unknown"; + if (g_strcmp0(reason, STANZA_REPORTING_SPAM) == 0) { + display_reason = "spam"; + } else if (g_strcmp0(reason, STANZA_REPORTING_ABUSE) == 0) { + display_reason = "abuse"; + } + + char* message = NULL; + xmpp_stanza_t* body = xmpp_stanza_get_child_by_name(report, STANZA_NAME_BODY); + if (body) { + message = xmpp_stanza_get_text(body); + } else { + xmpp_stanza_t* text = xmpp_stanza_get_child_by_name(report, STANZA_NAME_TEXT); + if (text) { + message = xmpp_stanza_get_text(text); + } + } + + // Attempt to find the reported JID if it's wrapped in an item (sync push style) + const char* reported_jid = NULL; + xmpp_stanza_t* block = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_BLOCKING); + if (block) { + xmpp_stanza_t* item = xmpp_stanza_get_child_by_name(block, STANZA_NAME_ITEM); + if (item) { + reported_jid = xmpp_stanza_get_attribute(item, STANZA_ATTR_JID); + } + } + + if (reported_jid) { + if (message) { + cons_show("Incoming %s report from %s: User %s reported for %s. Content: \"%s\"", + display_reason, from, reported_jid, display_reason, message); + } else { + cons_show("Incoming %s report from %s: User %s reported for %s.", + display_reason, from, reported_jid, display_reason); + } + } else { + if (message) { + cons_show("Incoming %s report from %s. Content: \"%s\"", + display_reason, from, message); + } else { + cons_show("Incoming %s report from %s.", display_reason, from); + } + } + + if (message) { + xmpp_free(xmpp_stanza_get_context(stanza), message); + } + + return 1; +} diff --git a/src/xmpp/blocking.h b/src/xmpp/blocking.h index b45dc9f3..7f0df5b4 100644 --- a/src/xmpp/blocking.h +++ b/src/xmpp/blocking.h @@ -12,5 +12,6 @@ void blocking_request(void); int blocked_set_handler(xmpp_stanza_t* stanza); +int reporting_set_handler(xmpp_stanza_t* stanza); #endif diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index 1bb2bb64..bbc5b5d4 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -208,6 +208,11 @@ _iq_handler(xmpp_conn_t* const conn, xmpp_stanza_t* const stanza, void* const us blocked_set_handler(stanza); } + xmpp_stanza_t* reporting = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_REPORTING); + if (reporting && (g_strcmp0(type, STANZA_TYPE_SET) == 0)) { + reporting_set_handler(stanza); + } + const char* id = xmpp_stanza_get_id(stanza); if (id) { ProfIqHandler* handler = g_hash_table_lookup(id_handlers, id);