add email back

This commit is contained in:
Ray Andrew 2025-12-02 15:41:10 -06:00
parent 54be488d73
commit 9e8182da6a
Signed by: rayandrew
SSH key fingerprint: SHA256:XYrYrxF0Z3A72n8P/p6mqPRNQZT22F88XcLsG+kX4xw
9 changed files with 368 additions and 29 deletions

View file

@ -1,9 +1,11 @@
keys: keys:
- &pickwick age13cfe8fhp4m978qlcur46vkkxepsl93ggwe53kmhue9xtpgr5zu5q4y6ln2 - &pickwick age13cfe8fhp4m978qlcur46vkkxepsl93ggwe53kmhue9xtpgr5zu5q4y6ln2
- &lemur age1pdk6dmyxqhdaja5d0nf8f9qjd43hmfahmkure5yrf8al9jyfmd8qfdxwl6 - &lemur age1pdk6dmyxqhdaja5d0nf8f9qjd43hmfahmkure5yrf8al9jyfmd8qfdxwl6
- &dango age15vscvpe79l287h8f3hssrj2r45xy0l3ns94zfue2fxlq43cqdsxq58vq3c
creation_rules: creation_rules:
- path_regex: home/email/secrets.yaml$ - path_regex: home/email/secrets.yaml$
key_groups: key_groups:
- age: - age:
- *pickwick - *pickwick
- *lemur - *lemur
- *dango

View file

@ -13,7 +13,7 @@ exec-on-workspace-change = ['/bin/bash', '-c',
'/run/current-system/sw/bin/sketchybar --trigger aerospace_workspace_changed FOCUSED_WORKSPACE=$AEROSPACE_FOCUSED_WORKSPACE PREV_WORKSPACE=$AEROSPACE_PREV_WORKSPACE && /etc/profiles/per-user/rayandrew/bin/aerospace-scratchpad hook pull-window $AEROSPACE_PREV_WORKSPACE $AEROSPACE_FOCUSED_WORKSPACE' '/run/current-system/sw/bin/sketchybar --trigger aerospace_workspace_changed FOCUSED_WORKSPACE=$AEROSPACE_FOCUSED_WORKSPACE PREV_WORKSPACE=$AEROSPACE_PREV_WORKSPACE && /etc/profiles/per-user/rayandrew/bin/aerospace-scratchpad hook pull-window $AEROSPACE_PREV_WORKSPACE $AEROSPACE_FOCUSED_WORKSPACE'
] ]
on-focus-changed = [ on-focus-changed = [
'move-mouse window-lazy-center', # 'move-mouse window-lazy-center',
'exec-and-forget /bin/bash -c /run/current-system/sw/bin/sketchybar --trigger front_app_switched', 'exec-and-forget /bin/bash -c /run/current-system/sw/bin/sketchybar --trigger front_app_switched',
'exec-and-forget /run/current-system/sw/bin/sketchybar --trigger update_windows' 'exec-and-forget /run/current-system/sw/bin/sketchybar --trigger update_windows'
] ]

View file

