package http import ( "io/fs" "net/http" "strings" "git.javil.eu/jacob1123/budgeteer" "git.javil.eu/jacob1123/budgeteer/bcrypt" "git.javil.eu/jacob1123/budgeteer/postgres" "git.javil.eu/jacob1123/budgeteer/web" "github.com/gin-gonic/gin" ) // Handler handles incoming requests type Handler struct { Service *postgres.Repository TokenVerifier budgeteer.TokenVerifier CredentialsVerifier *bcrypt.Verifier } const ( expiration = 72 authCookie = "authentication" ) // Serve starts the HTTP Server func (h *Handler) Serve() { router := gin.Default() templates, err := NewTemplates(router.FuncMap) if err != nil { panic(err) } router.HTMLRender = templates static, err := fs.Sub(web.Static, "static") if err != nil { panic("couldn't open static files") } router.Use(headersByRequestURI()) router.StaticFS("/static", http.FS(static)) router.GET("/", func(c *gin.Context) { c.HTML(http.StatusOK, "index.html", nil) }) router.GET("/login", h.login) router.GET("/register", h.register) withLogin := router.Group("") withLogin.Use(h.verifyLoginWithRedirect) withLogin.GET("/dashboard", h.dashboard) withLogin.GET("/admin", h.admin) withLogin.GET("/admin/clear-database", h.clearDatabase) withBudget := router.Group("") withBudget.Use(h.verifyLoginWithRedirect) withBudget.Use(h.getImportantData) withBudget.GET("/budget/:budgetid", h.budgeting) withBudget.GET("/budget/:budgetid/:year/:month", h.budgeting) withBudget.GET("/budget/:budgetid/all-accounts", h.budget) withBudget.GET("/budget/:budgetid/accounts", h.accounts) withBudget.GET("/budget/:budgetid/account/:accountid", h.account) withBudget.GET("/budget/:budgetid/clear", h.clearBudget) withBudget.GET("/budget/:budgetid/clean-negative", h.cleanNegativeBudget) api := router.Group("/api/v1") unauthenticated := api.Group("/user") unauthenticated.GET("/login", func(c *gin.Context) { c.Redirect(http.StatusPermanentRedirect, "/login") }) unauthenticated.POST("/login", h.loginPost) unauthenticated.POST("/register", h.registerPost) authenticated := api.Group("") authenticated.Use(h.verifyLoginWithRedirect) user := authenticated.Group("/user") user.GET("/logout", logout) budget := authenticated.Group("/budget") budget.POST("/new", h.newBudget) transaction := authenticated.Group("/transaction") transaction.POST("/new", h.newTransaction) transaction.POST("/import/ynab", h.importYNAB) router.Run(":1323") } func headersByRequestURI() gin.HandlerFunc { return func(c *gin.Context) { if strings.HasPrefix(c.Request.RequestURI, "/static/") { c.Header("Cache-Control", "max-age=86400") } } }