blob: 40047dd2bb64d80966003b6a28e07a344053edbb [file] [log] [blame]
Skyler Grey (Minion3665)e430df32023-06-23 18:22:19 +00001{ base, pkgs, drive_paths, lib, config, ... }:
Samuel Shuertf68685d2023-10-28 20:07:56 -04002if drive_paths == null
3then {}
4else lib.recursiveUpdate {
TheCodedProfb6184602023-06-13 17:04:59 -04005 environment.systemPackages = with pkgs; [ vaultwarden ];
TheCodedProfaec8c452023-06-12 18:26:46 -04006
TheCodedProfb6184602023-06-13 17:04:59 -04007 services.vaultwarden.enable = true;
8 services.vaultwarden.dbBackend = "postgresql";
TheCodedProfaec8c452023-06-12 18:26:46 -04009
Skyler Greyfe1740c2023-10-21 01:24:18 +000010 sops.secrets = lib.pipe [
11 "ADMIN_TOKEN"
12 "SMTP_PASSWORD"
13 "YUBICO_SECRET_KEY"
14 "HIBP_API_KEY"
15 ] [
Skyler Grey87a11552023-06-14 23:02:25 +020016 (map (name: {
Skyler Greyfe1740c2023-10-21 01:24:18 +000017 inherit name;
18 value = {
19 mode = "0400";
20 owner = config.users.users.root.name;
Skyler Greybcb46d32023-11-10 20:48:38 +000021 group = config.users.users.root.group;
Samuel Shuertf68685d2023-10-28 20:07:56 -040022 sopsFile = ../../secrets/vaultwarden.json;
Skyler Greyfe1740c2023-10-21 01:24:18 +000023 format = "json";
24 };
Skyler Grey87a11552023-06-14 23:02:25 +020025 }))
TheCodedProfb6184602023-06-13 17:04:59 -040026 builtins.listToAttrs
27 ];
Skyler Greyfe1740c2023-10-21 01:24:18 +000028} (let isDerived = base != null;
29in if isDerived
30# We cannot use mkIf as both sides are evaluated no matter the condition value
31# Given we use base as an attrset, mkIf will error if base is null in here
32then
33 with lib;
34 let
35 cfg = config.services.vaultwarden;
36
37 vaultwarden_config = {
38 # Server Settings
39 DOMAIN = "https://passwords.clicks.codes";
40 ROCKET_ADDRESS = "127.0.0.1";
41 ROCKET_PORT = 8452;
42
43 # General Settings
44 SIGNUPS_ALLOWED = false;
45 INVITATIONS_ALLOWED = true;
46 SIGNUPS_DOMAINS_WHITELIST =
47 "clicks.codes,coded.codes,thecoded.prof,starrysky.fyi,hopescaramels.com,pinea.dev,trans.gg";
48 SIGNUPS_VERIFY = true;
49
50 RSA_KEY_FILENAME =
51 "${drive_paths.External1000SSD.path}/bitwarden/rsa_key";
52 ICON_CACHE_FOLDER =
53 "${drive_paths.External1000SSD.path}/bitwarden/icon_cache";
54 ATTACHMENTS_FOLDER =
55 "${drive_paths.External4000HDD.path}/bitwarden/attachments";
56 SENDS_FOLDER = "${drive_paths.External4000HDD.path}/bitwarden/sends";
57 TMP_FOLDER = "${drive_paths.External4000HDD.path}/bitwarden/tmp";
58
59 DISABLE_2FA_REMEMBER = true;
60
61 # Admin Account
62 ADMIN_TOKEN = "!!ADMIN_TOKEN!!";
63
64 # Database Settings
65 DATABASE_URL =
66 "postgresql://vaultwarden:!!clicks_bitwarden_db_secret!!@127.0.0.1:${
67 toString config.services.postgresql.port
68 }/vaultwarden";
69
70 # Mail Settings
71 SMTP_HOST = "mail.clicks.codes";
72 SMTP_FROM = "bitwarden@clicks.codes";
73 SMTP_FROM_NAME = "Clicks Bitwarden";
74 SMTP_SECURITY = "starttls";
75 SMTP_PORT = 587;
76
77 SMTP_USERNAME = "bitwarden@clicks.codes";
78 SMTP_PASSWORD = "!!SMTP_PASSWORD!!";
79
80 REQUIRE_DEVICE_EMAIL = true;
81
82 IP_HEADER = "X-Forwarded-For";
83
84 # YubiKey Settings
85 YUBICO_CLIENT_ID = "89788";
86 YUBICO_SECRET_KEY = "!!YUBICO_SECRET_KEY!!";
87
88 # TODO: Buy a license
89 # HIBP Settings
90 # HIBP_API_KEY="!!HIBP_API_KEY!!";
91
92 ORG_ENABLE_GROUPS = true;
93 # I have looked at the risks. They seem relatively small in comparison to the utility
94 # (stuff like sync issues if you don't refresh your page)
95 # Also a general lack of real-world testing. Which, honestly, doesn't
96 # seem too bad. Please contact me *immediately* upon noticing issues
97 # as I want to make sure that as little as possible is lost if we need
98 # to restore from backups (although I doubt it'll come to that)
99 };
100
101 nameToEnvVar = name:
Skyler Grey31618512023-08-20 21:54:44 +0000102 let
Skyler Greyfe1740c2023-10-21 01:24:18 +0000103 parts = builtins.split "([A-Z0-9]+)" name;
104 partsToEnvVar = parts:
105 foldl' (key: x:
106 let last = stringLength key - 1;
107 in if isList x then
108 key
109 + optionalString (key != "" && substring last 1 key != "_") "_"
110 + head x
111 else if key != "" && elem (substring 0 1 x)
112 lowerChars then # to handle e.g. [ "disable" [ "2FAR" ] "emember" ]
113 substring 0 last key
114 + optionalString (substring (last - 1) 1 key != "_") "_"
115 + substring last 1 key + toUpper x
116 else
117 key + toUpper x) "" parts;
118 in if builtins.match "[A-Z0-9_]+" name != null then
119 name
120 else
121 partsToEnvVar parts;
TheCodedProfb6184602023-06-13 17:04:59 -0400122
Skyler Greyfe1740c2023-10-21 01:24:18 +0000123 # Due to the different naming schemes allowed for config keys,
124 # we can only check for values consistently after converting them to their corresponding environment variable name.
125 configEnv = let
126 configEnv = concatMapAttrs (name: value:
127 optionalAttrs (value != null) {
128 ${nameToEnvVar name} =
129 if isBool value then boolToString value else toString value;
130 }) vaultwarden_config;
131 in {
132 DATA_FOLDER = "/var/lib/bitwarden_rs";
133 } // optionalAttrs (!(configEnv ? WEB_VAULT_ENABLED)
134 || configEnv.WEB_VAULT_ENABLED == "true") {
135 WEB_VAULT_FOLDER = "${cfg.webVaultPackage}/share/vaultwarden/vault";
136 } // configEnv;
Skyler Grey31618512023-08-20 21:54:44 +0000137
Skyler Greyfe1740c2023-10-21 01:24:18 +0000138 configFile = pkgs.writeText "vaultwarden.env" (concatStrings (mapAttrsToList
139 (name: value: ''
140 ${name}=${value}
141 '') configEnv));
142 in {
143 scalpel.trafos."vaultwarden.env" = {
144 source = toString configFile;
145 matchers."ADMIN_TOKEN".secret = config.sops.secrets.ADMIN_TOKEN.path;
146 matchers."SMTP_PASSWORD".secret = config.sops.secrets.SMTP_PASSWORD.path;
147 matchers."YUBICO_SECRET_KEY".secret =
148 config.sops.secrets.YUBICO_SECRET_KEY.path;
149 matchers."HIBP_API_KEY".secret = config.sops.secrets.HIBP_API_KEY.path;
150 matchers."clicks_bitwarden_db_secret".secret =
151 config.sops.secrets.clicks_bitwarden_db_password.path;
152 owner = config.users.users.vaultwarden.name;
153 group = config.users.groups.vaultwarden.name;
154 mode = "0400";
155 };
Skyler Grey31618512023-08-20 21:54:44 +0000156
Skyler Greyfe1740c2023-10-21 01:24:18 +0000157 services.vaultwarden.environmentFile =
158 config.scalpel.trafos."vaultwarden.env".destination;
159 }
160else
161 { })