v0.243.0: FileBrowser generated admin password (R-513); per-tier whole-guest backup truth (R-517); skip absent-storage tiers (R-518); OOM-killed worker visible (R-514)
gates / gates (push) Successful in 14s

MinAgent: 0.131.0

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-09-15 10:12:08 +02:00
parent 406755fa8f
commit 843b319f35
23 changed files with 1095 additions and 8 deletions
+34
View File
@@ -36,6 +36,15 @@ type Settings struct {
LauncherShareToken string `json:"launcher_share_token,omitempty"`
LauncherSharePasswordHash string `json:"launcher_share_password_hash,omitempty"`
// FileBrowser admin login (R-513, v0.243.0). Every box used to accept admin/admin. The controller
// sets a generated password ONCE through FileBrowser's own API when admin/admin still works, and
// records "set by the operator" when it does not (a hand-set password is never overwritten).
// FileBrowserAdminPasswordEnc is AES-encrypted with the controller's app key (crypto.Encrypt),
// never plaintext. FileBrowserAdminState: "" (not yet decided) | "generated" | "operator".
FileBrowserAdminPasswordEnc string `json:"filebrowser_admin_password_enc,omitempty"`
FileBrowserAdminState string `json:"filebrowser_admin_state,omitempty"`
FileBrowserAdminDecidedAt string `json:"filebrowser_admin_decided_at,omitempty"` // RFC3339
// Customer-claim arc (v0.122.0, F-4). Claimed is SET-ONLY (a claim or reset completed at
// least once — never cleared). ClaimCode* cache the freshest hub-delivered code state (report
// ACK; beats controller.yaml when its generation is newer). ClaimConsumedGeneration records
@@ -834,6 +843,31 @@ func (s *Settings) SetLauncherSharePasswordHash(hash string) error {
return s.save()
}
// ── FileBrowser admin login (R-513) ─────────────────────────────────────────────
const (
FileBrowserAdminGenerated = "generated"
FileBrowserAdminOperator = "operator"
)
// GetFileBrowserAdmin returns the recorded decision: state ("" = undecided), the ENCRYPTED password
// (empty unless state is generated) and when it was decided.
func (s *Settings) GetFileBrowserAdmin() (state, passwordEnc, decidedAt string) {
s.mu.RLock()
defer s.mu.RUnlock()
return s.FileBrowserAdminState, s.FileBrowserAdminPasswordEnc, s.FileBrowserAdminDecidedAt
}
// SetFileBrowserAdmin records the decision and saves. passwordEnc must already be encrypted.
func (s *Settings) SetFileBrowserAdmin(state, passwordEnc, decidedAt string) error {
s.mu.Lock()
defer s.mu.Unlock()
s.FileBrowserAdminState = state
s.FileBrowserAdminPasswordEnc = passwordEnc
s.FileBrowserAdminDecidedAt = decidedAt
return s.save()
}
// ── Hub-held recovery package (v0.199.0, R-204 item 4) ─────────────────────────
// GetHubEscrowIdentityPresent reports whether the hub is holding a sealed identity/recovery package