package main import ( "errors" "log" "net/http" "strings" "water/api/internal/database" "water/api/internal/controllers" "github.com/gin-gonic/gin" _ "github.com/mattn/go-sqlite3" ) func CORSMiddleware() gin.HandlerFunc { return func(c *gin.Context) { c.Writer.Header().Set("Access-Control-Allow-Origin", "*") c.Writer.Header().Set("Access-Control-Allow-Credentials", "true") c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With") c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT") if c.Request.Method == "OPTIONS" { log.Println(c.Request.Header) c.AbortWithStatus(http.StatusNoContent) return } c.Next() } } func checkForTokenInContext(c *gin.Context) (string, error) { authorizationHeader := c.GetHeader("Authorization") if authorizationHeader == "" { return "", errors.New("authorization header is missing") } parts := strings.Split(authorizationHeader, " ") if len(parts) != 2 || parts[0] != "Bearer" { return "", errors.New("invalid Authorization header format") } return parts[1], nil } func TokenRequired() gin.HandlerFunc { return func(c *gin.Context) { _, err := checkForTokenInContext(c) if err != nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) c.Abort() return } c.Next() } } func setupRouter() *gin.Engine { // Disable Console Color // gin.DisableConsoleColor() r := gin.Default() r.Use(CORSMiddleware()) r.Use(gin.Logger()) r.Use(gin.Recovery()) api := r.Group("api/v1") api.POST("/auth", controllers.AuthHandler) user := api.Group("/user/:uuid") user.Use(TokenRequired()) { user.GET("", controllers.GetUser) user.GET("preferences", controllers.GetUserPreferences) user.PATCH("preferences", controllers.UpdateUserPreferences) } stats := api.Group("/stats") stats.Use(TokenRequired()) { stats.GET("/", controllers.GetAllStatistics) stats.POST("/", controllers.PostNewStatistic) stats.GET("weekly/", controllers.GetWeeklyStatistics) stats.GET("daily/", controllers.GetDailyUserStatistics) stats.GET("user/:uuid", controllers.GetUserStatistics) stats.PATCH("user/:uuid", controllers.UpdateUserStatistic) stats.DELETE("user/:uuid", controllers.DeleteUserStatistic) } return r } func main() { database.SetupDatabase() r := setupRouter() // Listen and Server in 0.0.0.0:8080 err := r.Run(":8080") if err != nil { return } }