@ -1,31 +1,35 @@
personal: ENC[AES256_GCM,data:aaZAYmnoQfGIH6bBneKtTA==,iv:xiy1eCyBhFulfRXGz0WDFLaqPj3kXsMD4Xkk7D4s5XA=,tag:Nk0KsgICo505VEMwVUt3TA==,type:str] personal: ENC[AES256_GCM,data:MG1ryntM2YKyjb0YH/8GYg==,iv:SvwAc1dBl8wc1YWdnOuCNAb5RUNA2vLX87uzOGOaqec=,tag:ixVU3FWGpZqZx/1PD3/3KA==,type:str]
uchicago: ENC[AES256_GCM,data:3ZkuIfvzOkKfQD0iyTk=,iv:aCfFrxDM5Ly/qLdLAQkK2tOxb89dFkCc9RhN5GVSGRw=,tag:7D54pkVX2F6IhM38JOUFQg==,type:str] uchicago: ENC[AES256_GCM,data:LqZTprY/9Li8ab9i0dg=,iv:tLJHXwsoL7PnwonHlnXiaLahr0+fIizsoshE0GFbkn8=,tag:FT5brU6pW7xFxnzpBYU2jA==,type:str]
sops: sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age: age:
- recipient: age13cfe8fhp4m978qlcur46vkkxepsl93ggwe53kmhue9xtpgr5zu5q4y6ln2 - recipient: age13cfe8fhp4m978qlcur46vkkxepsl93ggwe53kmhue9xtpgr5zu5q4y6ln2
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMMTcwTEc5VTdEMlZSK1FI YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBxUjF4Nm0yVWFwMUM1Y2hn
c2VVdjJOc3B3V2RGS0pIVGQralJ4MGFwSkRvCm5mVTNxMHUzNythNHVyRG52bVYz SVRhUmEweDNVd3Z2NVpEVW1yaDRYaDhLZ0NZCjE3WkVTWXUrKzE1VGN5ZUtSb2VZ
RVp2d1hKUnpucko1SG01SDdWNFZGV1EKLS0tIDB2OGF1UlUyN2xnRm1WR1RleUhN WnJFRkkwZmJKTm5OWlpMLzlCZHR6aE0KLS0tIFZ3UEFmcTJIYlcrUXhyU1hSMFRK
S1hFWjhCMlNZVC83ZzR4NittcXlCQlUKQO6NHCMwWKwrfwwnwLK/sO4HO6ES+PyT MjhvU0NQamQzcE1sWG5FSmpoajdNc0UKslJWrvq4BIeMoZ6ZSA6anlldGOpUuXrL
dh3tRhPlv7/viO+MtHqUfQ5cbW+OWoic4prfK/UxIz5VeY331kpq+g== PV7pVpTihxWtzPbPV36oPRVoN3GzNZXUPJryExtUzdnufbhfu9LBTw==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age1pdk6dmyxqhdaja5d0nf8f9qjd43hmfahmkure5yrf8al9jyfmd8qfdxwl6 - recipient: age1pdk6dmyxqhdaja5d0nf8f9qjd43hmfahmkure5yrf8al9jyfmd8qfdxwl6
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0ajhrbkdqcmpRd2svYmNx YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOZ01sMXhvMG5BMmxwa3h1
dHIzRDJTTTVGV3VON0NBZnpaQTdGM2w4aXpNClNqb2Y4Qzg4OWx2a3FNdG5MY1ZQ aXArSkxUNUkwOHAzQnlkYk4vVmEzckZkaFVzCnpYRmpqMW9QM29VTWFnc0NYTURj
R2dOSC9CdzBPM1I5b1lCVnptMGM3eUEKLS0tIGZRM1pSV3J0NlJvQUZBcTVNZGxy REp0OVNPN1lRRUdPWlQrTmhYcEZwbm8KLS0tIFI2dFBzbmQ4Q01PU1BLUXI5eXIy
SS9qQlJiRU1EelZySWpNdWRiTms3ZncKkwp1WT9LWxnJb+yjilikTHRm1fbs89TU Y0ZMMmJTOVRrbXpOVkYxektxOFFkZUEKcjX/wDMvuZ+PzfydOGOf938mCVcFFD/h
1Xzy+GNiZbtm2I6e5XaaD+9d3PFvqqu0OdqrMrTMmiNAys0WhwB8Iw== nGdbXAoE+cD7/rmpaF0Bpm2WqWrkiAvE/csyaWV/HNzQ6JkXp/4jtQ==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2025-03-04T21:54:28Z" - recipient: age15vscvpe79l287h8f3hssrj2r45xy0l3ns94zfue2fxlq43cqdsxq58vq3c
mac: ENC[AES256_GCM,data:r+2SOcW7xLHee9kL8369yB6l/Z2XdnzGkeFygSrDgcZVfBfp/fT1xeMvu5tuu8aqsUeJ7lkFD2VKiBue95XSojdlM+5YyTerqdzLyMCRbkRivC3O2xXe90B4hVqm+twE9uu74mIznAQ2e0EO9E0MMlMNBo3EwsEcYA8gyVuB5mc=,iv:plNu3BircQ+kpPaXqlNvYlLAL5V5RX/yiETs+nY1pfw=,tag:7gVuOpzx5YsHtwodIRr4TQ==,type:str] enc: |
pgp: [] -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQdVV6Vy9pRmg1ZjR5c01w
L1JWWDF6U05RNnNGTjF1VEN6ZCt6SENod2xJCjA1QngrQnJXMi9BdFByT3FPSVVR
eUEyd29YQXphZ2VuTmorOWU4MjZ1TmMKLS0tIFNSZG5iV21MSHVBNkZoZW5pV09k
eS9JTWRDaVZVN2hLcVF1S2NTdk1TWGMKVnpl9T5ZycSlJmE8M8QY62kxDp5lgagF
D6hxceNiqvgGg+GwIRXoVYiVhmNAE1R9dVTyMlAfFa2pxGg7JrPj1A==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-12-02T05:42:16Z"
mac: ENC[AES256_GCM,data:95V5+/M85gUaeJD8UhkMZCcMbYEnEBIA3qFDSDd0ZoxXQkw+IXy3/C8rV9QPK/Bq/Hv3fPWbs+0CwH5GqhjfaoIlVgo3MBlk6Z1iSuw7MTy8vGOBFWpYBrObib8f9yYIZ74CrpvCHHoFtqP5cKevmHsCvgrJpbkw4gZIhZVkjLk=,iv:0/v8QzgZYc/VMei0qP1PlK4oc4b2ch5VoBEW3P3gXxU=,tag:rFTyhSixSzl1BOIhGDJo+g==,type:str]
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.9.4 version: 3.11.0

