diff --git a/internal/pihole/client.go b/internal/pihole/client.go
index df0a4ac..72cb517 100644
--- a/internal/pihole/client.go
+++ b/internal/pihole/client.go
@@ -71,7 +71,11 @@ func New(rawURL string, insecureTLS bool) (*Client, error) {
}
func normalizeBaseURL(raw string) (string, error) {
- parsed, err := url.Parse(strings.TrimSpace(raw))
+ raw = strings.TrimSpace(raw)
+ if address := net.ParseIP(raw); address != nil && address.To4() != nil {
+ raw = "http://" + raw
+ }
+ parsed, err := url.Parse(raw)
if err != nil || parsed.Host == "" || (parsed.Scheme != "http" && parsed.Scheme != "https") {
return "", errors.New("Pi-hole-Adresse muss eine vollständige HTTP- oder HTTPS-URL sein")
}
diff --git a/internal/pihole/client_test.go b/internal/pihole/client_test.go
index 479b02f..62a3daf 100644
--- a/internal/pihole/client_test.go
+++ b/internal/pihole/client_test.go
@@ -101,6 +101,10 @@ func TestNewValidatesAndNormalizesPiHoleURL(t *testing.T) {
if err != nil || client.BaseURL() != "http://pihole.local/custom/api" {
t.Fatalf("custom path not normalized: %q err=%v", client.BaseURL(), err)
}
+ client, err = New("10.0.20.100", false)
+ if err != nil || client.BaseURL() != "http://10.0.20.100/api" {
+ t.Fatalf("bare IPv4 address not normalized: %q err=%v", client.BaseURL(), err)
+ }
for _, invalid := range []string{"pi.hole", "ftp://pi.hole", "https://user:pass@pi.hole", "https://pi.hole?sid=secret"} {
if _, err := New(invalid, false); err == nil {
t.Errorf("invalid URL accepted: %s", invalid)
diff --git a/internal/web/server_test.go b/internal/web/server_test.go
index 0f917d9..0aca317 100644
--- a/internal/web/server_test.go
+++ b/internal/web/server_test.go
@@ -317,7 +317,7 @@ func TestPiHolePageRendersConnectionAndLocalDNSControls(t *testing.T) {
t.Fatalf("render Pi-hole page: %v", err)
}
body := rendered.String()
- for _, expected := range []string{`href="/pihole"`, `aria-current="page"`, `action="/pihole/7/records"`, `action="/pihole/7/records/update"`, `action="/pihole/7/records/archive"`, `action="/pihole/7/records/restore"`, `action="/pihole/7/records/delete"`, `action="/pihole/7/remove"`, `action="/pihole/7/delete"`, `action="/pihole/7/save"`, `action="/pihole/7/password"`, `name="active"`, `name="link_id" value="11"`, `name="insecure_tls"`, `data-dirty-form`, `data-dirty-submit disabled aria-disabled="true"`, `data-scroll-page-end`, `Anwendungspasswort anzeigen`, `Passwort entschlüsseln`, `Nur aus der WebUI entfernen`, `Anwendungspasswort`, `nas.lan`, `old.lan`, `192.168.1.20`} {
+ for _, expected := range []string{`href="/pihole"`, `aria-current="page"`, `action="/pihole/7/records"`, `action="/pihole/7/records/update"`, `action="/pihole/7/records/archive"`, `action="/pihole/7/records/restore"`, `action="/pihole/7/records/delete"`, `action="/pihole/7/remove"`, `action="/pihole/7/delete"`, `action="/pihole/7/save"`, `action="/pihole/7/password"`, `name="active"`, `name="link_id" value="11"`, `name="insecure_tls"`, `name="base_url" type="text"`, `data-dirty-form`, `data-dirty-submit disabled aria-disabled="true"`, `data-scroll-page-end`, `Anwendungspasswort anzeigen`, `Passwort entschlüsseln`, `Nur aus der WebUI entfernen`, `Anwendungspasswort`, `nas.lan`, `old.lan`, `192.168.1.20`} {
if !strings.Contains(body, expected) {
t.Errorf("Pi-hole page is missing %q", expected)
}
@@ -359,7 +359,7 @@ func TestPiHoleDisconnectedPageCentersConnectFormWithoutEmptyState(t *testing.T)
t.Fatalf("render disconnected Pi-hole page: %v", err)
}
body := rendered.String()
- for _, expected := range []string{`class="pihole-connect-stage"`, `class="form-panel pihole-connect-panel"`, `action="/pihole/connect"`} {
+ for _, expected := range []string{`class="pihole-connect-stage"`, `class="form-panel pihole-connect-panel"`, `action="/pihole/connect"`, `name="base_url" type="text"`, `10.0.20.100 oder https://pi.hole`} {
if !strings.Contains(body, expected) {
t.Errorf("disconnected Pi-hole page is missing %q", expected)
}
diff --git a/internal/web/templates/layout.html b/internal/web/templates/layout.html
index 4769f31..d792729 100644
--- a/internal/web/templates/layout.html
+++ b/internal/web/templates/layout.html
@@ -6,8 +6,8 @@
{{.Title}} · DNS Control
-
-
+
+
Zum Inhalt springen
diff --git a/internal/web/templates/pihole.html b/internal/web/templates/pihole.html
index 640d350..655d384 100644
--- a/internal/web/templates/pihole.html
+++ b/internal/web/templates/pihole.html
@@ -69,7 +69,7 @@
API-Zugang
Verbindung verwalten
{{if $view.FetchError}}Nicht erreichbar{{else}}Verbunden{{end}}
Das Anwendungspasswort bleibt verschlüsselt und standardmäßig verborgen. Eine Anzeige erfordert erneut dein Admin-Passwort.
-
+
Anwendungspasswort anzeigen
@@ -82,7 +82,7 @@
{{end}}