Compare commits
No commits in common. "8b681922f6b5f450feab8a15aecb9ce657cc6088" and "82c00b9a01902fac7f7610c21c1ad3693191a0da" have entirely different histories.
8b681922f6
...
82c00b9a01
@ -147,7 +147,7 @@ func (app *application) putUserSettings(w http.ResponseWriter, r *http.Request)
|
|||||||
}
|
}
|
||||||
form.CheckField(validator.PermittedValue(form.LocalTimezone, app.timezones...), "timezone", "Invalid value")
|
form.CheckField(validator.PermittedValue(form.LocalTimezone, app.timezones...), "timezone", "Invalid value")
|
||||||
if !form.Valid() {
|
if !form.Valid() {
|
||||||
// TODO: rerender template with errors
|
// rerender template with errors
|
||||||
app.clientError(w, http.StatusUnprocessableEntity)
|
app.clientError(w, http.StatusUnprocessableEntity)
|
||||||
}
|
}
|
||||||
err = app.users.SetLocalTimezone(userId, form.LocalTimezone)
|
err = app.users.SetLocalTimezone(userId, form.LocalTimezone)
|
||||||
|
@ -59,19 +59,13 @@ func main() {
|
|||||||
sessionManager: sessionManager,
|
sessionManager: sessionManager,
|
||||||
websites: &models.WebsiteModel{DB: db},
|
websites: &models.WebsiteModel{DB: db},
|
||||||
guestbooks: &models.GuestbookModel{DB: db},
|
guestbooks: &models.GuestbookModel{DB: db},
|
||||||
users: &models.UserModel{DB: db, Settings: make(map[string]models.Setting)},
|
users: &models.UserModel{DB: db},
|
||||||
guestbookComments: &models.GuestbookCommentModel{DB: db},
|
guestbookComments: &models.GuestbookCommentModel{DB: db},
|
||||||
formDecoder: formDecoder,
|
formDecoder: formDecoder,
|
||||||
debug: *debug,
|
debug: *debug,
|
||||||
timezones: getAvailableTimezones(),
|
timezones: getAvailableTimezones(),
|
||||||
}
|
}
|
||||||
|
|
||||||
err = app.users.InitializeSettingsMap()
|
|
||||||
if err != nil {
|
|
||||||
logger.Error(err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
tlsConfig := &tls.Config{
|
tlsConfig := &tls.Config{
|
||||||
CurvePreferences: []tls.CurveID{tls.X25519, tls.CurveP256},
|
CurvePreferences: []tls.CurveID{tls.X25519, tls.CurveP256},
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ CREATE TABLE user_settings (
|
|||||||
Id integer primary key autoincrement,
|
Id integer primary key autoincrement,
|
||||||
UserId integer NOT NULL,
|
UserId integer NOT NULL,
|
||||||
SettingId integer NOT NULL,
|
SettingId integer NOT NULL,
|
||||||
AllowedSettingValueId integer,
|
AllowedSettingValueId integer NOT NULL,
|
||||||
UnconstrainedValue varchar(256),
|
UnconstrainedValue varchar(256),
|
||||||
FOREIGN KEY (UserId) REFERENCES users(Id)
|
FOREIGN KEY (UserId) REFERENCES users(Id)
|
||||||
ON DELETE RESTRICT
|
ON DELETE RESTRICT
|
||||||
@ -55,7 +55,7 @@ CREATE TABLE guestbook_settings (
|
|||||||
Id integer primary key autoincrement,
|
Id integer primary key autoincrement,
|
||||||
GuestbookId integer NOT NULL,
|
GuestbookId integer NOT NULL,
|
||||||
SettingId integer NOT NULL,
|
SettingId integer NOT NULL,
|
||||||
AllowedSettingValueId integer,
|
AllowedSettingValueId integer NOT NULL,
|
||||||
UnconstrainedValue varchar(256),
|
UnconstrainedValue varchar(256),
|
||||||
FOREIGN KEY (GuestbookId) REFERENCES guestbooks(Id)
|
FOREIGN KEY (GuestbookId) REFERENCES guestbooks(Id)
|
||||||
ON DELETE RESTRICT
|
ON DELETE RESTRICT
|
||||||
|
@ -3,11 +3,9 @@ package models
|
|||||||
import "errors"
|
import "errors"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrNoRecord = errors.New("models: no matching record found")
|
ErrNoRecord = errors.New("models: no matching record found")
|
||||||
|
|
||||||
ErrInvalidCredentials = errors.New("models: invalid credentials")
|
ErrInvalidCredentials = errors.New("models: invalid credentials")
|
||||||
|
|
||||||
ErrDuplicateEmail = errors.New("models: duplicate email")
|
ErrDuplicateEmail = errors.New("models: duplicate email")
|
||||||
|
|
||||||
ErrInvalidSettingValue = errors.New("models: invalid setting value")
|
|
||||||
)
|
)
|
||||||
|
@ -5,14 +5,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type GuestbookSettings struct {
|
|
||||||
IsCommentingEnabled bool
|
|
||||||
ReenableCommenting time.Time
|
|
||||||
IsVisible bool
|
|
||||||
FilteredWords []string
|
|
||||||
AllowRemoteHostAccess bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type Guestbook struct {
|
type Guestbook struct {
|
||||||
ID int64
|
ID int64
|
||||||
ShortId uint64
|
ShortId uint64
|
||||||
@ -21,7 +13,6 @@ type Guestbook struct {
|
|||||||
Created time.Time
|
Created time.Time
|
||||||
Deleted time.Time
|
Deleted time.Time
|
||||||
IsActive bool
|
IsActive bool
|
||||||
Settings GuestbookSettings
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type GuestbookModel struct {
|
type GuestbookModel struct {
|
||||||
@ -79,47 +70,3 @@ func (m *GuestbookModel) GetAll(userId int64) ([]Guestbook, error) {
|
|||||||
}
|
}
|
||||||
return guestbooks, nil
|
return guestbooks, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *GuestbookModel) initializeGuestbookSettings(guestbookId int64, settings UserSettings) error {
|
|
||||||
stmt := `INSERT INTO guestbook_settings (GuestbookId, SettingId, AllowedSettingValueId, UnconstrainedValue) VALUES
|
|
||||||
(?, ?, ?, ?),
|
|
||||||
(?, ?, ?, ?),
|
|
||||||
(?, ?, ?, ?),
|
|
||||||
(?, ?, ?, ?),
|
|
||||||
(?, ?, ?, ?)`
|
|
||||||
_ = len(stmt)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *GuestbookModel) UpdateSetting(guestbookId int64, value string) {
|
|
||||||
stmt := `UPDATE guestbook_settings SET
|
|
||||||
AllowedSettingValueId=IFNULL((SELECT Id FROM allowed_setting_values WHERE SettingId = guestbook_settings.SettingId AND ItemValue = ?), AllowedSettingValueId),
|
|
||||||
UnconstrainedValue=(SELECT ? FROM settings WHERE settings.Id = guestbook_settings.SettingId AND settings.Constrained=0)
|
|
||||||
WHERE GuestbookId = ?
|
|
||||||
AND SettingId = (SELECT Id from Settings WHERE Description=?);`
|
|
||||||
_ = len(stmt)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *GuestbookModel) SetCommentingEnabled(guestbookId int64, enabled bool) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *GuestbookModel) SetReenableCommentingDate(guestbookId int64, reenableTime time.Time) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *GuestbookModel) SetVisible(guestbookId int64, visible bool) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *GuestbookModel) AddFilteredWord(guestbookId int64, word string) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *GuestbookModel) RemoveFilteredWord(guestbookId int64, word string) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *GuestbookModel) SetRemoteHostAccess(guestbookId int64, allowed bool) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
@ -1,223 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"database/sql"
|
|
||||||
"maps"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type SettingModel struct {
|
|
||||||
DB *sql.DB
|
|
||||||
}
|
|
||||||
|
|
||||||
type SettingConfig struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
type SettingGroup int
|
|
||||||
|
|
||||||
const (
|
|
||||||
SettingGroupUser SettingGroup = 1
|
|
||||||
SettingGroupGuestbook SettingGroup = 2
|
|
||||||
)
|
|
||||||
|
|
||||||
type SettingDataType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
SettingTypeInt SettingDataType = 1
|
|
||||||
SettingTypeDate SettingDataType = 2
|
|
||||||
SettingTypeAlphanum SettingDataType = 3
|
|
||||||
)
|
|
||||||
|
|
||||||
type SettingValue struct {
|
|
||||||
Id int
|
|
||||||
SettingId int
|
|
||||||
AllowedSettingId int
|
|
||||||
UnconstrainedValue string
|
|
||||||
}
|
|
||||||
|
|
||||||
type AllowedSettingValue struct {
|
|
||||||
id int
|
|
||||||
itemValue string
|
|
||||||
caption string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *AllowedSettingValue) Id() int {
|
|
||||||
return s.id
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *AllowedSettingValue) ItemValue() string {
|
|
||||||
return s.itemValue
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *AllowedSettingValue) Caption() string {
|
|
||||||
return s.caption
|
|
||||||
}
|
|
||||||
|
|
||||||
type Setting struct {
|
|
||||||
id int
|
|
||||||
description string
|
|
||||||
constrained bool
|
|
||||||
dataType SettingDataType
|
|
||||||
dataTypeDesc string
|
|
||||||
settingGroup SettingGroup
|
|
||||||
settingGroupDesc string
|
|
||||||
minValue string // TODO: Maybe should be int?
|
|
||||||
maxValue string
|
|
||||||
allowedValues map[int]AllowedSettingValue
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Setting) Id() int {
|
|
||||||
return s.id
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Setting) Description() string {
|
|
||||||
return s.description
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Setting) Constrained() bool {
|
|
||||||
return s.constrained
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Setting) DataType() SettingDataType {
|
|
||||||
return s.dataType
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Setting) SettingGroup() SettingGroup {
|
|
||||||
return s.settingGroup
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Setting) MinValue() string {
|
|
||||||
return s.minValue
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Setting) MaxValue() string {
|
|
||||||
return s.maxValue
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Setting) AllowedValues() map[int]AllowedSettingValue {
|
|
||||||
result := make(map[int]AllowedSettingValue, 50)
|
|
||||||
maps.Copy(result, s.allowedValues)
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Setting) ValidateUnconstrained(value string) bool {
|
|
||||||
switch s.dataType {
|
|
||||||
case SettingTypeInt:
|
|
||||||
return s.validateInt(value)
|
|
||||||
case SettingTypeAlphanum:
|
|
||||||
return s.validateAlphanum(value)
|
|
||||||
case SettingTypeDate:
|
|
||||||
return s.validateDatetime(value)
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Setting) ValidateConstrained(value *AllowedSettingValue) bool {
|
|
||||||
_, exists := s.allowedValues[value.id]
|
|
||||||
if s.constrained && exists {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Setting) validateInt(value string) bool {
|
|
||||||
v, err := strconv.ParseInt(value, 10, 0)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
var min int64
|
|
||||||
var max int64
|
|
||||||
if len(s.minValue) > 0 {
|
|
||||||
min, err = strconv.ParseInt(s.minValue, 10, 0)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if v < min {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(s.maxValue) > 0 {
|
|
||||||
max, err = strconv.ParseInt(s.maxValue, 10, 0)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if v < max {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Setting) validateDatetime(value string) bool {
|
|
||||||
v, err := time.Parse(time.DateTime, value)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
var min time.Time
|
|
||||||
var max time.Time
|
|
||||||
|
|
||||||
if len(s.minValue) > 0 {
|
|
||||||
min, err = time.Parse(time.DateTime, s.minValue)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if v.Before(min) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(s.maxValue) > 0 {
|
|
||||||
max, err = time.Parse(time.DateTime, s.maxValue)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if v.After(max) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Setting) validateAlphanum(value string) bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Setting) Validate(value string) bool {
|
|
||||||
switch s.dataType {
|
|
||||||
case SettingTypeInt:
|
|
||||||
return s.validateInt(value)
|
|
||||||
case SettingTypeAlphanum:
|
|
||||||
return s.validateAlphanum(value)
|
|
||||||
case SettingTypeDate:
|
|
||||||
return s.validateDatetime(value)
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func validateSetting(db *sql.DB, settingId int, value string) (bool, error) {
|
|
||||||
stmt := `SELECT s.Id, Description, Constrained, DataType, SettingGroup, MinValue, MaxValue, a.Id
|
|
||||||
FROM settings AS s LEFT JOIN allowed_setting_values AS a ON s.Id = a.SettingId AND a.ItemValue = ?
|
|
||||||
WHERE s.Id = ?`
|
|
||||||
result := db.QueryRow(stmt, value, settingId)
|
|
||||||
|
|
||||||
var s Setting
|
|
||||||
var minval sql.NullString
|
|
||||||
var maxval sql.NullString
|
|
||||||
var allowedId sql.NullInt64
|
|
||||||
err := result.Scan(&s.id, &s.description, &s.constrained, &s.dataType, &s.settingGroup, &minval, &maxval, &allowedId)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if s.constrained && allowedId.Valid {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
switch s.dataType {
|
|
||||||
case SettingTypeInt:
|
|
||||||
return s.validateInt(value), nil
|
|
||||||
case SettingTypeAlphanum:
|
|
||||||
return s.validateAlphanum(value), nil
|
|
||||||
case SettingTypeDate:
|
|
||||||
return s.validateDatetime(value), nil
|
|
||||||
}
|
|
||||||
return false, nil
|
|
||||||
}
|
|
@ -10,14 +10,14 @@ import (
|
|||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
u_timezone = 1
|
||||||
|
)
|
||||||
|
|
||||||
type UserSettings struct {
|
type UserSettings struct {
|
||||||
LocalTimezone *time.Location
|
LocalTimezone *time.Location
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
|
||||||
USER_TIMEZONE = "local_timezone"
|
|
||||||
)
|
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
ID int64
|
ID int64
|
||||||
ShortId uint64
|
ShortId uint64
|
||||||
@ -31,40 +31,7 @@ type User struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type UserModel struct {
|
type UserModel struct {
|
||||||
DB *sql.DB
|
DB *sql.DB
|
||||||
Settings map[string]Setting
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *UserModel) InitializeSettingsMap() error {
|
|
||||||
if m.Settings == nil {
|
|
||||||
m.Settings = make(map[string]Setting)
|
|
||||||
}
|
|
||||||
stmt := `SELECT settings.Id, settings.Description, Constrained, d.Id, d.Description, g.Id, g.Description, MinValue, MaxValue
|
|
||||||
FROM settings
|
|
||||||
LEFT JOIN setting_data_types d ON settings.DataType = d.Id
|
|
||||||
LEFT JOIN setting_groups g ON settings.SettingGroup = g.Id
|
|
||||||
WHERE SettingGroup = (SELECT Id FROM setting_groups WHERE Description = 'user' LIMIT 1)`
|
|
||||||
result, err := m.DB.Query(stmt)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for result.Next() {
|
|
||||||
var s Setting
|
|
||||||
var mn sql.NullString
|
|
||||||
var mx sql.NullString
|
|
||||||
err := result.Scan(&s.id, &s.description, &s.constrained, &s.dataType, &s.dataTypeDesc, &s.settingGroup, &s.settingGroupDesc, &mn, &mx)
|
|
||||||
if mn.Valid {
|
|
||||||
s.minValue = mn.String
|
|
||||||
}
|
|
||||||
if mx.Valid {
|
|
||||||
s.maxValue = mx.String
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
m.Settings[s.description] = s
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *UserModel) Insert(shortId uint64, username string, email string, password string, settings UserSettings) error {
|
func (m *UserModel) Insert(shortId uint64, username string, email string, password string, settings UserSettings) error {
|
||||||
@ -87,7 +54,13 @@ func (m *UserModel) Insert(shortId uint64, username string, email string, passwo
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = m.initializeUserSettings(id, settings)
|
settingsStmt := `INSERT INTO user_settings
|
||||||
|
(UserId, SettingId, AllowedSettingValueId, UnconstrainedValue)
|
||||||
|
VALUES (?, ?, ?, ?)`
|
||||||
|
_, err = m.DB.Exec(settingsStmt, id, u_timezone, nil, settings.LocalTimezone.String())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,7 +174,7 @@ func (m *UserModel) GetSettings(userId int64) (UserSettings, error) {
|
|||||||
return settings, err
|
return settings, err
|
||||||
}
|
}
|
||||||
switch id {
|
switch id {
|
||||||
case m.Settings[USER_TIMEZONE].id:
|
case u_timezone:
|
||||||
settings.LocalTimezone, err = time.LoadLocation(unconstrainedValue.String)
|
settings.LocalTimezone, err = time.LoadLocation(unconstrainedValue.String)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -211,53 +184,9 @@ func (m *UserModel) GetSettings(userId int64) (UserSettings, error) {
|
|||||||
return settings, err
|
return settings, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *UserModel) initializeUserSettings(userId int64, settings UserSettings) error {
|
|
||||||
stmt := `INSERT INTO user_settings (UserId, SettingId, AllowedSettingValueId, UnconstrainedValue)
|
|
||||||
VALUES (?, ?, ?, ?)`
|
|
||||||
_, err := m.DB.Exec(stmt, userId, m.Settings[USER_TIMEZONE].id, nil, settings.LocalTimezone.String())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *UserModel) UpdateUserSettings(userId int64, settings UserSettings) error {
|
|
||||||
err := m.UpdateSetting(userId, m.Settings[USER_TIMEZONE], settings.LocalTimezone.String())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *UserModel) UpdateSetting(userId int64, setting Setting, value string) error {
|
|
||||||
stmt := `UPDATE user_settings SET
|
|
||||||
AllowedSettingValueId=IFNULL(
|
|
||||||
(SELECT Id FROM allowed_setting_values WHERE SettingId = user_settings.SettingId AND ItemValue = ?), AllowedSettingValueId
|
|
||||||
),
|
|
||||||
UnconstrainedValue=(SELECT ? FROM settings WHERE settings.Id = user_settings.SettingId AND settings.Constrained=0)
|
|
||||||
WHERE userId = ?
|
|
||||||
AND SettingId = (SELECT Id from Settings WHERE Description=?);`
|
|
||||||
result, err := m.DB.Exec(stmt, value, value, userId, setting.description)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
rows, err := result.RowsAffected()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if rows != 1 {
|
|
||||||
return ErrInvalidSettingValue
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *UserModel) SetLocalTimezone(userId int64, timezone string) error {
|
func (m *UserModel) SetLocalTimezone(userId int64, timezone string) error {
|
||||||
setting := m.Settings[USER_TIMEZONE]
|
stmt := `UPDATE user_settings SET UnconstrainedValue = ? WHERE UserId = ?`
|
||||||
valid := setting.Validate(timezone)
|
_, err := m.DB.Exec(stmt, timezone, userId)
|
||||||
if !valid {
|
|
||||||
return ErrInvalidSettingValue
|
|
||||||
}
|
|
||||||
err := m.UpdateSetting(userId, setting, timezone)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Code generated by templ - DO NOT EDIT.
|
// Code generated by templ - DO NOT EDIT.
|
||||||
|
|
||||||
// templ: version: v0.3.833
|
// templ: version: v0.3.857
|
||||||
package views
|
package views
|
||||||
|
|
||||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Code generated by templ - DO NOT EDIT.
|
// Code generated by templ - DO NOT EDIT.
|
||||||
|
|
||||||
// templ: version: v0.3.833
|
// templ: version: v0.3.857
|
||||||
package views
|
package views
|
||||||
|
|
||||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Code generated by templ - DO NOT EDIT.
|
// Code generated by templ - DO NOT EDIT.
|
||||||
|
|
||||||
// templ: version: v0.3.833
|
// templ: version: v0.3.857
|
||||||
package views
|
package views
|
||||||
|
|
||||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Code generated by templ - DO NOT EDIT.
|
// Code generated by templ - DO NOT EDIT.
|
||||||
|
|
||||||
// templ: version: v0.3.833
|
// templ: version: v0.3.857
|
||||||
package views
|
package views
|
||||||
|
|
||||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Code generated by templ - DO NOT EDIT.
|
// Code generated by templ - DO NOT EDIT.
|
||||||
|
|
||||||
// templ: version: v0.3.833
|
// templ: version: v0.3.857
|
||||||
package views
|
package views
|
||||||
|
|
||||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Code generated by templ - DO NOT EDIT.
|
// Code generated by templ - DO NOT EDIT.
|
||||||
|
|
||||||
// templ: version: v0.3.833
|
// templ: version: v0.3.857
|
||||||
package views
|
package views
|
||||||
|
|
||||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user