View file

@ -91,5 +91,11 @@
hammerspoon.enable = true; hammerspoon.enable = true;
kitty.enable = true; kitty.enable = true;
}; };
email = {
enable = true;
davmail = true;
neomutt = true;
mbsync = true;
};
}; };
} }

View file

@ -59,6 +59,7 @@ let
imports = [ imports = [
inputs.nix-index-database.homeModules.nix-index inputs.nix-index-database.homeModules.nix-index
inputs.sops-nix.homeManagerModules.sops inputs.sops-nix.homeManagerModules.sops
../modules/home-manager
../home ../home
] ]
++ lib.optional (builtins.pathExists ./${host}/home.nix) ./${host}/home.nix; ++ lib.optional (builtins.pathExists ./${host}/home.nix) ./${host}/home.nix;
@ -134,6 +135,7 @@ let
inputs.nix-index-database.homeModules.nix-index inputs.nix-index-database.homeModules.nix-index
inputs.sops-nix.homeManagerModules.sops inputs.sops-nix.homeManagerModules.sops
inputs.mac-app-util.homeManagerModules.default inputs.mac-app-util.homeManagerModules.default
../modules/home-manager
../home ../home
] ]
++ lib.optional (builtins.pathExists ./${host}/home.nix) ./${host}/home.nix; ++ lib.optional (builtins.pathExists ./${host}/home.nix) ./${host}/home.nix;

View file

