dealroom/internal/handler/auth.go

93 lines
2.4 KiB
Go

package handler
import (
"crypto/rand"
"encoding/hex"
"net/http"
"time"
"dealroom/templates"
)
func (h *Handler) handleLoginPage(w http.ResponseWriter, r *http.Request) {
// If already logged in, redirect to dashboard
cookie, err := r.Cookie("session")
if err == nil && cookie.Value != "" {
var count int
h.db.QueryRow("SELECT COUNT(*) FROM sessions WHERE token = ? AND expires_at > datetime('now')", cookie.Value).Scan(&count)
if count > 0 {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
}
templates.Login().Render(r.Context(), w)
}
func (h *Handler) handleLogin(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Redirect(w, r, "/login", http.StatusSeeOther)
return
}
email := r.FormValue("email")
password := r.FormValue("password")
var userID string
var passHash string
err := h.db.QueryRow("SELECT id, password_hash FROM profiles WHERE email = ?", email).Scan(&userID, &passHash)
if err != nil || (passHash != "demo" && passHash != password) {
http.Redirect(w, r, "/login?error=invalid", http.StatusSeeOther)
return
}
h.createSession(w, userID)
http.Redirect(w, r, "/", http.StatusSeeOther)
}
func (h *Handler) handleDemoLogin(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Redirect(w, r, "/login", http.StatusSeeOther)
return
}
role := r.FormValue("role") // "seller" or "buyer"
var userID string
if role == "buyer" {
userID = "user-buyer"
} else {
userID = "user-seller"
}
h.createSession(w, userID)
http.Redirect(w, r, "/", http.StatusSeeOther)
}
func (h *Handler) handleLogout(w http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie("session")
if err == nil {
h.db.Exec("DELETE FROM sessions WHERE token = ?", cookie.Value)
}
http.SetCookie(w, &http.Cookie{Name: "session", Value: "", MaxAge: -1, Path: "/"})
http.Redirect(w, r, "/login", http.StatusSeeOther)
}
func (h *Handler) createSession(w http.ResponseWriter, userID string) {
token := generateToken()
expires := time.Now().Add(24 * time.Hour)
h.db.Exec("INSERT INTO sessions (token, user_id, expires_at) VALUES (?, ?, ?)", token, userID, expires)
http.SetCookie(w, &http.Cookie{
Name: "session",
Value: token,
Path: "/",
Expires: expires,
HttpOnly: true,
SameSite: http.SameSiteLaxMode,
})
}
func generateToken() string {
b := make([]byte, 32)
rand.Read(b)
return hex.EncodeToString(b)
}