termbox/internal/db/user.go
2025-08-06 05:50:24 +01:00

73 lines
1.6 KiB
Go

package db
import (
"context"
"time"
"golang.org/x/crypto/bcrypt"
)
type User struct {
ID int `json:"id"`
Username string `json:"username"`
PasswordHash string `json:"-"`
CreatedAt time.Time `json:"created_at"`
}
type CreateUserRequest struct {
Username string `json:"username"`
Password string `json:"password"`
}
type LoginRequest struct {
Username string `json:"username"`
Password string `json:"password"`
}
func CreateUser(ctx context.Context, req CreateUserRequest) (*User, error) {
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
if err != nil {
return nil, err
}
var user User
err = Pool.QueryRow(ctx,
"INSERT INTO users (username, password_hash) VALUES ($1, $2) RETURNING id, username, created_at",
req.Username, string(hashedPassword),
).Scan(&user.ID, &user.Username, &user.CreatedAt)
if err != nil {
return nil, err
}
return &user, nil
}
func GetUserByUsername(ctx context.Context, username string) (*User, error) {
var user User
err := Pool.QueryRow(ctx,
"SELECT id, username, password_hash, created_at FROM users WHERE username = $1",
username,
).Scan(&user.ID, &user.Username, &user.PasswordHash, &user.CreatedAt)
if err != nil {
return nil, err
}
return &user, nil
}
func ValidateUserCredentials(ctx context.Context, username, password string) (*User, error) {
user, err := GetUserByUsername(ctx, username)
if err != nil {
return nil, err
}
err = bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(password))
if err != nil {
return nil, err
}
return user, nil
}