package api import ( "log" "time" "gitea.urkob.com/urko/prosody-password/internal/api/handler" "gitea.urkob.com/urko/prosody-password/internal/services/fail2ban" "gitea.urkob.com/urko/prosody-password/internal/services/prosody" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/cors" "github.com/gofiber/fiber/v2/middleware/limiter" "github.com/gofiber/template/handlebars/v2" ) type RestServer struct { app *fiber.App prosodyService *prosody.Prosody fail2banSrv *fail2ban.Fail2Ban } func NewRestServer( prosodyService *prosody.Prosody, fail2banSrv *fail2ban.Fail2Ban, ) *RestServer { return &RestServer{ prosodyService: prosodyService, fail2banSrv: fail2banSrv, } } func (s *RestServer) Start(apiPort, views string) error { engine := handlebars.New(views, ".hbs") s.app = fiber.New(fiber.Config{ Views: engine, ProxyHeader: "X-Forwarded-For", EnableIPValidation: true, }) s.app.Use(limiter.New(limiter.Config{ Max: 8, Expiration: 30 * time.Minute, LimiterMiddleware: limiter.SlidingWindow{}, })) s.app.Use(cors.New(cors.Config{ AllowMethods: "POST,OPTIONS", AllowOrigins: "*", AllowHeaders: "Origin, Accept, Content-Type, X-CSRF-Token, Authorization", ExposeHeaders: "Origin", })) s.loadViews() prosodyHdl := handler.NewProsodyHandler(s.prosodyService, s.fail2banSrv) s.app.Post("/changePassword", prosodyHdl.Post) if err := s.app.Listen(":" + apiPort); err != nil { log.Fatalln("app.Listen:", err) return err } return nil } func (s *RestServer) loadViews() { s.app.Get("/", func(c *fiber.Ctx) error { return c.Render("index", fiber.Map{}) }) s.app.Get("/error", func(c *fiber.Ctx) error { message := c.Query("message") return renderError(c, nil, message) }) } func renderError(c *fiber.Ctx, err error, message string) error { if err != nil { log.Printf("renderError: %s\n", err) } return c.Render("error", fiber.Map{ "message": message, }) } func (s *RestServer) Shutdown() error { if err := s.app.Server().Shutdown(); err != nil { log.Printf("app.Server().Shutdown(): %s\n", err) return err } return nil }