mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-07-21 16:11:22 +00:00
Merge staging-next into staging
This commit is contained in:
@@ -16468,6 +16468,12 @@
|
||||
githubId = 115777584;
|
||||
name = "Lutz Berger";
|
||||
};
|
||||
luuumine = {
|
||||
email = "nix@luuumine.com";
|
||||
github = "luuumine";
|
||||
githubId = 55056797;
|
||||
name = "Romain Delhommais";
|
||||
};
|
||||
lux = {
|
||||
email = "lux@lux.name";
|
||||
github = "luxzeitlos";
|
||||
|
||||
@@ -1813,6 +1813,7 @@
|
||||
./services/web-apps/umami.nix
|
||||
./services/web-apps/vikunja.nix
|
||||
./services/web-apps/wakapi.nix
|
||||
./services/web-apps/wealthfolio.nix
|
||||
./services/web-apps/weblate.nix
|
||||
./services/web-apps/websurfx.nix
|
||||
./services/web-apps/whitebophir.nix
|
||||
|
||||
184
nixos/modules/services/web-apps/wealthfolio.nix
Normal file
184
nixos/modules/services/web-apps/wealthfolio.nix
Normal file
@@ -0,0 +1,184 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.services.wealthfolio;
|
||||
in
|
||||
{
|
||||
options.services.wealthfolio = {
|
||||
enable = lib.mkEnableOption "Wealthfolio personal investment tracker";
|
||||
package = lib.mkPackageOption pkgs "wealthfolio-server" { };
|
||||
|
||||
address = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "127.0.0.1";
|
||||
description = "The IP address the Wealthfolio server binds to.";
|
||||
};
|
||||
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 8088;
|
||||
description = "The port the Wealthfolio server listens on.";
|
||||
};
|
||||
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to automatically open the specified port in the system firewall.";
|
||||
};
|
||||
|
||||
secretKeyFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
default = null;
|
||||
example = lib.literalExpression "config.age.secrets.wealthfolio-key.path";
|
||||
description = ''
|
||||
Path to a file containing the 32-byte secret key used for encrypting sensitive data
|
||||
at rest (broker credentials, API keys) and signing JWT tokens.
|
||||
|
||||
Generate with: `openssl rand -base64 32`.
|
||||
|
||||
Note: Losing this key means losing access to all stored encrypted secrets.
|
||||
There is no recovery.
|
||||
'';
|
||||
};
|
||||
|
||||
authPasswordHashFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
default = null;
|
||||
example = lib.literalExpression "config.age.secrets.wealthfolio-hash.path";
|
||||
description = ''
|
||||
Path to a file containing the Argon2id PHC string defining the login password.
|
||||
Required for web access unless `authRequired` is false.
|
||||
|
||||
Generate with: `printf 'your-password' | argon2 yoursalt16chars! -id -e`
|
||||
'';
|
||||
};
|
||||
|
||||
authRequired = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to require internal authentication.
|
||||
|
||||
Security Note: The server panics at startup if the listener is bound to a
|
||||
non-loopback address and authentication is disabled. Set this to `false`
|
||||
only if a reverse proxy handles authentication for you.
|
||||
'';
|
||||
};
|
||||
|
||||
corsAllowOrigins = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "*";
|
||||
example = "https://wealthfolio.example.com";
|
||||
description = ''
|
||||
Comma-separated list of allowed CORS origins.
|
||||
|
||||
Security Note: The server panics at startup if `*` is used while authentication
|
||||
is enabled, as this is a CSRF vector. Set explicit origins matching your
|
||||
deployment URL (scheme + host + port).
|
||||
'';
|
||||
};
|
||||
|
||||
authTokenTtlMinutes = lib.mkOption {
|
||||
type = lib.types.ints.positive;
|
||||
default = 60;
|
||||
description = "JWT access token lifetime in minutes. (e.g., 1440 for 24h, 10080 for 7d).";
|
||||
};
|
||||
|
||||
cookieSecure = lib.mkOption {
|
||||
type = lib.types.enum [
|
||||
"auto"
|
||||
"true"
|
||||
"false"
|
||||
];
|
||||
default = "auto";
|
||||
description = ''
|
||||
Controls the Secure attribute on the authentication session cookie.
|
||||
- auto: Sets Secure based on HTTPS protocol.
|
||||
- true: Always sets Secure (Use behind a reverse proxy that terminates HTTPS).
|
||||
- false: Never sets Secure (Not recommended).
|
||||
'';
|
||||
};
|
||||
|
||||
requestTimeoutMs = lib.mkOption {
|
||||
type = lib.types.ints.positive;
|
||||
default = 300000;
|
||||
description = "HTTP request timeout in milliseconds. Default (5m) accommodates large broker syncs.";
|
||||
};
|
||||
|
||||
logFormat = lib.mkOption {
|
||||
type = lib.types.enum [
|
||||
"text"
|
||||
"json"
|
||||
];
|
||||
default = "text";
|
||||
description = "Log output format. `json` is recommended if shipping to log aggregators.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
networking.firewall.allowedTCPPorts = lib.optional cfg.openFirewall cfg.port;
|
||||
|
||||
assertions = [
|
||||
{
|
||||
assertion = cfg.secretKeyFile != null;
|
||||
message = "services.wealthfolio: secretKeyFile must be provided.";
|
||||
}
|
||||
{
|
||||
assertion = cfg.authRequired -> cfg.authPasswordHashFile != null;
|
||||
message = "services.wealthfolio: authPasswordHashFile must be provided when authRequired is true.";
|
||||
}
|
||||
{
|
||||
assertion = cfg.authRequired -> cfg.corsAllowOrigins != "*";
|
||||
message = "services.wealthfolio: corsAllowOrigins cannot be '*' when authRequired is true. Provide an explicit domain.";
|
||||
}
|
||||
];
|
||||
|
||||
systemd.services.wealthfolio = {
|
||||
description = "Wealthfolio server service daemon.";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
environment = {
|
||||
WF_LISTEN_ADDR = "${cfg.address}:${toString cfg.port}";
|
||||
WF_DB_PATH = "/var/lib/wealthfolio/wealthfolio.db";
|
||||
WF_AUTH_REQUIRED = lib.boolToString cfg.authRequired;
|
||||
WF_CORS_ALLOW_ORIGINS = cfg.corsAllowOrigins;
|
||||
WF_AUTH_TOKEN_TTL_MINUTES = toString cfg.authTokenTtlMinutes;
|
||||
WF_COOKIE_SECURE = cfg.cookieSecure;
|
||||
WF_REQUEST_TIMEOUT_MS = toString cfg.requestTimeoutMs;
|
||||
WF_LOG_FORMAT = cfg.logFormat;
|
||||
};
|
||||
|
||||
script = ''
|
||||
${lib.optionalString (
|
||||
cfg.secretKeyFile != null
|
||||
) "export WF_SECRET_KEY=$(<\"$CREDENTIALS_DIRECTORY/secret_key\")"}
|
||||
${lib.optionalString (
|
||||
cfg.authPasswordHashFile != null
|
||||
) "export WF_AUTH_PASSWORD_HASH=$(<\"$CREDENTIALS_DIRECTORY/auth_hash\")"}
|
||||
|
||||
exec ${lib.getExe cfg.package}
|
||||
'';
|
||||
|
||||
serviceConfig = {
|
||||
LoadCredential =
|
||||
lib.optional (cfg.secretKeyFile != null) "secret_key:${cfg.secretKeyFile}"
|
||||
++ lib.optional (cfg.authPasswordHashFile != null) "auth_hash:${cfg.authPasswordHashFile}";
|
||||
|
||||
DynamicUser = true;
|
||||
StateDirectory = "wealthfolio";
|
||||
ProtectSystem = "strict";
|
||||
ProtectHome = true;
|
||||
PrivateTmp = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
meta = {
|
||||
maintainers = with lib.maintainers; [ luuumine ];
|
||||
};
|
||||
}
|
||||
@@ -14,22 +14,29 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
rev = "v${finalAttrs.version}";
|
||||
hash = "sha256-H0l8H2JhPT1Rs0p+CJC1a1qYtnZNgLGe6n7PmM+WvE4=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ gnumake ];
|
||||
|
||||
buildInputs = [ zlib ];
|
||||
|
||||
strictDeps = true;
|
||||
__structuredAttrs = true;
|
||||
|
||||
makefile = "Makefile.cbm";
|
||||
|
||||
# scripts/build.sh verifies CC via `file`, which fails on Nix's compiler wrapper.
|
||||
# Call make directly — mirrors upstream flake.nix.
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
make -j$NIX_BUILD_CORES -f Makefile.cbm cbm CFLAGS_EXTRA='-DCBM_VERSION=\"${finalAttrs.version}\"'
|
||||
runHook postBuild
|
||||
'';
|
||||
makeFlags = [
|
||||
"cbm"
|
||||
"CFLAGS_EXTRA='-DCBM_VERSION=\"${finalAttrs.version}\"'"
|
||||
];
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
install -Dm755 build/c/codebase-memory-mcp $out/bin/codebase-memory-mcp
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
meta = {
|
||||
homepage = "https://github.com/DeusData/codebase-memory-mcp";
|
||||
description = "High-performance C11 MCP server that indexes codebases into a persistent knowledge graph";
|
||||
|
||||
@@ -56,7 +56,7 @@ let
|
||||
davinci = (
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "davinci-resolve${lib.optionalString studioVariant "-studio"}";
|
||||
version = "20.3.3";
|
||||
version = "21.0.1";
|
||||
|
||||
nativeBuildInputs = [
|
||||
appimageTools.appimage-exec
|
||||
@@ -78,9 +78,9 @@ let
|
||||
outputHashAlgo = "sha256";
|
||||
outputHash =
|
||||
if studioVariant then
|
||||
"sha256-q5VGp0kkno//nYtT82QDZDJG92uumAtomUK4B55795g="
|
||||
"sha256-8JN3ptd8jcacxHihZHXuhdkyambUsnFIj+AruvpztKI="
|
||||
else
|
||||
"sha256-2pfJz71fS/oEmK3n4cESKb9EDYCeDBhbzGLgFpb+OLI=";
|
||||
"sha256-ioAqvqHjwFX1ec6fDoxg2VUZy1moYoGx/aEewDuN1+g=";
|
||||
|
||||
impureEnvVars = lib.fetchers.proxyImpureEnvVars;
|
||||
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "fasmg";
|
||||
version = "l5p0";
|
||||
version = "l7xm";
|
||||
|
||||
src = fetchzip {
|
||||
url = "https://flatassembler.net/fasmg.${finalAttrs.version}.zip";
|
||||
sha256 = "sha256-8nX45tHvKq6FPVhWQGNgrpkZgWuNbfsxL9YJxKa7P3I=";
|
||||
sha256 = "sha256-m/mLZLluvoxr0VsNVcBnHvv1LlagafkX6fwZSovtO9s=";
|
||||
stripRoot = false;
|
||||
};
|
||||
|
||||
|
||||
@@ -18,16 +18,16 @@
|
||||
|
||||
buildNpmPackage rec {
|
||||
pname = "igir";
|
||||
version = "5.1.0";
|
||||
version = "5.2.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "emmercm";
|
||||
repo = "igir";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-OgWf4xhgYsk9vQSbwrLdjbDElXrhI7r+4CaxZ7yRs7E=";
|
||||
hash = "sha256-LWdJPweZ0BFIjdXHUZvJuk8oZb8JtuGo3LIJtdwdG70=";
|
||||
};
|
||||
|
||||
npmDepsHash = "sha256-r/1ImMfTFuRHvcH3713sDFNq7LJvgjt8a1rE8JtuaUk=";
|
||||
npmDepsHash = "sha256-bRZlaRnPY8k2Xahb994GUYlROmR9ZQj2neEPVKDwv4g=";
|
||||
|
||||
# I have no clue why I have to do this
|
||||
postPatch = ''
|
||||
|
||||
@@ -30,13 +30,13 @@
|
||||
|
||||
rustPlatform.buildRustPackage (finalAttrs: {
|
||||
pname = "music-assistant-desktop";
|
||||
version = "0.4.0";
|
||||
version = "0.4.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "music-assistant";
|
||||
repo = "desktop-app";
|
||||
tag = finalAttrs.version;
|
||||
hash = "sha256-Gx6bmipNRT5V5EHSCP6KjZ8Lgt7BcNV8zo0nrhaVmOs=";
|
||||
hash = "sha256-AzKUv0lEpxM4lVEmgDV89RCD78YKcGNj1FTBs8spdyI=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
|
||||
91
pkgs/by-name/we/wealthfolio-server/package.nix
Normal file
91
pkgs/by-name/we/wealthfolio-server/package.nix
Normal file
@@ -0,0 +1,91 @@
|
||||
{
|
||||
lib,
|
||||
fetchFromGitHub,
|
||||
rustPlatform,
|
||||
fetchPnpmDeps,
|
||||
stdenv,
|
||||
pnpm_10,
|
||||
pnpmConfigHook,
|
||||
nodejs,
|
||||
makeWrapper,
|
||||
}:
|
||||
|
||||
rustPlatform.buildRustPackage (
|
||||
finalAttrs:
|
||||
let
|
||||
frontendPname = "wealthfolio-frontend";
|
||||
|
||||
frontend = stdenv.mkDerivation {
|
||||
pname = frontendPname;
|
||||
inherit (finalAttrs) version src;
|
||||
|
||||
__structuredAttrs = true;
|
||||
strictDeps = true;
|
||||
|
||||
pnpmDeps = fetchPnpmDeps {
|
||||
pname = frontendPname;
|
||||
inherit (finalAttrs) version src;
|
||||
|
||||
pnpm = pnpm_10;
|
||||
fetcherVersion = 3;
|
||||
hash = "sha256-Pt8eDb7tCTM1YD/7I8Ot9+fNzsvpcPfhWsniRD5OjcU=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
nodejs
|
||||
pnpm_10
|
||||
pnpmConfigHook
|
||||
];
|
||||
|
||||
buildPhase = ''
|
||||
export BUILD_TARGET=web
|
||||
pnpm --filter frontend... build
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out
|
||||
cp -R dist/* $out/
|
||||
'';
|
||||
|
||||
inherit (finalAttrs) meta;
|
||||
};
|
||||
in
|
||||
{
|
||||
__structuredAttrs = true;
|
||||
|
||||
pname = "wealthfolio-server";
|
||||
version = "3.5.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "wealthfolio";
|
||||
repo = "wealthfolio";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-WU87VmnbzUno1CmIVwBLYjmTZybM4qSuRmBH/2n/Tfo=";
|
||||
};
|
||||
|
||||
cargoRoot = ".";
|
||||
buildAndTestSubdir = "apps/server";
|
||||
cargoHash = "sha256-KoS2EouZ0Uf3cijUUOpwYBYEjEB5VxIArU1CuCji2+I=";
|
||||
|
||||
nativeBuildInputs = [ makeWrapper ];
|
||||
|
||||
postInstall = ''
|
||||
mkdir -p $out/share/wealthfolio/dist
|
||||
|
||||
cp -R ${frontend}/* $out/share/wealthfolio/dist/
|
||||
|
||||
wrapProgram $out/bin/wealthfolio-server \
|
||||
--set WF_STATIC_DIR "$out/share/wealthfolio/dist"
|
||||
'';
|
||||
|
||||
meta = {
|
||||
description = "Self-hosted web app for Wealthfolio";
|
||||
homepage = "https://wealthfolio.app/";
|
||||
changelog = "https://github.com/wealthfolio/wealthfolio/tag/${finalAttrs.src.tag}";
|
||||
mainProgram = "wealthfolio-server";
|
||||
license = lib.licenses.agpl3Only;
|
||||
maintainers = with lib.maintainers; [ luuumine ];
|
||||
platforms = lib.platforms.linux;
|
||||
};
|
||||
}
|
||||
)
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
buildPythonPackage (finalAttrs: {
|
||||
pname = "databricks-sdk";
|
||||
version = "0.118.0";
|
||||
version = "0.119.0";
|
||||
pyproject = true;
|
||||
__structuredAttrs = true;
|
||||
|
||||
@@ -30,7 +30,7 @@ buildPythonPackage (finalAttrs: {
|
||||
owner = "databricks";
|
||||
repo = "databricks-sdk-py";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-ukb5Sit+BRJd7DipvGMqXbFrC8jXsLDJjCbJdIO5G0U=";
|
||||
hash = "sha256-tdlFT0Rg0VGjtJ9UZSDu6zt5O+fXdmr484+3n4D0p8M=";
|
||||
};
|
||||
|
||||
build-system = [
|
||||
|
||||
Reference in New Issue
Block a user