controller: F-15 instant reset codes — reset-request response hash applied via the ACK's generation-guarded ClaimSync (emailed code works immediately; old-hub bare response = no-op)
Claude-Session: https://claude.ai/code/session_01GzammAMzsJTgpQHqxwM2bC
This commit is contained in:
@@ -8,11 +8,13 @@ import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gitea.dooplex.hu/admin/felhom-controller/internal/report"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
@@ -369,6 +371,10 @@ func (s *Server) handleClaimRequestNewCode(w http.ResponseWriter, r *http.Reques
|
||||
}
|
||||
|
||||
// requestHubResetCode calls POST /api/v1/claim/reset-request with the box's own report key.
|
||||
// v0.123.0 (take-two F-15): a hub ≥0.52.0 returns the freshly rotated code state in the response;
|
||||
// it is applied through the SAME generation-guarded consumer as the report ACK (ClaimSync), so the
|
||||
// emailed code works the moment it lands instead of after the next ACK (~15 min). An old hub's
|
||||
// bare {"status":"ok"} response is a clean no-op (no claim object → Reconcile skips).
|
||||
func (s *Server) requestHubResetCode() {
|
||||
if s.cfg.Hub.URL == "" || s.cfg.Hub.APIKey == "" {
|
||||
s.logger.Printf("[WARN] [web] claim: cannot request a new code — hub URL/key not configured")
|
||||
@@ -388,12 +394,23 @@ func (s *Server) requestHubResetCode() {
|
||||
s.logger.Printf("[ERROR] [web] claim: reset-request to hub failed: %v", err)
|
||||
return
|
||||
}
|
||||
resp.Body.Close()
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||
s.logger.Printf("[WARN] [web] claim: hub reset-request returned HTTP %d", resp.StatusCode)
|
||||
return
|
||||
}
|
||||
s.logger.Printf("[INFO] [web] claim: requested a fresh code from the hub for %s", s.cfg.Customer.ID)
|
||||
var payload struct {
|
||||
Claim *report.ClaimStatus `json:"claim"`
|
||||
}
|
||||
if err := json.NewDecoder(io.LimitReader(resp.Body, 64<<10)).Decode(&payload); err != nil {
|
||||
s.logger.Printf("[WARN] [web] claim: parsing reset-request response failed (code arrives via the next ACK): %v", err)
|
||||
return
|
||||
}
|
||||
if payload.Claim != nil && s.settings != nil {
|
||||
sync := &report.ClaimSync{Settings: s.settings, Logger: s.logger}
|
||||
sync.Reconcile(payload.Claim)
|
||||
}
|
||||
}
|
||||
|
||||
// PrintLocalResetCode is the root escape hatch (v0.122.0, --print-reset-code): generate a fresh
|
||||
|
||||
Reference in New Issue
Block a user