60f0a86bd4
gates / gates (push) Successful in 25s
The READ PATH for a second language in `.felhom.yml`. An `i18n: {en: …}` sibling
block inside the same file; `Metadata.For(lang)` merges it FIELD BY FIELD over the
Hungarian, so a missing or blank English field shows the Hungarian one and a
half-translated app is a legal, shippable state.
`For("hu")` is the parsed struct with `I18n` cleared and nothing else — measured
against all 53 real catalog files, copied into `internal/stacks/testdata/catalog/`.
Lists replace whole; every other list is matched by its own key, never by position.
`For` never writes through the receiver: the metadata is the stack manager's, shared
by concurrent requests, and an in-place merge would leak one household's language
into another household's page.
Pages reach catalog copy only through `LocalizeStacks`/`LocalizeStackPtr`/`MetaFor`,
and `TestNoDirectMetaCopyReadOnPages` keeps a named, reasoned allow-list of every
direct `.Meta.<copy>` read in `internal/web` so the NEXT page to read one fails the
suite instead of quietly rendering Hungarian to an English household.
Eight red-proofs. Two of them convicted a hollow TEST rather than the code: a struct
copy shares its slices' backing arrays, so the obvious DeepEqual mutation check
passed a deliberately broken merge; and a one-entry fixture cannot tell key matching
from position matching. Both rewritten, both then seen to fail.
MinAgent: 0.131.0 (unchanged). Older controllers are unaffected — `LoadMetadata`
uses non-strict `yaml.Unmarshal`, so a pre-0.257.0 box drops the whole block.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
113 lines
4.4 KiB
YAML
113 lines
4.4 KiB
YAML
# =============================================================================
|
||
# .felhom.yml — App metadata for felhom-controller
|
||
# =============================================================================
|
||
# Place alongside docker-compose.yml in each stack directory:
|
||
# /opt/docker/stacks/vaultwarden/.felhom.yml
|
||
# =============================================================================
|
||
|
||
# --- Display info (shown on dashboard) ---
|
||
display_name: "Vaultwarden"
|
||
description: "Jelszókezelő (Bitwarden-kompatibilis)"
|
||
category: "security"
|
||
subdomain: "vault"
|
||
|
||
# --- Asset slug ---
|
||
slug: "vaultwarden"
|
||
# catalog_since: the date THIS repo last changed this app's pinned images. Any commit that
|
||
# changes an image: line must set this to the same day (see CLAUDE.md).
|
||
catalog_since: "2026-07-18"
|
||
|
||
# --- Resource hints (displayed on deploy screen) ---
|
||
resources:
|
||
mem_request: "50M"
|
||
mem_limit: "256M"
|
||
pi_compatible: true
|
||
needs_hdd: false
|
||
|
||
# --- Deploy fields ---
|
||
deploy_fields:
|
||
- env_var: DOMAIN
|
||
label: "Domain"
|
||
type: domain
|
||
description: "A szerver domain neve"
|
||
locked_after_deploy: true
|
||
|
||
- env_var: SUBDOMAIN
|
||
label: "Aldomain"
|
||
type: subdomain
|
||
default: "vault"
|
||
required: true
|
||
locked_after_deploy: true
|
||
description: "Az alkalmazás aldomainje"
|
||
|
||
- env_var: ADMIN_TOKEN
|
||
label: "Admin panel token"
|
||
type: secret
|
||
generate: "hex:32"
|
||
description: "Token az admin panel eléréséhez (https://vault.<domain>/admin)"
|
||
locked_after_deploy: true
|
||
|
||
- env_var: SIGNUPS_ALLOWED
|
||
label: "Regisztráció engedélyezése"
|
||
type: select
|
||
default: "false"
|
||
options:
|
||
- value: "false"
|
||
label: "Nem – csak meghívással (ajánlott)"
|
||
- value: "true"
|
||
label: "Igen – bárki regisztrálhat, aki ismeri a címet"
|
||
description: "Alapból lezárva: a család tagjait az admin panelen hívod meg (lásd Első lépések). Nyitott regisztrációval bárki fiókot nyithat, aki kitalálja a címet."
|
||
locked_after_deploy: false
|
||
|
||
# --- App info (info page content) ---
|
||
app_info:
|
||
tagline: 'Jelszókezelő - Bitwarden kompatibilis, a saját szerveren'
|
||
docs_url: 'https://github.com/dani-garcia/vaultwarden/wiki'
|
||
|
||
use_cases:
|
||
- 'Jelszavak biztonságos tárolása és automatikus kitöltése'
|
||
- 'Bitwarden kliensek teljes kompatibilitása (böngésző, mobil, asztali)'
|
||
- 'Jelszavak megosztása családtagokkal szervezeten belül'
|
||
- 'Kétfaktoros hitelesítés (TOTP) kódok tárolása'
|
||
- 'Biztonságos jegyzetek és bankkártya adatok tárolása'
|
||
|
||
first_steps:
|
||
- 'Nyisd meg a vault.DOMAIN/admin címet, és lépj be az admin panel tokenjével (Beállítások → Automatikusan generált értékek)'
|
||
- 'A „Users" fülön az „Invite User" mezőben hívd meg a saját és a családtagok e-mail címét — a regisztráció alapból le van zárva, csak meghívott cím nyithat fiókot'
|
||
- 'Nyisd meg a vault.DOMAIN címet, válaszd a „Create account" lehetőséget a meghívott címmel, és adj meg erős mesterjelszót'
|
||
- 'Telepítsd a Bitwarden bővítményt a böngésződbe'
|
||
- 'Telepítsd a Bitwarden alkalmazást a telefonodra'
|
||
- 'Importáld a meglévő jelszavaidat (Chrome, Firefox, LastPass, stb.)'
|
||
|
||
|
||
# --- Controller-side health probe ---
|
||
healthcheck:
|
||
checks:
|
||
- type: api
|
||
port: 80
|
||
path: "/alive"
|
||
expect:
|
||
status: 200
|
||
|
||
# --- App-email mapping (apps → in-controller shim → hub → Resend) ---
|
||
# When app-email is on (global toggle + this app's per-app toggle), the controller injects
|
||
# the relay SMTP settings: host = the on-box shim, port = 2525, From = vaultwarden@felhom.eu.
|
||
# Vaultwarden uses STARTTLS to the shim and accepts its self-signed cert
|
||
# (SMTP_ACCEPT_INVALID_CERTS/HOSTNAMES). SMTP_USERNAME/SMTP_PASSWORD are intentionally left
|
||
# unset — the shim accepts no-auth on the Docker network and holds no Resend key.
|
||
smtp_mapping:
|
||
host_var: SMTP_HOST
|
||
port_var: SMTP_PORT
|
||
security_var: SMTP_SECURITY
|
||
security_value: starttls
|
||
from_var: SMTP_FROM
|
||
from_name_var: SMTP_FROM_NAME
|
||
from_local: vaultwarden
|
||
extra:
|
||
SMTP_ACCEPT_INVALID_CERTS: "true"
|
||
SMTP_ACCEPT_INVALID_HOSTNAMES: "true"
|
||
# Boot-gate for Vaultwarden's strict SMTP validation (campaign finding F1, 2026-07-06):
|
||
# the image errors out when SMTP_HOST/SMTP_FROM are defined-but-empty, so the compose
|
||
# default is _ENABLE_SMTP=false and this injection flips it on with the rest of the group.
|
||
_ENABLE_SMTP: "true"
|