@ -1,13 +1,5 @@
{ {
inputs,
lib,
config,
pkgs,
system,
dots,
user, user,
hm,
host,
... ...
}: }:
{ {

View file

@ -0,0 +1,163 @@
{
config,
lib,
pkgs,
...
}:
let
inherit (lib)
getExe
mapAttrsRecursive
mkDefault
mkEnableOption
mkIf
mkMerge
mkOption
optionalAttrs
types
;
cfg = config.services.davmail;
isDarwin = pkgs.stdenv.isDarwin;
isLinux = pkgs.stdenv.isLinux;
javaProperties = pkgs.formats.javaProperties { };
settingsFile = javaProperties.generate "davmail.properties" cfg.settings;
in
{
meta.maintainers = [ lib.maintainers.bmrips ];
options.services.davmail = {
enable = mkEnableOption "DavMail, an MS Exchange gateway.";
package = lib.mkPackageOption pkgs "davmail" { };
imitateOutlook = mkOption {
type = types.bool;
default = false;
description = "Whether DavMail pretends to be Outlook.";
example = true;
};
settings = mkOption {
type = javaProperties.type;
default = { };
description = ''
Davmail configuration. Refer to
<http://davmail.sourceforge.net/serversetup.html>
and <http://davmail.sourceforge.net/advanced.html>
for details on supported values.
'';
example = {
"davmail.url" = "https://outlook.office365.com/EWS/Exchange.asmx";
"davmail.allowRemote" = true;
"davmail.imapPort" = 55555;
"davmail.bindAddress" = "10.0.1.2";
"davmail.smtpSaveInSent" = true;
"davmail.folderSizeLimit" = 10;
"davmail.caldavAutoSchedule" = false;
"log4j.logger.rootLogger" = "DEBUG";
};
};
};
config = mkIf cfg.enable (mkMerge [
# Common configuration for all platforms
{
services.davmail.settings =
mapAttrsRecursive (_: mkDefault) {
"davmail.server" = true;
"davmail.disableUpdateCheck" = true;
"davmail.logFilePath" = "${config.xdg.stateHome}/davmail.log";
"davmail.logFileSize" = "1MB";
"davmail.mode" = "auto";
"davmail.url" = "https://outlook.office365.com/EWS/Exchange.asmx";
"davmail.caldavPort" = 1080;
"davmail.imapPort" = 1143;
"davmail.ldapPort" = 1389;
"davmail.popPort" = 1110;
"davmail.smtpPort" = 1025;
"davmail.oauth.tokenFilePath" = "${config.xdg.stateHome}/davmail-tokens";
"log4j.logger.davmail" = "WARN";
"log4j.logger.httpclient.wire" = "WARN";
"log4j.logger.org.apache.commons.httpclient" = "WARN";
"log4j.rootLogger" = "WARN";
}
// optionalAttrs cfg.imitateOutlook {
"davmail.oauth.clientId" = "d3590ed6-52b3-4102-aeff-aad2292ab01c";
"davmail.oauth.redirectUri" = "urn:ietf:wg:oauth:2.0:oob";
};
home.packages = [ cfg.package ];
}
# Linux-specific: systemd user service
(mkIf isLinux {
systemd.user.services.davmail = {
Unit = {
Description = "DavMail POP/IMAP/SMTP Exchange Gateway";
After = [
"graphical-session.target"
"network.target"
];
};
Install.WantedBy = [ "graphical-session.target" ];
Service = {
Type = "exec";
ExecStart = "${getExe cfg.package} ${settingsFile}";
Restart = "on-failure";
CapabilityBoundingSet = [ "" ];
DeviceAllow = [ "" ];
LockPersonality = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateTmp = true;
PrivateUsers = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectSystem = "strict";
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
RemoveIPC = true;
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
"AF_UNIX"
];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallFilter = "@system-service";
SystemCallErrorNumber = "EPERM";
UMask = "0077";
};
};
})
# Darwin-specific: launchd agent
(mkIf isDarwin {
launchd.agents.davmail = {
enable = true;
config = {
ProgramArguments = [
"${getExe cfg.package}"
"${settingsFile}"
];
KeepAlive = true;
RunAtLoad = true;
StandardErrorPath = "/tmp/davmail.err.log";
StandardOutPath = "/tmp/davmail.out.log";
};
};
})
]);
}

View file

@ -0,0 +1,11 @@
{
disabledModules = [
"services/davmail.nix"
"services/mbsync.nix"
];
imports = [
./davmail.nix
./mbsync.nix
];
}

View file

