feat: Add /force-encryption command and update message handling

Implement /force-encryption command to configure forced encryption
settings with on|off and policy resend-to-confirm|block options.

The changes enhance user experience by clarifying encryption requirements
and providing actionable commands. Users can now press Enter again to
confirm unencrypted messages in resend-to-confirm mode.
This commit is contained in:
2025-08-25 20:40:32 +02:00
parent a3e23c3514
commit 442bfb6ce1
13 changed files with 121 additions and 1 deletions

View File

@@ -45,6 +45,7 @@
#include "config/preferences.h"
#include "event/common.h"
#include "plugins/plugins.h"
#include "ui/inputwin.h"
#include "ui/window_list.h"
#include "xmpp/chat_session.h"
#include "xmpp/session.h"
@@ -129,6 +130,38 @@ cl_ev_presence_send(const resource_presence_t presence_type, const int idle_secs
presence_send(presence_type, idle_secs, signed_status);
}
// Checks if an unencrypted message can be sent based on encryption preferences.
// Returns TRUE if allowed, FALSE if blocked.
static gboolean
_allow_unencrypted_message(ProfChatWin* chatwin, const char* const msg)
{
if (!prefs_get_boolean(PREF_FORCE_ENCRYPTION)) {
return TRUE; // Encryption not enforced
}
auto_gchar gchar* force_enc_mode = prefs_get_string(PREF_FORCE_ENCRYPTION_MODE);
if (g_strcmp0(force_enc_mode, "block") == 0) {
win_println((ProfWin*)chatwin, THEME_ERROR, "-", "Message not sent: encryption required. Enable (omemo/pgp/otr) encryption or /force-encryption off.");
return FALSE;
}
if (g_strcmp0(force_enc_mode, "resend-to-confirm") == 0) {
// We do not use chatwin->last_message because it should be set only if it's sent.
guint msg_hash = g_str_hash(msg);
if (msg_hash != chatwin->last_attempted_msg_hash) {
win_println((ProfWin*)chatwin, THEME_ERROR, "-", "Message not sent: encryption required. Enable (omemo/pgp/otr) encryption or press Enter again to send without encryption. Use /force-encryption off to disable this protection.");
chatwin->last_attempted_msg_hash = msg_hash;
inp_set_line(msg); // reset message to prevent the need to retype it
return FALSE;
}
return TRUE;
}
win_println((ProfWin*)chatwin, THEME_ERROR, "-", "Message not sent: invalid encryption mode (%s). Use '/force-encryption policy resend-to-confirm'.", force_enc_mode);
return FALSE;
}
void
cl_ev_send_msg_correct(ProfChatWin* chatwin, const char* const msg, const char* const oob_url, gboolean correct_last_msg)
{
@@ -177,7 +210,7 @@ cl_ev_send_msg_correct(ProfChatWin* chatwin, const char* const msg, const char*
#ifdef HAVE_LIBOTR
handled = otr_on_message_send(chatwin, message, request_receipt, replace_id);
#endif
if (!handled) {
if (!handled && _allow_unencrypted_message(chatwin, message)) {
auto_char char* id = message_send_chat(chatwin->barejid, message, oob_url, request_receipt, replace_id);
chat_log_msg_out(chatwin->barejid, message, NULL);
log_database_add_outgoing_chat(id, chatwin->barejid, message, replace_id, PROF_MSG_ENC_NONE);