Skip to content

feat(portal): Pi-hole DNS-Schutz-Widget pro-Gerät (TP2a, zero-login) - #192

Merged
CallMeTechie merged 8 commits into
masterfrom
feature/pihole-portal-device
Jun 26, 2026
Merged

CallMeTechie merged 8 commits into
masterfrom
feature/pihole-portal-device

Conversation

@CallMeTechie

Copy link
Copy Markdown
Owner

Teilprojekt 2a der Initiative „Pi-hole im Portal"

Ein viertes, zero-login Portal-Widget „DNS-Schutz". Es zeigt diesem Gerät (identifiziert über die bestehende portalIdentityreq.portalPeerId, per IP) seine eigenen Pi-hole-Zähler: Anfragen · Geblockt (+ %) · Durchgelassen + Block-Rate-Balken. Reines pro-Gerät-Fundament — kein Owner/Haushalt, kein Login-Gate, kein portalIdentity-Eingriff (alles TP2b).

Bausteine (7 Commits)

  • Sync (e54f01d): neues In-Memory-Cache-Feld topClientsBlocked (peer-angereichert, mergeTopList(…,'ip',10)mapClientsToPeers, analog topClients). Keine DB-Migration.
  • Setting (5b911a8): portal.widget.pihole (Config + PUT, Default an).
  • Endpoint (620e01d): GET /api/v1/portal/pihole — gated, gewhitelistet, kein Leck.
  • Leak-Regression (e6c0146): verhaltensbasiert + strukturell (server + client).
  • Admin-Toggle (1770f47): 3 Themes (aurora/default/pro) + i18n.
  • Frontend (28dd648): Widget-Block (njk) + hydratePihole() + CSS + i18n.
  • Fix (70cb000): unavailable versteckt das Widget (Spec §5); self-contained feature-off-Test.

Sicherheit / Datengrenze

Der Endpoint liefert ausschließlich ein lokal konstruiertes Aggregat { total, blocked, allowed, blockedPct, asOf }. Nie rohe Listen, fremde Geräte/IPs, peerId, user_id oder owner_name. Dreifach abgesichert (Verhaltens-Leak-Test mit Fremdgerät, struktureller Server-Test, struktureller Client-Test). src/middleware/portalIdentity.js nachweislich unangetastet (git diff-Guard im Test).

Gate-Reihenfolge (deterministisch)

enabled→404 · widgets.pihole→404 · !hasFeature('pihole_integration') ODER instances.length===0unavailable · portalPeerId==nullunidentified · attribution==='collapsed'collapsed · in KEINER Liste→no_data (keine vorgetäuschten Nullen) · in einer Liste mit echtem 0→data total:0. Frontend: unavailable→Widget versteckt sich; collapsed/no_data/unidentified→statischer Hinweis; Netz-/Endpoint-Fehler→Retry.

Lizenz

Pro-Feature pihole_integration wiederverwendet (kein neuer Schlüssel). Widget-Toggle = Community; Datenfeature bleibt Pro-gegatet (Inline-Check → unavailable statt 403).

Tests

  • TP2a-Suite (6 neue Dateien): 21/21 grün.
  • Regression inkl. portal_identity*/portal_api/pihole_sync/pihole_aggregate/pihole_settings_api: 41/41 grün.
  • i18n-Parität: 2/2 grün.

Bekannte Einschränkung / Folge-Ticket

topClients (allowed) und topClientsBlocked (blocked) sind unabhängige Top-10-Listen → bei Geräten nahe der Listengrenze kann ein Zähler 0 statt „kein Datensatz" sein. Folge-Ticket: count-Parameter in piholeClient.getTopClients/Sync für volle pro-Gerät-Genauigkeit.

Abgrenzung

TP2b (pro-Besitzer + Haushalt, login-gegatet) baut darauf den req.portalOwnerId-Seam + Aggregation + Trust-Boundary auf.

🤖 Subagent-driven (7 Tasks, TDD, zweistufiges Review pro Task + finales opus-Whole-Branch-Review).

@CallMeTechie
CallMeTechie merged commit 951ff5b into master Jun 26, 2026
8 checks passed
@CallMeTechie
CallMeTechie deleted the feature/pihole-portal-device branch June 26, 2026 05:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant