diff --git a/nixos-module/default.nix b/nixos-module/default.nix index 4b7e267..11d1afe 100644 --- a/nixos-module/default.nix +++ b/nixos-module/default.nix @@ -91,8 +91,8 @@ let APP_CONTACT = "dbrendel1988@gmail.com"; APP_DEBUG = false; APP_BASEDIR = ""; - APP_LANG = "en"; - APP_WORKSPACE = "My workspace"; + APP_LANG = cfg.language; + APP_WORKSPACE = cfg.workspace; APP_OVERDUETASK_HOURS = 10; APP_CRONJOB_MAILLIMIT = 5; APP_GITHUB_URL = "https://github.com/danielbrendel/hortusfox-web"; @@ -256,6 +256,23 @@ in { timezone = lib.mkOption { type = lib.types.str; default = "UTC"; }; + language = lib.mkOption { + type = lib.types.str; + default = "en"; + example = "de"; + description = '' + UI language (APP_LANG). Must match one of the language codes + upstream ships translation files for under lang/. + ''; + }; + + workspace = lib.mkOption { + type = lib.types.str; + default = "My workspace"; + example = "Greenhouse"; + description = "Workspace name shown in the UI (APP_WORKSPACE)."; + }; + database.name = lib.mkOption { type = lib.types.str; default = "hortusfox"; }; secretFile = lib.mkOption { @@ -492,7 +509,38 @@ in { if [ ! -e "${stateDir}/.installed" ]; then php asatru migrate:fresh - # 5. Seed the initial admin account. migrate:fresh creates no + # 5. Seed the AppModel settings row. migrate:fresh only creates + # the (empty) table -- upstream's own web installer is what + # inserts the single settings row that app()/AppModel's own + # admin-panel features (the Environment tab's Language/ + # Timezone fields, SMTP toggle, etc.) read and write, and we + # bypass that installer entirely. Without this row, + # AppModel::updateSet()'s `UPDATE AppModel SET ...` -- no + # WHERE clause, since it's a de-facto single-row table -- + # matches zero rows, so every "Save" in the admin Environment + # tab reports success but silently changes nothing. This + # includes Language/Timezone: those live here, not in .env + # (.env's APP_LANG is only a fallback used when this row is + # missing, and APP_TIMEZONE only sets PHP's global default + # timezone -- see AppHelper.php/bootstrap.php upstream, + # neither is what the admin UI's fields actually edit). It + # also means app_mail_config() -- called at the top of every + # single request/cronjob -- was overwriting $_ENV['SMTP_*'] + # with NULLs read from this nonexistent row on every request, + # silently breaking outbound mail regardless of smtp.*/ + # secretFile; seeding smtp_* here fixes that too. smtp_password + # is deliberately left NULL: it's secret-only (see + # secretFile), not a plain Nix option, and leaving it NULL is + # no regression versus the previous (rowless) behavior either + # way. cronjob_pw is generated the same way AppModel's own + # generateCronjobToken() does. Every other column either has + # no corresponding Nix option yet or just mirrors the + # migration's own column default, same as upstream's + # installer does. + cronjob_pw="$(php -r 'echo md5(random_bytes(55) . date("Y-m-d H:i:s"));')" + mariadb "${cfg.database.name}" -e "INSERT INTO AppModel (id, workspace, language, timezone, scroller, chat_enable, chat_timelimit, chat_showusers, chat_indicator, chat_system, history_enable, history_name, enable_media_share, cronjob_pw, overlay_alpha, smtp_enable_auth, smtp_fromname, smtp_fromaddress, smtp_host, smtp_port, smtp_username, smtp_password, smtp_encryption, pwa_enable, owm_enable, owm_api_key, owm_latitude, owm_longitude, owm_unittype, owm_cache) VALUES (NULL, '${sqlEscape envVars.APP_WORKSPACE}', '${sqlEscape cfg.language}', '${sqlEscape cfg.timezone}', 1, 1, 5, 1, 1, 1, 1, 'History', 0, '$cronjob_pw', NULL, 1, '${sqlEscape cfg.smtp.fromName}', '${sqlEscape cfg.smtp.fromAddress}', '${sqlEscape cfg.smtp.host}', ${toString cfg.smtp.port}, '${sqlEscape cfg.smtp.username}', NULL, '${sqlEscape cfg.smtp.encryption}', 0, 0, NULL, NULL, NULL, 'default', 300);" + + # 6. Seed the initial admin account. migrate:fresh creates no # user rows at all, and the app's only "create user" flow # lives behind the admin panel -- without this, a fresh # deployment has no way to log in, ever. Insert directly