feat: do not create device messages for IMAP authentication errors

Authentication failures may happen because of internal server errors.
Device message saying "Please check if the email address and the password are correct"
was written for classic email setups when the user knows the password.
For users of chatmail relays this message is not actionable,
but still appears when relay fails to check the password.
This commit is contained in:
link2xt
2026-08-26 13:53:02 +00:00
committed by l
parent 49496756e4
commit 7421e67ab6
8 changed files with 14 additions and 84 deletions
+8 -50
View File
@@ -28,7 +28,6 @@ use crate::context::Context;
use crate::ensure_and_debug_assert;
use crate::events::EventType;
use crate::headerdef::{HeaderDef, HeaderDefMap};
use crate::log::LogExt;
use crate::log::warn;
use crate::message::{self, Message};
use crate::mimeparser;
@@ -37,7 +36,6 @@ use crate::net::session::SessionStream;
use crate::push::encrypt_device_token;
use crate::receive_imf::{ReceivedMsg, from_field_to_contact_id, receive_imf_inner};
use crate::scheduler::connectivity::ConnectivityStore;
use crate::stock_str;
use crate::tools::{self, create_id, duration_to_str, time};
use crate::transport::{
ConfiguredLoginParam, ConfiguredServerLoginParam, prioritize_server_login_params,
@@ -87,8 +85,6 @@ pub(crate) struct Imap {
/// Watched folder.
pub(crate) folder: String,
authentication_failed_once: bool,
pub(crate) connectivity: ConnectivityStore,
conn_last_try: tools::Time,
@@ -234,7 +230,6 @@ impl Imap {
proxy_config,
strict_tls,
folder,
authentication_failed_once: false,
connectivity: Default::default(),
conn_last_try: UNIX_EPOCH,
conn_backoff_ms: 0,
@@ -267,11 +262,7 @@ impl Imap {
/// Calling this function is not enough to perform IMAP operations. Use [`Imap::prepare`]
/// instead if you are going to actually use connection rather than trying connection
/// parameters.
pub(crate) async fn connect(
&mut self,
context: &Context,
configuring: bool,
) -> Result<Session> {
pub(crate) async fn connect(&mut self, context: &Context) -> Result<Session> {
let now = tools::Time::now();
let until_can_send = max(
min(self.conn_last_try, now)
@@ -342,7 +333,10 @@ impl Imap {
let imap_pw: &str = &self.password;
info!(context, "Logging into IMAP server with LOGIN.");
let login_res = client.login(imap_user, imap_pw).await;
let login_res = client
.login(imap_user, imap_pw)
.await
.with_context(|| format!("IMAP failed to login as {imap_user}"));
match login_res {
Ok((mut session, login_capabilities_opt)) => {
@@ -395,7 +389,6 @@ impl Imap {
let mut lock = context.server_id.write().await;
lock.clone_from(&session.capabilities.server_id);
self.authentication_failed_once = false;
context.emit_event(EventType::ImapConnected(format!(
"IMAP-LOGIN as {}",
lp.user
@@ -406,42 +399,8 @@ impl Imap {
}
Err(err) => {
let imap_user = lp.user.to_owned();
let message = stock_str::cannot_login(context, &imap_user);
warn!(context, "IMAP failed to login: {err:#}.");
first_error.get_or_insert(format_err!("{message} ({err:#})"));
// If it looks like the password is wrong, send a notification:
let _lock = context.wrong_pw_warning_mutex.lock().await;
if err.to_string().to_lowercase().contains("authentication") {
if self.authentication_failed_once
&& !configuring
&& context.get_config_bool(Config::NotifyAboutWrongPw).await?
{
let mut msg = Message::new_text(message);
if let Err(e) = chat::add_device_msg_with_importance(
context,
None,
Some(&mut msg),
true,
)
.await
{
warn!(context, "Failed to add device message: {e:#}.");
} else {
context
.set_config_internal(Config::NotifyAboutWrongPw, None)
.await
.log_err(context)
.ok();
}
} else {
self.authentication_failed_once = true;
}
} else {
self.authentication_failed_once = false;
}
warn!(context, "{err:#}.");
first_error.get_or_insert(err);
}
}
}
@@ -454,8 +413,7 @@ impl Imap {
/// This creates a new IMAP connection and ensures
/// that folders are created and IMAP capabilities are determined.
pub(crate) async fn prepare(&mut self, context: &Context) -> Result<Session> {
let configuring = false;
let session = match self.connect(context, configuring).await {
let session = match self.connect(context).await {
Ok(session) => session,
Err(err) => {
self.connectivity.set_err(context, format!("{err:#}"));