package lib import ( "time" "github.com/google/uuid" "golang.org/x/crypto/bcrypt" ) type User struct { ID int Username string PasswordHash string } // hash password func HashPassword(password string) (string, error) { bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14) return string(bytes), err } // check password func CheckPasswordHash(password, hash string) bool { err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) return err == nil } // create new user func CreateUser(username, password string) error { hash, err := HashPassword(password) if err != nil { return err } _, err = DB.Exec("INSERT INTO users (username, password_hash) VALUES (?, ?)", username, hash) return err } // get user by name func GetUserByUsername(username string) (*User, error) { row := DB.QueryRow("SELECT id, username, password_hash FROM users WHERE username = ?", username) u := &User{} err := row.Scan(&u.ID, &u.Username, &u.PasswordHash) if err != nil { return nil, err } return u, nil } // create session token func CreateSession(userID int) (string, error) { sessionID := uuid.New().String() expiresAt := time.Now().Add(24 * time.Hour) _, err := DB.Exec("INSERT INTO sessions (id, user_id, expires_at) VALUES (?, ?, ?)", sessionID, userID, expiresAt) if err != nil { return "", err } return sessionID, nil } // get user from session func GetUserFromSession(sessionID string) (*User, error) { row := DB.QueryRow(` SELECT u.id, u.username, u.password_hash FROM users u JOIN sessions s ON u.id = s.user_id WHERE s.id = ? AND s.expires_at > ? `, sessionID, time.Now()) u := &User{} err := row.Scan(&u.ID, &u.Username, &u.PasswordHash) if err != nil { return nil, err } return u, nil } // delete session func DeleteSession(sessionID string) error { _, err := DB.Exec("DELETE FROM sessions WHERE id = ?", sessionID) return err }