@ -0,0 +1,159 @@
{
config,
lib,
pkgs,
...
}:
let
inherit (lib)
concatStringsSep
mkIf
mkMerge
mkOption
optionalAttrs
types
;
cfg = config.services.mbsync;
isDarwin = pkgs.stdenv.isDarwin;
isLinux = pkgs.stdenv.isLinux;
mbsyncOptions = [
"--all"
]
++ lib.optional cfg.verbose "--verbose"
++ lib.optional (cfg.configFile != null) "--config ${cfg.configFile}";
mbsyncCommand = "${cfg.package}/bin/mbsync ${concatStringsSep " " mbsyncOptions}";
# Convert systemd calendar format to launchd interval (approximate)
# Format like "*:0/5" means every 5 minutes
# We'll parse simple cases, default to 5 minutes
parseFrequencyToSeconds =
freq:
let
# Try to extract minute interval from patterns like "*:0/5" or "*:*:0/30"
parts = builtins.match ".*\\*/([0-9]+).*" freq;
in
if parts != null then (lib.toInt (builtins.head parts)) * 60 else 300;
in
{
meta.maintainers = [ lib.maintainers.pjones ];
options.services.mbsync = {
enable = lib.mkEnableOption "mbsync";
package = lib.mkPackageOption pkgs "isync" { };
frequency = mkOption {
type = types.str;
default = "*:0/5";
description = ''
How often to run mbsync. On Linux, this value is passed to the systemd
timer configuration as the onCalendar option. See
{manpage}`systemd.time(7)` for more information about the format.
On Darwin, this is converted to an approximate interval in seconds.
'';
};
verbose = mkOption {
type = types.bool;
default = true;
description = ''
Whether mbsync should produce verbose output.
'';
};
configFile = mkOption {
type = types.nullOr types.path;
default = null;
description = ''
Optional configuration file to link to use instead of
the default file ({file}`~/.mbsyncrc`).
'';
};
preExec = mkOption {
type = types.nullOr types.str;
default = null;
example = "mkdir -p %h/mail";
description = ''
An optional command to run before mbsync executes. This is
useful for creating the directories mbsync is going to use.
'';
};
postExec = mkOption {
type = types.nullOr types.str;
default = null;
example = "\${pkgs.mu}/bin/mu index";
description = ''
An optional command to run after mbsync executes successfully.
This is useful for running mailbox indexing tools.
'';
};
};
config = mkIf cfg.enable (mkMerge [
# Linux-specific: systemd user service and timer
(mkIf isLinux {
systemd.user.services.mbsync = {
Unit = {
Description = "mbsync mailbox synchronization";
};
Service = {
Type = "oneshot";
ExecStart = mbsyncCommand;
}
// (optionalAttrs (cfg.postExec != null) {
ExecStartPost = cfg.postExec;
})
// (optionalAttrs (cfg.preExec != null) {
ExecStartPre = cfg.preExec;
});
};
systemd.user.timers.mbsync = {
Unit = {
Description = "mbsync mailbox synchronization";
};
Timer = {
OnCalendar = cfg.frequency;
Unit = "mbsync.service";
};
Install = {
WantedBy = [ "timers.target" ];
};
};
})
# Darwin-specific: launchd agent
(mkIf isDarwin {
launchd.agents.mbsync = {
enable = true;
config =
let
# Build a script that handles pre/post exec
mbsyncScript = pkgs.writeShellScript "mbsync-wrapper" ''
set -e
${lib.optionalString (cfg.preExec != null) cfg.preExec}
${mbsyncCommand}
${lib.optionalString (cfg.postExec != null) cfg.postExec}
'';
in
{
ProgramArguments = [ "${mbsyncScript}" ];
StartInterval = parseFrequencyToSeconds cfg.frequency;
RunAtLoad = true;
StandardErrorPath = "/tmp/mbsync.err.log";
StandardOutPath = "/tmp/mbsync.out.log";
};
};
})
]);
}