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..dd6e60f2f 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" @@ -514,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); + } } } } @@ -728,17 +732,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: @@ -822,7 +815,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, ...) {