website/api/main.go

132 lines
3.4 KiB
Go
Raw Permalink Normal View History

2023-11-12 17:43:23 +03:00
package main
/*
* website/api | API server for my personal website
* written by ngn (https://ngn.tf) (2025)
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
2023-11-12 17:43:23 +03:00
import (
"net/http"
2023-11-12 17:43:23 +03:00
"github.com/gofiber/fiber/v2"
2024-10-06 17:30:25 +03:00
"github.com/ngn13/website/api/config"
"github.com/ngn13/website/api/database"
2023-11-12 17:43:23 +03:00
"github.com/ngn13/website/api/routes"
"github.com/ngn13/website/api/status"
2024-10-06 17:30:25 +03:00
"github.com/ngn13/website/api/util"
2023-11-12 17:43:23 +03:00
)
func main() {
var (
app *fiber.App
stat status.Type
conf config.Type
db database.Type
err error
)
if err = conf.Load(); err != nil {
util.Fail("failed to load the configuration: %s", err.Error())
2024-10-06 17:30:25 +03:00
return
}
if !conf.GetBool("debug") {
util.Debg = func(m string, v ...any) {}
}
if err = db.Load(); err != nil {
util.Fail("failed to load the database: %s", err.Error())
return
}
if err = stat.Setup(&conf, &db); err != nil {
util.Fail("failed to setup the status checker: %s", err.Error())
2024-10-06 17:30:25 +03:00
return
}
app = fiber.New(fiber.Config{
AppName: "ngn's website",
DisableStartupMessage: true,
ServerHeader: "",
})
app.Use("*", func(c *fiber.Ctx) error {
// CORS stuff
c.Set("Access-Control-Allow-Origin", "*")
c.Set("Access-Control-Allow-Headers",
"Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
c.Set("Access-Control-Allow-Methods", "PUT, DELETE, GET") // POST can be sent from HTML forms, so I prefer PUT for API endpoints
2024-10-06 17:30:25 +03:00
c.Locals("status", &stat)
c.Locals("config", &conf)
c.Locals("database", &db)
2024-10-06 17:30:25 +03:00
return c.Next()
})
// index route
app.Get("/", routes.GET_Index)
// version groups
v1 := app.Group("v1")
2024-10-06 17:30:25 +03:00
// v1 user routes
v1.Get("/services", routes.GET_Services)
2025-01-09 00:30:59 +03:00
v1.Get("/projects", routes.GET_Projects)
v1.Get("/metrics", routes.GET_Metrics)
v1.Get("/news/:lang", routes.GET_News)
2024-10-06 17:30:25 +03:00
// v1 admin routes
v1.Use("/admin", routes.AuthMiddleware)
v1.Get("/admin/logs", routes.GET_AdminLogs)
2025-01-09 00:30:59 +03:00
v1.Get("/admin/service/check", routes.GET_CheckService)
v1.Put("/admin/service/add", routes.PUT_AddService)
v1.Delete("/admin/service/del", routes.DEL_DelService)
2025-01-09 00:30:59 +03:00
v1.Put("/admin/project/add", routes.PUT_AddProject)
v1.Delete("/admin/project/del", routes.DEL_DelProject)
v1.Put("/admin/news/add", routes.PUT_AddNews)
v1.Delete("/admin/news/del", routes.DEL_DelNews)
2024-10-06 17:30:25 +03:00
// 404 route
app.All("*", func(c *fiber.Ctx) error {
return util.JSON(c, http.StatusNotFound, fiber.Map{
"error": "Endpoint not found",
})
})
// start the status checker
if err = stat.Run(); err != nil {
util.Fail("failed to start the status checker: %s", err.Error())
return
}
2024-10-06 17:30:25 +03:00
// start the app
util.Info("starting web server on %s", conf.GetStr("host"))
if err = app.Listen(conf.GetStr("host")); err != nil {
util.Fail("failed to start the web server: %s", err.Error())
}
stat.Stop()
2023-11-12 17:43:23 +03:00
}