Add display names for app users

This commit is contained in:
DonVoo 2026-07-13 00:56:38 +02:00
parent 6e7aa87de6
commit b625c95c29
3 changed files with 92 additions and 35 deletions

View file

@ -41,6 +41,7 @@ type Account struct {
type AppUser struct {
ID int64
Username string
DisplayName string
Role string
Active bool
PasswordHash string
@ -119,6 +120,7 @@ func ConnectDB() error {
`CREATE TABLE IF NOT EXISTS app_users(
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL UNIQUE,
display_name TEXT NOT NULL DEFAULT '',
password_hash TEXT NOT NULL,
role TEXT NOT NULL DEFAULT 'user',
active INTEGER NOT NULL DEFAULT 1,
@ -139,6 +141,41 @@ func ConnectDB() error {
}
}
DB = db
if err := ensureAppUserColumns(); err != nil {
_ = db.Close()
return err
}
return nil
}
func ensureAppUserColumns() error {
hasDisplayName := false
rows, err := DB.Query(`PRAGMA table_info(app_users)`)
if err != nil {
return err
}
defer rows.Close()
for rows.Next() {
var cid int
var name, typ string
var notNull int
var defaultValue any
var pk int
if err := rows.Scan(&cid, &name, &typ, &notNull, &defaultValue, &pk); err != nil {
return err
}
if name == "display_name" {
hasDisplayName = true
}
}
if err := rows.Err(); err != nil {
return err
}
if !hasDisplayName {
if _, err := DB.Exec(`ALTER TABLE app_users ADD COLUMN display_name TEXT NOT NULL DEFAULT ''`); err != nil {
return err
}
}
return nil
}
@ -149,7 +186,7 @@ func CountAppUsers() (int, error) {
}
func ListAppUsers() ([]AppUser, error) {
rows, err := DB.Query(`SELECT id, username, password_hash, role, active FROM app_users ORDER BY username`)
rows, err := DB.Query(`SELECT id, username, display_name, password_hash, role, active FROM app_users ORDER BY username`)
if err != nil {
return nil, err
}
@ -166,30 +203,32 @@ func ListAppUsers() ([]AppUser, error) {
}
func GetAppUser(username string) (AppUser, error) {
row := DB.QueryRow(`SELECT id, username, password_hash, role, active FROM app_users WHERE username=?`, username)
row := DB.QueryRow(`SELECT id, username, display_name, password_hash, role, active FROM app_users WHERE username=?`, username)
return scanAppUser(row)
}
func GetAppUserByID(id int64) (AppUser, error) {
row := DB.QueryRow(`SELECT id, username, password_hash, role, active FROM app_users WHERE id=?`, id)
row := DB.QueryRow(`SELECT id, username, display_name, password_hash, role, active FROM app_users WHERE id=?`, id)
return scanAppUser(row)
}
func SaveAppUser(username, passwordHash, role string, active bool) error {
func SaveAppUser(username, displayName, passwordHash, role string, active bool) error {
displayName = strings.TrimSpace(displayName)
role = normalizeRole(role)
if passwordHash == "" {
_, err := DB.Exec(`UPDATE app_users SET role=?, active=?, updated_at=CURRENT_TIMESTAMP WHERE username=?`,
role, boolInt(active), username)
_, err := DB.Exec(`UPDATE app_users SET display_name=?, role=?, active=?, updated_at=CURRENT_TIMESTAMP WHERE username=?`,
displayName, role, boolInt(active), username)
return err
}
_, err := DB.Exec(`INSERT INTO app_users(username, password_hash, role, active)
VALUES(?,?,?,?)
_, err := DB.Exec(`INSERT INTO app_users(username, display_name, password_hash, role, active)
VALUES(?,?,?,?,?)
ON CONFLICT(username) DO UPDATE SET
display_name=excluded.display_name,
password_hash=excluded.password_hash,
role=excluded.role,
active=excluded.active,
updated_at=CURRENT_TIMESTAMP`,
username, passwordHash, role, boolInt(active))
username, displayName, passwordHash, role, boolInt(active))
return err
}
@ -209,7 +248,7 @@ func DeleteSession(token string) error {
}
func SessionUser(token string) (AppUser, error) {
row := DB.QueryRow(`SELECT u.id, u.username, u.password_hash, u.role, u.active
row := DB.QueryRow(`SELECT u.id, u.username, u.display_name, u.password_hash, u.role, u.active
FROM app_sessions s JOIN app_users u ON u.id=s.user_id
WHERE s.token=? AND s.expires_at > CURRENT_TIMESTAMP AND u.active=1`, token)
return scanAppUser(row)
@ -351,7 +390,7 @@ func normalizeAccount(a *Account) {
func scanAppUser(s appUserScanner) (AppUser, error) {
var u AppUser
var active int
err := s.Scan(&u.ID, &u.Username, &u.PasswordHash, &u.Role, &active)
err := s.Scan(&u.ID, &u.Username, &u.DisplayName, &u.PasswordHash, &u.Role, &active)
u.Role = normalizeRole(u.Role)
u.Active = active != 0
return u, err