From 321ff571505355c07cd8a57a39bef22d9d95f64c Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Wed, 18 Mar 2026 20:05:04 +0100 Subject: [PATCH 1/3] feat(omemo): suppress repetitive missing device ID warnings When sending OMEMO messages, we print a warning message for every participant without a device ID on every single send: ``` Can't find a OMEMO device id for my@jid.org ``` This clutters the UI due to the high volume of repetitive information. This is solved by tracking suppressed warnings within the window structure. A warning for a specific JID and type is only shown once per window context. Suppression state is stored in the base ProfWin structure and managed via helper functions (win_warn_needed, win_warn_sent). The state is lazily initialized to save resources and automatically cleaned up when the window is closed. Warnings are explicitly reset when an OMEMO session is started or ended to ensure users see fresh alerts when toggling encryption. --- src/command/cmd_funcs.c | 5 +++++ src/omemo/omemo.c | 7 +++++- src/ui/win_types.h | 1 + src/ui/window.c | 42 ++++++++++++++++++++++++++++++++++++ src/ui/window.h | 4 ++++ tests/unittests/ui/stub_ui.c | 16 ++++++++++++++ 6 files changed, 74 insertions(+), 1 deletion(-) diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index 107b1caf8..05d032274 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -57,6 +57,7 @@ #include "plugins/plugins.h" #include "ui/inputwin.h" #include "ui/ui.h" +#include "ui/window.h" #include "ui/window_list.h" #include "xmpp/avatar.h" #include "xmpp/chat_session.h" @@ -8456,6 +8457,7 @@ cmd_omemo_start(ProfWin* window, const char* const command, gchar** args) win_println((ProfWin*)chatwin, THEME_DEFAULT, "!", "Initiating OMEMO session with %s...", chatwin->barejid); omemo_start_session(chatwin->barejid); chatwin->is_omemo = TRUE; + win_clear_warned_jids((ProfWin*)chatwin); } else if (window->type == WIN_MUC) { ProfMucWin* mucwin = (ProfMucWin*)window; assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); @@ -8471,6 +8473,7 @@ cmd_omemo_start(ProfWin* window, const char* const command, gchar** args) win_println((ProfWin*)mucwin, THEME_DEFAULT, "!", "Initiating OMEMO session in %s...", mucwin->roomjid); omemo_start_muc_sessions(mucwin->roomjid); mucwin->is_omemo = TRUE; + win_clear_warned_jids((ProfWin*)mucwin); } else { win_println(window, THEME_DEFAULT, "!", "MUC must be non-anonymous (i.e. be configured to present real jid to anyone) and members-only in order to support OMEMO."); } @@ -8589,6 +8592,7 @@ cmd_omemo_end(ProfWin* window, const char* const command, gchar** args) chatwin->is_omemo = FALSE; accounts_add_omemo_state(session_get_account_name(), chatwin->barejid, FALSE); + win_clear_warned_jids((ProfWin*)chatwin); } else if (window->type == WIN_MUC) { ProfMucWin* mucwin = (ProfMucWin*)window; assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK); @@ -8600,6 +8604,7 @@ cmd_omemo_end(ProfWin* window, const char* const command, gchar** args) mucwin->is_omemo = FALSE; accounts_add_omemo_state(session_get_account_name(), mucwin->roomjid, FALSE); + win_clear_warned_jids((ProfWin*)mucwin); } else { win_println(window, THEME_DEFAULT, "-", "You must be in a regular chat window to start an OMEMO session."); return TRUE; diff --git a/src/omemo/omemo.c b/src/omemo/omemo.c index bfd984a33..54dba460f 100644 --- a/src/omemo/omemo.c +++ b/src/omemo/omemo.c @@ -30,6 +30,7 @@ #include "omemo/omemo.h" #include "omemo/store.h" #include "ui/ui.h" +#include "ui/window.h" #include "ui/window_list.h" #include "xmpp/connection.h" #include "xmpp/muc.h" @@ -822,7 +823,11 @@ omemo_on_message_send(ProfWin* win, const char* const message, gboolean request_ recipient_device_id = g_hash_table_lookup(omemo_ctx.device_list, recipients_iter->data); if (!recipient_device_id) { log_warning("[OMEMO][SEND] cannot find device ids for %s", recipients_iter->data); - win_println(win, THEME_ERROR, "!", "Can't find a OMEMO device id for %s.\n", recipients_iter->data); + + if (win_warn_needed(win, "omemo_no_device", recipients_iter->data)) { + win_println(win, THEME_ERROR, "!", "Can't find a OMEMO device id for %s.", recipients_iter->data); + win_warn_sent(win, "omemo_no_device", recipients_iter->data); + } continue; } diff --git a/src/ui/win_types.h b/src/ui/win_types.h index 2f83eb607..dddab862b 100644 --- a/src/ui/win_types.h +++ b/src/ui/win_types.h @@ -133,6 +133,7 @@ typedef struct prof_win_t ProfLayout* layout; Autocomplete urls_ac; Autocomplete quotes_ac; + GHashTable* warned_jids; } ProfWin; typedef struct prof_console_win_t diff --git a/src/ui/window.c b/src/ui/window.c index 178a2c0b0..a2fc10ea2 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -557,6 +557,10 @@ win_free(ProfWin* window) } free(window->layout); + if (window->warned_jids) { + g_hash_table_destroy(window->warned_jids); + } + switch (window->type) { case WIN_CHAT: { @@ -609,6 +613,44 @@ win_free(ProfWin* window) free(window); } +gboolean +win_warn_needed(ProfWin* window, const char* const type, const char* const jid) +{ + if (!window || !type || !jid) { + return TRUE; + } + + if (!window->warned_jids) { + return TRUE; + } + + auto_gchar gchar* key = g_strdup_printf("%s:%s", type, jid); + return !g_hash_table_contains(window->warned_jids, key); +} + +void +win_warn_sent(ProfWin* window, const char* const type, const char* const jid) +{ + if (!window || !type || !jid) { + return; + } + + if (!window->warned_jids) { + window->warned_jids = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + } + + gchar* key = g_strdup_printf("%s:%s", type, jid); + g_hash_table_insert(window->warned_jids, key, GINT_TO_POINTER(1)); +} + +void +win_clear_warned_jids(ProfWin* window) +{ + if (window && window->warned_jids) { + g_hash_table_remove_all(window->warned_jids); + } +} + void win_page_up(ProfWin* window, int scroll_size) { diff --git a/src/ui/window.h b/src/ui/window.h index 026392eee..08e3e8e3e 100644 --- a/src/ui/window.h +++ b/src/ui/window.h @@ -59,6 +59,10 @@ void win_update_entry_message(ProfWin* window, const char* const id, const char* gboolean win_has_active_subwin(ProfWin* window); +gboolean win_warn_needed(ProfWin* window, const char* const type, const char* const jid); +void win_warn_sent(ProfWin* window, const char* const type, const char* const jid); +void win_clear_warned_jids(ProfWin* window); + void win_page_up(ProfWin* window, int scroll_size); void win_page_down(ProfWin* window, int scroll_size); void win_sub_page_down(ProfWin* window); diff --git a/tests/unittests/ui/stub_ui.c b/tests/unittests/ui/stub_ui.c index 4beb62006..2d0a200af 100644 --- a/tests/unittests/ui/stub_ui.c +++ b/tests/unittests/ui/stub_ui.c @@ -1318,6 +1318,22 @@ win_refresh_with_subwin(ProfWin* window) { } +gboolean +win_warn_needed(ProfWin* window, const char* const type, const char* const jid) +{ + return TRUE; +} + +void +win_warn_sent(ProfWin* window, const char* const type, const char* const jid) +{ +} + +void +win_clear_warned_jids(ProfWin* window) +{ +} + void win_println(ProfWin* window, theme_item_t theme, const char* ch, const char* const message, ...) { From 4253da99c5a28bd80ef475bb024973352ae20129 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Wed, 18 Mar 2026 21:57:06 +0100 Subject: [PATCH 2/3] feat(omemo): suppress redundant `session already exists` messages Removing the UI notification in omemo_start_device_session to reduce noise during /omemo start. The information is still available in the debug logs. And I think for existing sessions its just too much without value. Ref: b20e3f1a --- src/omemo/omemo.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/omemo/omemo.c b/src/omemo/omemo.c index 54dba460f..4ba048a3c 100644 --- a/src/omemo/omemo.c +++ b/src/omemo/omemo.c @@ -729,17 +729,6 @@ omemo_start_device_session(const char* const jid, uint32_t device_id, } } else { log_debug("[OMEMO] session with %s device %d exists", jid, device_id); - if (omemo_ctx.notifying) { - ProfChatWin* chatwin = wins_get_chat(jid); - if (chatwin) { - win_println((ProfWin*)chatwin, THEME_DEFAULT, "!", "OMEMO session with %s (device %u) already exists.", jid, device_id); - } else { - ProfMucWin* mucwin = wins_get_muc(jid); - if (mucwin) { - win_println((ProfWin*)mucwin, THEME_DEFAULT, "!", "OMEMO session with %s (device %u) already exists.", jid, device_id); - } - } - } } out: From b7c8f8235c08fb45556a4831469c8840e431fd30 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Wed, 18 Mar 2026 22:14:45 +0100 Subject: [PATCH 3/3] feat(omemo): suppress "new device" alerts for already known devices Modify omemo_set_device_list to check against the persistent known_devices.txt file before notifying the user. This prevents false-positive security alerts on every restart for devices that have already been registered and trusted. Check against the persistent known_devices.txt file before notifying the user. This ensures that "New OMEMO device" alerts are only shown for devices that are truly new to this client. Ref: ce9b5140d --- src/omemo/omemo.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/omemo/omemo.c b/src/omemo/omemo.c index 4ba048a3c..dd6e60f2f 100644 --- a/src/omemo/omemo.c +++ b/src/omemo/omemo.c @@ -515,18 +515,21 @@ omemo_set_device_list(const char* const from, GList* device_list) } if (!found) { - if (equals_our_barejid(jid->barejid)) { - if (dev_id != omemo_ctx.device_id) { - cons_show("New OMEMO device (ID: %u) added to your account.", dev_id); - } - } else { - ProfChatWin* chatwin = wins_get_chat(jid->barejid); - if (chatwin) { - win_println((ProfWin*)chatwin, THEME_DEFAULT, "!", "New OMEMO device (ID: %u) found for %s.", dev_id, jid->barejid); + auto_gchar gchar* dev_id_str = g_strdup_printf("%u", dev_id); + if (!g_key_file_has_key(omemo_ctx.knowndevices.keyfile, jid->barejid, dev_id_str, NULL)) { + if (equals_our_barejid(jid->barejid)) { + if (dev_id != omemo_ctx.device_id) { + cons_show("New OMEMO device (ID: %u) added to your account.", dev_id); + } } else { - ProfMucWin* mucwin = wins_get_muc(jid->barejid); - if (mucwin) { - win_println((ProfWin*)mucwin, THEME_DEFAULT, "!", "New OMEMO device (ID: %u) found for %s.", dev_id, jid->barejid); + ProfChatWin* chatwin = wins_get_chat(jid->barejid); + if (chatwin) { + win_println((ProfWin*)chatwin, THEME_DEFAULT, "!", "New OMEMO device (ID: %u) found for %s.", dev_id, jid->barejid); + } else { + ProfMucWin* mucwin = wins_get_muc(jid->barejid); + if (mucwin) { + win_println((ProfWin*)mucwin, THEME_DEFAULT, "!", "New OMEMO device (ID: %u) found for %s.", dev_id, jid->barejid); + } } } }