From 75b24cc557d4947ab46691142863e5a5db5c3f78 Mon Sep 17 00:00:00 2001
From: Alois Wohlschlager <alois1@gmx-topmail.de>
Date: Sat, 11 Feb 2023 20:29:48 +0100
Subject: [PATCH] thunderbird: support aliases

The main email address, as well as all aliases, each get mapped to one
identity in Thunderbird. All these identities are then linked to their
account.
---
 modules/programs/thunderbird.nix              | 53 +++++++++++++++----
 .../thunderbird/thunderbird-expected-first.js | 14 ++++-
 .../programs/thunderbird/thunderbird.nix      |  2 +
 3 files changed, 58 insertions(+), 11 deletions(-)

diff --git a/modules/programs/thunderbird.nix b/modules/programs/thunderbird.nix
index 786eff051..c072c984f 100644
--- a/modules/programs/thunderbird.nix
+++ b/modules/programs/thunderbird.nix
@@ -38,16 +38,17 @@ let
     };
   }));
 
-  toThunderbirdAccount = account: profile:
-    let id = account.id;
+  toThunderbirdIdentity = account: address:
+    # For backwards compatibility, the primary address reuses the account ID.
+    let
+      id = if address == account.address then
+        account.id
+      else
+        builtins.hashString "sha256" address;
     in {
-      "mail.account.account_${id}.identities" = "id_${id}";
-      "mail.account.account_${id}.server" = "server_${id}";
       "mail.identity.id_${id}.fullName" = account.realName;
-      "mail.identity.id_${id}.useremail" = account.address;
+      "mail.identity.id_${id}.useremail" = address;
       "mail.identity.id_${id}.valid" = true;
-    } // optionalAttrs account.primary {
-      "mail.accountmanager.defaultaccount" = "account_${id}";
     } // optionalAttrs (account.gpg != null) {
       "mail.identity.id_${id}.attachPgpKey" = false;
       "mail.identity.id_${id}.autoEncryptDrafts" = true;
@@ -60,6 +61,20 @@ let
       "mail.identity.id_${id}.openpgp_key_id" = account.gpg.key;
       "mail.identity.id_${id}.protectSubject" = true;
       "mail.identity.id_${id}.sign_mail" = account.gpg.signByDefault;
+    } // account.thunderbird.perIdentitySettings id;
+
+  toThunderbirdAccount = account: profile:
+    let
+      id = account.id;
+      addresses = [ account.address ] ++ account.aliases;
+    in {
+      "mail.account.account_${id}.identities" = concatStringsSep ","
+        ([ "id_${id}" ]
+          ++ map (address: "id_${builtins.hashString "sha256" address}")
+          account.aliases);
+      "mail.account.account_${id}.server" = "server_${id}";
+    } // optionalAttrs account.primary {
+      "mail.accountmanager.defaultaccount" = "account_${id}";
     } // optionalAttrs (account.imap != null) {
       "mail.server.server_${id}.directory" =
         "${thunderbirdProfilesPath}/${profile.name}/ImapMail/${id}";
@@ -92,7 +107,9 @@ let
       "mail.smtpserver.smtp_${id}.username" = account.userName;
     } // optionalAttrs (account.smtp != null && account.primary) {
       "mail.smtp.defaultserver" = "smtp_${id}";
-    } // account.thunderbird.settings id;
+    } // builtins.foldl' (a: b: a // b) { }
+    (builtins.map (address: toThunderbirdIdentity account address) addresses)
+    // account.thunderbird.settings id;
 
   mkUserJs = prefs: extraPrefs: ''
     // Generated by Home Manager.
@@ -246,8 +263,7 @@ in {
               defaultText = literalExpression "_: { }";
               example = literalExpression ''
                 id: {
-                  "mail.identity.id_''${id}.protectSubject" = false;
-                  "mail.identity.id_''${id}.autoEncryptDrafts" = false;
+                  "mail.server.server_''${id}.check_new_mail" = false;
                 };
               '';
               description = ''
@@ -256,6 +272,23 @@ in {
                 generated account identifier.
               '';
             };
+
+            perIdentitySettings = mkOption {
+              type = with types; functionTo (attrsOf (oneOf [ bool int str ]));
+              default = _: { };
+              defaultText = literalExpression "_: { }";
+              example = literalExpression ''
+                id: {
+                  "mail.identity.id_''${id}.protectSubject" = false;
+                  "mail.identity.id_''${id}.autoEncryptDrafts" = false;
+                };
+              '';
+              description = ''
+                Extra settings to add to each identity of this Thunderbird
+                account configuration. The <varname>id</varname> given as
+                argument is an automatically generated identifier.
+              '';
+            };
           };
         });
     };
diff --git a/tests/modules/programs/thunderbird/thunderbird-expected-first.js b/tests/modules/programs/thunderbird/thunderbird-expected-first.js
index e9c3d6d9d..0c5a65a82 100644
--- a/tests/modules/programs/thunderbird/thunderbird-expected-first.js
+++ b/tests/modules/programs/thunderbird/thunderbird-expected-first.js
@@ -3,10 +3,22 @@
 user_pref("general.useragent.override", "");
 user_pref("mail.account.account_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc.identities", "id_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc");
 user_pref("mail.account.account_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc.server", "server_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc");
-user_pref("mail.account.account_cda3f13b64c1db7d4b58ce07a31304a362d7dcaf14476bfabcca913ae41ada9f.identities", "id_cda3f13b64c1db7d4b58ce07a31304a362d7dcaf14476bfabcca913ae41ada9f");
+user_pref("mail.account.account_cda3f13b64c1db7d4b58ce07a31304a362d7dcaf14476bfabcca913ae41ada9f.identities", "id_cda3f13b64c1db7d4b58ce07a31304a362d7dcaf14476bfabcca913ae41ada9f,id_8bbcff78f53202c0bfaa490a2068e3e5d6e36872144c659952ecc0ada47d7562");
 user_pref("mail.account.account_cda3f13b64c1db7d4b58ce07a31304a362d7dcaf14476bfabcca913ae41ada9f.server", "server_cda3f13b64c1db7d4b58ce07a31304a362d7dcaf14476bfabcca913ae41ada9f");
 user_pref("mail.accountmanager.accounts", "account_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc,account_cda3f13b64c1db7d4b58ce07a31304a362d7dcaf14476bfabcca913ae41ada9f");
 user_pref("mail.accountmanager.defaultaccount", "account_cda3f13b64c1db7d4b58ce07a31304a362d7dcaf14476bfabcca913ae41ada9f");
+user_pref("mail.identity.id_8bbcff78f53202c0bfaa490a2068e3e5d6e36872144c659952ecc0ada47d7562.attachPgpKey", false);
+user_pref("mail.identity.id_8bbcff78f53202c0bfaa490a2068e3e5d6e36872144c659952ecc0ada47d7562.autoEncryptDrafts", true);
+user_pref("mail.identity.id_8bbcff78f53202c0bfaa490a2068e3e5d6e36872144c659952ecc0ada47d7562.e2etechpref", 0);
+user_pref("mail.identity.id_8bbcff78f53202c0bfaa490a2068e3e5d6e36872144c659952ecc0ada47d7562.encryptionpolicy", 0);
+user_pref("mail.identity.id_8bbcff78f53202c0bfaa490a2068e3e5d6e36872144c659952ecc0ada47d7562.fullName", "H. M. Test");
+user_pref("mail.identity.id_8bbcff78f53202c0bfaa490a2068e3e5d6e36872144c659952ecc0ada47d7562.is_gnupg_key_id", true);
+user_pref("mail.identity.id_8bbcff78f53202c0bfaa490a2068e3e5d6e36872144c659952ecc0ada47d7562.last_entered_external_gnupg_key_id", "ABC");
+user_pref("mail.identity.id_8bbcff78f53202c0bfaa490a2068e3e5d6e36872144c659952ecc0ada47d7562.openpgp_key_id", "ABC");
+user_pref("mail.identity.id_8bbcff78f53202c0bfaa490a2068e3e5d6e36872144c659952ecc0ada47d7562.protectSubject", true);
+user_pref("mail.identity.id_8bbcff78f53202c0bfaa490a2068e3e5d6e36872144c659952ecc0ada47d7562.sign_mail", false);
+user_pref("mail.identity.id_8bbcff78f53202c0bfaa490a2068e3e5d6e36872144c659952ecc0ada47d7562.useremail", "home-manager@example.com");
+user_pref("mail.identity.id_8bbcff78f53202c0bfaa490a2068e3e5d6e36872144c659952ecc0ada47d7562.valid", true);
 user_pref("mail.identity.id_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc.autoEncryptDrafts", false);
 user_pref("mail.identity.id_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc.fullName", "H. M. Test Jr.");
 user_pref("mail.identity.id_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc.protectSubject", false);
diff --git a/tests/modules/programs/thunderbird/thunderbird.nix b/tests/modules/programs/thunderbird/thunderbird.nix
index 2536ff41a..1b0441a1d 100644
--- a/tests/modules/programs/thunderbird/thunderbird.nix
+++ b/tests/modules/programs/thunderbird/thunderbird.nix
@@ -8,6 +8,8 @@
         profiles = [ "first" ];
       };
 
+      aliases = [ "home-manager@example.com" ];
+
       gpg.key = "ABC";
 
       imap = {