72 lines
3.1 KiB
Go
72 lines
3.1 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
)
|
|
|
|
// R-1199 reopened (2026-10-22). See store/household_prefs.go for the measured case (demo-felhom's list overwritten by
|
|
// controller 0.338.0's start-up default push). Two halves live here:
|
|
//
|
|
// - prefsPushIsHousehold: which pushes are the household's own save. A controller ≥ 0.339.0 says so (`source`). An
|
|
// older one does not: its pushes with an address or a clear are the household's (only a saved list carries
|
|
// them, R-922); a push with neither is either a page save without an address or 0.338.0's default push, and the
|
|
// two cannot be told apart — it is treated as NOT the household's, so it never overwrites a household's list
|
|
// (the cost: on a box still on ≤ 0.338.0, a household that saves without an address does not change a list it
|
|
// saved earlier, until the box takes the release that sends `source`).
|
|
// - handleGetPreferences: a box with no local list reads the household's list and adopts it, instead of pushing
|
|
// its default over it. Self-scoped like the save: a per-customer key reads only its own customer.
|
|
//
|
|
// Pinned by TestR1199Reopened_* (household_prefs_test.go).
|
|
func prefsPushIsHousehold(source, email string, emailCleared bool) bool {
|
|
switch source {
|
|
case "household":
|
|
return true
|
|
case "default":
|
|
return false
|
|
}
|
|
return email != "" || emailCleared
|
|
}
|
|
|
|
// handleGetPreferences answers GET /api/v1/preferences?customer_id=<id> with the stored list and whether the
|
|
// household saved it. `exists` false = no row. The address is returned only to the household's own box key (or the
|
|
// global key) — the box shows it on its own page.
|
|
func (h *Handler) handleGetPreferences(w http.ResponseWriter, r *http.Request) {
|
|
authCustomerID, isGlobal, ok := h.checkAuthCustomer(r)
|
|
if !ok {
|
|
http.Error(w, "Unauthorized", http.StatusUnauthorized)
|
|
return
|
|
}
|
|
customerID := r.URL.Query().Get("customer_id")
|
|
if customerID == "" {
|
|
http.Error(w, "customer_id required", http.StatusBadRequest)
|
|
return
|
|
}
|
|
if !isGlobal && authCustomerID != customerID {
|
|
http.Error(w, "Forbidden: customer_id does not match the key", http.StatusForbidden)
|
|
return
|
|
}
|
|
prefs, err := h.store.GetNotificationPrefs(customerID)
|
|
if err != nil {
|
|
h.logger.Printf("[ERROR] Reading notification prefs for %s: %v", customerID, err)
|
|
http.Error(w, "Internal error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
out := struct {
|
|
Exists bool `json:"exists"`
|
|
HouseholdSaved bool `json:"household_saved"`
|
|
Email string `json:"email"`
|
|
EnabledEvents []string `json:"enabled_events"`
|
|
CooldownHours int `json:"cooldown_hours"`
|
|
}{EnabledEvents: []string{}}
|
|
if prefs != nil {
|
|
out.Exists, out.HouseholdSaved, out.Email, out.CooldownHours = true, prefs.HouseholdSaved, prefs.Email, prefs.CooldownHours
|
|
if prefs.EnabledEvents != nil {
|
|
out.EnabledEvents = prefs.EnabledEvents
|
|
}
|
|
}
|
|
h.logger.Printf("[DEBUG] Notification prefs read for %s: exists=%t household_saved=%t", customerID, out.Exists, out.HouseholdSaved)
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(out)
|
|
}
|