1package daemon23import (4 "context"5 "database/sql"6 "encoding/json"7 "errors"8 "io"9 "net/http"10 "strings"11)1213const chatSharePresenceSetting = "account.chat.share_presence."1415type chatPreferences struct {16 SharePresence bool `json:"share_presence"`17}1819func chatPreferenceKey(actor string) string {20 return chatSharePresenceSetting + actor21}2223func (t *Tenant) chatPreferencesHTTP(w http.ResponseWriter, r *http.Request) {24 w.Header().Set("Cache-Control", "private, no-store")25 r.Body = http.MaxBytesReader(w, r.Body, 4096)26 actor, err := t.resolveUIActor(r)27 if err != nil || actor == "" {28 http.Error(w, "authentication required", http.StatusUnauthorized)29 return30 }31 key := chatPreferenceKey(actor)32 if r.Method == http.MethodGet || r.Method == http.MethodHead {33 preferences := chatPreferences{}34 if err := t.store.GetSetting(r.Context(), key, &preferences); err != nil && !errors.Is(err, sql.ErrNoRows) {35 http.Error(w, "could not read chat preferences", http.StatusInternalServerError)36 return37 }38 writeJSON(w, http.StatusOK, preferences)39 return40 }41 if r.Method != http.MethodPost {42 w.Header().Set("Allow", "GET, HEAD, POST")43 w.WriteHeader(http.StatusMethodNotAllowed)44 return45 }46 var preferences chatPreferences47 decoder := json.NewDecoder(r.Body)48 decoder.DisallowUnknownFields()49 if err := decoder.Decode(&preferences); err != nil {50 http.Error(w, "invalid chat preferences", http.StatusBadRequest)51 return52 }53 var extra any54 if err := decoder.Decode(&extra); err != io.EOF {55 http.Error(w, "invalid chat preferences", http.StatusBadRequest)56 return57 }58 if err := t.store.PutSetting(r.Context(), key, preferences); err != nil {59 http.Error(w, "could not save chat preferences", http.StatusInternalServerError)60 return61 }62 writeJSON(w, http.StatusOK, preferences)63}6465func (t *Tenant) chatSharePresence(ctx context.Context, actor string) bool {66 if strings.TrimSpace(actor) == "" {67 return false68 }69 var preferences chatPreferences70 if err := t.store.GetSetting(ctx, chatPreferenceKey(actor), &preferences); err != nil {71 return false72 }73 return preferences.SharePresence74}