package handlers import ( "context" "go-backend/internal/auth" "go-backend/internal/database/sqlc" "go-backend/internal/services" "log" "net/http" "text/template" ) // UserService and AuthService are defined here, on the consumer side, so // handlers depend only on the methods they actually use and tests can swap // in fakes without touching the services package. type UserService interface { FindByID(ctx context.Context, id string) (*sqlc.UserAuth, error) FindByUsername(ctx context.Context, username string) (*sqlc.UserAuth, error) CreateUser(ctx context.Context, userInput sqlc.InsertUserParams) (*sqlc.UserAuth, error) } type AuthService interface { CreateSession(ctx context.Context, userID string) (*services.SessionWithToken, error) ValidateSessionToken(ctx context.Context, token string) (*sqlc.UserSession, bool, error) DeleteSession(ctx context.Context, token string) error } type Handler struct { users UserService auth AuthService } func NewHandler(users UserService, auth AuthService) *Handler { return &Handler{ users: users, auth: auth, } } func (h *Handler) HomeHandler(w http.ResponseWriter, r *http.Request) { cookie, err := r.Cookie("session") if err != nil { http.Redirect(w, r, "/login", http.StatusSeeOther) return } session, bump, err := h.auth.ValidateSessionToken(r.Context(), cookie.Value) if err != nil { http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } if session == nil { http.Redirect(w, r, "/login", http.StatusSeeOther) return } if bump { http.SetCookie(w, auth.NewSessionCookie(cookie.Value, false)) } user, err := h.users.FindByID(r.Context(), session.UserID) if err != nil { http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } files := []string{ "./ui/html/base.tmpl", "./ui/html/pages/index.tmpl", } ts, err := template.ParseFiles(files...) if err != nil { log.Print(err.Error()) http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } err = ts.ExecuteTemplate(w, "base", user.Username) if err != nil { log.Print(err.Error()) http.Error(w, "Internal Server Error", http.StatusInternalServerError) } } func (h *Handler) LoginPageHandler(w http.ResponseWriter, r *http.Request) { cookie, err := r.Cookie("session") if cookie != nil { session, bump, err := h.auth.ValidateSessionToken(r.Context(), cookie.Value) if err != nil { log.Print(err.Error()) http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } if bump { http.SetCookie(w, auth.NewSessionCookie(cookie.Value, false)) } if session != nil { http.Redirect(w, r, "/", http.StatusSeeOther) return } } files := []string{ "./ui/html/base.tmpl", "./ui/html/pages/login.tmpl", } ts, err := template.ParseFiles(files...) if err != nil { log.Print(err.Error()) http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } err = ts.ExecuteTemplate(w, "base", nil) if err != nil { log.Print(err.Error()) http.Error(w, "Internal Server Error", http.StatusInternalServerError) } } func (h *Handler) SignUpPageHandler(w http.ResponseWriter, r *http.Request) { cookie, err := r.Cookie("session") if cookie != nil { session, bump, err := h.auth.ValidateSessionToken(r.Context(), cookie.Value) if err != nil { log.Print(err.Error()) http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } if bump { http.SetCookie(w, auth.NewSessionCookie(cookie.Value, false)) } if session != nil { http.Redirect(w, r, "/", http.StatusSeeOther) return } } files := []string{ "./ui/html/base.tmpl", "./ui/html/pages/signup.tmpl", } ts, err := template.ParseFiles(files...) if err != nil { log.Print(err.Error()) http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } err = ts.ExecuteTemplate(w, "base", nil) if err != nil { log.Print(err.Error()) http.Error(w, "Internal Server Error", http.StatusInternalServerError) } }