b3e3a06858
Co-authored-by: Cursor <cursoragent@cursor.com>
132 lines
3.3 KiB
Go
132 lines
3.3 KiB
Go
package handlers
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"shop/internal/auth"
|
|
)
|
|
|
|
type AuthHandler struct {
|
|
pages *Pages
|
|
auth *auth.Service
|
|
}
|
|
|
|
func NewAuthHandler(pages *Pages, authSvc *auth.Service) *AuthHandler {
|
|
return &AuthHandler{pages: pages, auth: authSvc}
|
|
}
|
|
|
|
type authPageData struct {
|
|
Layout
|
|
Email string
|
|
Name string
|
|
Next string
|
|
}
|
|
|
|
func (h *AuthHandler) Register(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
h.showRegister(w, r, "", "")
|
|
case http.MethodPost:
|
|
h.postRegister(w, r)
|
|
default:
|
|
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
|
}
|
|
}
|
|
|
|
func (h *AuthHandler) showRegister(w http.ResponseWriter, r *http.Request, errMsg string, email string) {
|
|
data := authPageData{
|
|
Layout: h.pages.layout(r, "Регистрация", "register"),
|
|
Email: email,
|
|
}
|
|
data.Error = errMsg
|
|
if msg := flashMsg(r, "ok"); msg != "" {
|
|
data.Success = msg
|
|
}
|
|
h.pages.render(w, "register.html", data)
|
|
}
|
|
|
|
func (h *AuthHandler) postRegister(w http.ResponseWriter, r *http.Request) {
|
|
if err := r.ParseForm(); err != nil {
|
|
h.showRegister(w, r, "Неверные данные формы", "")
|
|
return
|
|
}
|
|
email := r.FormValue("email")
|
|
name := r.FormValue("name")
|
|
password := r.FormValue("password")
|
|
password2 := r.FormValue("password_confirm")
|
|
if password != password2 {
|
|
h.showRegister(w, r, "Пароли не совпадают", email)
|
|
return
|
|
}
|
|
_, err := h.auth.Register(r.Context(), email, password, name)
|
|
if err != nil {
|
|
h.showRegister(w, r, err.Error(), email)
|
|
return
|
|
}
|
|
http.Redirect(w, r, "/login?ok=registered", http.StatusSeeOther)
|
|
}
|
|
|
|
func (h *AuthHandler) Login(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
h.showLogin(w, r, "", "")
|
|
case http.MethodPost:
|
|
h.postLogin(w, r)
|
|
default:
|
|
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
|
}
|
|
}
|
|
|
|
func (h *AuthHandler) showLogin(w http.ResponseWriter, r *http.Request, errMsg, email string) {
|
|
data := authPageData{
|
|
Layout: h.pages.layout(r, "Вход", "login"),
|
|
Email: email,
|
|
Next: safeNext(r.URL.Query().Get("next")),
|
|
}
|
|
data.Error = errMsg
|
|
data.Success = flashMsg(r, "ok")
|
|
if data.Layout.User != nil {
|
|
http.Redirect(w, r, "/account", http.StatusSeeOther)
|
|
return
|
|
}
|
|
h.pages.render(w, "login.html", data)
|
|
}
|
|
|
|
func (h *AuthHandler) postLogin(w http.ResponseWriter, r *http.Request) {
|
|
if err := r.ParseForm(); err != nil {
|
|
h.showLogin(w, r, "Неверные данные формы", "")
|
|
return
|
|
}
|
|
email := r.FormValue("email")
|
|
password := r.FormValue("password")
|
|
if err := h.auth.Login(r.Context(), w, email, password); err != nil {
|
|
msg := err.Error()
|
|
if errors.Is(err, auth.ErrInvalidCredentials) {
|
|
msg = "Неверный email или пароль"
|
|
}
|
|
h.showLogin(w, r, msg, email)
|
|
return
|
|
}
|
|
next := safeNext(r.FormValue("next"))
|
|
http.Redirect(w, r, next+"?ok=login", http.StatusSeeOther)
|
|
}
|
|
|
|
func (h *AuthHandler) Logout(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodPost {
|
|
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
h.auth.Logout(r.Context(), w, r)
|
|
http.Redirect(w, r, "/?ok=logout", http.StatusSeeOther)
|
|
}
|
|
|
|
func safeNext(next string) string {
|
|
next = strings.TrimSpace(next)
|
|
if next == "" || !strings.HasPrefix(next, "/") || strings.HasPrefix(next, "//") {
|
|
return "/account"
|
|
}
|
|
return next
|
|
}
|