From 6faf432e226fb2cdf863afdc84dfeb5f3466fb0b Mon Sep 17 00:00:00 2001 From: kisfenyo Date: Tue, 29 Sep 2026 11:08:56 +0200 Subject: [PATCH] Setup gate on 28 more apps; signup_block on 11 (decision 47); claper R-713 base64; FIRST-ADMIN current Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS --- CHANGELOG.md | 16 ++++++ FIRST-ADMIN.md | 73 ++++++++++++++------------- README.md | 18 +++++++ REPORT.md | 25 +++------ REUSE.md | 1 + scripts/check-copy-i18n.py | 4 +- scripts/copy_freeze/hu.json | 11 ++++ templates/actualbudget/.felhom.yml | 9 ++++ templates/adventurelog/.felhom.yml | 8 +++ templates/calcom/.felhom.yml | 8 +++ templates/claper/.felhom.yml | 4 +- templates/docmost/.felhom.yml | 4 ++ templates/emby/.felhom.yml | 4 ++ templates/ghost/.felhom.yml | 4 ++ templates/gitea/.felhom.yml | 8 +++ templates/gramps-web/.felhom.yml | 8 +++ templates/home-assistant/.felhom.yml | 4 ++ templates/homebox/.felhom.yml | 8 +++ templates/jellyfin/.felhom.yml | 9 ++++ templates/komga/.felhom.yml | 9 ++++ templates/navidrome/.felhom.yml | 4 ++ templates/opengist/.felhom.yml | 8 +++ templates/outline/.felhom.yml | 4 ++ templates/papra/.felhom.yml | 8 +++ templates/plant-it/.felhom.yml | 4 ++ templates/radarr/.felhom.yml | 4 ++ templates/rallly/.felhom.yml | 4 ++ templates/recipe-importer/.felhom.yml | 4 ++ templates/romm/.felhom.yml | 9 ++++ templates/seerr/.felhom.yml | 4 ++ templates/sonarr/.felhom.yml | 4 ++ templates/sparkyfitness/.felhom.yml | 8 +++ templates/tandoor/.felhom.yml | 4 ++ templates/termix/.felhom.yml | 13 +++++ templates/vikunja/.felhom.yml | 8 +++ templates/wishlist/.felhom.yml | 8 +++ templates/zipline/.felhom.yml | 9 ++++ 37 files changed, 287 insertions(+), 55 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69fc127..a96c456 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,19 @@ +## The setup gate on 28 more apps; open sign-up closed after the first admin; claper's password never in code (2026-09-29 afternoon, decisions 46–47) + +- **`setup_gate: true` on 28 more class-4 apps** (32 of 34; controller ≥ 0.281.0). Probes measured before and after + the setup on 9202: actualbudget, komga, jellyfin, romm, zipline (`/api/server/public` — its `/api/setup` answers 403 + afterwards), termix. The rest open by the household's press. Every app: a stranger got the gate page / 401, the + household reached the first-setup screen, the gate opened, the app answered after (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`). + seerr, outline, rallly: gated; their opening needs a media server / e-mail, not proven here. +- **`signup_block:` + `app_info.add_people`** (decision 47) on gitea, calcom, adventurelog, homebox, papra, + sparkyfitness, vikunja, opengist, wishlist, termix, gramps-web — each measured: a stranger's sign-up succeeded after + the setup, and was refused with the block. 11 more apps refuse a stranger by themselves (measured). +- **Not gated:** wanderer (its web part calls its own database host through the public name — a gate would stop the + setup; R-714). plant-it: not installable. +- **claper (R-713):** `Base.decode64!("${ADMIN_PASSWORD|base64}")` — proven with a typed password holding `"` and `#{`. +- `scripts/check-copy-i18n.py` knows `app_info.add_people`; copy freeze recaptured (diff = the 11 sentences). +- `FIRST-ADMIN.md`: 5 fixed, 32 gated, 2 not gated. README + REUSE: `signup_block`, the probe's 200-JSON rule. + ## The setup gate on four apps; every hard-coded default replaced; stale notes; grafana; wger's sign-in (2026-09-29, `09` §3 decisions 45–46) - **The setup gate (decision 46, controller ≥ 0.280.0):** `setup_gate: true` on **immich**, **n8n**, **audiobookshelf** diff --git a/FIRST-ADMIN.md b/FIRST-ADMIN.md index a53e0e5..5592c98 100644 --- a/FIRST-ADMIN.md +++ b/FIRST-ADMIN.md @@ -24,66 +24,67 @@ first-run screen (the first visitor creates the admin) · 5 no login by design **Sources:** **M** = measured on a box (named) · **R** = read in this catalog · **U** = upstream, read or remembered, NOT measured. Every U must be measured before a fix is built on it. -**Status 2026-09-29:** 5 fixed by a generated first password (bookstack, calibre-web, claper, mealie, wger — every -class-3 app); 4 class-4 apps gated (immich, n8n, audiobookshelf, uptime-kuma). **30 class-4 apps remain open** — the -next sessions gate them app by app (R-707): a probe measured on 9202 where the app has one, the button where it has -none. Until an app is gated, its risk is the window until the household opens it first. +**Status 2026-09-29 (afternoon):** every class-3 app fixed (5); **32 of 34 class-4 apps gated** (controller ≥ 0.281.0) — +9 open by the app's own status (probe measured before and after on 9202), the rest by the household's press, which +asks the probe first where there is one. Open sign-up is closed by the box after the setup on 11 apps (decision 47); +11 more refuse a stranger by themselves. **Not gated:** wanderer (R-714, needs a design); plant-it is not installable. +**Not provable on 9202:** the opening of seerr (media server), outline and rallly (e-mail). | app | class | how the first admin exists | fix route | status | source | |---|---|---|---|---|---| -| actualbudget | 4 | first visitor sets the server password | (b) `POST /account/bootstrap` | open | R, harness fixture | -| adventurelog | 4 | open sign-up | (a) `DJANGO_ADMIN_*` env; (b) `createsuperuser --noinput` | open | R; U (env) | +| **actualbudget** | 4 | first visitor sets the server password | **setup gate**, opened by probe `/account/needs-bootstrap` → `data.bootstrapped`; the app itself refuses a stranger's second first-admin / sign-up call | **GATED** — catalog, 2026-09-29 (decisions 46–47) | **M 9202**: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | +| **adventurelog** | 4 | open sign-up | **setup gate**, opened by the household's press („Kész, beállítottam", confirm first); sign-up closed by the box after the setup: `/signup` + allauth signup | **GATED** — catalog, 2026-09-29 (decisions 46–47) | **M 9202**: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | | **audiobookshelf** | 4 | first visitor creates root | **setup gate**, probe `GET /status` → `isInit` | **GATED** — catalog, 2026-09-29 | **M 9202**: as immich (the probe, read from upstream, measured: opened ~20 s after `POST /init`); its app's login 200 after | | bentopdf | 5 | browser-only PDF tool, no accounts | – | fine | R | | **bookstack** | 3 | `admin@admin.com / password` | (b) `artisan bookstack:create-admin --initial` | **FIXED** — catalog, decision 45 | **M 9202**: default fails, generated works; **M demo-hp**: default still works on the installed app (unchanged, page warns) | -| calcom | 4 | first visitor becomes admin (`/api/auth/setup`) | (b) `POST /api/auth/setup`; (a) `NEXT_PUBLIC_DISABLE_SIGNUP` | open | **M 9202** (setup 200 once, then 400) | +| **calcom** | 4 | first visitor becomes admin (`/api/auth/setup`) | **setup gate**, opened by the household's press („Kész, beállítottam", confirm first); sign-up closed by the box after the setup: `/signup`, `/auth/signup`, `/api/auth/signup` | **GATED** — catalog, 2026-09-29 (decisions 46–47) | **M 9202**: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | | **calibre-web** | 3 | `admin / admin123` | (b) `cps.py -p /config/app.db -s admin:` as `abc`; `generate: password:24:special` (controller ≥ 0.280.0) | **FIXED** — catalog, 2026-09-29 | **M 9202**: fresh install — default refused, generated signs in (302), wrong refused; **M demo-hp**: the installed app's password changed by the operator's ruling (Part A) | | **claper** | 3 (+ open sign-up) | seeds `admin@claper.co / claper` | (b) `bin/claper rpc … update_user_password` | **FIXED** — catalog, decision 45 | **M 9202**: default fails, generated works, a restore keeps it | | code-server | 1 | `PASSWORD` generated, applied every start | – | fine | R | | crafty-controller | 1 | `CRAFTY_PASSWORD` → default.json | – | fine | R | -| docmost | 4 | first registered user is admin | (b) `POST /api/auth/setup` | open | R, fixture | -| emby | 4 | setup wizard | (b) `/Startup/*` API | open | U | -| ghost | 4 | `/ghost/` setup | (b) `POST /ghost/api/admin/authentication/setup/` | open | U | -| gitea | 4 | web installer open (no `INSTALL_LOCK`) | (a) `INSTALL_LOCK` + (b) `gitea admin user create` | open | R; R-624 | +| **docmost** | 4 | first registered user is admin | **setup gate**, opened by the household's press („Kész, beállítottam", confirm first); the app itself refuses a stranger's second first-admin / sign-up call; no JSON status before/after → button | **GATED** — catalog, 2026-09-29 (decisions 46–47) | **M 9202**: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | +| **emby** | 4 | setup wizard | **setup gate**, opened by the household's press („Kész, beállítottam", confirm first); the app itself refuses a stranger's second first-admin / sign-up call | **GATED** — catalog, 2026-09-29 (decisions 46–47) | **M 9202**: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | +| **ghost** | 4 | `/ghost/` setup | **setup gate**, opened by the household's press („Kész, beállítottam", confirm first); the app itself refuses a stranger's second first-admin / sign-up call; its status exists but is a list (`setup[0].status`) — the box reads only objects → button | **GATED** — catalog, 2026-09-29 (decisions 46–47) | **M 9202**: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | +| **gitea** | 4 | web installer open (no `INSTALL_LOCK`) | **setup gate**, opened by the household's press („Kész, beállítottam", confirm first); sign-up closed by the box after the setup: `/user/sign_up`; `/api/v1/version` is not JSON before the install → button | **GATED** — catalog, 2026-09-29 (decisions 46–47) | **M 9202**: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | | glance | 5 | config-file dashboard, no users | – | fine | R | | gokapi | 1 | `GOKAPI_PASSWORD` before first serve | – | fine | R | | grafana | 1 | `GF_SECURITY_ADMIN_PASSWORD` — **falls back to `admin` if empty** (R-708) | – | fine while the field is set | R | -| gramps-web | 4 | first-run onboarding | (b) `python3 -m gramps_webapi user add` | open | U | -| home-assistant | 4 | onboarding | (b) `POST /api/onboarding/users` | open | R, fixture | -| homebox | 4 | open registration | (b) register API; (a) disable registration after | open | U | +| **gramps-web** | 4 | first-run onboarding | **setup gate**, opened by the household's press („Kész, beállítottam", confirm first); sign-up closed by the box after the setup: `/api/users//register/`; its status answers HTTP 405 after the setup — the box reads only 200 answers (measured: the press was then refused, fail closed) → button; self-registration answered 500, blocked anyway | **GATED** — catalog, 2026-09-29 (decisions 46–47) | **M 9202**: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | +| **home-assistant** | 4 | onboarding | **setup gate**, opened by the household's press („Kész, beállítottam", confirm first); the app itself refuses a stranger's second first-admin / sign-up call; its status is a list (`/api/onboarding`) → button | **GATED** — catalog, 2026-09-29 (decisions 46–47) | **M 9202**: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | +| **homebox** | 4 | open registration | **setup gate**, opened by the household's press („Kész, beállítottam", confirm first); sign-up closed by the box after the setup: `/api/v1/users/register` | **GATED** — catalog, 2026-09-29 (decisions 46–47) | **M 9202**: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | | homepage | 5 | static start page | – | fine | R | | **immich** | 4 | first visitor admin sign-up | **setup gate**, probe `GET /api/server/config` → `isInitialized` | **GATED** — catalog, 2026-09-29 (decision 46) | **M 9202**: stranger 302→gate page / 401 during and after the install; household in 0.2 s; probe opened it 0–20 s after the sign-up; phone-app API (Bearer) 200 after (`felhom.eu/documentation/audits/login-gate-2026-09-29/C/`) | -| jellyfin | 4 | startup wizard | (b) `/Startup/*` | open | U | +| **jellyfin** | 4 | startup wizard | **setup gate**, opened by probe `/System/Info/Public` → `StartupWizardCompleted`; the app itself refuses a stranger's second first-admin / sign-up call | **GATED** — catalog, 2026-09-29 (decisions 46–47) | **M 9202**: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | | kimai | 1 | `ADMIN_PASSWORD` → `ADMINPASS` | – | fine | R | -| komga | 4 | first visitor claims | (b) `POST /api/v1/claim` | open | U | +| **komga** | 4 | first visitor claims | **setup gate**, opened by probe `/api/v1/claim` → `isClaimed`; the app itself refuses a stranger's second first-admin / sign-up call | **GATED** — catalog, 2026-09-29 (decisions 46–47) | **M 9202**: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | | **mealie** | 3 | `changeme@example.com / MyPassword` | (b) its own user repository (`update_password`), password as `sys.argv[1]` | **FIXED** — catalog, 2026-09-29 | **M 9202**: fresh install — default 401, generated 200, wrong 401 (`felhom.eu/documentation/audits/login-gate-2026-09-29/D/`) | | **n8n** | 4 | owner setup | **setup gate**, probe `GET /rest/settings` → `data.userManagement.showSetupOnFirstLoad` = false | **GATED** — catalog, 2026-09-29 | **M 9202**: as immich; opened by the probe ~20 s after the owner setup | -| navidrome | 4 | first user is admin | (a) `ND_DEVAUTOCREATEADMINPASSWORD`; (b) `/auth/createAdmin` | open | R, fixture; U (env) | +| **navidrome** | 4 | first user is admin | **setup gate**, opened by the household's press („Kész, beállítottam", confirm first); the app itself refuses a stranger's second first-admin / sign-up call | **GATED** — catalog, 2026-09-29 (decisions 46–47) | **M 9202**: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | | nextcloud | 1 | `NEXTCLOUD_ADMIN_PASSWORD` → auto-install | – | fine | R; **M** demo-hp 2026-09-28 | | onlyoffice | 5 | JWT-protected API, no login screen | – | fine | R | -| opengist | 4 | first registered user is admin | (b) `POST /register`; (a) `OG_DISABLE_SIGNUP` | open | R, fixture | -| outline | 4 | e-mail / magic-link onboarding | (c) none found (R-624) | open — page note needed | R | +| **opengist** | 4 | first registered user is admin | **setup gate**, opened by the household's press („Kész, beállítottam", confirm first); sign-up closed by the box after the setup: `/-/register` | **GATED** — catalog, 2026-09-29 (decisions 46–47) | **M 9202**: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | +| **outline** | 4 | e-mail / magic-link onboarding | **setup gate**, the household's press; needs e-mail or SSO to sign anyone in — not provable on 9202 | **GATED** — catalog, 2026-09-29; the opening NOT proven | **M 9202**: stranger → gate page / 401, household reached the first-setup screen (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | | paperless-ngx | 1 | `PAPERLESS_ADMIN_PASSWORD` | – | fine | R | -| papra | 4 | open e-mail sign-up | (b) sign-up API; (a) disable registration | open | R, fixture | -| plant-it | 4 | open, `USERS_LIMIT=-1` | (a) `USERS_LIMIT=1` + (b) sign-up | open | U | +| **papra** | 4 | open e-mail sign-up | **setup gate**, opened by the household's press („Kész, beállítottam", confirm first); sign-up closed by the box after the setup: `/api/auth/sign-up` | **GATED** — catalog, 2026-09-29 (decisions 46–47) | **M 9202**: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | +| plant-it | 4 | open, `USERS_LIMIT=-1` | `setup_gate: true` in the template; the catalog marks it NOT installable (`lifecycle: abandoned`) — nothing to prove | not installable | R | | plex | 2 | the household's plex.tv claim token | – | fine | R | | privatebin | 5 | anonymous pastes by design | – | fine | R | -| radarr | 4 | first visitor sets auth | (b) `PUT /api/v3/config/host` with the apikey | open | U | -| rallly | 4 | magic link to any e-mail | (a) `INITIAL_ADMIN_EMAIL` + `ALLOWED_EMAILS` | open | U | -| recipe-importer | 4 | our own image, open until set | (c) now; our own code | open | R | -| romm | 4 (catalog said 3) | first unauthenticated `POST /api/users` creates the user (harness); the stale `admin / admin` note is **removed** (2026-09-29) | (b) `POST /api/users`; or the setup gate | open | **M demo-hp** (401 for the old note); fixture | -| seerr | 4 | setup wizard (needs a media server) | (c) | open | U | -| sonarr | 4 | as radarr | (b) | open | U | -| sparkyfitness | 4 | open registration | (a) `SPARKY_FITNESS_ADMIN_EMAIL` + disable sign-up | open | U | -| tandoor | 4 | setup page while no users | (b) `createsuperuser --noinput` | open | R, fixture | -| termix | 4 | first registered user is admin | (b) user-create API | open | U | +| **radarr** | 4 | first visitor sets auth | **setup gate**, opened by the household's press („Kész, beállítottam", confirm first); no sign-up to close (single user / no accounts); `/initialize.json` hands anyone the API key BEFORE the setup — the gate hides it; after, it needs a login | **GATED** — catalog, 2026-09-29 (decisions 46–47) | **M 9202**: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | +| **rallly** | 4 | magic link to any e-mail | **setup gate**, the household's press; magic link by e-mail — not provable on 9202 | **GATED** — catalog, 2026-09-29; the opening NOT proven | **M 9202**: stranger → gate page / 401, household reached the first-setup screen (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | +| **recipe-importer** | 4 | our own image, open until set | **setup gate**, opened by the household's press („Kész, beállítottam", confirm first); no sign-up to close (single user / no accounts); our own app: open until a password is set in its settings — the confirm says so | **GATED** — catalog, 2026-09-29 (decisions 46–47) | **M 9202**: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | +| **romm** | 4 | first unauthenticated `POST /api/users` creates the user (harness); the stale `admin / admin` note is **removed** (2026-09-29) | **setup gate**, opened by probe `/api/heartbeat` → `SYSTEM.SHOW_SETUP_WIZARD` = false; the app itself refuses a stranger's second first-admin / sign-up call | **GATED** — catalog, 2026-09-29 (decisions 46–47) | **M 9202**: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | +| **seerr** | 4 | setup wizard (needs a media server) | **setup gate**, the household's press; needs a media server to finish its setup — not provable on 9202 (its `initialized` status measured false before) | **GATED** — catalog, 2026-09-29; the opening NOT proven | **M 9202**: stranger → gate page / 401, household reached the first-setup screen (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | +| **sonarr** | 4 | as radarr | **setup gate**, opened by the household's press („Kész, beállítottam", confirm first); no sign-up to close (single user / no accounts); as radarr | **GATED** — catalog, 2026-09-29 (decisions 46–47) | **M 9202**: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | +| **sparkyfitness** | 4 | open registration | **setup gate**, opened by the household's press („Kész, beállítottam", confirm first); sign-up closed by the box after the setup: `/api/auth/sign-up` | **GATED** — catalog, 2026-09-29 (decisions 46–47) | **M 9202**: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | +| **tandoor** | 4 | setup page while no users | **setup gate**, opened by the household's press („Kész, beállítottam", confirm first); the app itself refuses a stranger's second first-admin / sign-up call | **GATED** — catalog, 2026-09-29 (decisions 46–47) | **M 9202**: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | +| **termix** | 4 | first registered user is admin | **setup gate**, opened by probe `/users/setup-required` → `setup_required` = false; sign-up closed by the box after the setup: `/users/create` | **GATED** — catalog, 2026-09-29 (decisions 46–47) | **M 9202**: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | | **uptime-kuma** | 4 | first visitor creates admin (socket.io `setup`) | **setup gate**, no HTTP probe → the household's „Kész, beállítottam" | **GATED** — catalog, 2026-09-29 | **M 9202**: gate held across a controller restart; the press opened it (second press 409). The proof pressed WITHOUT doing the socket.io setup — the press trusts the household | | vaultwarden | 1 | `ADMIN_TOKEN` generated; invite-only (R-512) | – | fine | R | -| vikunja | 4 | open registration | (b) `vikunja user create`; (a) disable registration | open | R, fixture | -| wanderer | 4 | `PUBLIC_DISABLE_SIGNUP=false` | (a) disable after first user | open | U | +| **vikunja** | 4 | open registration | **setup gate**, opened by the household's press („Kész, beállítottam", confirm first); sign-up closed by the box after the setup: `/api/v1/register` | **GATED** — catalog, 2026-09-29 (decisions 46–47) | **M 9202**: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | +| wanderer | 4 | `PUBLIC_DISABLE_SIGNUP=false` | NOT gated: its web part calls its own database host through the public name, which a gate would refuse (the household could not finish the setup); open sign-up (`PUBLIC_DISABLE_SIGNUP=false`) and PocketBase's own first-run screen on the second host — R-714 | open — **needs a design** | R; measured the call on 9202 | | **wger** | 3 | `admin / adminadmin` | (b) Django `set_password`, password as `sys.argv[1]` | **FIXED** — catalog, 2026-09-29; + R-712 (a browser's https Origin was refused by CSRF) | **M 9202**: fresh install — default refused, generated signs in (302), wrong refused, with the browser's https Origin | -| wishlist | 4 | first sign-up is admin | (b) `POST /signup` | open | R, fixture | -| zipline | 4 (catalog said 3) | v4 sets up on first run; the stale `admin / zipline` note is **removed** (2026-09-29) | (b) setup API (U); or the setup gate (probe `/api/setup` `firstSetup`, U) | open | R; audit logs | +| **wishlist** | 4 | first sign-up is admin | **setup gate**, opened by the household's press („Kész, beállítottam", confirm first); sign-up closed by the box after the setup: `/signup` | **GATED** — catalog, 2026-09-29 (decisions 46–47) | **M 9202**: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | +| **zipline** | 4 | v4 sets up on first run; the stale `admin / zipline` note is **removed** (2026-09-29) | **setup gate**, opened by probe `/api/server/public` → `firstSetup` = false; the app itself refuses a stranger's second first-admin / sign-up call | **GATED** — catalog, 2026-09-29 (decisions 46–47) | **M 9202**: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (`felhom.eu/documentation/audits/gate-rollout-2026-09-29/`) | -**Counts (computed from the table, 2026-09-29):** class 1: 8 · class 2: 1 · class 3: 5 · class 4: 34 · class 5: 5. -**Fixed: 5** (every class-3 app). **Gated: 4.** **Open: 30** (class 4). Fine: 14. +**Counts (computed from the table, 2026-09-29 afternoon):** class 1: 8 · class 2: 1 · class 3: 5 · class 4: 34 · class 5: 5. +**Fixed: 5.** **Gated: 32** (3 of them without a proven opening). **Not gated: 2** (wanderer — R-714; plant-it — not installable). Fine: 14. diff --git a/README.md b/README.md index be31c74..e7df9c2 100644 --- a/README.md +++ b/README.md @@ -191,6 +191,24 @@ setup_done_probe: # optional — without it the The url uses the app's `container_name` and its internal port. **Measure the probe on 9202 before and after the setup** (it must flip), and prove a stranger gets the gate page / 401 until then. Per-app status: `FIRST-ADMIN.md`. +A probe must answer **HTTP 200 with a JSON object** on both sides of the setup (the box reads only that; a 403/405 +or a list never opens the gate, and it also blocks the household's press — gramps-web, ghost, home-assistant). + +### Open sign-up after the first admin (`signup_block`, controller ≥ 0.281.0) + +`09` §3 decision 47: once the gate opens, a stranger cannot make an account. Where the app itself keeps sign-up open, +the template names its sign-up address as a traefik matcher; the box answers it with "sign-up is closed" from then on, +and the household can open it for 15 minutes from the app page. `add_people:` (hu, + `i18n.en`) tells them how. + +```yaml +signup_block: "PathPrefix(`/-/register`)" # opengist +app_info: + add_people: "Nyisd meg a regisztrációt 15 percre, és a családtagod regisztrál." +``` + +**Measure it on 9202:** after the setup a stranger's sign-up succeeds (the reason for the block), with the block it is +refused, and the rest of the app still answers. + ### App-email mapping (`smtp_mapping`) Apps that can send outbound email (password resets, invites, confirmations) get it through diff --git a/REPORT.md b/REPORT.md index cc044f8..8c8d875 100644 --- a/REPORT.md +++ b/REPORT.md @@ -1,19 +1,10 @@ -# REPORT — 2026-09-29: the setup gate on four apps; every hard-coded default replaced (decisions 45–46) +# REPORT — 2026-09-29 afternoon: the setup gate on 28 more apps; sign-up closed after the first admin (decisions 46–47) -Architecture: `09-update-architecture.md` §3 decisions 45–46; `01-topology-and-trust.md` §5. Controller 0.280.0. -Evidence: `felhom.eu/documentation/audits/login-gate-2026-09-29/` (B spike, C gate live, D defaults live). +Architecture: `09-update-architecture.md` §3 decisions 46–47; `01-topology-and-trust.md` §5. Controller 0.281.0. +Evidence: `felhom.eu/documentation/audits/gate-rollout-2026-09-29/`. Per-app status: `FIRST-ADMIN.md`. -| app | change | proof on 9202 (drill catalog, fresh install, controller 0.280.0) | -|---|---|---| -| immich | setup gate, probe `isInitialized` | stranger: gate page / 401 during install and until setup; household in 0.2 s; probe opened it; phone-app API 200 after | -| n8n | setup gate, probe `showSetupOnFirstLoad` | as immich; opened ~20 s after the owner setup | -| audiobookshelf | setup gate, probe `/status isInit` | as immich; opened ~20 s after `POST /init` | -| uptime-kuma | setup gate, the household's button | held across a controller restart; the press opened it; a second press 409 | -| mealie | `after_install` (argv) | default 401, generated 200, wrong 401 | -| wger | `after_install` (argv) + R-712 CSRF | default refused, generated signs in with a browser's https Origin, wrong refused | -| calibre-web | `after_install`, `password:24:special` | default refused, generated signs in, wrong refused | -| romm, zipline | stale `default_creds` removed | the page no longer names a login that does not exist | -| grafana | R-708 `${…:?…}` | `docker compose config`: empty/unset refused (rc 1), set → rc 0 | - -Gates: the catalog pre-push gates; `check-copy-i18n.py --capture-freeze` (diff = only these apps' strings). -Status: `FIRST-ADMIN.md` — 5 fixed, 4 gated, 30 open (R-707). +- 32 of 34 class-4 apps gated; 9 by a measured probe, the rest by the household's press (which asks the probe first). +- 11 apps get a sign-up block (measured open before, refused after); 11 more refuse a stranger by themselves. +- wanderer not gated (R-714); plant-it not installable; seerr/outline/rallly's opening not provable on 9202. +- claper: the password reaches its Elixir code base64-encoded (R-713), proven live with `"` and `#{`. +- Gates: pre-push catalog gates; copy freeze recaptured (diff = the 11 new sentences). diff --git a/REUSE.md b/REUSE.md index aa00173..6c0c143 100644 --- a/REUSE.md +++ b/REUSE.md @@ -23,6 +23,7 @@ Templates are config; the few script helpers other scripts must REUSE, never re- | deploy_fields conventions | `templates/paperless-ngx/.felhom.yml` (`deploy_fields:` block) | Every app starts with `DOMAIN` (type `domain`) + `SUBDOMAIN` (type `subdomain`, `locked_after_deploy: true`). Secrets: `type: secret` + `generate:` — dominant generators `password:24` (DB passwords) and `hex:32` (app secret keys); `password:16` for shown admin passwords (`type: password`). HDD apps add `HDD_PATH` (`type: path`, placeholder `/mnt/felhom-drives/hdd_1`, locked). Labels/descriptions in Hungarian. | | **Known default login → `after_install:`** (decision 45, controller ≥ 0.279.0) | `templates/bookstack/.felhom.yml` (`ADMIN_PASSWORD` field + `after_install:` block); `FIRST-ADMIN.md` for every app | An app that starts with a known admin login gets a generated `type: password` field (`generate: "password:24"`, `locked_after_deploy: true`) and ONE `after_install: {service, env: [ADMIN_PASSWORD], command: [...], success: ""}` through the app's OWN CLI, run once after a FRESH install. Keep `app_info.default_creds` — the page hides it once the command succeeded and warns while it is in effect. **Prove on 9202 (drill catalog) before live: the default fails, the generated password works, a wrong one fails.** TRAPS: `success:` is required because a CLI can exit 0 on an error (claper's `rpc`); **pass the password as its own argument, never inside program code** (`sys.argv[1]` — mealie, wger; security review 2026-09-29); a special-character policy uses `generate: "password:24:special"` (controller ≥ 0.280.0, calibre-web); a Hungarian first-steps change needs `check-copy-i18n.py --capture-freeze`. | | **Open first-run screen → `setup_gate:`** (decision 46, controller ≥ 0.280.0) | `templates/n8n/.felhom.yml` (probe), `templates/uptime-kuma/.felhom.yml` (no probe → the household's button); `FIRST-ADMIN.md` | `setup_gate: true` + optional `setup_done_probe: {url: http://:/, field: , done: ""}` | TRAPS: the probe must FLIP on the setup — measure it before and after on 9202; an app with open sign-up after setup (R-711) is not closed by the gate; `url` is read on the docker network, so it names the container, not the subdomain. | +| **Open sign-up after the setup → `signup_block:`** (decision 47, controller ≥ 0.281.0) | `templates/opengist/.felhom.yml`, `templates/calcom/.felhom.yml` | `signup_block: ""` + `app_info.add_people` (hu) / `i18n.en.app_info.add_people` | TRAPS: block the app's API sign-up call, not only the page; an app's own invite link often uses the same address (the household's 15-minute window covers it); `add_people` is copy — `--capture-freeze`. | | Controller-side health probe | `templates/vaultwarden/.felhom.yml` (`healthcheck:` block) | `healthcheck.checks[]` with `type: http` (port only), `type: api` (port + `path` + `expect.status: 200`), or `type: tcp` (port only — mealie, crafty-controller). Prefer `api` with a real health path when the app has one. | | App lifecycle (`available`/`hidden`/`abandoned`) | `templates/plant-it/.felhom.yml` (`lifecycle:` block) | Optional top-level `lifecycle:` in `.felhom.yml`. Absent/empty ≡ `available`. `hidden` = not offered for new installs; `abandoned` = same, PLUS a permanent "Nem karbantartott" badge + notice on every box already running it. **Deployed instances keep full function in both states** — lifecycle governs what is OFFERED, never what runs; the controller refuses a deploy of a non-available template server-side (fail-closed, so a stale link or direct POST cannot install one). Unknown value → treated as `available` + one WARN, never a broken template. **Do NOT take an app out of circulation by deleting or moving its directory** — that orphans every customer already running it, which is what the 2026-07-21 `retired/` experiment got wrong. The resolvability gate skips non-available apps, so an abandoned app's dead image is not a standing red. | | **Catalog gates — THE entry point** | `scripts/catalog_gates.py` | **Run `python3 scripts/catalog_gates.py ` after ANY template change** (mandated in `CLAUDE.md`). Runs all four gates below in order — image-pins, image-resolvable, volume-persistence, engine-major (2026-09-13; git-history diff, hook-only until CI fetches deeper, R-452) — and exits **non-zero if any fails**; **2 (UNDETERMINED) is reported distinctly and is never a pass**, 1 (convicted) outranks 2 in the summary. Naming app(s) scopes the two gates that accept scoping, which is the normal after-a-change run; with no names the RUNTIME gate deploys every template, so that form is **scratch host only**. **Why a runner** (operator ruling 2026-08-02, R-161): the only gates in this project that ever get run are the ones with a single entry point named in a CLAUDE.md — `felhom.eu/scripts/site_gates.py` is run, R-29's three orphans are named nowhere and have stopped nothing. Controller-side enforcement was rejected because a load-time check reads only the file and a static audit reports the catalog clean **including papra** — it would pass on the very defect it exists to catch; CI was rejected for now (neither repo has any, no users yet). Adding a fourth gate here means adding it to `GATES` in this file — nothing else. | diff --git a/scripts/check-copy-i18n.py b/scripts/check-copy-i18n.py index f6d6e84..54d9f4a 100644 --- a/scripts/check-copy-i18n.py +++ b/scripts/check-copy-i18n.py @@ -152,6 +152,7 @@ def copy_strings(meta): ai = meta.get("app_info") or {} add("app_info.tagline", ai.get("tagline")) add("app_info.default_creds", ai.get("default_creds")) + add("app_info.add_people", ai.get("add_people")) # decision 47 (controller >= 0.281.0): how to add a family member for k in ("use_cases", "first_steps", "prerequisites"): for i, v in enumerate(ai.get(k) or []): add("app_info.%s[%d]" % (k, i), v) @@ -220,10 +221,11 @@ def overlay_strings(ov, hu_meta): errs.append("app_info must be a mapping") else: for k in ai: - if k not in ("tagline", "default_creds", "use_cases", "first_steps", "prerequisites"): + if k not in ("tagline", "default_creds", "add_people", "use_cases", "first_steps", "prerequisites"): errs.append("unknown key app_info.%s — `docs_url` and the rest are not copy" % k) scalar("app_info.tagline", ai.get("tagline"), "app_info.tagline") scalar("app_info.default_creds", ai.get("default_creds"), "app_info.default_creds") + scalar("app_info.add_people", ai.get("add_people"), "app_info.add_people") hu_ai = hu_meta.get("app_info") or {} for k in ("use_cases", "first_steps", "prerequisites"): lst = ai.get(k) diff --git a/scripts/copy_freeze/hu.json b/scripts/copy_freeze/hu.json index 79f181a..0fb0ddd 100644 --- a/scripts/copy_freeze/hu.json +++ b/scripts/copy_freeze/hu.json @@ -20,6 +20,7 @@ "description": "Személyes pénzügyek és költségvetés kezelése" }, "adventurelog": { + "app_info.add_people": "Nyisd meg a regisztrációt 15 percre, és a családtagod a saját címével regisztrál.", "app_info.first_steps[0]": "Nyisd meg a travel.DOMAIN címet a böngészőben", "app_info.first_steps[1]": "Hozd létre a fiókodat", "app_info.first_steps[2]": "Add hozzá az első utazásodat", @@ -101,6 +102,7 @@ "description": "Egyszerű, könyv-szerű wiki és dokumentáció platform" }, "calcom": { + "app_info.add_people": "Beállítások → Adminisztráció → Felhasználók → Új felhasználó.", "app_info.first_steps[0]": "Nyisd meg a cal.DOMAIN címet a böngészőben", "app_info.first_steps[1]": "Hozd létre az admin fiókot", "app_info.first_steps[2]": "Állíts be egy foglalási típust (pl. 30 perces megbeszélés)", @@ -284,6 +286,7 @@ "description": "Professzionális blog és hírlevél platform" }, "gitea": { + "app_info.add_people": "Webhely adminisztráció → Felhasználói fiókok → Új felhasználói fiók létrehozása.", "app_info.first_steps[0]": "Nyisd meg a git.DOMAIN címet a böngészőben", "app_info.first_steps[1]": "Kövesd az első beállítás varázslót", "app_info.first_steps[2]": "Hozd létre az admin fiókot", @@ -361,6 +364,7 @@ "description": "Professzionális monitoring és vizualizációs platform" }, "gramps-web": { + "app_info.add_people": "Adminként: Beállítások → Felhasználók kezelése → Új felhasználó.", "app_info.first_steps[0]": "Nyisd meg a family.DOMAIN címet a böngészőben", "app_info.first_steps[1]": "Hozd létre az admin fiókot", "app_info.first_steps[2]": "Importálj egy meglévő GEDCOM fájlt, vagy kezdd az üres családfát", @@ -399,6 +403,7 @@ "description": "Nyílt forráskódú okos otthon központ" }, "homebox": { + "app_info.add_people": "Nyisd meg a regisztrációt 15 percre, és küldd el a családtagodnak a Homebox csoport meghívó linkjét (Beállítások → Csoport → Meghívó).", "app_info.first_steps[0]": "Nyisd meg az inventory.DOMAIN címet a böngészőben", "app_info.first_steps[1]": "Hozd létre a fiókodat az első megnyitáskor", "app_info.first_steps[2]": "Add hozzá a helyszíneket (pl. nappali, konyha, garázs)", @@ -648,6 +653,7 @@ "integrations[nextcloud].label": "Nextcloud integráció" }, "opengist": { + "app_info.add_people": "Nyisd meg a regisztrációt 15 percre, és a családtagod regisztrál.", "app_info.first_steps[0]": "Nyisd meg a gist.DOMAIN címet a böngészőben", "app_info.first_steps[1]": "Hozd létre a fiókodat (az első felhasználó admin lesz)", "app_info.first_steps[2]": "Hozd létre az első gistet - írd be a kódot és mentsd", @@ -723,6 +729,7 @@ "description": "Dokumentumok digitalizálása és rendszerezése" }, "papra": { + "app_info.add_people": "Nyisd meg a regisztrációt 15 percre; a családtagod regisztrál, aztán meghívod a szervezetedbe (Szervezet → Tagok → Meghívás).", "app_info.first_steps[0]": "Nyisd meg a papra.DOMAIN címet a böngészőben", "app_info.first_steps[1]": "Hozd létre a fiókodat", "app_info.first_steps[2]": "Töltsd fel az első dokumentumot", @@ -951,6 +958,7 @@ "description": "Automatikus sorozat letöltő és rendszerező" }, "sparkyfitness": { + "app_info.add_people": "Nyisd meg a regisztrációt 15 percre, és a családtagod regisztrál.", "app_info.first_steps[0]": "Nyisd meg a sparky.DOMAIN címet a böngészőben", "app_info.first_steps[1]": "Regisztrálj egy fiókot e-mail címmel és jelszóval", "app_info.first_steps[2]": "Állítsd be a profilodat és a napi céljaidat", @@ -993,6 +1001,7 @@ "description": "Receptkezelő és étkezés tervező" }, "termix": { + "app_info.add_people": "Nyisd meg a regisztrációt 15 percre, és a családtagod regisztrál.", "app_info.first_steps[0]": "Nyisd meg a terminal.DOMAIN címet a böngészőben", "app_info.first_steps[1]": "Csatlakozz a szerveredhez SSH-n keresztül", "app_info.tagline": "Webes SSH terminál - szerver hozzáférés a böngészőből", @@ -1049,6 +1058,7 @@ "description": "Jelszókezelő (Bitwarden-kompatibilis)" }, "vikunja": { + "app_info.add_people": "Nyisd meg a regisztrációt 15 percre, és a családtagod regisztrál; utána megoszthatod vele a projektjeidet.", "app_info.first_steps[0]": "Nyisd meg a tasks.DOMAIN címet a böngészőben", "app_info.first_steps[1]": "Hozd létre a fiókodat", "app_info.first_steps[2]": "Hozd létre az első projektet és feladatlistát", @@ -1111,6 +1121,7 @@ "description": "Edzésnapló és fitnesz tervező" }, "wishlist": { + "app_info.add_people": "Nyisd meg a regisztrációt 15 percre, és a családtagod regisztrál (a Wishlist meghívó linkje is ebben az időben működik).", "app_info.first_steps[0]": "Nyisd meg a wishes.DOMAIN címet a böngészőben", "app_info.first_steps[1]": "Hozd létre a fiókodat", "app_info.first_steps[2]": "Hozd létre az első kívánságlistádat", diff --git a/templates/actualbudget/.felhom.yml b/templates/actualbudget/.felhom.yml index 6915ee4..b635d0c 100644 --- a/templates/actualbudget/.felhom.yml +++ b/templates/actualbudget/.felhom.yml @@ -40,6 +40,15 @@ deploy_fields: locked_after_deploy: true description: "Az alkalmazás aldomainje" +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true +# measured on 9202 2026-09-29: data.bootstrapped false -> true once the server password is set. +setup_done_probe: + url: http://actualbudget:5006/account/needs-bootstrap + field: data.bootstrapped + done: "true" + # --- App info (info page content) --- app_info: tagline: 'Költségvetés tervező - pénzügyeid kézben tartása egyszerűen' diff --git a/templates/adventurelog/.felhom.yml b/templates/adventurelog/.felhom.yml index 9fc7623..bfd3527 100644 --- a/templates/adventurelog/.felhom.yml +++ b/templates/adventurelog/.felhom.yml @@ -52,9 +52,16 @@ deploy_fields: generate: "password:24" locked_after_deploy: true +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true +# Decision 47: the app's own sign-up address is closed once the gate opens (measured on 9202 2026-09-29: a stranger's sign-up succeeded after the setup). +signup_block: "Path(`/signup`) || PathPrefix(`/auth/browser/v1/auth/signup`) || PathPrefix(`/_allauth/browser/v1/auth/signup`) || PathPrefix(`/accounts/signup`)" + # --- App info (info page content) --- app_info: tagline: "Utazási napló - utazások dokumentálása térképpel és fotókkal" + add_people: "Nyisd meg a regisztrációt 15 percre, és a családtagod a saját címével regisztrál." docs_url: "https://adventurelog.app/docs/" use_cases: @@ -88,6 +95,7 @@ i18n: description: 'Travel journal and trip planner' app_info: tagline: 'Travel journal - keep your trips with a map and photos' + add_people: "Open sign-up for 15 minutes, and your family member signs up with their own address." use_cases: - 'Keep your trips with pictures and notes' - 'See everywhere you have been on a map' diff --git a/templates/calcom/.felhom.yml b/templates/calcom/.felhom.yml index dca3e68..ad7edc9 100644 --- a/templates/calcom/.felhom.yml +++ b/templates/calcom/.felhom.yml @@ -53,9 +53,16 @@ deploy_fields: generate: "password:24" locked_after_deploy: true +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true +# Decision 47: the app's own sign-up address is closed once the gate opens (measured on 9202 2026-09-29: a stranger's POST /api/auth/signup created an account (201) after the setup). +signup_block: "Path(`/signup`) || PathPrefix(`/auth/signup`) || PathPrefix(`/api/auth/signup`)" + # --- App info (info page content) --- app_info: tagline: "Időpontfoglaló - Calendly alternatíva saját szerveren" + add_people: "Beállítások → Adminisztráció → Felhasználók → Új felhasználó." docs_url: "https://cal.com/docs/" use_cases: @@ -108,6 +115,7 @@ i18n: description: 'Open source appointment booking (a Calendly alternative)' app_info: tagline: 'Appointment booking - a Calendly alternative on your own server' + add_people: "Settings → Admin → Users → Add user." use_cases: - 'Give people a page where they can book time with you' - 'Calendar sync (Google Calendar, Outlook)' diff --git a/templates/claper/.felhom.yml b/templates/claper/.felhom.yml index 5e77469..4975770 100644 --- a/templates/claper/.felhom.yml +++ b/templates/claper/.felhom.yml @@ -80,13 +80,15 @@ app_info: # --- After a fresh install (controller >= 0.279.0, decision 45) --- # claper's OWN release CLI, in the running node: the seeded default admin's password becomes ADMIN_PASSWORD. # Measured on 9202 2026-09-28: afterwards `admin@claper.co / claper` no longer authenticates. +# R-713 (controller >= 0.281.0): the password reaches the Elixir code base64-encoded (${ADMIN_PASSWORD|base64}) and is +# decoded there — a quote or #{ in a household-typed password can no longer end the string or run code. after_install: service: claper env: [ADMIN_PASSWORD] command: - /app/bin/claper - rpc - - 'u = Claper.Accounts.get_user_by_email("admin@claper.co"); r = if u, do: Claper.Accounts.update_user_password(u, "claper", %{password: "${ADMIN_PASSWORD}", password_confirmation: "${ADMIN_PASSWORD}"}), else: :no_default_admin; case r do {:ok, _} -> IO.puts("FELHOM_AFTER_INSTALL_OK"); other -> IO.puts("FELHOM_AFTER_INSTALL_FAILED #{inspect(other, limit: 3)}") end' + - 'pw = Base.decode64!("${ADMIN_PASSWORD|base64}"); u = Claper.Accounts.get_user_by_email("admin@claper.co"); r = if u, do: Claper.Accounts.update_user_password(u, "claper", %{password: pw, password_confirmation: pw}), else: :no_default_admin; case r do {:ok, _} -> IO.puts("FELHOM_AFTER_INSTALL_OK"); other -> IO.puts("FELHOM_AFTER_INSTALL_FAILED #{inspect(other, limit: 3)}") end' success: FELHOM_AFTER_INSTALL_OK # --- Controller-side health probe --- diff --git a/templates/docmost/.felhom.yml b/templates/docmost/.felhom.yml index 1f9ae05..7ac9bc6 100644 --- a/templates/docmost/.felhom.yml +++ b/templates/docmost/.felhom.yml @@ -52,6 +52,10 @@ deploy_fields: generate: "password:24" locked_after_deploy: true +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true + # --- App info (info page content) --- app_info: tagline: 'Modern wiki és dokumentáció platform Notion-szerű szerkesztővel' diff --git a/templates/emby/.felhom.yml b/templates/emby/.felhom.yml index 880c1df..12b51f4 100644 --- a/templates/emby/.felhom.yml +++ b/templates/emby/.felhom.yml @@ -49,6 +49,10 @@ deploy_fields: description: "A külső merevlemez elérési útja" locked_after_deploy: true +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true + # --- App info (info page content) --- app_info: tagline: "Személyes média szerver élő TV és DVR támogatással" diff --git a/templates/ghost/.felhom.yml b/templates/ghost/.felhom.yml index b19dea2..a9d57b0 100644 --- a/templates/ghost/.felhom.yml +++ b/templates/ghost/.felhom.yml @@ -37,6 +37,10 @@ deploy_fields: locked_after_deploy: true description: "Az alkalmazás aldomainje" +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true + # --- App info (info page content) --- app_info: tagline: "Professzionális blog és hírlevél platform" diff --git a/templates/gitea/.felhom.yml b/templates/gitea/.felhom.yml index 30a3bb9..e8b801b 100644 --- a/templates/gitea/.felhom.yml +++ b/templates/gitea/.felhom.yml @@ -35,9 +35,16 @@ deploy_fields: locked_after_deploy: true description: "Az alkalmazás aldomainje" +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true +# Decision 47: the app's own sign-up address is closed once the gate opens (measured on 9202 2026-09-29: /user/sign_up served the registration form after the setup). +signup_block: "PathPrefix(`/user/sign_up`)" + # --- App info (info page content) --- app_info: tagline: "Saját Git szerver - GitHub-szerű felület, privát repók" + add_people: "Webhely adminisztráció → Felhasználói fiókok → Új felhasználói fiók létrehozása." docs_url: "https://docs.gitea.com/" use_cases: @@ -88,6 +95,7 @@ i18n: description: 'A light Git server of your own, with a web interface' app_info: tagline: 'Your own Git server - a GitHub-like interface and private repositories' + add_people: "Site Administration → User Accounts → Create User Account." use_cases: - 'Private Git repositories on your own server' - 'A GitHub-like interface: pull requests, issues, a wiki' diff --git a/templates/gramps-web/.felhom.yml b/templates/gramps-web/.felhom.yml index 6c4f7de..285ec5b 100644 --- a/templates/gramps-web/.felhom.yml +++ b/templates/gramps-web/.felhom.yml @@ -41,9 +41,16 @@ deploy_fields: generate: "hex:32" locked_after_deploy: true +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true +# Decision 47: the app's own sign-up address is closed once the gate opens (measured on 9202 2026-09-29: the self-registration address answered (500 here); closed to be safe). +signup_block: "PathRegexp(`^/api/users/[^/]+/register/`)" + # --- App info (info page content) --- app_info: tagline: "Családfa készítő - genealógiai adatbázis webes felületen" + add_people: "Adminként: Beállítások → Felhasználók kezelése → Új felhasználó." docs_url: "https://gramps-project.github.io/web/" use_cases: @@ -74,6 +81,7 @@ i18n: description: 'Family tree and genealogy software' app_info: tagline: 'A family tree - a genealogy database with a web interface' + add_people: "As the admin: Settings → Manage users → New user." use_cases: - 'Build a family tree and see it drawn' - 'Record people, events, places and how they connect' diff --git a/templates/home-assistant/.felhom.yml b/templates/home-assistant/.felhom.yml index a504e6d..ff97fd5 100644 --- a/templates/home-assistant/.felhom.yml +++ b/templates/home-assistant/.felhom.yml @@ -35,6 +35,10 @@ deploy_fields: locked_after_deploy: true description: "Az alkalmazás aldomainje" +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true + # --- App info (info page content) --- app_info: tagline: "Okos otthon központ - automatizálás és vezérlés egy helyről" diff --git a/templates/homebox/.felhom.yml b/templates/homebox/.felhom.yml index ef277de..f8e1907 100644 --- a/templates/homebox/.felhom.yml +++ b/templates/homebox/.felhom.yml @@ -50,9 +50,16 @@ deploy_fields: locked_after_deploy: true description: "Az alkalmazás aldomainje" +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true +# Decision 47: the app's own sign-up address is closed once the gate opens (measured on 9202 2026-09-29: a stranger's sign-up succeeded after the setup). +signup_block: "PathPrefix(`/api/v1/users/register`)" + # --- App info (info page content) --- app_info: tagline: 'Otthoni leltár kezelő - tartsd számon a tárgyaidat' + add_people: "Nyisd meg a regisztrációt 15 percre, és küldd el a családtagodnak a Homebox csoport meghívó linkjét (Beállítások → Csoport → Meghívó)." docs_url: 'https://homebox.software/en/' use_cases: @@ -85,6 +92,7 @@ i18n: description: 'A home inventory for your things' app_info: tagline: 'A home inventory - keep track of what you own' + add_people: "Open sign-up for 15 minutes and send your family member Homebox's group invite link (Settings → Group → Invite)." use_cases: - 'List and keep track of the things in your home' - 'Sort by location, tag and category' diff --git a/templates/jellyfin/.felhom.yml b/templates/jellyfin/.felhom.yml index ed7baa7..505ee1a 100644 --- a/templates/jellyfin/.felhom.yml +++ b/templates/jellyfin/.felhom.yml @@ -49,6 +49,15 @@ deploy_fields: description: "A külső merevlemez elérési útja, ahol a filmek, sorozatok és zenék tárolódnak" locked_after_deploy: true +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true +# measured on 9202 2026-09-29: StartupWizardCompleted false -> true after the startup wizard. +setup_done_probe: + url: http://jellyfin:8096/System/Info/Public + field: StartupWizardCompleted + done: "true" + # --- App info (info page content) --- app_info: tagline: "Ingyenes média szerver - filmek, sorozatok és zene streamelése" diff --git a/templates/komga/.felhom.yml b/templates/komga/.felhom.yml index 0a2aa50..4c9d91f 100644 --- a/templates/komga/.felhom.yml +++ b/templates/komga/.felhom.yml @@ -49,6 +49,15 @@ deploy_fields: description: "A külső merevlemez elérési útja" locked_after_deploy: true +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true +# measured on 9202 2026-09-29: isClaimed false -> true once the admin claimed it. +setup_done_probe: + url: http://komga:25600/api/v1/claim + field: isClaimed + done: "true" + # --- App info (info page content) --- app_info: tagline: "Képregény, manga és könyv szerver webes olvasóval" diff --git a/templates/navidrome/.felhom.yml b/templates/navidrome/.felhom.yml index 9b13d91..225e847 100644 --- a/templates/navidrome/.felhom.yml +++ b/templates/navidrome/.felhom.yml @@ -49,6 +49,10 @@ deploy_fields: description: "A külső merevlemez elérési útja, ahol a zenefájlok tárolódnak" locked_after_deploy: true +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true + # --- App info (info page content) --- app_info: tagline: "Könnyű zene szerver - streameld a saját zenegyűjteményedet" diff --git a/templates/opengist/.felhom.yml b/templates/opengist/.felhom.yml index f13bd14..3fcd034 100644 --- a/templates/opengist/.felhom.yml +++ b/templates/opengist/.felhom.yml @@ -35,9 +35,16 @@ deploy_fields: locked_after_deploy: true description: "Az alkalmazás aldomainje" +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true +# Decision 47: the app's own sign-up address is closed once the gate opens (measured on 9202 2026-09-29: a stranger's sign-up succeeded after the setup). +signup_block: "PathPrefix(`/-/register`)" + # --- App info (info page content) --- app_info: tagline: "Kód snippetek megosztása - privát GitHub Gist alternatíva" + add_people: "Nyisd meg a regisztrációt 15 percre, és a családtagod regisztrál." docs_url: "https://github.com/thomiceli/opengist" use_cases: @@ -71,6 +78,7 @@ i18n: description: 'Share code snippets (a GitHub Gist alternative)' app_info: tagline: 'Share code snippets - a private GitHub Gist alternative' + add_people: "Open sign-up for 15 minutes, and your family member signs up." use_cases: - 'Share code snippets and pieces of text' - 'Syntax highlighting for many languages' diff --git a/templates/outline/.felhom.yml b/templates/outline/.felhom.yml index 571b40f..2e1033a 100644 --- a/templates/outline/.felhom.yml +++ b/templates/outline/.felhom.yml @@ -53,6 +53,10 @@ deploy_fields: generate: "password:24" locked_after_deploy: true +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true + # --- App info (info page content) --- app_info: tagline: "Modern tudásbázis - Markdown, valós idejű együttműködés, keresés" diff --git a/templates/papra/.felhom.yml b/templates/papra/.felhom.yml index 014e180..a828d02 100644 --- a/templates/papra/.felhom.yml +++ b/templates/papra/.felhom.yml @@ -46,9 +46,16 @@ deploy_fields: data_key: true description: "Az alkalmazás aldomainje" +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true +# Decision 47: the app's own sign-up address is closed once the gate opens (measured on 9202 2026-09-29: a stranger's sign-up succeeded after the setup). +signup_block: "PathPrefix(`/api/auth/sign-up`)" + # --- App info (info page content) --- app_info: tagline: "Minimalista dokumentumtár - egyszerű rendszerezés és keresés" + add_people: "Nyisd meg a regisztrációt 15 percre; a családtagod regisztrál, aztán meghívod a szervezetedbe (Szervezet → Tagok → Meghívás)." docs_url: "https://docs.papra.app/" use_cases: @@ -77,6 +84,7 @@ i18n: description: 'A minimalist document store and organiser' app_info: tagline: 'A minimalist document store - simple sorting and search' + add_people: "Open sign-up for 15 minutes; your family member signs up, then you invite them into your organization (Organization → Members → Invite)." use_cases: - 'Upload and sort documents without fuss' - 'Search across your documents quickly' diff --git a/templates/plant-it/.felhom.yml b/templates/plant-it/.felhom.yml index 86dcef1..9a330b1 100644 --- a/templates/plant-it/.felhom.yml +++ b/templates/plant-it/.felhom.yml @@ -54,6 +54,10 @@ deploy_fields: generate: "hex:32" locked_after_deploy: true +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true + # --- App info (info page content) --- app_info: tagline: "Növénynapló - emlékeztetők öntözésre, trágyázásra és fotónapló" diff --git a/templates/radarr/.felhom.yml b/templates/radarr/.felhom.yml index d29d339..75e5419 100644 --- a/templates/radarr/.felhom.yml +++ b/templates/radarr/.felhom.yml @@ -51,6 +51,10 @@ deploy_fields: description: "A külső merevlemez elérési útja" locked_after_deploy: true +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true + # --- App info (info page content) --- app_info: tagline: "Automatikus film letöltő és rendszerező" diff --git a/templates/rallly/.felhom.yml b/templates/rallly/.felhom.yml index edfd7b5..b4e4018 100644 --- a/templates/rallly/.felhom.yml +++ b/templates/rallly/.felhom.yml @@ -47,6 +47,10 @@ deploy_fields: generate: "password:24" locked_after_deploy: true +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true + # --- App info (info page content) --- app_info: tagline: "Időpont szavazás - Doodle alternatíva a saját szerveren" diff --git a/templates/recipe-importer/.felhom.yml b/templates/recipe-importer/.felhom.yml index 5419b1a..c2d2ac1 100644 --- a/templates/recipe-importer/.felhom.yml +++ b/templates/recipe-importer/.felhom.yml @@ -47,6 +47,10 @@ deploy_fields: locked_after_deploy: true description: "Flask munkamenet titkos kulcs (automatikusan generált)" +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true + # --- App info (info page content) --- app_info: tagline: 'Magyar receptoldalak importálása egyszerűen — egyedi és tömeges import Mealie-be és Tandoor-ba' diff --git a/templates/romm/.felhom.yml b/templates/romm/.felhom.yml index 765317c..9c2b9f6 100644 --- a/templates/romm/.felhom.yml +++ b/templates/romm/.felhom.yml @@ -77,6 +77,15 @@ deploy_fields: description: "A külső merevlemez elérési útja, ahol a ROM-ok és borítóképek tárolódnak" locked_after_deploy: true +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true +# measured on 9202 2026-09-29: SYSTEM.SHOW_SETUP_WIZARD true -> false once the first user exists. +setup_done_probe: + url: http://romm:8080/api/heartbeat + field: SYSTEM.SHOW_SETUP_WIZARD + done: "false" + # --- App info (info page content) --- app_info: tagline: "Retró játékgyűjtemény kezelő, böngésző és lejátszó" diff --git a/templates/seerr/.felhom.yml b/templates/seerr/.felhom.yml index 0989616..349edec 100644 --- a/templates/seerr/.felhom.yml +++ b/templates/seerr/.felhom.yml @@ -35,6 +35,10 @@ deploy_fields: locked_after_deploy: true description: "Az alkalmazás aldomainje" +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true + # --- App info (info page content) --- app_info: tagline: "Film és sorozat igénylő a háztartás tagjai számára" diff --git a/templates/sonarr/.felhom.yml b/templates/sonarr/.felhom.yml index 2dea239..a7da9ac 100644 --- a/templates/sonarr/.felhom.yml +++ b/templates/sonarr/.felhom.yml @@ -51,6 +51,10 @@ deploy_fields: description: "A külső merevlemez elérési útja" locked_after_deploy: true +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true + # --- App info (info page content) --- app_info: tagline: "Automatikus sorozat letöltő és rendszerező" diff --git a/templates/sparkyfitness/.felhom.yml b/templates/sparkyfitness/.felhom.yml index ed3f0f6..95fccb9 100644 --- a/templates/sparkyfitness/.felhom.yml +++ b/templates/sparkyfitness/.felhom.yml @@ -64,8 +64,15 @@ deploy_fields: # boot — changing it locks out any user who enabled two-factor auth. data_key: true +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true +# Decision 47: the app's own sign-up address is closed once the gate opens (measured on 9202 2026-09-29: a stranger's sign-up succeeded after the setup). +signup_block: "PathPrefix(`/api/auth/sign-up`)" + app_info: tagline: "Táplálkozási napló, kalóriaszámláló és edzéskövető – önállóan üzemeltetve" + add_people: "Nyisd meg a regisztrációt 15 percre, és a családtagod regisztrál." docs_url: "https://github.com/CodeWithCJ/SparkyFitness" use_cases: @@ -98,6 +105,7 @@ i18n: description: 'A food and exercise tracker' app_info: tagline: 'A food diary, calorie counter and exercise tracker - on your own server' + add_people: "Open sign-up for 15 minutes, and your family member signs up." use_cases: - 'Log what you eat and how many calories it comes to' - 'Track your weight and measurements on a graph' diff --git a/templates/tandoor/.felhom.yml b/templates/tandoor/.felhom.yml index a338ab5..7f3adc3 100644 --- a/templates/tandoor/.felhom.yml +++ b/templates/tandoor/.felhom.yml @@ -47,6 +47,10 @@ deploy_fields: generate: "password:24" locked_after_deploy: true +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true + # --- App info (info page content) --- app_info: tagline: "Receptkezelő és étkezés tervező a családnak" diff --git a/templates/termix/.felhom.yml b/templates/termix/.felhom.yml index 0659bf1..8fd3e84 100644 --- a/templates/termix/.felhom.yml +++ b/templates/termix/.felhom.yml @@ -35,9 +35,21 @@ deploy_fields: locked_after_deploy: true description: "Az alkalmazás aldomainje" +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true +# measured on 9202 2026-09-29: setup_required true -> false once the first user exists. +setup_done_probe: + url: http://termix:8080/users/setup-required + field: setup_required + done: "false" +# Decision 47: the app's own sign-up address is closed once the gate opens (measured on 9202 2026-09-29: a stranger's sign-up succeeded after the setup). +signup_block: "PathPrefix(`/users/create`)" + # --- App info (info page content) --- app_info: tagline: "Webes SSH terminál - szerver hozzáférés a böngészőből" + add_people: "Nyisd meg a regisztrációt 15 percre, és a családtagod regisztrál." docs_url: "https://github.com/Termix-SSH/Termix" use_cases: @@ -64,6 +76,7 @@ i18n: description: 'SSH and server management in a browser' app_info: tagline: 'An SSH terminal in your browser - reach a server from anywhere' + add_people: "Open sign-up for 15 minutes, and your family member signs up." use_cases: - 'Reach your server over SSH from a browser' - 'No SSH client needed on the computer you are sitting at' diff --git a/templates/vikunja/.felhom.yml b/templates/vikunja/.felhom.yml index 78c7fc8..b805ed5 100644 --- a/templates/vikunja/.felhom.yml +++ b/templates/vikunja/.felhom.yml @@ -41,9 +41,16 @@ deploy_fields: generate: "hex:32" locked_after_deploy: true +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true +# Decision 47: the app's own sign-up address is closed once the gate opens (measured on 9202 2026-09-29: a stranger's sign-up succeeded after the setup). +signup_block: "PathPrefix(`/api/v1/register`)" + # --- App info (info page content) --- app_info: tagline: "Feladatkezelő - listák, Kanban táblák és Gantt diagramok" + add_people: "Nyisd meg a regisztrációt 15 percre, és a családtagod regisztrál; utána megoszthatod vele a projektjeidet." docs_url: "https://vikunja.io/docs/" use_cases: @@ -78,6 +85,7 @@ i18n: description: 'Task lists and boards (a Todoist/Trello alternative)' app_info: tagline: 'Task management - lists, Kanban boards and Gantt charts' + add_people: "Open sign-up for 15 minutes, and your family member signs up; then share your projects with them." use_cases: - 'Keep your task lists and to-dos' - 'A Kanban board view (Trello-like)' diff --git a/templates/wishlist/.felhom.yml b/templates/wishlist/.felhom.yml index 4242c6a..c496a14 100644 --- a/templates/wishlist/.felhom.yml +++ b/templates/wishlist/.felhom.yml @@ -35,9 +35,16 @@ deploy_fields: locked_after_deploy: true description: "Az alkalmazás aldomainje" +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true +# Decision 47: the app's own sign-up address is closed once the gate opens (measured on 9202 2026-09-29: a stranger's sign-up succeeded after the setup). +signup_block: "Path(`/signup`)" + # --- App info (info page content) --- app_info: tagline: "Családi kívánságlista - karácsonyra, születésnapokra" + add_people: "Nyisd meg a regisztrációt 15 percre, és a családtagod regisztrál (a Wishlist meghívó linkje is ebben az időben működik)." docs_url: "https://github.com/cmintey/wishlist" use_cases: @@ -68,6 +75,7 @@ i18n: description: 'Wish lists shared across the household' app_info: tagline: 'A family wish list - for Christmas and birthdays' + add_people: "Open sign-up for 15 minutes, and your family member signs up (Wishlist's invite link works in that time too)." use_cases: - 'Make wish lists for Christmas and birthdays' - 'Invite the household so each keeps their own list' diff --git a/templates/zipline/.felhom.yml b/templates/zipline/.felhom.yml index 68c8361..219d524 100644 --- a/templates/zipline/.felhom.yml +++ b/templates/zipline/.felhom.yml @@ -47,6 +47,15 @@ deploy_fields: generate: "password:24" locked_after_deploy: true +# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) --- +# The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done. +setup_gate: true +# measured on 9202 2026-09-29: firstSetup true -> false once the first user exists (/api/setup itself answers 403 after the setup, so it cannot be the check). +setup_done_probe: + url: http://zipline:3000/api/server/public + field: firstSetup + done: "false" + # --- App info (info page content) --- app_info: tagline: "Screenshot és fájlmegosztó szerver ShareX/Flameshot integrációval"