package main import ( "encoding/json" "net/mail" "strings" "github.com/abhinavxd/libredesk/internal/envelope" "github.com/abhinavxd/libredesk/internal/setting/models" "github.com/abhinavxd/libredesk/internal/stringutil" "github.com/valyala/fasthttp" "github.com/zerodha/fastglue" ) // handleGetGeneralSettings fetches general settings, this endpoint is not behind auth as it has no sensitive data and is required for the app to function. func handleGetGeneralSettings(r *fastglue.Request) error { var ( app = r.Context.(*App) ) out, err := app.setting.GetByPrefix("app") if err != nil { return sendErrorEnvelope(r, err) } // Unmarshal to set the app.update to the settings, so the frontend can show that an update is available. var settings map[string]interface{} if err := json.Unmarshal(out, &settings); err != nil { app.lo.Error("error unmarshalling settings", "err", err) return sendErrorEnvelope(r, envelope.NewError(envelope.GeneralError, app.i18n.Ts("globals.messages.errorFetching", "name", app.i18n.T("globals.terms.setting")), nil)) } // Set the app.update to the settings, adding `app` prefix to the key to match the settings structure in db. settings["app.update"] = app.update // Set app version. settings["app.version"] = versionString // Set restart required flag. settings["app.restart_required"] = app.restartRequired return r.SendEnvelope(settings) } // handleUpdateGeneralSettings updates general settings. func handleUpdateGeneralSettings(r *fastglue.Request) error { var ( app = r.Context.(*App) req = models.General{} ) if err := r.Decode(&req, "json"); err != nil { return r.SendErrorEnvelope(fasthttp.StatusBadRequest, app.i18n.T("globals.messages.badRequest"), nil, envelope.InputError) } // Get current language before update. app.Lock() oldLang := ko.String("app.lang") app.Unlock() // Remove any trailing slash `/` from the root url. req.RootURL = strings.TrimRight(req.RootURL, "/") if err := app.setting.Update(req); err != nil { return sendErrorEnvelope(r, err) } // Reload the settings and templates. if err := reloadSettings(app); err != nil { return envelope.NewError(envelope.GeneralError, app.i18n.Ts("globals.messages.couldNotReload", "name", app.i18n.T("globals.terms.setting")), nil) } // Check if language changed and reload i18n if needed. app.Lock() newLang := ko.String("app.lang") if oldLang != newLang { app.lo.Info("language changed, reloading i18n", "old_lang", oldLang, "new_lang", newLang) app.i18n = initI18n(app.fs) app.lo.Info("reloaded i18n", "old_lang", oldLang, "new_lang", newLang) } app.Unlock() if err := reloadTemplates(app); err != nil { return envelope.NewError(envelope.GeneralError, app.i18n.Ts("globals.messages.couldNotReload", "name", app.i18n.T("globals.terms.setting")), nil) } return r.SendEnvelope(true) } // handleGetEmailNotificationSettings fetches email notification settings. func handleGetEmailNotificationSettings(r *fastglue.Request) error { var ( app = r.Context.(*App) notif = models.EmailNotification{} ) out, err := app.setting.GetByPrefix("notification.email") if err != nil { return sendErrorEnvelope(r, err) } // Unmarshal and filter out password. if err := json.Unmarshal(out, ¬if); err != nil { return sendErrorEnvelope(r, envelope.NewError(envelope.GeneralError, app.i18n.Ts("globals.messages.errorFetching", "name", app.i18n.T("globals.terms.setting")), nil)) } if notif.Password != "" { notif.Password = strings.Repeat(stringutil.PasswordDummy, 10) } return r.SendEnvelope(notif) } // handleUpdateEmailNotificationSettings updates email notification settings. func handleUpdateEmailNotificationSettings(r *fastglue.Request) error { var ( app = r.Context.(*App) req = models.EmailNotification{} cur = models.EmailNotification{} ) if err := r.Decode(&req, "json"); err != nil { return r.SendErrorEnvelope(fasthttp.StatusBadRequest, app.i18n.T("globals.messages.badRequest"), nil, envelope.InputError) } out, err := app.setting.GetByPrefix("notification.email") if err != nil { return sendErrorEnvelope(r, err) } if err := json.Unmarshal(out, &cur); err != nil { return sendErrorEnvelope(r, envelope.NewError(envelope.GeneralError, app.i18n.Ts("globals.messages.errorUpdating", "name", app.i18n.T("globals.terms.setting")), nil)) } // Make sure it's a valid from email address. if _, err := mail.ParseAddress(req.EmailAddress); err != nil { return r.SendErrorEnvelope(fasthttp.StatusBadRequest, app.i18n.T("globals.messages.invalidFromAddress"), nil, envelope.InputError) } // If empty then retain previous password. if req.Password == "" { req.Password = cur.Password } if err := app.setting.Update(req); err != nil { return sendErrorEnvelope(r, err) } // Email notification settings require app restart to take effect. app.Lock() app.restartRequired = true app.Unlock() return r.SendEnvelope(true) }