From 00006431871d4a401d01217c9db0c0515dc69d04 Mon Sep 17 00:00:00 2001 From: sysops Date: Sun, 12 Jul 2026 16:38:22 +0200 Subject: [PATCH] Add missing server delete: handler, route, and UI button DeleteServer already existed in the store layer (refuses if clients still reference the server) but was never wired up anywhere, so there was no way to actually remove a server from the UI or API. Co-Authored-By: Claude Sonnet 5 --- handler/routes.go | 13 +++++++++++++ main.go | 1 + templates/servers.html | 31 +++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/handler/routes.go b/handler/routes.go index 4ed65a6..f204c9b 100644 --- a/handler/routes.go +++ b/handler/routes.go @@ -709,6 +709,19 @@ func CreateServer(db store.IStore) echo.HandlerFunc { } } +// RemoveServer handler deletes a server, refusing if any client still +// references it (see store.DeleteServer). Admin-only. +func RemoveServer(db store.IStore) echo.HandlerFunc { + return func(c echo.Context) error { + serverID := c.Param("id") + if err := db.DeleteServer(serverID); err != nil { + return c.JSON(http.StatusBadRequest, jsonHTTPResponse{false, err.Error()}) + } + log.Infof("Removed server %s", serverID) + return c.JSON(http.StatusOK, jsonHTTPResponse{true, "Server removed successfully"}) + } +} + // NewClient handler func NewClient(db store.IStore) echo.HandlerFunc { return func(c echo.Context) error { diff --git a/main.go b/main.go index e5596c6..2cbc8ec 100644 --- a/main.go +++ b/main.go @@ -264,6 +264,7 @@ func main() { app.POST(util.BasePath+"/servers/:id/settings", handler.SaveServerSettingsHandler(db), handler.ValidSession, handler.ContentTypeJson, handler.NeedsAdmin) app.POST(util.BasePath+"/servers/:id/interface", handler.UpdateServerInterfaceHandler(db), handler.ValidSession, handler.ContentTypeJson, handler.NeedsAdmin) app.POST(util.BasePath+"/servers/:id/keypair", handler.UpdateServerKeyPairHandler(db), handler.ValidSession, handler.ContentTypeJson, handler.NeedsAdmin) + app.POST(util.BasePath+"/servers/:id/delete", handler.RemoveServer(db), handler.ValidSession, handler.ContentTypeJson, handler.NeedsAdmin) app.POST(util.BasePath+"/backup/download", handler.DownloadBackup(db), handler.ValidSession, handler.ContentTypeJson, handler.NeedsAdmin) app.GET(util.BasePath+"/api/clients", handler.GetClients(db), handler.ValidSession) app.GET(util.BasePath+"/api/client/:id", handler.GetClient(db), handler.ValidSession) diff --git a/templates/servers.html b/templates/servers.html index c504c8a..f40c164 100644 --- a/templates/servers.html +++ b/templates/servers.html @@ -203,6 +203,9 @@ All Servers +
+ +

${safeName} ID: ${obj.id} @@ -470,6 +473,34 @@ All Servers }); }); + // Delete server button: rendered dynamically, use event delegation + $(document).ready(function () { + $('#servers-list').on('click', '.btn-delete-server', function () { + const serverId = $(this).data('serverid'); + const serverName = $(this).data('servername'); + if (!confirm("Are you sure you want to delete server \"" + serverName + "\" (" + serverId + ")?\n" + + "This only works if no clients are assigned to it anymore.")) { + return; + } + $.ajax({ + cache: false, + method: 'POST', + url: '{{.basePath}}/servers/' + serverId + '/delete', + dataType: 'json', + contentType: "application/json", + success: function (data) { + toastr.success("Server deleted successfully"); + $('#servers-list').empty(); + populateServersList(); + }, + error: function (jqXHR, exception) { + const responseJson = jQuery.parseJSON(jqXHR.responseText); + toastr.error(responseJson['message']); + } + }); + }); + }); + $(document).ready(function () { $.validator.setDefaults({ submitHandler: function (form) {