Compare commits
5 commits
c02946aba3
...
6e88c391f9
Author | SHA1 | Date | |
---|---|---|---|
Natsu Kagami | 6e88c391f9 | ||
Natsu Kagami | 2326c903c0 | ||
Natsu Kagami | cc7d62745c | ||
Natsu Kagami | 23c2436ab6 | ||
Natsu Kagami | cbb496cb47 |
|
@ -95,6 +95,12 @@ in
|
||||||
{ face = "ts_markup_italic"; token = "text"; modifiers = [ "emph" ]; }
|
{ face = "ts_markup_italic"; token = "text"; modifiers = [ "emph" ]; }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
programs.kak-lsp.languageServers.elixir-ls = {
|
||||||
|
args = [ ];
|
||||||
|
command = "elixir-ls";
|
||||||
|
filetypes = [ "elixir" ];
|
||||||
|
roots = [ "mix.exs" ];
|
||||||
|
};
|
||||||
programs.kak-lsp.languageServers.typescript-language-server = {
|
programs.kak-lsp.languageServers.typescript-language-server = {
|
||||||
args = [ "--stdio" ];
|
args = [ "--stdio" ];
|
||||||
command = "typescript-language-server";
|
command = "typescript-language-server";
|
||||||
|
|
|
@ -92,7 +92,7 @@ hook global InsertCompletionHide .* %{
|
||||||
try %{
|
try %{
|
||||||
eval %sh{test -z "$WE_STARTED_KAK" && kak-lsp --kakoune -s $kak_session}
|
eval %sh{test -z "$WE_STARTED_KAK" && kak-lsp --kakoune -s $kak_session}
|
||||||
}
|
}
|
||||||
hook global WinSetOption filetype=(racket|rust|python|go|javascript|typescript|c|cpp|tex|latex|fsharp|ocaml|haskell|nix|scala|typst|html|css|json|markdown|templ) %{
|
hook global WinSetOption filetype=(racket|rust|python|go|javascript|typescript|c|cpp|tex|latex|fsharp|ocaml|haskell|nix|scala|typst|html|css|json|markdown|templ|elixir) %{
|
||||||
lsp-enable-window
|
lsp-enable-window
|
||||||
map window lsp N -docstring "Display the next message request" ": lsp-show-message-request-next<ret>"
|
map window lsp N -docstring "Display the next message request" ": lsp-show-message-request-next<ret>"
|
||||||
map window normal <c-l> ": enter-user-mode lsp<ret>"
|
map window normal <c-l> ": enter-user-mode lsp<ret>"
|
||||||
|
|
|
@ -193,29 +193,27 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable
|
||||||
|
{
|
||||||
home.packages = [ cfg.package ];
|
home.packages = [ cfg.package ];
|
||||||
|
|
||||||
# Configurations
|
# Configurations
|
||||||
xdg.configFile."kak-lsp/kak-lsp.toml" = {
|
xdg.configFile."kak-lsp/kak-lsp.toml" =
|
||||||
source = pkgs.runCommand "config.toml"
|
let
|
||||||
|
toml = pkgs.formats.toml { };
|
||||||
|
stripNulls = lib.filterAttrsRecursive (n: v: v != null);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
source = toml.generate "config.toml"
|
||||||
{
|
{
|
||||||
buildInputs = [ pkgs.yj ];
|
|
||||||
preferLocalBuild = true;
|
|
||||||
} ''
|
|
||||||
yj -jt -i \
|
|
||||||
< ${
|
|
||||||
pkgs.writeText "config.json" (builtins.toJSON {
|
|
||||||
semantic_tokens.faces = cfg.semanticTokens.faces ++ cfg.semanticTokens.additionalFaces;
|
semantic_tokens.faces = cfg.semanticTokens.faces ++ cfg.semanticTokens.additionalFaces;
|
||||||
server.timeout = cfg.serverTimeout;
|
server.timeout = cfg.serverTimeout;
|
||||||
snippet_support = cfg.enableSnippets;
|
snippet_support = cfg.enableSnippets;
|
||||||
verbosity = 255;
|
verbosity = 255;
|
||||||
language_server = lspConfig.language_servers // cfg.languageServers;
|
language_server = stripNulls (lspConfig.language_servers // cfg.languageServers);
|
||||||
language_ids = lspConfig.language_ids // cfg.languageIds;
|
language_ids = lspConfig.language_ids // cfg.languageIds;
|
||||||
})
|
};
|
||||||
} \
|
|
||||||
> $out
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,6 +124,12 @@ in
|
||||||
config.wayland.windowManager.sway = mkIf cfg.enable {
|
config.wayland.windowManager.sway = mkIf cfg.enable {
|
||||||
enable = true;
|
enable = true;
|
||||||
systemd.enable = true;
|
systemd.enable = true;
|
||||||
|
systemd.variables = [
|
||||||
|
"PATH" # for portals
|
||||||
|
];
|
||||||
|
systemd.extraCommands = [
|
||||||
|
"systemctl --user restart xdg-desktop-portals.service"
|
||||||
|
];
|
||||||
|
|
||||||
checkConfig = false; # Not working atm
|
checkConfig = false; # Not working atm
|
||||||
config = {
|
config = {
|
||||||
|
|
|
@ -30,7 +30,7 @@ miniflux:
|
||||||
oidc-client-secret: ENC[AES256_GCM,data:lvPFzc1ZXOTArs6VfFzJmKjW7pFpWU1XMCzHfUWC8WRq3CTvd6iQSwnGgBmUtHtDJCF1un/32fOaqBtSeMkgt5nkd/j8fLhTrTZyo8hJV2l1p16RBC2C0+igQh8PMah1Yp+V4zTMd5UKYMPkK9Iwb/tJ5zXeqQ20LvmGk+E7lCCVrnyyJrJNwr310mzYaUmpRz9/1AEM,iv:+9yhwYxnB5zPSRjX9o3PRvBpq4hM45jNF3acqT6lSJc=,tag:yMTWbxHlTZgg4XxNjfc8wQ==,type:str]
|
oidc-client-secret: ENC[AES256_GCM,data:lvPFzc1ZXOTArs6VfFzJmKjW7pFpWU1XMCzHfUWC8WRq3CTvd6iQSwnGgBmUtHtDJCF1un/32fOaqBtSeMkgt5nkd/j8fLhTrTZyo8hJV2l1p16RBC2C0+igQh8PMah1Yp+V4zTMd5UKYMPkK9Iwb/tJ5zXeqQ20LvmGk+E7lCCVrnyyJrJNwr310mzYaUmpRz9/1AEM,iv:+9yhwYxnB5zPSRjX9o3PRvBpq4hM45jNF3acqT6lSJc=,tag:yMTWbxHlTZgg4XxNjfc8wQ==,type:str]
|
||||||
pocket-consumer-key: ENC[AES256_GCM,data:NXY9Y8rFlzCVVG3ATUL/u7Sj6Im1RU/D16toUOLcIfKvddBjlu+QddKXWfLKppV1BQZ0,iv:nf3gkm098UhpZOgMbOdyG1FYVcl5G0gxoI6RTsZ1r14=,tag:bMOYwtFwUJ4SFornsWo8ig==,type:str]
|
pocket-consumer-key: ENC[AES256_GCM,data:NXY9Y8rFlzCVVG3ATUL/u7Sj6Im1RU/D16toUOLcIfKvddBjlu+QddKXWfLKppV1BQZ0,iv:nf3gkm098UhpZOgMbOdyG1FYVcl5G0gxoI6RTsZ1r14=,tag:bMOYwtFwUJ4SFornsWo8ig==,type:str]
|
||||||
admin-creds: ENC[AES256_GCM,data:cBCwwRZR0B8nH7XLxHVZCThqmnUI6ZHFp3wH9TjdRbBTmySjPqU526ltn3lRQtopgqQ0IOuneTztXJ+wfqmLUABV6xlLBkXD7VX6Mf43RtIDyHL+UC56eIdn3xeawGsIjnta,iv:DOwHUL64ufLS7FbvnJCPxPYwMJF1pMPqjx78vltm9IY=,tag:A2Fpk4rI0/WK0jFtTlGhaA==,type:str]
|
admin-creds: ENC[AES256_GCM,data:cBCwwRZR0B8nH7XLxHVZCThqmnUI6ZHFp3wH9TjdRbBTmySjPqU526ltn3lRQtopgqQ0IOuneTztXJ+wfqmLUABV6xlLBkXD7VX6Mf43RtIDyHL+UC56eIdn3xeawGsIjnta,iv:DOwHUL64ufLS7FbvnJCPxPYwMJF1pMPqjx78vltm9IY=,tag:A2Fpk4rI0/WK0jFtTlGhaA==,type:str]
|
||||||
writefreely-dtth: ENC[AES256_GCM,data:Q2b3eCr5GLLyBMrGlTUSIuMN/vZXmMZV8T56+t7RjcoHQmEVDKGwPGgka4jf/yO9Nf6TdGB7iiXft+XK3t74XdnzTCTYYVFzFsv49eZDKpTeaR6pKcbesfJYyqOcHIuatQz/orQ1X6Ext9Xf9aBStY4GV6ticLpvdW3GtHzchMPuMm8vY8A8DYNH/kLGb96aHpQ53paKkckeDWcbDyCulUU=,iv:G4TNJ4vY6qo4iOrEBmsf6hHJWAqbl3t8JAyDIZ1lUUg=,tag:HEknuS+MjBBFbkpDEIRUfw==,type:str]
|
writefreely-oauth-secret: ENC[AES256_GCM,data:UTeJMo4MMLcPUL6RlSfNzluMs4Hu5iKkav3oH16Q0TvEhxCKMU1SkXgLAjbpjx5OidXKLXGc72kGQcVJegvWjfhVGH6eoDQiizyHSwznRyA4pGNhlJKm3w0tKKRzVJZjBKQgjQ6gODyeU7SdI6g0jK42t3Sm91404erRMOoKyZo=,iv:FQx/XE7FGhHhiKG7d4LfgIXQZq+nj9tvKgY6SRiZbXY=,tag:5rfCeM/yYFNukY4/CqOJ3g==,type:str]
|
||||||
matrix-synapse-dtth:
|
matrix-synapse-dtth:
|
||||||
oidc-config: ENC[AES256_GCM,data:06lv5ejqnQ1jBAhCBxXY3nNulXFnDt/S2ycma9+hlG6mSMGfRfIcfDZfKOfUUuV2uMI7ix4r0QdM3351VucvnWCZZlXz5YpVgNg1YZDvtSQxe3SJqKj/y3u+nYbPPIRgACiFpiajBeEvS/evIT8+Ty3myDVPHovYkuCb0U1eD3/xGK38lx6+H3Cjk3LyszMg1EwXdkDjbcDVYDhSEelkB9rWXH1vw5qNZOzGgIoYEe6ppMmPZjpUM9jyounuF/+FzLbkWz6YvY4zWD5fND5fFdT4AA1e1jzCLQIsaVZ8N6co5lwzfBfydLosEy+h/COv1wzvfXiEjNi4f+2Ol7kSu4+G3u3V6EcqTyVjj38oTLaAx1cG9pnPmAc/zTUCmepITAWysvuzIVd8gwde1CheANLp1WnQrAAKJiHv/6bxPoi0ROu0BpQqupU9XUcTXRysuTjBH5/ABjlvk8lTiFi8Ryt7KzC23kPWf541B8BO/yfpmq8mheMz1AYm+fkTZOqKgkfm4NStN58oiYn6NEyWpuaAx7DEUgO/MIrIKXfTzGCT++33Cnr41fLSqWgqIUhBxd9P1s3cYk942UxC2VdKf1qq6IGZK4iq8T1FUoXqmTnjEfwvTm2hDkZqwEdvkKZUolKvnsZL44KRBow/LMGGsDDFoOMsMT9MqE2fBGOudTnHncs3I/T7eEDnHH+z+60Axo6mKGwmaHRHeqeiV4OIrPmM5X8uUIWvKoNsY3UvL/VgKA2Zh7wm8irB0rgcaKDW6QMmJIxqd3RK9WwmOT4hPy/SC5nm1ZRlag/f+H6q+WOtEaK+,iv:5pYzz4QzKHVhHh+YFnerD5Q2S93stqBKILM2sxD23Fc=,tag:V0rVa/nTH3hv77Z8KOQOiw==,type:str]
|
oidc-config: ENC[AES256_GCM,data:06lv5ejqnQ1jBAhCBxXY3nNulXFnDt/S2ycma9+hlG6mSMGfRfIcfDZfKOfUUuV2uMI7ix4r0QdM3351VucvnWCZZlXz5YpVgNg1YZDvtSQxe3SJqKj/y3u+nYbPPIRgACiFpiajBeEvS/evIT8+Ty3myDVPHovYkuCb0U1eD3/xGK38lx6+H3Cjk3LyszMg1EwXdkDjbcDVYDhSEelkB9rWXH1vw5qNZOzGgIoYEe6ppMmPZjpUM9jyounuF/+FzLbkWz6YvY4zWD5fND5fFdT4AA1e1jzCLQIsaVZ8N6co5lwzfBfydLosEy+h/COv1wzvfXiEjNi4f+2Ol7kSu4+G3u3V6EcqTyVjj38oTLaAx1cG9pnPmAc/zTUCmepITAWysvuzIVd8gwde1CheANLp1WnQrAAKJiHv/6bxPoi0ROu0BpQqupU9XUcTXRysuTjBH5/ABjlvk8lTiFi8Ryt7KzC23kPWf541B8BO/yfpmq8mheMz1AYm+fkTZOqKgkfm4NStN58oiYn6NEyWpuaAx7DEUgO/MIrIKXfTzGCT++33Cnr41fLSqWgqIUhBxd9P1s3cYk942UxC2VdKf1qq6IGZK4iq8T1FUoXqmTnjEfwvTm2hDkZqwEdvkKZUolKvnsZL44KRBow/LMGGsDDFoOMsMT9MqE2fBGOudTnHncs3I/T7eEDnHH+z+60Axo6mKGwmaHRHeqeiV4OIrPmM5X8uUIWvKoNsY3UvL/VgKA2Zh7wm8irB0rgcaKDW6QMmJIxqd3RK9WwmOT4hPy/SC5nm1ZRlag/f+H6q+WOtEaK+,iv:5pYzz4QzKHVhHh+YFnerD5Q2S93stqBKILM2sxD23Fc=,tag:V0rVa/nTH3hv77Z8KOQOiw==,type:str]
|
||||||
appservice-discord: ENC[AES256_GCM,data:lAAEa6ltXi29+POrG87bMAvv8du3DiGYl8f7npqW0ga3YgrvofgYnC8QJUyznIQ3Ye9yWxzjzaClu7viFgkN0yIXlpENIOcSTrdlMgg5mdJ8f9elltp/VPiwVimubPa8QnpLNRy/NAEVpDFygw9VOM+Fu203M/pofK0qX6NfO9PeQGma1iKQeMKrV/6RwjF+70rnTMEhO0PCyTl2PEwZiDtkxgI7Yyl37p8bUuJ4YZ5MhZN94lODb+toPaN29BZT4q23VrJmxiW3VEeJj+tEmx4X+KeCO5AArtPl9YOkoRt/uSRKljsf109AIiclRj0wITqOx/QL2qntFuAidxTm8MoJQ6eoq/bwQp/BUpPubIMeY+z2b8XIgZGZSPZMdaObvaqDFdMLq7GW61GxYKFgNxHYA4uhndbE5VDNkcFkw4FEC5x40fwqGaunmqvAdb3p4I9EhlQ28e5S+hX1FFrMHjsJWlnjSySDRjCodJMtep19J+qVVgyf5A==,iv:PBo7+OSqBGxI7DzUpclcGWEFwTpcNqySRJzqHu7medU=,tag:fi06xru3e92WfqOJxHXd2w==,type:str]
|
appservice-discord: ENC[AES256_GCM,data:lAAEa6ltXi29+POrG87bMAvv8du3DiGYl8f7npqW0ga3YgrvofgYnC8QJUyznIQ3Ye9yWxzjzaClu7viFgkN0yIXlpENIOcSTrdlMgg5mdJ8f9elltp/VPiwVimubPa8QnpLNRy/NAEVpDFygw9VOM+Fu203M/pofK0qX6NfO9PeQGma1iKQeMKrV/6RwjF+70rnTMEhO0PCyTl2PEwZiDtkxgI7Yyl37p8bUuJ4YZ5MhZN94lODb+toPaN29BZT4q23VrJmxiW3VEeJj+tEmx4X+KeCO5AArtPl9YOkoRt/uSRKljsf109AIiclRj0wITqOx/QL2qntFuAidxTm8MoJQ6eoq/bwQp/BUpPubIMeY+z2b8XIgZGZSPZMdaObvaqDFdMLq7GW61GxYKFgNxHYA4uhndbE5VDNkcFkw4FEC5x40fwqGaunmqvAdb3p4I9EhlQ28e5S+hX1FFrMHjsJWlnjSySDRjCodJMtep19J+qVVgyf5A==,iv:PBo7+OSqBGxI7DzUpclcGWEFwTpcNqySRJzqHu7medU=,tag:fi06xru3e92WfqOJxHXd2w==,type:str]
|
||||||
|
@ -73,8 +73,8 @@ sops:
|
||||||
by9kZFlTRVdCZFkxYTVVb0RIRk8zUlkKCqMw9oL9RaYBV5Hhy3o8Nm5xmGrPH8Sd
|
by9kZFlTRVdCZFkxYTVVb0RIRk8zUlkKCqMw9oL9RaYBV5Hhy3o8Nm5xmGrPH8Sd
|
||||||
hv36sxRFFNZT/DCKaHaSRbT3mfpBZSTXJt1dgl4nZe6whH54t/1KmA==
|
hv36sxRFFNZT/DCKaHaSRbT3mfpBZSTXJt1dgl4nZe6whH54t/1KmA==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2024-04-18T20:44:57Z"
|
lastmodified: "2024-06-11T20:55:31Z"
|
||||||
mac: ENC[AES256_GCM,data:S8Z9P8gJIdjKZPHq3LEO0w1wxm6KsDYWB/Bb+JqoeuI0QyNzXqpfKtbthxtLisJJFcnS/ngnPjafVu6bG95ywjprfuB4o69l7PMd8rC4rZm38pG/pjw2tXYef+B3iuE2ZV7Y/7hXHhTd3ZPu8/ALD8kczTuZd+xFVsgTZu+F2F8=,iv:aFj0v+NB/NnnsReG234wmhyAhqkhADk7Ndpi/TaVNEg=,tag:7YlcGy68YACs+K10lMMohA==,type:str]
|
mac: ENC[AES256_GCM,data:IdpNGX3E2TwGnmHhc7HXPjBEaYC7jO1dnEHQGoVra+scnKO66nt6uD2wK91G2wvdp2ekkR4qnF9/NYbpOt2vbzyaZG0xMHTr1w1Y5oqxzbTUned9sWjpsL2lCHpg4FQ+dImim05N76Qcna7gC5Y9wyh78/eB177SJ5mTEnyZhwE=,iv:3kjluCoHIMEQOTuDJbQZJWl3BLWzp/UqcC8jmlkVyDE=,tag:nmqkhmqXKB5/LKX7RpQB6g==,type:str]
|
||||||
pgp: []
|
pgp: []
|
||||||
unencrypted_suffix: _unencrypted
|
unencrypted_suffix: _unencrypted
|
||||||
version: 3.8.1
|
version: 3.8.1
|
||||||
|
|
|
@ -11,7 +11,7 @@ in
|
||||||
# traefik
|
# traefik
|
||||||
cloud.traefik.hosts.writefreely-dtth = { inherit host port; };
|
cloud.traefik.hosts.writefreely-dtth = { inherit host port; };
|
||||||
|
|
||||||
sops.secrets."writefreely-dtth" = { owner = user; };
|
sops.secrets."writefreely-oauth-secret" = { owner = user; };
|
||||||
|
|
||||||
users.users.${user} = {
|
users.users.${user} = {
|
||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
|
@ -53,22 +53,24 @@ in
|
||||||
monetization = false;
|
monetization = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
"oauth.generic" = {
|
"oauth.generic" = { };
|
||||||
client_id = "rpoTTr2Wz0h4EgOSCHe0G85O8DCQDMup7JW9U9fV";
|
};
|
||||||
host = "https://auth.dtth.ch";
|
|
||||||
display_name = "DTTH";
|
oauth = {
|
||||||
token_endpoint = "/application/o/token/";
|
enable = true;
|
||||||
inspect_endpoint = "/application/o/userinfo/";
|
clientId = "rpoTTr2Wz0h4EgOSCHe0G85O8DCQDMup7JW9U9fV";
|
||||||
auth_endpoint = "/application/o/authorize/";
|
clientSecretFile = config.sops.secrets."writefreely-oauth-secret".path;
|
||||||
scope = "email openid profile";
|
host = "https://auth.dtth.ch";
|
||||||
map_user_id = "nickname";
|
displayName = "DTTH";
|
||||||
map_username = "preferred_username";
|
tokenEndpoint = "/application/o/token/";
|
||||||
map_display_name = "name";
|
inspectEndpoint = "/application/o/userinfo/";
|
||||||
allow_registration = true;
|
authEndpoint = "/application/o/authorize/";
|
||||||
};
|
scopes = [ "email" "openid" "profile" ];
|
||||||
|
mapUserId = "nickname";
|
||||||
|
mapUsername = "preferred_username";
|
||||||
|
mapDisplayName = "name";
|
||||||
};
|
};
|
||||||
|
|
||||||
extraSettingsFile = config.sops.secrets."writefreely-dtth".path;
|
|
||||||
|
|
||||||
database.type = "sqlite3";
|
database.type = "sqlite3";
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,7 @@ let
|
||||||
if value == true then "true" else "false"
|
if value == true then "true" else "false"
|
||||||
else
|
else
|
||||||
toString value);
|
toString value);
|
||||||
in
|
in "${key} = ${value'}";
|
||||||
"${key} = ${value'}";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
cfg = config.nki.services.writefreely;
|
cfg = config.nki.services.writefreely;
|
||||||
|
@ -32,8 +31,7 @@ let
|
||||||
host = cfg.settings.app.host or "${hostProtocol}://${cfg.host}";
|
host = cfg.settings.app.host or "${hostProtocol}://${cfg.host}";
|
||||||
};
|
};
|
||||||
|
|
||||||
database =
|
database = if cfg.database.type == "sqlite3" then {
|
||||||
if cfg.database.type == "sqlite3" then {
|
|
||||||
type = "sqlite3";
|
type = "sqlite3";
|
||||||
filename = cfg.settings.database.filename or "writefreely.db";
|
filename = cfg.settings.database.filename or "writefreely.db";
|
||||||
database = cfg.database.name;
|
database = cfg.database.name;
|
||||||
|
@ -58,6 +56,24 @@ let
|
||||||
cfg.settings.server.pages_parent_dir or cfg.package.src;
|
cfg.settings.server.pages_parent_dir or cfg.package.src;
|
||||||
keys_parent_dir = cfg.settings.server.keys_parent_dir or cfg.stateDir;
|
keys_parent_dir = cfg.settings.server.keys_parent_dir or cfg.stateDir;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
"oauth.generic" = cfg.settings."oauth.generic" or { } // (if cfg.oauth.enable then {
|
||||||
|
client_id = cfg.oauth.clientId;
|
||||||
|
client_secret = "#oauth_client_secret#";
|
||||||
|
host = cfg.oauth.host;
|
||||||
|
display_name = cfg.oauth.displayName;
|
||||||
|
callback_proxy = cfg.oauth.callbackProxy;
|
||||||
|
callback_proxy_api = cfg.oauth.callbackProxyApi;
|
||||||
|
token_endpoint = cfg.oauth.tokenEndpoint;
|
||||||
|
inspect_endpoint = cfg.oauth.inspectEndpoint;
|
||||||
|
auth_endpoint = cfg.oauth.authEndpoint;
|
||||||
|
scope = lib.concatStringsSep " " cfg.oauth.scopes;
|
||||||
|
allow_disconnect = cfg.oauth.allowDisconnect;
|
||||||
|
map_user_id = cfg.oauth.mapUserId;
|
||||||
|
map_username = cfg.oauth.mapUsername;
|
||||||
|
map_display_name = cfg.oauth.mapDisplayName;
|
||||||
|
map_email = cfg.oauth.mapEmail;
|
||||||
|
} else { });
|
||||||
};
|
};
|
||||||
|
|
||||||
configFile = format.generate "config.ini" settings;
|
configFile = format.generate "config.ini" settings;
|
||||||
|
@ -91,10 +107,14 @@ let
|
||||||
optionalString (cfg.database.passwordFile != null)
|
optionalString (cfg.database.passwordFile != null)
|
||||||
"$(head -n1 ${cfg.database.passwordFile})"
|
"$(head -n1 ${cfg.database.passwordFile})"
|
||||||
}
|
}
|
||||||
|
oauth_client_secret=${
|
||||||
|
optionalString cfg.oauth.enable
|
||||||
|
"$(head -n1 ${cfg.oauth.clientSecretFile})"
|
||||||
|
}
|
||||||
|
|
||||||
install -m 0660 ${configFile} '${cfg.stateDir}/config.ini'
|
cp -f ${configFile} '${cfg.stateDir}/config.ini'
|
||||||
sed -e "s,#dbpass#,$db_pass,g" -i '${cfg.stateDir}/config.ini'
|
sed -e "s,#dbpass#,$db_pass,g" -i '${cfg.stateDir}/config.ini'
|
||||||
${if cfg.extraSettingsFile != null then "cat ${cfg.extraSettingsFile} >> ${cfg.stateDir}/config.ini" else ""}
|
sed -e "s,#oauth_client_secret#,$oauth_client_secret,g" -i '${cfg.stateDir}/config.ini'
|
||||||
chmod 440 '${cfg.stateDir}/config.ini'
|
chmod 440 '${cfg.stateDir}/config.ini'
|
||||||
|
|
||||||
${text}
|
${text}
|
||||||
|
@ -123,7 +143,7 @@ let
|
||||||
withConfigFile ''
|
withConfigFile ''
|
||||||
query () {
|
query () {
|
||||||
local result=$(${sqlite}/bin/sqlite3 \
|
local result=$(${sqlite}/bin/sqlite3 \
|
||||||
'${cfg.stateDir}/${settings.database.filename}'
|
'${cfg.stateDir}/${settings.database.filename}' \
|
||||||
"$1" \
|
"$1" \
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -132,53 +152,46 @@ let
|
||||||
|
|
||||||
${text}
|
${text}
|
||||||
'';
|
'';
|
||||||
in
|
in {
|
||||||
{
|
|
||||||
options.nki.services.writefreely = {
|
options.nki.services.writefreely = {
|
||||||
enable =
|
enable =
|
||||||
lib.mkEnableOption (lib.mdDoc "Writefreely, build a digital writing community");
|
lib.mkEnableOption "Writefreely, build a digital writing community";
|
||||||
|
|
||||||
package = lib.mkOption {
|
package = lib.mkOption {
|
||||||
type = lib.types.package;
|
type = lib.types.package;
|
||||||
default = pkgs.writefreely;
|
default = pkgs.writefreely;
|
||||||
defaultText = lib.literalExpression "pkgs.writefreely";
|
defaultText = lib.literalExpression "pkgs.writefreely";
|
||||||
description = lib.mdDoc "Writefreely package to use.";
|
description = "Writefreely package to use.";
|
||||||
};
|
};
|
||||||
|
|
||||||
stateDir = mkOption {
|
stateDir = mkOption {
|
||||||
type = types.path;
|
type = types.path;
|
||||||
default = "/var/lib/writefreely";
|
default = "/var/lib/writefreely";
|
||||||
description = lib.mdDoc "The state directory where keys and data are stored.";
|
description = "The state directory where keys and data are stored.";
|
||||||
};
|
};
|
||||||
|
|
||||||
user = mkOption {
|
user = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "writefreely";
|
default = "writefreely";
|
||||||
description = lib.mdDoc "User under which Writefreely is ran.";
|
description = "User under which Writefreely is ran.";
|
||||||
};
|
};
|
||||||
|
|
||||||
group = mkOption {
|
group = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "writefreely";
|
default = "writefreely";
|
||||||
description = lib.mdDoc "Group under which Writefreely is ran.";
|
description = "Group under which Writefreely is ran.";
|
||||||
};
|
};
|
||||||
|
|
||||||
host = mkOption {
|
host = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "";
|
default = "";
|
||||||
description = lib.mdDoc "The public host name to serve.";
|
description = "The public host name to serve.";
|
||||||
example = "example.com";
|
example = "example.com";
|
||||||
};
|
};
|
||||||
|
|
||||||
extraSettingsFile = mkOption {
|
|
||||||
type = types.nullOr types.path;
|
|
||||||
default = null;
|
|
||||||
description = lib.mdDoc "Additional configs to be appended to the config file";
|
|
||||||
};
|
|
||||||
|
|
||||||
settings = mkOption {
|
settings = mkOption {
|
||||||
default = { };
|
default = { };
|
||||||
description = lib.mdDoc ''
|
description = ''
|
||||||
Writefreely configuration ({file}`config.ini`). Refer to
|
Writefreely configuration ({file}`config.ini`). Refer to
|
||||||
<https://writefreely.org/docs/latest/admin/config>
|
<https://writefreely.org/docs/latest/admin/config>
|
||||||
for details.
|
for details.
|
||||||
|
@ -192,7 +205,7 @@ in
|
||||||
theme = mkOption {
|
theme = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "write";
|
default = "write";
|
||||||
description = lib.mdDoc "The theme to apply.";
|
description = "The theme to apply.";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -201,7 +214,7 @@ in
|
||||||
type = types.port;
|
type = types.port;
|
||||||
default = if cfg.nginx.enable then 18080 else 80;
|
default = if cfg.nginx.enable then 18080 else 80;
|
||||||
defaultText = "80";
|
defaultText = "80";
|
||||||
description = lib.mdDoc "The port WriteFreely should listen on.";
|
description = "The port WriteFreely should listen on.";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -212,74 +225,158 @@ in
|
||||||
type = mkOption {
|
type = mkOption {
|
||||||
type = types.enum [ "sqlite3" "mysql" ];
|
type = types.enum [ "sqlite3" "mysql" ];
|
||||||
default = "sqlite3";
|
default = "sqlite3";
|
||||||
description = lib.mdDoc "The database provider to use.";
|
description = "The database provider to use.";
|
||||||
};
|
};
|
||||||
|
|
||||||
name = mkOption {
|
name = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "writefreely";
|
default = "writefreely";
|
||||||
description = lib.mdDoc "The name of the database to store data in.";
|
description = "The name of the database to store data in.";
|
||||||
};
|
};
|
||||||
|
|
||||||
user = mkOption {
|
user = mkOption {
|
||||||
type = types.nullOr types.str;
|
type = types.nullOr types.str;
|
||||||
default = if cfg.database.type == "mysql" then "writefreely" else null;
|
default = if cfg.database.type == "mysql" then "writefreely" else null;
|
||||||
defaultText = "writefreely";
|
defaultText = "writefreely";
|
||||||
description = lib.mdDoc "The database user to connect as.";
|
description = "The database user to connect as.";
|
||||||
};
|
};
|
||||||
|
|
||||||
passwordFile = mkOption {
|
passwordFile = mkOption {
|
||||||
type = types.nullOr types.path;
|
type = types.nullOr types.path;
|
||||||
default = null;
|
default = null;
|
||||||
description = lib.mdDoc "The file to load the database password from.";
|
description = "The file to load the database password from.";
|
||||||
};
|
};
|
||||||
|
|
||||||
host = mkOption {
|
host = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "localhost";
|
default = "localhost";
|
||||||
description = lib.mdDoc "The database host to connect to.";
|
description = "The database host to connect to.";
|
||||||
};
|
};
|
||||||
|
|
||||||
port = mkOption {
|
port = mkOption {
|
||||||
type = types.port;
|
type = types.port;
|
||||||
default = 3306;
|
default = 3306;
|
||||||
description = lib.mdDoc "The port used when connecting to the database host.";
|
description = "The port used when connecting to the database host.";
|
||||||
};
|
};
|
||||||
|
|
||||||
tls = mkOption {
|
tls = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description =
|
description = "Whether or not TLS should be used for the database connection.";
|
||||||
lib.mdDoc "Whether or not TLS should be used for the database connection.";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
migrate = mkOption {
|
migrate = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
description =
|
description = "Whether or not to automatically run migrations on startup.";
|
||||||
lib.mdDoc "Whether or not to automatically run migrations on startup.";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
createLocally = mkOption {
|
createLocally = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description = lib.mdDoc ''
|
description = ''
|
||||||
When {option}`services.writefreely.database.type` is set to
|
When {option}`services.writefreely.database.type` is set to
|
||||||
`"mysql"`, this option will enable the MySQL service locally.
|
`"mysql"`, this option will enable the MySQL service locally.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
oauth = {
|
||||||
|
enable = lib.mkEnableOption "Enable generic OAuth authentication";
|
||||||
|
clientId = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The client ID associated with WriteFreely in the OAuth provider application.";
|
||||||
|
};
|
||||||
|
clientSecretFile = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The file to load the OAuth client secret from.";
|
||||||
|
};
|
||||||
|
host = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The base url of the OAuth provider application, including the protocol.";
|
||||||
|
example = "https://example.com";
|
||||||
|
};
|
||||||
|
displayName = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The human-readable name of the OAuth service that appears on the login button, will appear as `Log in with [display_name]`.";
|
||||||
|
};
|
||||||
|
|
||||||
|
callbackProxy = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
description = "The url of an inbound proxy that sits in front of the default `/oauth/callback/generic` endpoint. Use if you want the OAuth callback to be somewhere other than that generic location. Default is blank.";
|
||||||
|
example = "https://example.com/whatever/path";
|
||||||
|
};
|
||||||
|
callbackProxyApi = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
description = "The url of an outbound proxy to send your OAuth requests through. Default is blank.";
|
||||||
|
example = "https://my-proxy.example.com";
|
||||||
|
};
|
||||||
|
|
||||||
|
tokenEndpoint = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The API endpoint of the OAuth provider implementation to obtain an access token by presenting an authorization grant or refresh token. This is a fragment of a url, appended to host as described above.";
|
||||||
|
example = "/oauth/token";
|
||||||
|
};
|
||||||
|
inspectEndpoint = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The API endpoint of the OAuth provider that returns basic user info given their authentication information. This is a fragment of a url, appended to host as described above.";
|
||||||
|
example = "/oauth/userinfo";
|
||||||
|
};
|
||||||
|
authEndpoint = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The API endpoint of the OAuth provider that returns an authorization grant. This is a fragment of a url, appended to host as described above.";
|
||||||
|
example = "public";
|
||||||
|
};
|
||||||
|
|
||||||
|
scopes = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ "read_user" ];
|
||||||
|
description = "A scope or set of scopes required by some OAuth providers. This will usually be blank in this config file, and is set to `read_user` by default.";
|
||||||
|
};
|
||||||
|
allowDisconnect = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Whether or not an individual user is allowed to disconnect this OAuth provider from their account.";
|
||||||
|
};
|
||||||
|
|
||||||
|
mapUserId = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
defaultText = "<none>";
|
||||||
|
description = "Use this User ID key in the provider's user info, instead of the default key (user_id).";
|
||||||
|
};
|
||||||
|
mapUsername = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
defaultText = "<none>";
|
||||||
|
description = "Use this Username key in the provider's user info, instead of the default key (username)";
|
||||||
|
};
|
||||||
|
mapDisplayName = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
defaultText = "<none>";
|
||||||
|
description = "Use this Display Name key in the provider's user info, instead of the default key (*none*)";
|
||||||
|
};
|
||||||
|
mapEmail = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
defaultText = "<none>";
|
||||||
|
description = "Use this Email key in the provider's user info, instead of the default key (email)";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
admin = {
|
admin = {
|
||||||
name = mkOption {
|
name = mkOption {
|
||||||
type = types.nullOr types.str;
|
type = types.nullOr types.str;
|
||||||
description = lib.mdDoc "The name of the first admin user.";
|
description = "The name of the first admin user.";
|
||||||
default = null;
|
default = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
initialPasswordFile = mkOption {
|
initialPasswordFile = mkOption {
|
||||||
type = types.path;
|
type = types.path;
|
||||||
description = lib.mdDoc ''
|
description = ''
|
||||||
Path to a file containing the initial password for the admin user.
|
Path to a file containing the initial password for the admin user.
|
||||||
If not provided, the default password will be set to `nixos`.
|
If not provided, the default password will be set to `nixos`.
|
||||||
'';
|
'';
|
||||||
|
@ -292,14 +389,13 @@ in
|
||||||
enable = mkOption {
|
enable = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description =
|
description = "Whether or not to enable and configure nginx as a proxy for WriteFreely.";
|
||||||
lib.mdDoc "Whether or not to enable and configure nginx as a proxy for WriteFreely.";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
forceSSL = mkOption {
|
forceSSL = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description = lib.mdDoc "Whether or not to force the use of SSL.";
|
description = "Whether or not to force the use of SSL.";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -307,8 +403,7 @@ in
|
||||||
enable = mkOption {
|
enable = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description =
|
description = "Whether or not to automatically fetch and configure SSL certs.";
|
||||||
lib.mdDoc "Whether or not to automatically fetch and configure SSL certs.";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -344,11 +439,12 @@ in
|
||||||
optionalAttrs (cfg.group == "writefreely") { writefreely = { }; };
|
optionalAttrs (cfg.group == "writefreely") { writefreely = { }; };
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.tmpfiles.rules =
|
systemd.tmpfiles.settings."10-writefreely".${cfg.stateDir}.d = {
|
||||||
[ "d '${cfg.stateDir}' 0750 ${cfg.user} ${cfg.group} - -" ];
|
inherit (cfg) user group;
|
||||||
|
mode = "0750";
|
||||||
|
};
|
||||||
|
|
||||||
systemd.services.writefreely = {
|
systemd.services.writefreely = {
|
||||||
path = with pkgs; [ openssl ];
|
|
||||||
after = [ "network.target" ]
|
after = [ "network.target" ]
|
||||||
++ optional isSqlite "writefreely-sqlite-init.service"
|
++ optional isSqlite "writefreely-sqlite-init.service"
|
||||||
++ optional isMysql "writefreely-mysql-init.service"
|
++ optional isMysql "writefreely-mysql-init.service"
|
||||||
|
@ -393,8 +489,7 @@ in
|
||||||
cfg.admin.initialPasswordFile;
|
cfg.admin.initialPasswordFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
script =
|
script = let
|
||||||
let
|
|
||||||
migrateDatabase = optionalString cfg.database.migrate ''
|
migrateDatabase = optionalString cfg.database.migrate ''
|
||||||
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' db migrate
|
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' db migrate
|
||||||
'';
|
'';
|
||||||
|
@ -406,8 +501,7 @@ in
|
||||||
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' --create-admin ${cfg.admin.name}:$admin_pass
|
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' --create-admin ${cfg.admin.name}:$admin_pass
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
in
|
in withSqlite ''
|
||||||
withSqlite ''
|
|
||||||
if ! test -f '${settings.database.filename}'; then
|
if ! test -f '${settings.database.filename}'; then
|
||||||
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' db init
|
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' db init
|
||||||
fi
|
fi
|
||||||
|
@ -432,8 +526,7 @@ in
|
||||||
cfg.admin.initialPasswordFile;
|
cfg.admin.initialPasswordFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
script =
|
script = let
|
||||||
let
|
|
||||||
updateUser = optionalString isMysqlLocal ''
|
updateUser = optionalString isMysqlLocal ''
|
||||||
# WriteFreely currently *requires* a password for authentication, so we
|
# WriteFreely currently *requires* a password for authentication, so we
|
||||||
# need to update the user in MySQL accordingly. By default MySQL users
|
# need to update the user in MySQL accordingly. By default MySQL users
|
||||||
|
@ -452,8 +545,7 @@ in
|
||||||
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' --create-admin ${cfg.admin.name}:$admin_pass
|
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' --create-admin ${cfg.admin.name}:$admin_pass
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
in
|
in withMysql ''
|
||||||
withMysql ''
|
|
||||||
${updateUser}
|
${updateUser}
|
||||||
|
|
||||||
if [[ $(query "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '${cfg.database.name}'") == 0 ]]; then
|
if [[ $(query "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '${cfg.database.name}'") == 0 ]]; then
|
||||||
|
@ -497,4 +589,3 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ let
|
||||||
|
|
||||||
overlay-versioning = final: prev: {
|
overlay-versioning = final: prev: {
|
||||||
gotosocial = prev.gotosocial.overrideAttrs (attrs: rec {
|
gotosocial = prev.gotosocial.overrideAttrs (attrs: rec {
|
||||||
version = "0.16.0-rc1";
|
version = "0.16.0-rc2";
|
||||||
ldflags = [
|
ldflags = [
|
||||||
"-s"
|
"-s"
|
||||||
"-w"
|
"-w"
|
||||||
|
@ -34,13 +34,13 @@ let
|
||||||
|
|
||||||
web-assets = final.fetchurl {
|
web-assets = final.fetchurl {
|
||||||
url = "https://github.com/superseriousbusiness/gotosocial/releases/download/v${version}/gotosocial_${version}_web-assets.tar.gz";
|
url = "https://github.com/superseriousbusiness/gotosocial/releases/download/v${version}/gotosocial_${version}_web-assets.tar.gz";
|
||||||
hash = "sha256-bSMbqiRslDQd+HEaB0AA1pIgXeqAhamhxAq22B9gUHk=";
|
hash = "sha256-fufQP9xaaaVBrgFSunDn9/jQd6eUMXqGL7TcoQHatnI=";
|
||||||
};
|
};
|
||||||
src = final.fetchFromGitHub {
|
src = final.fetchFromGitHub {
|
||||||
owner = "superseriousbusiness";
|
owner = "superseriousbusiness";
|
||||||
repo = "gotosocial";
|
repo = "gotosocial";
|
||||||
rev = "v${version}";
|
rev = "v${version}";
|
||||||
hash = "sha256-nO6WvGkWm5K5sitNypDLEESBAO+4ZXBMGDrkYmGDIks=";
|
hash = "sha256-+H4rpUgjDlCc6tEIGTzkPYktwo9aCWgXr5sln8M6DNk=";
|
||||||
};
|
};
|
||||||
postInstall = ''
|
postInstall = ''
|
||||||
tar xf ${web-assets}
|
tar xf ${web-assets}
|
||||||
|
|
Loading…
Reference in a new issue