package main import ( "embed" _ "embed" "fmt" "io/fs" "log" "net/http" "os" "github.com/asdine/storm/v3" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/basicauth" "github.com/gofiber/fiber/v2/middleware/cors" "github.com/gofiber/fiber/v2/middleware/filesystem" "github.com/gofiber/fiber/v2/middleware/logger" "github.com/rs/zerolog" ) var ( //go:embed frontend/build frontend embed.FS ) type Server struct { Config *Config Database *storm.DB WebServer *fiber.App LogFile *os.File Log zerolog.Logger } func main() { server := Server{} err := LoadConfig(&server) if err != nil { log.Fatal("Unable to setup config and logging: ", err) } fmt.Println("Server: ", server.Config) app := fiber.New() // Setup CORS app.Use(cors.New(cors.Config{ AllowOrigins: "http://localhost:3000, http://localhost", AllowHeaders: "Origin, Content-Type, Accept", })) // Setup our logger app.Use(logger.New(logger.Config{ Output: server.LogFile, TimeZone: server.Config.Timezone, Format: `{"logtype":"webserver", "pid":"${pid}", "requestid":"${locals:requestid}", "status":"${status}", "method":"${method}", "path":"${path}​"}​` + "\n", })) server.WebServer = app defer server.LogFile.Close() // Close out our logfile when closing server. server.Database = SetupDatabase(&server) // Setup our database defer server.Database.Close() server.Log.Info().Msg("Database and Config loaded, starting webserver...") // Send all good message // Loading in the frontend files that were embedded reactFE, err := fs.Sub(frontend, "frontend/build") if err != nil { server.Log.Fatal().Msgf("Unable to load frontend/build: ", err) } staticFE, err := fs.Sub(frontend, "frontend/build/static") if err != nil { server.Log.Fatal().Msgf("Unable to load static files: ", err) } // serve our frontend and static files from our embed server.WebServer.Use("/", filesystem.New(filesystem.Config{ Root: http.FS(reactFE), })) server.WebServer.Use("/static", filesystem.New(filesystem.Config{ Root: http.FS(staticFE), PathPrefix: "static", })) // Serve up our static images server.WebServer.Static("/files", server.Config.Server.LocationFilesDir) // Load in our routes server.WebServer.Get("/hello", func(c *fiber.Ctx) error { // Basic Hello Route return c.SendString("GoInventorize Backend Hello Route!") }) // Unauthenticated config route to fetch the config server.WebServer.Get("api/config", server.GetServerConfig) // Setup our basic authentication if defined if server.Config.Authentication.BasicAuth { app.Use(basicauth.New(basicauth.Config{ Users: map[string]string{ server.Config.Authentication.UserName: server.Config.Authentication.Password, }, })) } // Location Routes server.WebServer.Get("/api/locations", server.GetAllLocationsHandler) server.WebServer.Get("/api/locations/:locID", server.GetSingleLocationHandler) server.WebServer.Post("/api/locations/new", server.AddNewLocationHandler) server.WebServer.Delete("/api/locations/:locID", server.DeleteLocationHandler) server.WebServer.Get("/api/locations/:locID/rooms", server.GetRoomsAtLocationHandler) // Room Routes server.WebServer.Get("/api/rooms", server.GetAllRoomsHandler) server.WebServer.Get("/api/rooms/:roomID", server.GetRoomHandler) server.WebServer.Post("/api/rooms/:locID/new", server.AddNewRoomHandler) server.WebServer.Delete("/api/rooms/:roomID", server.DeleteRoomHandler) server.WebServer.Get("/api/rooms/:roomID/cabinets", server.GetCabinetsAtRoomHandler) server.WebServer.Get("/api/rooms/:roomID/items", server.GetAllItemsAtRoomHandler) // Cabinet Routes server.WebServer.Get("/api/cabinets", server.GetAllCabinetsHandler) server.WebServer.Get("/api/cabinets/:cabinetID", server.GetCabinetHandler) server.WebServer.Post("/api/cabinets/:roomID/new", server.AddNewCabinetHandler) server.WebServer.Delete("/api/cabinets/:cabinetID", server.DeleteCabinetHandler) server.WebServer.Get("/api/cabinets/:cabinetID/items", server.GetAllItemsAtCabinetHandler) // Item Routes server.WebServer.Get("/api/items", server.GetAllItemsHandler) server.WebServer.Get("/api/items/:itemID", server.GetItemHandler) server.WebServer.Post("/api/items/cabinet/:cabinetID/new", server.AddNewItemHandler) server.WebServer.Post("/api/items/room/:roomID/new", server.AddNewItemHandler) server.WebServer.Delete("/api/items/:itemID", server.DeleteItemHandler) // Misc Routes server.WebServer.Get("/api/search/all", server.SearchAllHandler) server.WebServer.Get("/api/overview/all", server.GetDatabaseOverview) // Start Server fmt.Println("Everything ready, starting server! ", fmt.Sprintf(":%s", server.Config.Server.Port)) server.WebServer.Listen(fmt.Sprintf(":%s", server.Config.Server.Port)) }