Files
nginx-proxy-manager/backend/internal/api/handler/setup.go
T
2026-10-01 13:22:36 +10:00

88 lines
2.5 KiB
Go

package handler
import (
"encoding/json"
"net/http"
"sync"
c "npm/internal/api/context"
h "npm/internal/api/http"
"npm/internal/config"
"npm/internal/database"
"npm/internal/logger"
)
// SetupDatabase tests the connection parameters provided by the setup
// wizard, saves them to the db.conf file and then calls onConfigured to
// connect, migrate and finish starting the application.
// Route: POST /setup/database
func SetupDatabase(onConfigured func() error) func(http.ResponseWriter, *http.Request) {
// Serialises submissions so that two browsers can't race to
// configure different databases
var mu sync.Mutex
return func(w http.ResponseWriter, r *http.Request) {
mu.Lock()
defer mu.Unlock()
if config.IsDBSetup {
h.ResultErrorJSON(w, r, http.StatusForbidden, "Database is already configured", nil)
return
}
bodyBytes, _ := r.Context().Value(c.BodyCtxKey).([]byte)
var newCfg config.DBConfig
if err := json.Unmarshal(bodyBytes, &newCfg); err != nil {
h.ResultErrorJSON(w, r, http.StatusBadRequest, h.ErrInvalidPayload.Error(), nil)
return
}
switch newCfg.GetDriver() {
case config.DatabaseSqlite:
// Sqlite lives in the data folder and needs nothing else
newCfg = config.DBConfig{Driver: config.DatabaseSqlite}
case config.DatabasePostgres:
if newCfg.SSLMode == "" {
newCfg.SSLMode = "disable"
}
newCfg.Schema = newCfg.GetSchema()
default:
if newCfg.SSLMode == "" {
newCfg.SSLMode = "disable"
}
// Schemas are a postgres concept
newCfg.Schema = ""
}
if err := database.TestConnection(newCfg); err != nil {
logger.Warn("Database setup connection test failed: %s", err.Error())
h.ResultErrorJSON(w, r, http.StatusBadRequest, err.Error(), nil)
return
}
if err := config.SaveDBConfig(newCfg); err != nil {
logger.Error("DatabaseConfigSaveError", err)
h.ResultErrorJSON(w, r, http.StatusInternalServerError, "Unable to save database configuration", nil)
return
}
prevCfg := config.Configuration.DB
config.Configuration.DB = newCfg
logger.Info("Database configuration saved to %s", config.GetDBConfigFile())
if err := onConfigured(); err != nil {
logger.Error("DatabaseSetupError", err)
// Roll back so the wizard can be attempted again
database.Close()
config.Configuration.DB = prevCfg
if rmErr := config.RemoveDBConfig(); rmErr != nil {
logger.Error("DatabaseConfigRemoveError", rmErr)
}
h.ResultErrorJSON(w, r, http.StatusInternalServerError, err.Error(), nil)
return
}
h.ResultResponseJSON(w, r, http.StatusOK, true)
}
}