Open Bug 1774143 Opened 8 months ago Updated 6 months ago

Catchall hints are ignored when header contains the exact email address of an identity

Categories

(Thunderbird :: Message Compose Window, defect)

Thunderbird 102
defect

Tracking

(Not tracked)

UNCONFIRMED

People

(Reporter: bernat, Unassigned)

References

(Blocks 1 open bug)

Details

User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0

Steps to reproduce:

  1. Configure me@domain1.example.com and me@domain2.example.com
  2. me@domain1.example.com has a catchall hint set to *@domain3.example.com
  3. Reply to an email delivered to me@domain2.example.com and with To field set to list@domain3.example.com

Actual results:

me@domain2.example.com is used as the best identity

Expected results:

me@domain1.example.com should be used instead

In MailUtils.jsm, getBestIdentity() is checking first for an exact match in the provided hints:

      for (let hint of hints) {
        for (let identity of identities.filter(i => i.email)) {
          if (hint.email.toLowerCase() == identity.email.toLowerCase()) {
            return [identity, hint];
          }
        }
      }

Then, it looks at the catchall hints:

      // Lets search again, this time for a match from catchAll.
      for (let hint of hints) {
        for (let identity of identities.filter(
          i => i.email && i.catchAll && i.catchAllHint
        )) {
          for (let caHint of identity.catchAllHint.toLowerCase().split(",")) {
            // If the hint started with *@, it applies to the whole domain. In
            // this case return the hint so it can be used for replying.
            // If the hint was for a more specific hint, don't return a hint
            // so that the normal from address for the identity is used.
            let wholeDomain = caHint.trim().startsWith("*@");
            caHint = caHint.trim().replace(/^\*/, ""); // Remove initial star.
            if (hint.email.toLowerCase().includes(caHint)) {
              return wholeDomain ? [identity, hint] : [identity, null];
            }
          }
        }
      }

This makes it difficult to override an identity, notably when using mailing lists. The two checks could be reverted and it would work for me. I expect that when providing catchall hints, they have precedence over other stuff.

Blocks: tb102found

I have tried this patch:

--- a/omni/modules/MailUtils.jsm	2022-08-23 03:45:28.000000000 +0200
+++ b/omni/modules/MailUtils.jsm	2022-08-23 15:34:39.723281445 +0200
@@ -474,15 +474,7 @@
         optionalHint
       );
 
-      for (let hint of hints) {
-        for (let identity of identities.filter(i => i.email)) {
-          if (hint.email.toLowerCase() == identity.email.toLowerCase()) {
-            return [identity, hint];
-          }
-        }
-      }
-
-      // Lets search again, this time for a match from catchAll.
+      // Lets for a match from catchAll.
       for (let hint of hints) {
         for (let identity of identities.filter(
           i => i.email && i.catchAll && i.catchAllHint
@@ -500,6 +492,15 @@
           }
         }
       }
+
+      // If not found, fallback to email addresses from identities
+      for (let hint of hints) {
+        for (let identity of identities.filter(i => i.email)) {
+          if (hint.email.toLowerCase() == identity.email.toLowerCase()) {
+            return [identity, hint];
+          }
+        }
+      }
     }
 
     // Still no matches? Give up and pick the default or the first one.

However, when there is a catchall match, it uses one of the addresses in the headers instead of mine. I don't understand how this hint system should be used.

Notably the following comment:

            // If the hint started with *@, it applies to the whole domain. In
            // this case return the hint so it can be used for replying.
            // If the hint was for a more specific hint, don't return a hint
            // so that the normal from address for the identity is used.

If I use this patch, it works as expected for me:

--- ./omni/modules/MailUtils.jsm	2022-08-23 03:45:28.000000000 +0200
+++ ./omni/modules/MailUtils.jsm	2022-08-23 16:28:26.192547963 +0200
@@ -474,32 +474,28 @@
         optionalHint
       );
 
-      for (let hint of hints) {
-        for (let identity of identities.filter(i => i.email)) {
-          if (hint.email.toLowerCase() == identity.email.toLowerCase()) {
-            return [identity, hint];
-          }
-        }
-      }
-
-      // Lets search again, this time for a match from catchAll.
+      // Let's search for a match from catchAll.
       for (let hint of hints) {
         for (let identity of identities.filter(
           i => i.email && i.catchAll && i.catchAllHint
         )) {
           for (let caHint of identity.catchAllHint.toLowerCase().split(",")) {
-            // If the hint started with *@, it applies to the whole domain. In
-            // this case return the hint so it can be used for replying.
-            // If the hint was for a more specific hint, don't return a hint
-            // so that the normal from address for the identity is used.
-            let wholeDomain = caHint.trim().startsWith("*@");
             caHint = caHint.trim().replace(/^\*/, ""); // Remove initial star.
             if (hint.email.toLowerCase().includes(caHint)) {
-              return wholeDomain ? [identity, hint] : [identity, null];
+              return [identity, null];
             }
           }
         }
       }
+
+      // Check against the email addresses of each identity.
+      for (let hint of hints) {
+        for (let identity of identities.filter(i => i.email)) {
+          if (hint.email.toLowerCase() == identity.email.toLowerCase()) {
+            return [identity, hint];
+          }
+        }
+      }
     }
 
     // Still no matches? Give up and pick the default or the first one.

If I reply when something is matching the catch all from one of the identity, the email address of the identity is used. If I reply when there is no such match, but there is a match for one of the email addresses, it uses this one and if there is no match at all, it uses the default identity.

You need to log in before you can comment on or make changes to this bug.