package database import ( "database/sql" "errors" "time" "github.com/owen/vibeproxy/internal/models" ) var ErrNotFound = errors.New("not found") const timeFmt = "2006-01-02T15:04:05.000Z" func parseTime(s string) time.Time { t, _ := time.Parse(timeFmt, s) return t } func GetUserByUsername(db *sql.DB, username string) (*models.User, error) { row := db.QueryRow(`SELECT id, username, password_hash, must_change_pw, created_at, updated_at FROM users WHERE username = ?`, username) u := &models.User{} var mustChange int var created, updated string if err := row.Scan(&u.ID, &u.Username, &u.PasswordHash, &mustChange, &created, &updated); err != nil { if errors.Is(err, sql.ErrNoRows) { return nil, ErrNotFound } return nil, err } u.MustChangePW = mustChange == 1 u.CreatedAt = parseTime(created) u.UpdatedAt = parseTime(updated) return u, nil } func CountUsers(db *sql.DB) (int, error) { var n int err := db.QueryRow(`SELECT COUNT(*) FROM users`).Scan(&n) return n, err } func CreateUser(db *sql.DB, username, passwordHash string, mustChange bool) error { _, err := db.Exec(`INSERT INTO users (username, password_hash, must_change_pw) VALUES (?, ?, ?)`, username, passwordHash, boolToInt(mustChange)) return err } func UpdateUserPassword(db *sql.DB, username, passwordHash string, mustChange bool) error { _, err := db.Exec(`UPDATE users SET password_hash = ?, must_change_pw = ?, updated_at = strftime('%Y-%m-%dT%H:%M:%fZ','now') WHERE username = ?`, passwordHash, boolToInt(mustChange), username) return err } func boolToInt(b bool) int { if b { return 1 } return 0 }