Merge staging-next into staging

This commit is contained in:
nixpkgs-ci[bot]
2026-06-28 18:26:56 +00:00
committed by GitHub
10 changed files with 306 additions and 17 deletions

View File

@@ -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";

View File

@@ -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

View 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 ];
};
}

View File

@@ -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";

View File

@@ -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;

View File

@@ -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;
};

View File

@@ -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 = ''

View File

@@ -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 = [

View 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;
};
}
)

View File

@@ -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 = [