2023-11-12 17:43:23 +03:00
|
|
|
package main
|
|
|
|
|
2025-01-04 00:00:10 +03:00
|
|
|
/*
|
|
|
|
|
|
|
|
* 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 (
|
2025-01-04 00:00:10 +03:00
|
|
|
"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"
|
2024-07-24 01:15:37 +03:00
|
|
|
"github.com/ngn13/website/api/database"
|
2023-11-12 17:43:23 +03:00
|
|
|
"github.com/ngn13/website/api/routes"
|
2025-01-04 00:00:10 +03:00
|
|
|
"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() {
|
2024-07-24 01:15:37 +03:00
|
|
|
var (
|
2025-01-04 00:00:10 +03:00
|
|
|
app *fiber.App
|
|
|
|
stat status.Type
|
|
|
|
|
|
|
|
conf config.Type
|
|
|
|
db database.Type
|
|
|
|
|
2024-07-24 01:15:37 +03:00
|
|
|
err error
|
|
|
|
)
|
|
|
|
|
2025-01-04 00:00:10 +03:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2025-01-04 00:00:10 +03:00
|
|
|
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())
|
2024-07-24 01:15:37 +03:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2025-01-04 00:00:10 +03:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2024-07-24 01:15:37 +03:00
|
|
|
app = fiber.New(fiber.Config{
|
2025-01-04 00:00:10 +03:00
|
|
|
AppName: "ngn's website",
|
2024-07-24 01:15:37 +03:00
|
|
|
DisableStartupMessage: true,
|
2025-01-04 00:00:10 +03:00
|
|
|
ServerHeader: "",
|
2024-07-24 01:15:37 +03:00
|
|
|
})
|
|
|
|
|
|
|
|
app.Use("*", func(c *fiber.Ctx) error {
|
2025-01-04 00:00:10 +03:00
|
|
|
// CORS stuff
|
2024-07-24 01:15:37 +03:00
|
|
|
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")
|
2025-01-04 00:00:10 +03:00
|
|
|
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
|
|
|
|
2025-01-04 00:00:10 +03:00
|
|
|
c.Locals("status", &stat)
|
|
|
|
c.Locals("config", &conf)
|
2024-07-24 01:15:37 +03:00
|
|
|
c.Locals("database", &db)
|
2024-10-06 17:30:25 +03:00
|
|
|
|
2024-07-24 01:15:37 +03:00
|
|
|
return c.Next()
|
|
|
|
})
|
|
|
|
|
|
|
|
// index route
|
2025-01-04 00:00:10 +03:00
|
|
|
app.Get("/", routes.GET_Index)
|
2024-07-24 01:15:37 +03:00
|
|
|
|
2025-01-04 00:00:10 +03:00
|
|
|
// version groups
|
|
|
|
v1 := app.Group("v1")
|
2024-10-06 17:30:25 +03:00
|
|
|
|
2025-01-04 00:00:10 +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)
|
2025-01-04 00:00:10 +03:00
|
|
|
v1.Get("/news/:lang", routes.GET_News)
|
2024-10-06 17:30:25 +03:00
|
|
|
|
2025-01-04 00:00:10 +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
|
|
|
|
2025-01-04 00:00:10 +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)
|
|
|
|
|
2025-01-04 00:00:10 +03:00
|
|
|
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
|
2024-07-24 01:15:37 +03:00
|
|
|
app.All("*", func(c *fiber.Ctx) error {
|
2025-01-04 00:00:10 +03:00
|
|
|
return util.JSON(c, http.StatusNotFound, fiber.Map{
|
|
|
|
"error": "Endpoint not found",
|
|
|
|
})
|
2024-07-24 01:15:37 +03:00
|
|
|
})
|
|
|
|
|
2025-01-04 00:00:10 +03:00
|
|
|
// 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
|
|
|
|
2025-01-04 00:00:10 +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())
|
2024-07-24 01:15:37 +03:00
|
|
|
}
|
2025-01-04 00:00:10 +03:00
|
|
|
|
|
|
|
stat.Stop()
|
2023-11-12 17:43:23 +03:00
|
|
|
}
|