feat(portal): Pi-hole-Portal-Widget pro-Besitzer + Haushalt (TP2b) - #193
Merged
Merged
Conversation
…eScope
The TP2b 8a refactor moved the device render logic out of hydratePihole()
(now a thin segment-wiring delegator to hydratePiholeScope('device')); the
PT-i18n usage and raw-field leak guard now live in hydratePiholeScope. The
guard's intent is preserved by inspecting that function. CI gate (the file
was not in the local task subsets).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pi-hole-Portal-Widget pro-Besitzer + Haushalt (Teilprojekt 2b)
Schließt die Initiative „Pi-hole im Portal" ab (TP1 #189 → TP2a #192 → TP2b). Erweitert das TP2a-„DNS-Schutz"-Widget um zwei login-gegatete Ansichten:
Segment-Umschalter [Gerät] Ich Haushalt in der bestehenden Karte; der bisherige zero-login Gerät-Scope (TP2a) bleibt unverändert.
Architektur (5 isolierte Bausteine, keine DB-Migration)
portalOwner(nachportalIdentitygemountet) — setztreq.portalOwnerId/portalOwnerSource/portalLoggedIn.portalIdentitybleibt unangetastet.peers.peersOfOwner(userId)(direkterpeers.user_id-Lookup aus TP1) + Cache-Summe, kein N+1.GET /api/v1/portal/pihole/owner— gewhitelistetes Aggregat{total,blocked,allowed,blockedPct,deviceCount,asOf}.GET /api/v1/portal/pihole/household—{total,blocked,blockedPct,activeClients,asOf}, immer login-gegatet.portal.trust_owner_mapping(Default aus) + Admin-Toggle in allen 3 Themes mit Kiosk-Pflicht-Hinweis.portal.js/portal.njk.Sicherheits-Invarianten (jede testgesichert)
req.session.userId(eingeloggt) oder — nur bei aktivem Trust und ohne Session — auspeers.user_iddes identifizierten Geräts. Nie aus Body/Query/Header; die Endpoints nehmen keinenownerId-Parameter. IDOR-Negativtest vorhanden.on()-Falle:settings.get('portal.trust_owner_mapping','0') !== '0'(nicht deron()-Helfer, der'1'defaultet).topClients/IPs/peerId/user_id/owner_name/fremde Geräte. Verhaltens- + struktureller Leak-Test (server + client).peers.user_idgenullt) →no_data, nichtno_owner.createElement/textContent, keininnerHTMLmit Daten/i18n). i18n en+de. Parametrisiertes SQL.Tests
peers_of_owner,portal_trust_setting,portal_owner_middleware(Präzedenz-Matrix),pihole_portal_owner(inkl. IDOR-Negativ + deleted-user + collapsed/no_owner/feature-off),pihole_portal_household(login_required auch bei Trust an),owner_household_no_leak(verhaltens + strukturell),portal_trust_settings_ui,scope_js,scope_markup.portal_identity,portal_identity_dynamic,portal_api,pihole_portal_device,peers*);git diffbestätigtportalIdentity.jsunangetastet; i18n-Parität grün.unavailableversteckte den Umschalter im Haushalt-Scope vor dem ersten Sync) direkt gefixt — Karten-Hide nur noch fürdevice-Scope.Folge-Tickets (außerhalb Scope)
count-Parameter ingetTopClientsfür volle Top-N-Genauigkeit (geteilt mit TP2a; bis dahin transparenter „Snapshot"-Hinweis).destroyByUserIdbeim User-Löschen (Session-Invalidierung; vorbestehender Gap).🤖 Generated with Claude Code
https://claude.ai/code/session_01PrxALUszC9wFkYv1fedKyd