package handlers import ( "net/http" "strings" "vpn-panel/internal/auth" "vpn-panel/internal/session" "vpn-panel/internal/store" ) func (h *Handler) currentUser(r *http.Request) *session.Data { c, err := r.Cookie(session.CookieName()) if err != nil { return nil } d, err := session.Verify(h.secret, c.Value) if err != nil { return nil } return d } func (h *Handler) RegisterAdmin(w http.ResponseWriter, r *http.Request) { ctx := r.Context() has, err := h.users.HasAdmin(ctx) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if has { flashSet(w, "Администратор уже создан. Регистрация закрыта.", "error") http.Redirect(w, r, "/", http.StatusSeeOther) return } if r.Method == http.MethodGet { h.render(w, "register", h.pageData(w, r, "Регистрация администратора", nil)) return } email := strings.TrimSpace(strings.ToLower(r.FormValue("email"))) password := r.FormValue("password") confirm := r.FormValue("password_confirm") if email == "" || len(password) < 8 { flashSet(w, "Email обязателен, пароль — минимум 8 символов.", "error") http.Redirect(w, r, "/register", http.StatusSeeOther) return } if password != confirm { flashSet(w, "Пароли не совпадают.", "error") http.Redirect(w, r, "/register", http.StatusSeeOther) return } hash, err := auth.HashPassword(password) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } u, err := h.users.CreateAdmin(ctx, email, hash) if err == store.ErrAdminExists { flashSet(w, "Администратор уже существует.", "error") http.Redirect(w, r, "/", http.StatusSeeOther) return } if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } token, err := session.Sign(h.secret, session.Data{ UserID: u.ID, Email: u.Email, Role: u.Role, }) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } http.SetCookie(w, &http.Cookie{ Name: session.CookieName(), Value: token, Path: "/", MaxAge: int((7 * 24 * 60 * 60)), HttpOnly: true, SameSite: http.SameSiteLaxMode, Secure: r.TLS != nil, }) flashSet(w, "Администратор успешно создан. Добро пожаловать!", "success") http.Redirect(w, r, "/", http.StatusSeeOther) } func (h *Handler) Login(w http.ResponseWriter, r *http.Request) { if r.Method == http.MethodGet { h.render(w, "login", h.pageData(w, r, "Вход", nil)) return } email := strings.TrimSpace(strings.ToLower(r.FormValue("email"))) password := r.FormValue("password") u, err := h.users.GetByEmail(r.Context(), email) if err != nil || u == nil || !auth.CheckPassword(u.PasswordHash, password) { flashSet(w, "Неверный email или пароль.", "error") http.Redirect(w, r, "/login", http.StatusSeeOther) return } token, err := session.Sign(h.secret, session.Data{ UserID: u.ID, Email: u.Email, Role: u.Role, }) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } http.SetCookie(w, &http.Cookie{ Name: session.CookieName(), Value: token, Path: "/", MaxAge: 7 * 24 * 60 * 60, HttpOnly: true, SameSite: http.SameSiteLaxMode, Secure: r.TLS != nil, }) http.Redirect(w, r, "/", http.StatusSeeOther) } func (h *Handler) Logout(w http.ResponseWriter, r *http.Request) { http.SetCookie(w, &http.Cookie{ Name: session.CookieName(), Path: "/", MaxAge: -1, }) http.Redirect(w, r, "/", http.StatusSeeOther) }