2023-08-27 19:09:23 +02:00
|
|
|
{ config, lib, confSections, confSection, ... }:
|
2022-08-11 23:08:28 +02:00
|
|
|
|
|
|
|
with lib;
|
|
|
|
|
|
|
|
let
|
|
|
|
mapAttrNames = f: attr:
|
|
|
|
listToAttrs (attrValues (mapAttrs (k: v: {
|
|
|
|
name = f k;
|
|
|
|
value = v;
|
|
|
|
}) attr));
|
2023-02-28 21:16:41 +01:00
|
|
|
|
2022-08-11 23:08:28 +02:00
|
|
|
addAccountName = name: k: "${k}:account=${name}";
|
2023-02-28 21:16:41 +01:00
|
|
|
|
|
|
|
oauth2Params = mkOption {
|
|
|
|
type = with types;
|
|
|
|
nullOr (submodule {
|
|
|
|
options = {
|
|
|
|
token_endpoint = mkOption {
|
|
|
|
type = nullOr str;
|
|
|
|
default = null;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = "The OAuth2 token endpoint.";
|
2023-02-28 21:16:41 +01:00
|
|
|
};
|
|
|
|
client_id = mkOption {
|
|
|
|
type = nullOr str;
|
|
|
|
default = null;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = "The OAuth2 client identifier.";
|
2023-02-28 21:16:41 +01:00
|
|
|
};
|
|
|
|
client_secret = mkOption {
|
|
|
|
type = nullOr str;
|
|
|
|
default = null;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = "The OAuth2 client secret.";
|
2023-02-28 21:16:41 +01:00
|
|
|
};
|
|
|
|
scope = mkOption {
|
|
|
|
type = nullOr str;
|
|
|
|
default = null;
|
2023-07-02 01:45:18 +02:00
|
|
|
description = "The OAuth2 requested scope.";
|
2023-02-28 21:16:41 +01:00
|
|
|
};
|
|
|
|
};
|
|
|
|
});
|
|
|
|
default = null;
|
|
|
|
example = { token_endpoint = "<token_endpoint>"; };
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2023-02-28 21:16:41 +01:00
|
|
|
Sets the oauth2 params if authentication mechanism oauthbearer or
|
|
|
|
xoauth2 is used.
|
2023-07-01 01:30:13 +02:00
|
|
|
See {manpage}`aerc-imap(5)`.
|
2023-02-28 21:16:41 +01:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2022-08-11 23:08:28 +02:00
|
|
|
in {
|
|
|
|
type = mkOption {
|
|
|
|
type = types.attrsOf (types.submodule {
|
|
|
|
options.aerc = {
|
2023-07-02 01:45:18 +02:00
|
|
|
enable = mkEnableOption "aerc";
|
2022-08-11 23:08:28 +02:00
|
|
|
extraAccounts = mkOption {
|
|
|
|
type = confSection;
|
|
|
|
default = { };
|
|
|
|
example =
|
|
|
|
literalExpression ''{ source = "maildir://~/Maildir/example"; }'';
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2023-07-14 20:34:28 +02:00
|
|
|
Extra config added to the configuration section for this account in
|
2023-07-01 01:30:13 +02:00
|
|
|
{file}`$HOME/.config/aerc/accounts.conf`.
|
|
|
|
See {manpage}`aerc-accounts(5)`.
|
2022-08-11 23:08:28 +02:00
|
|
|
'';
|
|
|
|
};
|
2023-06-13 10:59:42 +02:00
|
|
|
|
2022-08-11 23:08:28 +02:00
|
|
|
extraBinds = mkOption {
|
|
|
|
type = confSections;
|
|
|
|
default = { };
|
|
|
|
example = literalExpression
|
|
|
|
''{ messages = { d = ":move ''${folder.trash}<Enter>"; }; }'';
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2022-08-11 23:08:28 +02:00
|
|
|
Extra bindings specific to this account, added to
|
2023-07-01 01:30:13 +02:00
|
|
|
{file}`$HOME/.config/aerc/binds.conf`.
|
|
|
|
See {manpage}`aerc-binds(5)`.
|
2022-08-11 23:08:28 +02:00
|
|
|
'';
|
|
|
|
};
|
2023-06-13 10:59:42 +02:00
|
|
|
|
2022-08-11 23:08:28 +02:00
|
|
|
extraConfig = mkOption {
|
|
|
|
type = confSections;
|
|
|
|
default = { };
|
2023-07-14 20:34:28 +02:00
|
|
|
example = literalExpression "{ ui = { sidebar-width = 25; }; }";
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2023-07-01 01:30:13 +02:00
|
|
|
Config specific to this account, added to {file}`$HOME/.config/aerc/aerc.conf`.
|
2023-07-14 20:34:28 +02:00
|
|
|
Aerc only supports per-account UI configuration.
|
2023-07-01 01:30:13 +02:00
|
|
|
For other sections of {file}`$HOME/.config/aerc/aerc.conf`,
|
|
|
|
use `programs.aerc.extraConfig`.
|
|
|
|
See {manpage}`aerc-config(5)`.
|
2023-02-28 21:16:41 +01:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
imapAuth = mkOption {
|
|
|
|
type = with types; nullOr (enum [ "oauthbearer" "xoauth2" ]);
|
|
|
|
default = null;
|
|
|
|
example = "auth";
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2023-02-28 21:16:41 +01:00
|
|
|
Sets the authentication mechanism if imap is used as the incoming
|
|
|
|
method.
|
2023-07-01 01:30:13 +02:00
|
|
|
See {manpage}`aerc-imap(5)`.
|
2022-08-11 23:08:28 +02:00
|
|
|
'';
|
|
|
|
};
|
2023-02-28 21:16:41 +01:00
|
|
|
|
|
|
|
imapOauth2Params = oauth2Params;
|
|
|
|
|
2022-08-11 23:08:28 +02:00
|
|
|
smtpAuth = mkOption {
|
2023-02-27 22:32:12 +01:00
|
|
|
type = with types;
|
|
|
|
nullOr (enum [ "none" "plain" "login" "oauthbearer" "xoauth2" ]);
|
2022-08-11 23:08:28 +02:00
|
|
|
default = "plain";
|
|
|
|
example = "auth";
|
2023-07-02 01:45:18 +02:00
|
|
|
description = ''
|
2022-08-11 23:08:28 +02:00
|
|
|
Sets the authentication mechanism if smtp is used as the outgoing
|
|
|
|
method.
|
2023-07-01 01:30:13 +02:00
|
|
|
See {manpage}`aerc-smtp(5)`.
|
2022-08-11 23:08:28 +02:00
|
|
|
'';
|
|
|
|
};
|
2023-02-28 21:16:41 +01:00
|
|
|
|
|
|
|
smtpOauth2Params = oauth2Params;
|
2022-08-11 23:08:28 +02:00
|
|
|
};
|
|
|
|
});
|
|
|
|
};
|
2023-06-13 10:59:42 +02:00
|
|
|
|
2022-08-11 23:08:28 +02:00
|
|
|
mkAccount = name: account:
|
|
|
|
let
|
|
|
|
nullOrMap = f: v: if v == null then v else f v;
|
2023-06-13 10:59:42 +02:00
|
|
|
|
2022-08-11 23:08:28 +02:00
|
|
|
optPort = port: if port != null then ":${toString port}" else "";
|
2023-06-13 10:59:42 +02:00
|
|
|
|
2022-08-11 23:08:28 +02:00
|
|
|
optAttr = k: v:
|
|
|
|
if v != null && v != [ ] && v != "" then { ${k} = v; } else { };
|
2023-06-13 10:59:42 +02:00
|
|
|
|
2022-08-11 23:08:28 +02:00
|
|
|
optPwCmd = k: p:
|
2023-06-13 10:59:42 +02:00
|
|
|
optAttr "${k}-cred-cmd" (nullOrMap (concatStringsSep " ") p);
|
2023-02-28 21:16:41 +01:00
|
|
|
|
|
|
|
useOauth = auth: builtins.elem auth [ "oauthbearer" "xoauth2" ];
|
|
|
|
|
|
|
|
oauthParams = { auth, params }:
|
|
|
|
if useOauth auth && params != null && params != { } then
|
|
|
|
"?" + builtins.concatStringsSep "&" lib.attrsets.mapAttrsToList
|
|
|
|
(k: v: k + "=" + lib.strings.escapeURL v) params
|
|
|
|
else
|
|
|
|
"";
|
|
|
|
|
2022-08-11 23:08:28 +02:00
|
|
|
mkConfig = {
|
|
|
|
maildir = cfg: {
|
|
|
|
source =
|
|
|
|
"maildir://${config.accounts.email.maildirBasePath}/${cfg.maildir.path}";
|
|
|
|
};
|
2023-06-13 10:59:42 +02:00
|
|
|
|
2023-12-22 18:14:39 +01:00
|
|
|
maildirpp = cfg: {
|
|
|
|
source =
|
|
|
|
"maildirpp://${config.accounts.email.maildirBasePath}/${cfg.maildir.path}/Inbox";
|
|
|
|
};
|
|
|
|
|
2022-08-11 23:08:28 +02:00
|
|
|
imap = { userName, imap, passwordCommand, aerc, ... }@cfg:
|
|
|
|
let
|
2023-02-28 21:16:41 +01:00
|
|
|
loginMethod' =
|
|
|
|
if cfg.aerc.imapAuth != null then "+${cfg.aerc.imapAuth}" else "";
|
|
|
|
|
|
|
|
oauthParams' = oauthParams {
|
|
|
|
auth = cfg.aerc.imapAuth;
|
|
|
|
params = cfg.aerc.imapOauth2Params;
|
|
|
|
};
|
|
|
|
|
2022-08-11 23:08:28 +02:00
|
|
|
protocol = if imap.tls.enable then
|
2023-02-28 21:16:41 +01:00
|
|
|
if imap.tls.useStartTls then "imap" else "imaps${loginMethod'}"
|
2022-08-11 23:08:28 +02:00
|
|
|
else
|
|
|
|
"imap+insecure";
|
2023-06-13 10:59:42 +02:00
|
|
|
|
2022-08-11 23:08:28 +02:00
|
|
|
port' = optPort imap.port;
|
2023-06-13 10:59:42 +02:00
|
|
|
|
2022-08-11 23:08:28 +02:00
|
|
|
in {
|
2023-02-28 21:16:41 +01:00
|
|
|
source =
|
|
|
|
"${protocol}://${userName}@${imap.host}${port'}${oauthParams'}";
|
2022-08-11 23:08:28 +02:00
|
|
|
} // optPwCmd "source" passwordCommand;
|
2023-06-13 10:59:42 +02:00
|
|
|
|
2022-08-11 23:08:28 +02:00
|
|
|
smtp = { userName, smtp, passwordCommand, ... }@cfg:
|
|
|
|
let
|
|
|
|
loginMethod' =
|
|
|
|
if cfg.aerc.smtpAuth != null then "+${cfg.aerc.smtpAuth}" else "";
|
2023-02-28 21:16:41 +01:00
|
|
|
|
|
|
|
oauthParams' = oauthParams {
|
|
|
|
auth = cfg.aerc.smtpAuth;
|
|
|
|
params = cfg.aerc.smtpOauth2Params;
|
|
|
|
};
|
|
|
|
|
2023-08-05 10:56:10 +02:00
|
|
|
protocol = if smtp.tls.enable then
|
|
|
|
if smtp.tls.useStartTls then
|
|
|
|
"smtp${loginMethod'}"
|
|
|
|
else
|
|
|
|
"smtps${loginMethod'}"
|
2022-08-11 23:08:28 +02:00
|
|
|
else
|
2023-08-05 10:56:10 +02:00
|
|
|
"smtp+insecure${loginMethod'}";
|
2023-06-13 10:59:42 +02:00
|
|
|
|
2022-08-11 23:08:28 +02:00
|
|
|
port' = optPort smtp.port;
|
2023-06-13 10:59:42 +02:00
|
|
|
|
2022-08-11 23:08:28 +02:00
|
|
|
in {
|
2023-02-28 21:16:41 +01:00
|
|
|
outgoing =
|
|
|
|
"${protocol}://${userName}@${smtp.host}${port'}${oauthParams'}";
|
2023-08-05 10:56:10 +02:00
|
|
|
} // optPwCmd "outgoing" passwordCommand;
|
2023-06-13 10:59:42 +02:00
|
|
|
|
2022-08-11 23:08:28 +02:00
|
|
|
msmtp = cfg: {
|
|
|
|
outgoing = "msmtpq --read-envelope-from --read-recipients";
|
|
|
|
};
|
2023-06-13 10:59:42 +02:00
|
|
|
|
2022-08-11 23:08:28 +02:00
|
|
|
};
|
2023-06-13 10:59:42 +02:00
|
|
|
|
2022-08-11 23:08:28 +02:00
|
|
|
basicCfg = account:
|
|
|
|
{
|
|
|
|
from = "${account.realName} <${account.address}>";
|
|
|
|
} // (optAttr "copy-to" account.folders.sent)
|
|
|
|
// (optAttr "default" account.folders.inbox)
|
|
|
|
// (optAttr "postpone" account.folders.drafts)
|
2023-06-13 10:59:42 +02:00
|
|
|
// (optAttr "aliases" account.aliases);
|
|
|
|
|
2022-08-11 23:08:28 +02:00
|
|
|
sourceCfg = account:
|
2023-12-22 18:14:39 +01:00
|
|
|
if account.mbsync.enable && account.mbsync.flatten == null
|
|
|
|
&& account.mbsync.subFolders == "Maildir++" then
|
|
|
|
mkConfig.maildirpp account
|
|
|
|
else if account.mbsync.enable || account.offlineimap.enable then
|
2022-08-11 23:08:28 +02:00
|
|
|
mkConfig.maildir account
|
|
|
|
else if account.imap != null then
|
|
|
|
mkConfig.imap account
|
|
|
|
else
|
|
|
|
{ };
|
2023-06-13 10:59:42 +02:00
|
|
|
|
2022-08-11 23:08:28 +02:00
|
|
|
outgoingCfg = account:
|
|
|
|
if account.msmtp.enable then
|
|
|
|
mkConfig.msmtp account
|
|
|
|
else if account.smtp != null then
|
|
|
|
mkConfig.smtp account
|
|
|
|
else
|
|
|
|
{ };
|
2023-06-13 10:59:42 +02:00
|
|
|
|
|
|
|
in (basicCfg account) // (sourceCfg account) // (outgoingCfg account)
|
|
|
|
// account.aerc.extraAccounts;
|
|
|
|
|
2022-08-11 23:08:28 +02:00
|
|
|
mkAccountConfig = name: account:
|
|
|
|
mapAttrNames (addAccountName name) account.aerc.extraConfig;
|
2023-06-13 10:59:42 +02:00
|
|
|
|
2022-08-11 23:08:28 +02:00
|
|
|
mkAccountBinds = name: account:
|
|
|
|
mapAttrNames (addAccountName name) account.aerc.extraBinds;
|
|
|
|
}
|