package web // The trusted setting modes (novox/hq ADR 0515 §4, issue 1859): which accounts Work and Personal each show, // by the accounts' names in mail-store; Everything shows every granted account and is not set. Read fresh // each time the page asks, like operators (config.go): a setting that cannot be read shows nothing in Work or // Personal and says why, never another mode's mail. import ( "encoding/json" "errors" "fmt" "os" "strings" ) // ModesFile is the setting as the mesh writes it. type ModesFile struct { Modes map[string][]string `json:"modes"` } // ReadModes reads the setting modes: only work and personal, each a list of account names. func ReadModes(path string) (map[string][]string, error) { if path == "" { return nil, errors.New("the module was started without its modes setting (MESH_MAIL_WEB_MODES)") } raw, err := os.ReadFile(path) if err != nil { return nil, fmt.Errorf("the modes setting cannot be read: %w", err) } dec := json.NewDecoder(strings.NewReader(string(raw))) dec.DisallowUnknownFields() var f ModesFile if err := dec.Decode(&f); err != nil { return nil, fmt.Errorf("the modes setting is not the module's: %w", err) } for name := range f.Modes { if name != "work" && name != "personal" { return nil, fmt.Errorf("the modes setting names the mode %q; it sets work and personal alone", name) } } return f.Modes, nil } // modeAccounts answers the accounts mode shows — nil for Everything, every granted account — or why it shows // none. func (b *Bundle) modeAccounts(mode Mode) ([]string, string) { if mode.Name == "everything" { return nil, "" } read := func() (map[string][]string, error) { return ReadModes(b.Env.Modes) } if b.ModesSetting != nil { read = b.ModesSetting } modes, err := read() if err != nil { return nil, err.Error() + "; " + mode.Label + " shows nothing until it can be." } accounts := modes[mode.Name] if len(accounts) == 0 { return nil, "The setting modes names no account for " + mode.Label + "; Everything shows every account." } return accounts, "" }