fix: NPM remote toggle auto-save, proxy resync on remote change, webhook URL as path

- Remote NPM toggle now auto-saves immediately when toggled
- Toggling npm_remote triggers proxy resync (re-creates routes with server_ip or container name)
- Webhook URL shows just the path (/api/webhook/{secret}) instead of full URL with wrong domain
- Fix tag dropdown: resolve registry ID from name before fetching tags
- Remove unused fmt import
This commit is contained in:
2026-04-05 02:27:41 +03:00
parent 195ef3e7e5
commit b54481aff8
3 changed files with 31 additions and 26 deletions
+5 -24
View File
@@ -2,7 +2,6 @@ package api
import (
"context"
"fmt"
"log/slog"
"net/http"
"path/filepath"
@@ -234,6 +233,7 @@ func (s *Server) updateSettings(w http.ResponseWriter, r *http.Request) {
// If proxy-affecting settings changed, re-sync all proxy routes in the background.
proxyChanged := existing.Domain != updated.Domain ||
existing.ProxyProvider != updated.ProxyProvider ||
existing.NpmRemote != updated.NpmRemote ||
sslChanged
if proxyChanged {
go s.resyncAllProxies(existing, updated)
@@ -267,20 +267,13 @@ func (s *Server) getWebhookURL(w http.ResponseWriter, r *http.Request) {
return
}
webhookURL := ""
webhookPath := ""
if settings.WebhookSecret != "" {
host := settings.Domain
scheme := "https"
if host == "" {
// Fall back to request host for dev/local setups.
host = r.Host
scheme = "http"
}
webhookURL = fmt.Sprintf("%s://%s/api/webhook/%s", scheme, host, settings.WebhookSecret)
webhookPath = "/api/webhook/" + settings.WebhookSecret
}
respondJSON(w, http.StatusOK, map[string]string{
"webhook_url": webhookURL,
"webhook_url": webhookPath,
})
}
@@ -292,19 +285,7 @@ func (s *Server) regenerateWebhookSecret(w http.ResponseWriter, r *http.Request)
return
}
settings, err := s.store.GetSettings()
if err != nil {
respondError(w, http.StatusInternalServerError, "failed to get settings: "+err.Error())
return
}
host := settings.Domain
scheme := "https"
if host == "" {
host = r.Host
scheme = "http"
}
webhookURL := fmt.Sprintf("%s://%s/api/webhook/%s", scheme, host, secret)
webhookURL := "/api/webhook/" + secret
respondJSON(w, http.StatusOK, map[string]string{
"webhook_url": webhookURL,
+6 -1
View File
@@ -158,7 +158,12 @@
tagsLoading = true;
try {
availableTags = await api.listRegistryTags(project.registry, project.image);
// Look up registry ID from name.
const registries = await api.listRegistries();
const reg = registries.find(r => r.name === project?.registry);
if (reg) {
availableTags = await api.listRegistryTags(reg.id, project.image);
}
} catch {
availableTags = [];
} finally {
+20 -1
View File
@@ -130,7 +130,26 @@
} catch { sslCertName = `Certificate #${sslCertificateId}`; }
}
async function init() { await loadData(); await resolveCertName(); }
let initialized = $state(false);
async function saveNpmRemote(value: boolean) {
try {
await updateSettings({ npm_remote: value } as any);
toasts.success($t('settingsCredentials.saved'));
} catch (err) {
toasts.error(err instanceof Error ? err.message : $t('settingsCredentials.saveFailed'));
}
}
// Auto-save npm_remote when toggled (skip initial load).
$effect(() => {
const val = npmRemote;
if (initialized) {
saveNpmRemote(val);
}
});
async function init() { await loadData(); await resolveCertName(); initialized = true; }
$effect(() => { init(); });
</script>