Files
sp-config/sp-modules/hedgedoc/module.nix

187 lines
4.7 KiB
Nix
Raw Normal View History

{
config,
lib,
pkgs,
...
}:
let
sp = config.selfprivacy;
cfg = sp.modules.hedgedoc;
oauthClientID = "hedgedoc";
auth-passthru = config.selfprivacy.passthru.auth;
oauth2-provider-origin = config.services.kanidm.serverSettings.origin;
usersGroup = "sp.hedgedoc.users";
oauthClientSecretFP = auth-passthru.mkOAuth2ClientSecretFP oauthClientID;
in
{
options.selfprivacy.modules.hedgedoc = {
enable =
(lib.mkOption {
default = false;
type = lib.types.bool;
description = "Enable HedgeDoc";
})
// {
meta = {
type = "enable";
};
};
location =
(lib.mkOption {
type = lib.types.str;
description = "HedgeDoc location";
})
// {
meta = {
type = "location";
};
};
subdomain =
(lib.mkOption {
default = "hedgedoc";
type = lib.types.strMatching "[A-Za-z0-9][A-Za-z0-9\-]{0,61}[A-Za-z0-9]";
description = "Subdomain";
})
// {
meta = {
widget = "subdomain";
type = "string";
regex = "[A-Za-z0-9][A-Za-z0-9\-]{0,61}[A-Za-z0-9]";
weight = 0;
};
};
allowAnonymous =
(lib.mkOption {
default = false;
type = lib.types.bool;
description = "Allow usage (e.g., notes creation) without an account";
})
// {
meta = {
type = "bool";
weight = 1;
};
};
allowLibravatar =
(lib.mkOption {
default = false;
type = lib.types.bool;
description = "Use Libravatar as profile picture source";
})
// {
meta = {
type = "bool";
weight = 2;
};
};
};
config = lib.mkIf cfg.enable {
assertions = [
{
assertion = sp.sso.enable;
message = "HedgeDoc cannot be enabled when SSO is disabled.";
}
];
fileSystems = lib.mkIf sp.useBinds {
"/var/lib/hedgedoc" = {
device = "/volumes/${cfg.location}/hedgedoc";
options = [ "bind" ];
};
};
services.postgresql = {
ensureDatabases = [ "hedgedoc" ];
ensureUsers = [
{
name = "hedgedoc";
ensureDBOwnership = true;
}
];
};
services.hedgedoc = {
enable = true;
package = pkgs.hedgedoc.overrideAttrs (old: {
doCheck = true;
patches = (old.patches or [ ]) ++ [
./hedgedocClientSecretAsFile.patch
];
});
settings = {
port = 3001;
protocolUseSSL = true;
useSSL = false;
domain = "${cfg.subdomain}.${sp.domain}";
host = "127.0.0.1";
# HedgeDoc saves the old option name for compatibility, even though it fetches avatars from Libravatar
allowGravatar = cfg.allowLibravatar;
db = {
username = "hedgedoc";
database = "hedgedoc";
host = "/run/postgresql";
dialect = "postgresql";
};
uploadsPath = "/var/lib/hedgedoc/uploads";
allowEmailRegister = false;
email = false;
allowAnonymous = cfg.allowAnonymous;
oauth2 = {
baseURL = oauth2-provider-origin;
clientID = "hedgedoc";
clientSecret = oauthClientSecretFP;
authorizationURL = "${oauth2-provider-origin}/ui/oauth2";
tokenURL = "${oauth2-provider-origin}/oauth2/token";
userProfileURL = "${oauth2-provider-origin}/oauth2/openid/${oauthClientID}/userinfo";
scope = "openid email profile";
userProfileUsernameAttr = "sub";
userProfileDisplayNameAttr = "name";
userProfileEmailAttr = "email";
};
loglevel = "error";
};
};
services.nginx.virtualHosts."${cfg.subdomain}.${sp.domain}" = {
useACMEHost = sp.domain;
forceSSL = true;
locations = {
"/" = {
proxyPass = "http://127.0.0.1:3001";
proxyWebsockets = true;
};
};
};
systemd = {
services.hedgedoc = {
unitConfig.RequiresMountsFor = lib.mkIf sp.useBinds "/volumes/${cfg.location}/hedgedoc";
serviceConfig.Slice = "hedgedoc.slice";
};
slices.hedgedoc = {
description = "HedgeDoc service slice";
};
};
selfprivacy.auth.clients.${oauthClientID} = {
inherit usersGroup;
subdomain = cfg.subdomain;
originLanding = "https://${cfg.subdomain}.${sp.domain}/";
originUrl = "https://${cfg.subdomain}.${sp.domain}/auth/oauth2/callback";
clientSystemdUnits = [ "hedgedoc.service" ];
enablePkce = false;
linuxUserOfClient = "hedgedoc";
linuxGroupOfClient = "hedgedoc";
};
};
}