blob: 0a3764e52262793bf21b6527ee0bba1a8e162526 [file] [log] [blame]
{ base, pkgs, drive_paths, lib, config, ... }:
lib.recursiveUpdate
{
environment.systemPackages = with pkgs; [ vaultwarden ];
services.vaultwarden.enable = true;
services.vaultwarden.dbBackend = "postgresql";
sops.secrets = lib.pipe [ "ADMIN_TOKEN" "SMTP_PASSWORD" "YUBICO_SECRET_KEY" "HIBP_API_KEY" ] [
(map (name: {
inherit name; value = {
mode = "0400";
owner = config.users.users.root.name;
group = config.users.users.nobody.group;
sopsFile = ../secrets/vaultwarden.json;
format = "json";
};
}))
builtins.listToAttrs
];
}
(
let
isDerived = base != null;
in
if isDerived
# We cannot use mkIf as both sides are evaluated no matter the condition value
# Given we use base as an attrset, mkIf will error if base is null in here
then
with lib;
let
cfg = config.services.vaultwarden;
vaultwarden_config = {
# Server Settings
DOMAIN = "https://passwords.clicks.codes";
ROCKET_ADDRESS = "127.0.0.1";
ROCKET_PORT = 8452;
# General Settings
SIGNUPS_ALLOWED = false;
INVITATIONS_ALLOWED = true;
SIGNUPS_DOMAINS_WHITELIST = "clicks.codes,coded.codes,thecoded.prof,starrysky.fyi,hopescaramels.com,pinea.dev,trans.gg";
SIGNUPS_VERIFY = true;
RSA_KEY_FILENAME = "${drive_paths.External1000SSD.path}/bitwarden/rsa_key";
ICON_CACHE_FOLDER = "${drive_paths.External1000SSD.path}/bitwarden/icon_cache";
ATTACHMENTS_FOLDER = "${drive_paths.External4000HDD.path}/bitwarden/attachments";
SENDS_FOLDER = "${drive_paths.External4000HDD.path}/bitwarden/sends";
TMP_FOLDER = "${drive_paths.External4000HDD.path}/bitwarden/tmp";
DISABLE_2FA_REMEMBER = true;
# Admin Account
ADMIN_TOKEN = "!!ADMIN_TOKEN!!";
# Database Settings
DATABASE_URL =
"postgresql://vaultwarden:!!clicks_bitwarden_db_secret!!@127.0.0.1:${toString config.services.postgresql.port}/vaultwarden";
# Mail Settings
SMTP_HOST = "mail.clicks.codes";
SMTP_FROM = "bitwarden@clicks.codes";
SMTP_FROM_NAME = "Clicks Bitwarden";
SMTP_SECURITY = "starttls";
SMTP_PORT = 587;
SMTP_USERNAME = "bitwarden@clicks.codes";
SMTP_PASSWORD = "!!SMTP_PASSWORD!!";
REQUIRE_DEVICE_EMAIL = true;
IP_HEADER = "X-Forwarded-For";
# YubiKey Settings
YUBICO_CLIENT_ID = "89788";
YUBICO_SECRET_KEY = "!!YUBICO_SECRET_KEY!!";
# TODO: Buy a license
# HIBP Settings
# HIBP_API_KEY="!!HIBP_API_KEY!!";
ORG_ENABLE_GROUPS = true;
# I have looked at the risks. They seem relatively small in comparison to the utility
# (stuff like sync issues if you don't refresh your page)
# Also a general lack of real-world testing. Which, honestly, doesn't
# seem too bad. Please contact me *immediately* upon noticing issues
# as I want to make sure that as little as possible is lost if we need
# to restore from backups (although I doubt it'll come to that)
};
nameToEnvVar = name:
let
parts = builtins.split "([A-Z0-9]+)" name;
partsToEnvVar = parts: foldl'
(key: x:
let last = stringLength key - 1; in
if isList x then key + optionalString (key != "" && substring last 1 key != "_") "_" + head x
else if key != "" && elem (substring 0 1 x) lowerChars then # to handle e.g. [ "disable" [ "2FAR" ] "emember" ]
substring 0 last key + optionalString (substring (last - 1) 1 key != "_") "_" + substring last 1 key + toUpper x
else key + toUpper x) ""
parts;
in
if builtins.match "[A-Z0-9_]+" name != null then name else partsToEnvVar parts;
# Due to the different naming schemes allowed for config keys,
# we can only check for values consistently after converting them to their corresponding environment variable name.
configEnv =
let
configEnv = concatMapAttrs
(name: value: optionalAttrs (value != null) {
${nameToEnvVar name} = if isBool value then boolToString value else toString value;
})
vaultwarden_config;
in
{ DATA_FOLDER = "/var/lib/bitwarden_rs"; } // optionalAttrs (!(configEnv ? WEB_VAULT_ENABLED) || configEnv.WEB_VAULT_ENABLED == "true") {
WEB_VAULT_FOLDER = "${cfg.webVaultPackage}/share/vaultwarden/vault";
} // configEnv;
configFile = pkgs.writeText "vaultwarden.env" (concatStrings (mapAttrsToList (name: value: "${name}=${value}\n") configEnv));
in
{
scalpel.trafos."vaultwarden.env" = {
source = toString configFile;
matchers."ADMIN_TOKEN".secret =
config.sops.secrets.ADMIN_TOKEN.path;
matchers."SMTP_PASSWORD".secret =
config.sops.secrets.SMTP_PASSWORD.path;
matchers."YUBICO_SECRET_KEY".secret =
config.sops.secrets.YUBICO_SECRET_KEY.path;
matchers."HIBP_API_KEY".secret =
config.sops.secrets.HIBP_API_KEY.path;
matchers."clicks_bitwarden_db_secret".secret =
config.sops.secrets.clicks_bitwarden_db_password.path;
owner = config.users.users.vaultwarden.name;
group = config.users.groups.vaultwarden.name;
mode = "0400";
};
services.vaultwarden.environmentFile = config.scalpel.trafos."vaultwarden.env".destination;
} else { }
)