102 lines
2.3 KiB
Go
102 lines
2.3 KiB
Go
package handlers
|
|
|
|
import (
|
|
"html/template"
|
|
"io/fs"
|
|
"net/http"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
"vpn-panel/internal/config"
|
|
"vpn-panel/internal/store"
|
|
"vpn-panel/web"
|
|
)
|
|
|
|
type Handler struct {
|
|
cfg *config.Config
|
|
pool *pgxpool.Pool
|
|
users *store.UserStore
|
|
tmpl map[string]*template.Template
|
|
secret string
|
|
domain string
|
|
}
|
|
|
|
func New(cfg *config.Config, pool *pgxpool.Pool) (*Handler, error) {
|
|
tmpl, err := loadTemplates()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &Handler{
|
|
cfg: cfg,
|
|
pool: pool,
|
|
users: store.NewUserStore(pool),
|
|
tmpl: tmpl,
|
|
secret: cfg.SecretKey,
|
|
domain: cfg.AppDomain,
|
|
}, nil
|
|
}
|
|
|
|
func loadTemplates() (map[string]*template.Template, error) {
|
|
funcs := template.FuncMap{
|
|
"eq": func(a, b any) bool { return a == b },
|
|
}
|
|
out := make(map[string]*template.Template)
|
|
|
|
err := fs.WalkDir(web.Templates, "templates", func(path string, d fs.DirEntry, err error) error {
|
|
if err != nil || d.IsDir() || !strings.HasSuffix(path, ".html") {
|
|
return err
|
|
}
|
|
name := strings.TrimSuffix(filepath.Base(path), ".html")
|
|
content, err := web.Templates.ReadFile(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
base, err := web.Templates.ReadFile("templates/layout.html")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
t, err := template.New("layout").Funcs(funcs).Parse(string(base))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if _, err := t.Parse(string(content)); err != nil {
|
|
return err
|
|
}
|
|
out[name] = t
|
|
return nil
|
|
})
|
|
return out, err
|
|
}
|
|
|
|
func (h *Handler) render(w http.ResponseWriter, name string, data any) {
|
|
t := h.tmpl[name]
|
|
if t == nil {
|
|
http.Error(w, "template not found", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
|
if err := t.ExecuteTemplate(w, "layout", data); err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
}
|
|
}
|
|
|
|
func (h *Handler) pageData(w http.ResponseWriter, r *http.Request, title string, extra map[string]any) map[string]any {
|
|
hasAdmin, _ := h.users.HasAdmin(r.Context())
|
|
data := map[string]any{
|
|
"Title": title,
|
|
"Domain": h.domain,
|
|
"Year": "2026",
|
|
"Flash": flashGet(w, r),
|
|
"CanRegister": !hasAdmin,
|
|
"HasAdmin": hasAdmin,
|
|
}
|
|
if sess := h.currentUser(r); sess != nil {
|
|
data["User"] = sess
|
|
}
|
|
for k, v := range extra {
|
|
data[k] = v
|
|
}
|
|
return data
|
|
}
|