diff --git a/modules/lib/maintainers.nix b/modules/lib/maintainers.nix index 4e5a4ebcf..bc4a41f08 100644 --- a/modules/lib/maintainers.nix +++ b/modules/lib/maintainers.nix @@ -474,7 +474,7 @@ }; zorrobert = { name = "zorrobert"; - email = "zorrobert@mailbox.org"; + email = "118135271+zorrobert@users.noreply.github.com"; github = "zorrobert"; githubId = 118135271; }; diff --git a/modules/misc/news/2025/07/2025-07-07_20-33-04.nix b/modules/misc/news/2025/07/2025-07-07_20-33-04.nix new file mode 100644 index 000000000..294c76bcf --- /dev/null +++ b/modules/misc/news/2025/07/2025-07-07_20-33-04.nix @@ -0,0 +1,9 @@ +{ config, ... }: +{ + time = "2025-07-07T18:33:04+00:00"; + condition = config.programs.thunderbird.enable; + message = '' + 'programs.thunderbird' now supports declaration of address books using + 'accounts.contact.accounts'. + ''; +} diff --git a/modules/programs/thunderbird.nix b/modules/programs/thunderbird.nix index 13b8a8d79..0085d95ad 100644 --- a/modules/programs/thunderbird.nix +++ b/modules/programs/thunderbird.nix @@ -41,6 +41,9 @@ let enabledCalendarAccounts = filterEnabled config.accounts.calendar.accounts; enabledCalendarAccountsWithId = addId enabledCalendarAccounts; + enabledContactAccounts = filterEnabled config.accounts.contact.accounts; + enabledContactAccountsWithId = addId enabledContactAccounts; + thunderbirdConfigPath = if isDarwin then "Library/Thunderbird" else ".thunderbird"; thunderbirdProfilesPath = @@ -216,6 +219,27 @@ let "calendar.registry.calendar_${id}.color" = calendar.thunderbird.color; }; + toThunderbirdContact = + contact: _: + let + inherit (contact) id; + in + lib.filterAttrs (n: v: v != null) ( + { + "ldap_2.servers.contact_${id}.description" = contact.name; + "ldap_2.servers.contact_${id}.filename" = "contact_${id}.sqlite"; # this is needed for carddav to work + } + // optionalAttrs (contact.remote == null) { + "ldap_2.servers.contact_${id}.dirType" = 101; # dirType 101 for local address book + } + // optionalAttrs (contact.remote != null && contact.remote.type == "carddav") { + "ldap_2.servers.contact_${id}.dirType" = 102; # dirType 102 for CardDAV + "ldap_2.servers.contact_${id}.carddav.url" = contact.remote.url; + "ldap_2.servers.contact_${id}.carddav.username" = contact.remote.userName; + "ldap_2.servers.contact_${id}.carddav.token" = contact.thunderbird.token; + } + ); + toThunderbirdFeed = feed: profile: let @@ -403,6 +427,7 @@ in ] ''; }; + calendarAccountsOrder = mkOption { type = types.listOf types.str; default = [ ]; @@ -685,6 +710,7 @@ in ) ); }; + accounts.calendar.accounts = mkOption { type = with types; @@ -720,6 +746,38 @@ in }; }); }; + + accounts.contact.accounts = mkOption { + type = + with types; + attrsOf (submodule { + options.thunderbird = { + enable = lib.mkEnableOption "the Thunderbird mail client for this account"; + + profiles = mkOption { + type = with types; listOf str; + default = [ ]; + example = literalExpression '' + [ "profile1" "profile2" ] + ''; + description = '' + List of Thunderbird profiles for which this account should be + enabled. If this list is empty (the default), this account will + be enabled for all declared profiles. + ''; + }; + + token = mkOption { + type = nullOr str; + default = null; + example = "secret_token"; + description = '' + A token is generated when adding an address book manually to Thunderbird, this can be entered here. + ''; + }; + }; + }); + }; }; config = mkIf cfg.enable { @@ -782,6 +840,44 @@ in ''; } ) + + ( + let + foundContacts = filter ( + a: a.remote != null && a.remote.type == "google_contacts" + ) enabledContactAccounts; + in + { + assertion = (length foundContacts == 0); + message = + '''accounts.contact.accounts..remote.type = "google_contacts";' is not directly supported by Thunderbird, '' + + "but declared for these address books: " + + (concatStringsSep ", " (lib.catAttrs "name" foundContacts)) + + "\n" + + '' + To use google address books in Thunderbird choose 'type = "caldav"' instead. + The 'url' will be something like "https://www.googleapis.com/carddav/v1/principals/[YOUR-MAIL-ADDRESS]/lists/default/". + To get the exact URL, add the address book to Thunderbird manually and copy the URL from the "Advanced Preferences" section. + ''; + } + ) + + ( + let + foundContacts = filter (a: a.remote != null && a.remote.type == "http") enabledContactAccounts; + in + { + assertion = (length foundContacts == 0); + message = + '''accounts.contact.accounts..remote.type = "http";' is not supported by Thunderbird, '' + + "but declared for these address books: " + + (concatStringsSep ", " (lib.catAttrs "name" foundContacts)) + + "\n" + + '' + Use a calendar of 'type = "caldav"' instead. + ''; + } + ) ]; home.packages = [ @@ -814,6 +910,7 @@ in let emailAccounts = getAccountsForProfile name enabledEmailAccountsWithId; calendarAccounts = getAccountsForProfile name enabledCalendarAccountsWithId; + contactAccounts = getAccountsForProfile name enabledContactAccountsWithId; smtp = filter (a: a.smtp != null) emailAccounts; @@ -882,8 +979,9 @@ in profile.settings ] ++ (map (a: toThunderbirdAccount a profile) emailAccounts) - ++ (map (c: toThunderbirdCalendar c profile) calendarAccounts) - ++ (map (f: toThunderbirdFeed f profile) feedAccounts) + ++ (map (calendar: toThunderbirdCalendar calendar profile) calendarAccounts) + ++ (map (contact: toThunderbirdContact contact profile) contactAccounts) + ++ (map (feed: toThunderbirdFeed feed profile) feedAccounts) )) profile.extraConfig; }; diff --git a/tests/modules/programs/thunderbird/thunderbird-expected-first-darwin.js b/tests/modules/programs/thunderbird/thunderbird-expected-first-darwin.js index 62a9be11a..852a91b26 100644 --- a/tests/modules/programs/thunderbird/thunderbird-expected-first-darwin.js +++ b/tests/modules/programs/thunderbird/thunderbird-expected-first-darwin.js @@ -16,6 +16,14 @@ user_pref("calendar.registry.calendar_5152790e278eb89039f8bfaa354b944ec1b44c5d3f user_pref("calendar.registry.calendar_5152790e278eb89039f8bfaa354b944ec1b44c5d3fc144edc5720c3edc045c73.uri", "https://my.caldav.server/calendar"); user_pref("calendar.registry.calendar_5152790e278eb89039f8bfaa354b944ec1b44c5d3fc144edc5720c3edc045c73.username", "testuser"); user_pref("general.useragent.override", ""); +user_pref("ldap_2.servers.contact_a4d26868017c0ccffe2efe50944ef4211834660cca834c6e9f86dec6a88246fa.description", "shared"); +user_pref("ldap_2.servers.contact_a4d26868017c0ccffe2efe50944ef4211834660cca834c6e9f86dec6a88246fa.dirType", 101); +user_pref("ldap_2.servers.contact_a4d26868017c0ccffe2efe50944ef4211834660cca834c6e9f86dec6a88246fa.filename", "contact_a4d26868017c0ccffe2efe50944ef4211834660cca834c6e9f86dec6a88246fa.sqlite"); +user_pref("ldap_2.servers.contact_d34a569ab7aaa54dacd715ae64953455d86b768846cd0085ef4e9e7471489b7b.carddav.url", "https://my.caldav.server/contact/"); +user_pref("ldap_2.servers.contact_d34a569ab7aaa54dacd715ae64953455d86b768846cd0085ef4e9e7471489b7b.carddav.username", "home-manager@example.com"); +user_pref("ldap_2.servers.contact_d34a569ab7aaa54dacd715ae64953455d86b768846cd0085ef4e9e7471489b7b.description", "family"); +user_pref("ldap_2.servers.contact_d34a569ab7aaa54dacd715ae64953455d86b768846cd0085ef4e9e7471489b7b.dirType", 102); +user_pref("ldap_2.servers.contact_d34a569ab7aaa54dacd715ae64953455d86b768846cd0085ef4e9e7471489b7b.filename", "contact_d34a569ab7aaa54dacd715ae64953455d86b768846cd0085ef4e9e7471489b7b.sqlite"); user_pref("mail.account.account_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc.identities", "id_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc"); user_pref("mail.account.account_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc.server", "server_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc"); user_pref("mail.account.account_c6cc42837ed0a8041f93ff12c579a4af0dbe702461c97eef069f9f5f8dc4bfab.server", "server_c6cc42837ed0a8041f93ff12c579a4af0dbe702461c97eef069f9f5f8dc4bfab"); diff --git a/tests/modules/programs/thunderbird/thunderbird-expected-first-linux.js b/tests/modules/programs/thunderbird/thunderbird-expected-first-linux.js index 87bec9a8b..8cbf7be38 100644 --- a/tests/modules/programs/thunderbird/thunderbird-expected-first-linux.js +++ b/tests/modules/programs/thunderbird/thunderbird-expected-first-linux.js @@ -16,6 +16,14 @@ user_pref("calendar.registry.calendar_5152790e278eb89039f8bfaa354b944ec1b44c5d3f user_pref("calendar.registry.calendar_5152790e278eb89039f8bfaa354b944ec1b44c5d3fc144edc5720c3edc045c73.uri", "https://my.caldav.server/calendar"); user_pref("calendar.registry.calendar_5152790e278eb89039f8bfaa354b944ec1b44c5d3fc144edc5720c3edc045c73.username", "testuser"); user_pref("general.useragent.override", ""); +user_pref("ldap_2.servers.contact_a4d26868017c0ccffe2efe50944ef4211834660cca834c6e9f86dec6a88246fa.description", "shared"); +user_pref("ldap_2.servers.contact_a4d26868017c0ccffe2efe50944ef4211834660cca834c6e9f86dec6a88246fa.dirType", 101); +user_pref("ldap_2.servers.contact_a4d26868017c0ccffe2efe50944ef4211834660cca834c6e9f86dec6a88246fa.filename", "contact_a4d26868017c0ccffe2efe50944ef4211834660cca834c6e9f86dec6a88246fa.sqlite"); +user_pref("ldap_2.servers.contact_d34a569ab7aaa54dacd715ae64953455d86b768846cd0085ef4e9e7471489b7b.carddav.url", "https://my.caldav.server/contact/"); +user_pref("ldap_2.servers.contact_d34a569ab7aaa54dacd715ae64953455d86b768846cd0085ef4e9e7471489b7b.carddav.username", "home-manager@example.com"); +user_pref("ldap_2.servers.contact_d34a569ab7aaa54dacd715ae64953455d86b768846cd0085ef4e9e7471489b7b.description", "family"); +user_pref("ldap_2.servers.contact_d34a569ab7aaa54dacd715ae64953455d86b768846cd0085ef4e9e7471489b7b.dirType", 102); +user_pref("ldap_2.servers.contact_d34a569ab7aaa54dacd715ae64953455d86b768846cd0085ef4e9e7471489b7b.filename", "contact_d34a569ab7aaa54dacd715ae64953455d86b768846cd0085ef4e9e7471489b7b.sqlite"); user_pref("mail.account.account_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc.identities", "id_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc"); user_pref("mail.account.account_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc.server", "server_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc"); user_pref("mail.account.account_c6cc42837ed0a8041f93ff12c579a4af0dbe702461c97eef069f9f5f8dc4bfab.server", "server_c6cc42837ed0a8041f93ff12c579a4af0dbe702461c97eef069f9f5f8dc4bfab"); diff --git a/tests/modules/programs/thunderbird/thunderbird-expected-second-darwin.js b/tests/modules/programs/thunderbird/thunderbird-expected-second-darwin.js index ca3549a24..c824aa01a 100644 --- a/tests/modules/programs/thunderbird/thunderbird-expected-second-darwin.js +++ b/tests/modules/programs/thunderbird/thunderbird-expected-second-darwin.js @@ -14,6 +14,12 @@ user_pref("calendar.registry.calendar_474c12b01f4f765680ac3bb3e0b670b7ac817c9f71 user_pref("calendar.registry.calendar_474c12b01f4f765680ac3bb3e0b670b7ac817c9f717997577cac3f12f1b5013a.uri", "https://www.thunderbird.net/media/caldata/autogen/GermanHolidays.ics"); user_pref("calendar.registry.calendar_474c12b01f4f765680ac3bb3e0b670b7ac817c9f717997577cac3f12f1b5013a.username", null); user_pref("general.useragent.override", ""); +user_pref("ldap_2.servers.contact_00e13ed7af55b27622f1d6eab5bec0147e68efe28dc2b12461117afa1a5ed40e.description", "work"); +user_pref("ldap_2.servers.contact_00e13ed7af55b27622f1d6eab5bec0147e68efe28dc2b12461117afa1a5ed40e.dirType", 101); +user_pref("ldap_2.servers.contact_00e13ed7af55b27622f1d6eab5bec0147e68efe28dc2b12461117afa1a5ed40e.filename", "contact_00e13ed7af55b27622f1d6eab5bec0147e68efe28dc2b12461117afa1a5ed40e.sqlite"); +user_pref("ldap_2.servers.contact_a4d26868017c0ccffe2efe50944ef4211834660cca834c6e9f86dec6a88246fa.description", "shared"); +user_pref("ldap_2.servers.contact_a4d26868017c0ccffe2efe50944ef4211834660cca834c6e9f86dec6a88246fa.dirType", 101); +user_pref("ldap_2.servers.contact_a4d26868017c0ccffe2efe50944ef4211834660cca834c6e9f86dec6a88246fa.filename", "contact_a4d26868017c0ccffe2efe50944ef4211834660cca834c6e9f86dec6a88246fa.sqlite"); user_pref("mail.account.account_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc.identities", "id_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc"); user_pref("mail.account.account_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc.server", "server_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc"); user_pref("mail.accountmanager.accounts", "account1,account_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc"); diff --git a/tests/modules/programs/thunderbird/thunderbird-expected-second-linux.js b/tests/modules/programs/thunderbird/thunderbird-expected-second-linux.js index ca124dbb4..ca288f24e 100644 --- a/tests/modules/programs/thunderbird/thunderbird-expected-second-linux.js +++ b/tests/modules/programs/thunderbird/thunderbird-expected-second-linux.js @@ -14,6 +14,12 @@ user_pref("calendar.registry.calendar_474c12b01f4f765680ac3bb3e0b670b7ac817c9f71 user_pref("calendar.registry.calendar_474c12b01f4f765680ac3bb3e0b670b7ac817c9f717997577cac3f12f1b5013a.uri", "https://www.thunderbird.net/media/caldata/autogen/GermanHolidays.ics"); user_pref("calendar.registry.calendar_474c12b01f4f765680ac3bb3e0b670b7ac817c9f717997577cac3f12f1b5013a.username", null); user_pref("general.useragent.override", ""); +user_pref("ldap_2.servers.contact_00e13ed7af55b27622f1d6eab5bec0147e68efe28dc2b12461117afa1a5ed40e.description", "work"); +user_pref("ldap_2.servers.contact_00e13ed7af55b27622f1d6eab5bec0147e68efe28dc2b12461117afa1a5ed40e.dirType", 101); +user_pref("ldap_2.servers.contact_00e13ed7af55b27622f1d6eab5bec0147e68efe28dc2b12461117afa1a5ed40e.filename", "contact_00e13ed7af55b27622f1d6eab5bec0147e68efe28dc2b12461117afa1a5ed40e.sqlite"); +user_pref("ldap_2.servers.contact_a4d26868017c0ccffe2efe50944ef4211834660cca834c6e9f86dec6a88246fa.description", "shared"); +user_pref("ldap_2.servers.contact_a4d26868017c0ccffe2efe50944ef4211834660cca834c6e9f86dec6a88246fa.dirType", 101); +user_pref("ldap_2.servers.contact_a4d26868017c0ccffe2efe50944ef4211834660cca834c6e9f86dec6a88246fa.filename", "contact_a4d26868017c0ccffe2efe50944ef4211834660cca834c6e9f86dec6a88246fa.sqlite"); user_pref("mail.account.account_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc.identities", "id_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc"); user_pref("mail.account.account_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc.server", "server_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc"); user_pref("mail.accountmanager.accounts", "account1,account_bcd3ace52bed41febb6cdc2fb1303aebaa573e0d993872da503950901bb6c6fc"); diff --git a/tests/modules/programs/thunderbird/thunderbird.nix b/tests/modules/programs/thunderbird/thunderbird.nix index 882656612..6c74aeba6 100644 --- a/tests/modules/programs/thunderbird/thunderbird.nix +++ b/tests/modules/programs/thunderbird/thunderbird.nix @@ -106,6 +106,29 @@ }; }; + accounts.contact.accounts = { + family = { + remote = { + type = "carddav"; + url = "https://my.caldav.server/contact/"; + userName = "home-manager@example.com"; + }; + thunderbird = { + enable = true; + profiles = [ "first" ]; + }; + }; + work = { + thunderbird = { + enable = true; + profiles = [ "second" ]; + }; + }; + shared = { + thunderbird.enable = true; + }; + }; + programs.thunderbird = { enable = true; package = config.lib.test.mkStubPackage {