Files
UmbrelApps/Docs/Plannen/Actief/005-Webinterface/TAKEN.md
T
HarmenandClaude Opus 5 c8d9765cb3 De app kijkt naar zijn eigen voordeur, en meet minder dan het plan beloofde
Open punt 5 van Webinterface, goedgekeurd en gebouwd. De agent verbindt met de
eigen TLS-poort, maakt de handdruk af en vergelijkt het getoonde certificaat
byte voor byte met het gekozen bestand.

Die vergelijking blijkt waardevoller dan de handdruk. Ze vangt een
certificaatwissel die nginx nooit heeft toegepast, en dat is precies het geval
waar een controle op vertrouwen blind voor is. Er wordt daarom bewust niet tegen
de certificaatwinkel van het besturingssysteem geverifieerd: een zelfondertekend
certificaat uploaden is een ondersteunde bron en die opstelling zou dan als kapot
gemeld worden.

Twee dingen liepen anders dan het plan zei en staan nu rechtgezet in PLAN 4a2,
OPEN punt 5 en de changelog. De belofte "luisteren, certificaat en doorverbinding
in een keer" klopt voor twee van de drie: na de handdruk wordt er niets
verstuurd. Een echt verzoek zou de sessie bytes geven, en sessies met bytes
worden nooit uit het activiteitenlog gefilterd, want die kunnen een storing zijn.

En dat filteren was de tweede verrassing. Elke meting is voor nginx een gewone
sessie en levert dus een logregel op; zonder rem ging het log over onszelf in
plaats van over wallets. Er zit nu een rem van vijf minuten op, er wordt niet
gemeten vlak na een herlading omdat het vorige certificaat er dan nog staat, en
de eigen regels worden weggelaten op grond van het moment.

Tests: 22 nieuw, met de nadruk op de niet-gelukkige paden en op de rem, want dat
is wat het log bruikbaar houdt. Alle vier de beslissende regels mutatie-getest.
De changelog kreeg ook de ontbrekende 0.0.15 erbij.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-27 15:24:24 +02:00

19 KiB
Raw Blame History

Taken - Webinterface

Prioriteit: A | Wacht op:

Wat hierna komt, besloten door de gebruiker op 27-08-2026: het masterplan Eigenimage. Dat is geen afhankelijkheid maar een volgordekeuze, en de reden staat aan die kant: een eigen image maakt van elke wijziging een bouwronde, en dat remt precies het itereren op de pagina dat dit plan nog doet. Rond je dit plan af, promoveer Eigenimage dan naar Actief/ met een nieuw tussennummer, en beantwoord eerst open punt 1 daar: blijft het Gitea-register ook bij publicatie de bron. Eigenaar van die vraag: gebruiker

Van C naar B naar A op 20-08-2026, op één dag. Eerst verviel de blokkade "de app geïnstalleerd en de agent draaiend". Aan het eind van die dag is dit het enige plan met werk dat nú te doen is: Appstore heeft alleen nog een herstart nodig die niet te plannen is, en Publicatie wacht op een publieke repo. Het nummer is daarom van 020 naar 005 gegaan; alleen dit plan kreeg een nieuw nummer, Appstore houdt 010.

Afgezakt van A naar C op 19-08-2026 bij het afsluiten van de sessie. De pagina is af voor zover dat zonder de Umbrel kan; al het resterende werk in dit plan begint met kijken of de agent doet wat hij zou moeten doen, en dat kan niet vóór de installatie.

Volgende stap

  • 0.0.10 op een telefoon nagekeken. In orde (20-08-2026). De gebruiker meldt dat het er goed uitziet op mobiel. Eén ding kwam eruit: de kopieerknoppen stonden niet op één lijn, omdat de knop door het omvouwen de lengte van het adres volgde. Verholpen in 0.0.11 met margin-left: auto op de knop. Bijvangst: 0.0.10 na 0.0.9 levert wél een update op, dus tweecijferige versiedelen zijn veilig

  • De agent zien draaien. Gelukt op 20-08-2026, over drie versies. De agent start en luistert, de pagina laadt, hij vond veertien certificaten in /certs/zoraxy en weigerde daarom te kiezen, een keuze op de pagina werd aangenomen, en daarna verbindt een wallet over 50022. De keten waar dit plan op wachtte is dus rond.

  • Het uploaden op het niet-gelukkige pad proberen, het enige stuk van 0.0.7 dat nog niet in een browser gezien is: een sleutel die niet bij het certificaat hoort. Verwacht: een weigering met een leesbare reden, en niets dat achterblijft in data/certs. De guard is met echte sleutelparen getoetst en mutatie-getest, dus dit gaat over de weg van de melding naar de pagina en niet over de controle zelf. Eigenaar: gebruiker

  • 0.0.7 en 0.0.9 in de browser nagekeken. Gelukt (20-08-2026): uploaden werkt, kiezen werkt, ook met de certificaten uit Zoraxy, de keuzelijst bij het installeren zag er goed uit en het versienummer op de pagina klopt. Daarmee is het uploadpad uit 0.0.7 bewezen op het gelukkige pad

  • 0.0.6 in de browser nagekeken (20-08-2026). Ziet er goed uit volgens de gebruiker. Wat eruit kwam: de badges konden weg, "your choice" zei niets, Trezor Suite is niet desktop-only, en Blockstream Green heet Blockstream

  • De pagina naast een werkende app gelegd (20-08-2026). Blokhoogte en backend-reactietijd komen binnen. Wat eruit kwam: van een verbonden wallet was niets te zien, de keuzelijst was te druk, en een reeks uitleg-teksten kon weg. Alles verwerkt in 0.0.6

  • Het activiteitenlog een etmaal laten lopen en dan kijken of het klopt: komt er een connected-regel bij een nieuwe wallet, en wat staat er na een nacht in. De teller is nieuw en is alleen tegen tijdelijke bestanden getoetst, niet tegen een echte wallet. Loopt sinds 27-08-2026 bij de gebruiker; hij kijkt er na een etmaal naar. Eigenaar: gebruiker

  • Fase 6, de tweede indeling. Opgegeven door de gebruiker op 27-08-2026 en het grootste blok werk dat er in dit plan nog ligt. Begint met de zelfcontrole, want dat is het enige echte nieuwe werk en het levert de vijfde widget van de bovenste rij

Daarna, en niet eerder:

  • Uitzoeken waar Nginx Proxy Manager op umbrelOS zijn certificaten neerzet. De mount staat uitgecommentarieerd in docker-compose.yml: een gok invullen zou Docker een lege maphierarchie laten aanmaken in de app-data van een app die er misschien niet eens is
  • Open punt 5: laten controleren of de TLS-poort zélf antwoordt. Dat is nu het enige wat de app niet over zichzelf weet, en het is zijn enige taak
  • Open punt 6: een certificaat uploaden via de pagina. Gebouwd in 0.0.7 (20-08-2026). Beschrijfbare mount voor de agent, een eigen nginx-locatie met een grotere limiet, en validatie met load_cert_chain voordat er iets geplaatst wordt. De bestandsnaam komt uit het certificaat zelf, dus padtrucs kunnen niet. Nog niet in een browser geprobeerd
  • Open punt 7: beslissen of Zoraxy een harde afhankelijkheid wordt. "Zoraxy of NPM" kan niet, en dat is op 20-08-2026 in de bron nagetrokken; alleen de wens staat nog open. Zie OPEN.md punt 7
  • Fase 5, het activiteitenlog, als de gebruiker het wil

De drie controles op openssl, nc en de WebDAV-module zijn vervallen met de komst van de agent: die doet dat werk zelf met de standaardbibliotheek. Zie PLAN.md §4a0.

Daarna, in deze volgorde:

  • Fase 2 bouwen op de uitkomst van die controle
  • Fase 5, als de gebruiker de wallet-activiteit wil

Fase 1 - Het liegen eruit

  • De verzonnen statusblokken (Online, Online) en het verzonnen logvenster weg
  • Het hardgecodeerde domein weg. De pagina bevat geen enkele installatiespecifieke waarde meer
  • Taal naar Engels, zie OPEN.md punt 2
  • Opnieuw opgebouwd op het design-systeem: tokens, card, badge, alert, list-item, btn, donker met een lichte variant en een schakelaar
  • De pagina verhuisd naar index.html.template in de app-root. Onder web/ zou elke latere wijziging een herinstallatie kosten: umbreld ververst bij een update alleen een whitelist en die kijkt niet in submappen. Als template zit hij in de whitelist én wordt hij bij elke start ingevuld

Fase 2 - De agent schrijft status.json

Herzien 19-08-2026: dit is een tweede container met een python-programma geworden in plaats van een shell-lus in de compose. Onderbouwing in PLAN.md §4a0.

  • agent.py.template, met de instellingen uit de omgeving in plaats van uit template-invulling. Daardoor staat er geen accolade-variabele in en blijft het geldige Python, dus is het te importeren in een test. De eerste toets in tests/ controleert precies die aanname
  • Schrijft status.json atomair via een tijdelijk bestand en os.replace, want de pagina leest het elke minuut en een half geschreven bestand geeft een lege pagina
  • Einddatum van het certificaat met een eigen DER-lezer. Getoetst tegen ssl op 74 echte CA-certificaten, op een levend servercertificaat, en op beide tijdvormen
  • Blokhoogte en reactietijd via blockchain.headers.subscribe over een verse socket
  • Een history-reeks bijhouden, afgekapt op 24 uur, met alléén de reactietijd. De sparkline is sinds 19-08-2026 de enige afnemer
  • Herkennen welke backend het is aan de hand van het adres, en unknown als hij niet in de tabel staat. Zie PLAN.md §4c: liever minder informatief dan onwaar
  • De lus valt nooit stil: een mislukte ronde wordt gelogd en overgeslagen. Stoppen zou de pagina op oude gegevens bevriezen, en dat is precies het liegen dat dit plan moest afschaffen
  • Draaien op de Umbrel. Niets hiervan is buiten de tests uitgevoerd

Fase 3 - De pagina vult zichzelf

  • fetch op status.json, elke minuut
  • Elk veld heeft een zichtbare onbekend-toestand; nooit een leeg veld, want dat leest als "in orde"
  • "Laatst bijgewerkt" tonen, en oude gegevens als zodanig laten zien zodra ze ouder zijn dan twee schrijfronden. Bijgesteld 19-08-2026 op verzoek van de gebruiker: dat gebeurt niet meer met een melding bovenaan de pagina maar alleen bij de waarden zelf, want die melding zei voor de vierde keer wat er al onder de blokhoogte, in de badge bij de Electrum-server en in de voettekst stond
  • Leesbare melding als het bestand ontbreekt, zonder dat het op een fout lijkt. Zie OPEN.md punt 1
  • Verifiëren tegen een échte status.json in plaats van tegen de voorbeeldversie uit de preview

Fase 4a - De indeling

Vastgesteld door de gebruiker op 19-08-2026 na het bekijken van de eerste versie. Ontwerp in PLAN.md §4a1.

  • Volgorde: Electrum-server, drie statustegels, activiteitenlog, certificaatkeuze, instellen van je wallet
  • "Point your wallet here" opgegaan in "Setting up your wallet"; het waren dezelfde kaders
  • Breed met een raster van twaalf kolommen, rijen die 5/7 en 7/5 afwisselen, afgekapt op 1760px
  • De leesvolgorde in de HTML is de bedoelde volgorde, zonder order in de CSS, zodat stapelen op een smal scherm dezelfde volgorde geeft. Gecontroleerd op 1760px en op mobiel
  • Statustegels rekken mee met de hoogte van hun buur, anders staat er een gat rechtsboven
  • Het logblok scrollt zelf horizontaal in plaats van de regel met puntjes af te kappen
  • Alle kaders hetzelfde opgebouwd (19-08-2026): een card-head met een titel in t-h3, dan de inhoud. De drie statustegels hadden een eigen kleine grijze kop in kapitalen. De titel gebruikt de token --text-primary, niet letterlijk wit, anders is hij onzichtbaar in de lichte variant
  • De onderregel van een statustegel is even hoog als de sparkline, zodat de drie getallen op één lijn staan. Gecontroleerd: koppen op y=153, getallen op y=311
  • De badge "Serving this page" verwijderd (19-08-2026, op aanwijzing van de gebruiker). Zie OPEN.md punt 5 voor wat er wél op die plek zou horen
  • De voetregel verwijderd (19-08-2026). Daarin stond "Last reading ... ago" plus het versienummer; het eerste stond al bij de waarden zelf
  • Het versienummer teruggezet, klein achter de tagline als v0.0.3. Dezelfde dag op verzoek van de gebruiker. In --text-sec en niet in --text-ter, want die laatste is in de lichte variant #bbbbbb op wit en op deze grootte onleesbaar
  • De certificaatlijst scrollt, met het aantal in de kop. Een gedeelde certificatenmap kan er tientallen bevatten. Gecontroleerd met 19 certificaten: 1062px inhoud in een vak van 360px, knop blijft eronder staan
  • Het logblok en het certificaatkader zijn even hoog. Het langste kader van de rij bepaalt de hoogte, en wat mag meegroeien zegt dat zelf met flex. Gemeten: 636px bij vier certificaten, 773px bij negentien, in beide gevallen allebei gelijk
  • Certificaat en activiteitenlog omgedraaid (19-08-2026, op verzoek). Certificaat links en smal, log rechts en breed. Dat pakt twee kanten goed uit: de kolomgrens valt nu samen met die van de rij erboven (gemeten: x=738 in beide rijen), en monospace logregels hebben de breedte beter nodig
  • Het losse verbindingsadres met kopieerknop eruit, plus het label "tested clients". Zonder verlies: hetzelfde adres staat bij elke clientregel, in de vorm die díe client wil, met een kopieerknop erbij. Het instelkader werd daarmee 533px in plaats van 610px
  • Nog niet met eigen ogen gezien op een echt breed scherm; gecontroleerd via de afmetingen van de kaders, niet visueel, want het browserpaneel stond dicht

Fase 4 - Bruikbaar in plaats van alleen eerlijk

  • Verloopwaarschuwing onder de dertig dagen, en een foutmelding als het certificaat verlopen is
  • Kopieerknop op het verbindingsadres, met terugval voor http zonder de clipboard-API
  • Verbindingsregels per client, met kopieerknop per regel. Bron: Referenties/Clients.md §4
  • Kopieerknoppen verschijnen bij hover over de regel. Met opacity en niet met display, zodat ze met de tab-toets bereikbaar blijven, plus focus-within en altijd zichtbaar op aanraakschermen
  • De kopieerknop echt uitproberen achter de app-proxy van umbrelOS. Die draait over http, dus de terugval met execCommand is daar het pad dat gebruikt wordt en niet de uitzondering. Wat op 19-08-2026 lokaal wél bewezen is: de faalroute meldt "Press Ctrl+C" in plaats van stil niets te doen. De geslaagde route vraagt een echte muisklik, want de clipboard-API weigert een klik die uit een script komt

Fase 4b - De certificaatkeuze

Besloten 19-08-2026 door de gebruiker: een keuzelijst op het dashboard in plaats van een sleutel in het configuratiebestand. Het ontwerp hoort bij het plan Configuratie §4e en §4f; hier staat alleen wat de pagina en de compose ervoor doen.

  • Keuzelijst op de pagina, met per certificaat de bron, de bestandsnaam, het domein en het aantal resterende dagen. Een verlopen certificaat staat er rood bij en wordt niet verborgen: het bestaat, en het kiezen ervan moet een zichtbare vergissing zijn en geen onvindbare
  • PUT naar api/certificate, doorgestuurd naar de agent. De WebDAV-truc is vervallen: de agent neemt de keuze aan en kan hem ook controleren, wat WebDAV niet kon
  • De pagina meldt níet zelf dat het gelukt is. Nginx moet het certificaat nog herladen, en dat blijkt pas uit de volgende status.json
  • De Zoraxy-mount van /certs naar /certs/zoraxy, en /certs/own erbij, zodat er per bron een map is. Beide containers hebben ze nodig: de agent om te kiezen, nginx om het bestand te openen
  • certificates in status.json, met per certificaat de bron, de naam, het domein uit het certificaat en de einddatum
  • De guard: een id die de agent niet zelf gevonden heeft, wordt geweigerd. Zowel bij de PUT als bij het kiezen. Getest, inclusief de mutatietest
  • Bij meerdere kandidaten kiest de app niet. Bijgesteld nadat bleek dat mijn eerste versie "de langst geldige" pakte, wat het plan Configuratie §4c uitdrukkelijk verbiedt: een verkeerd certificaat geeft een verbinding die het lijkt te doen en bij de wallet stukloopt op naamverificatie. De pagina toont dan een foutmelding met de kandidaten erin
  • De pagina toont bovenaan een foutmelding als er geen certificaat actief is, want dan is er geen TLS en dat is het ergste wat deze app kan overkomen

Fase 5 - Het activiteitenlog

Voorstel, nog niet besloten. Ontwerp in PLAN.md §4e. De kaart staat al op de pagina en toont no data, zodat de vorm te beoordelen is voordat er iets voor gebouwd wordt.

  • Vorm: logregels onder elkaar, monospace, nieuwste bovenaan, met de grens erbij vermeld dat een regel per protocolaanroep niet kan zonder het verkeer van de gebruiker uit te lezen
  • Gelukt, precies langs de weg die hier voorgesteld werd (opgemerkt 27-08-2026, het vinkje bleef staan terwijl het werk gedaan was). Het command-blok schrijft /var/lib/gate/stream-log.conf met $$ ontsnapt, en stream.conf.template haalt dat op met een include. Daarmee is het log_format langs de template-invulling gekomen zonder dat umbreld de dollartekens leegmaakte
  • Bytes van een lópende verbinding: nog steeds niet, en dat is een bewuste halve oplossing. nginx logt een stream-sessie pas bij het sluiten, dus een wallet die uren openstaat levert geen regel op. Wat er in plaats daarvan kwam is een teller uit /proc/net/tcp in het command-blok: die ziet dat er verbindingen zijn, maar niet hoeveel er doorheen gaat. Voor "is mijn wallet verbonden" is dat genoeg; wie bytes wil, moet iets anders verzinnen
  • log in status.json, zonder client-IP en zonder bronpoort. Gebouwd (vinkje bleef staan). De agent leest stream.log, voegt de vorige regels samen en houdt de laatste 200 aan

Fase 6 - De tweede indeling

Opgegeven door de gebruiker op 27-08-2026, na het zien en testen van alles uit de eerste indeling. Ontwerp in PLAN.md §4a2, inclusief de twee besluiten die hier bewust teruggedraaid worden en de eis die deze indeling zelf oproept.

Volgorde: eerst de zelfcontrole, dan de opmaak. Die eerste is het enige echte nieuwe werk en hij levert de vijfde widget; de rest is de pagina verbouwen om wat er dan staat.

  • De zelfcontrole gebouwd in 0.0.16 (27-08-2026). De agent verbindt met poort 50022 van de nginx-container ernaast, maakt de handdruk af en vergelijkt het getoonde certificaat byte voor byte met het gekozen bestand. Die vergelijking is het punt: een herlading die niet aankwam ziet er van buiten goed uit. Vier toestanden in status.json onder tls.self_check: off, ok, wrong-certificate, failed. Bij een wijziging komt er een regel in het activiteitenlog

    **Twee dingen die bij het bouwen anders liepen dan het plan zei.** Ten eerste bewijst de controle de
    doorverbinding naar de Electrum-server **niet**; zie §4a2 voor waarom dat een bewuste ruil is. Ten
    tweede bleek elke meting een sessieregel op te leveren, dus er zit nu een rem op (vijf minuten) en
    een filter die de eigen regels weglaat. Zonder die twee ging het activiteitenlog over onszelf
    
    Getest in `tests/test_agent_zelfcontrole.py`, 22 toetsen, met de nadruk op de niet-gelukkige paden:
    geen certificaat, dichte poort, iets dat luistert maar geen TLS spreekt, en een ander certificaat aan
    de lijn. Alle vier de beslissende regels zijn mutatie-getest
    
  • Rij 1 wordt vijf gelijke widgets: Electrum-server, blokhoogte, reactietijd, certificaat, zelfcontrole

  • Een eigen raster van vijf kolommen voor die rij, en beslissen wat er tussen "vijf naast elkaar" en "gestapeld op mobiel" gebeurt. Vijf valt niet netjes in twaalf kolommen; dit is nieuw werk

  • De Electrum-serverwidget kleiner, met minder onderteksten

  • De certificaatwidget toont het gekozen certificaat: naam en dagen tot vernieuwing. Niet de keuze

  • Kiezen, uploaden en afhandelen naar een dialoog achter een hamburger- of puntjesmenu rechtsboven. Met het dialog-element, want focus en Escape zitten erin. De lijst blijft een lijst, zie §4a2

  • De licht/donker-schakelaar het menu in (27-08-2026). Staat nu als losse knop rechtsboven. Let op de vorm: in een menu hoort de huidige stand te staan en niet de handeling, dus niet het label "Light" overnemen terwijl de pagina licht is. Zie §4a2

  • De foutmelding "geen certificaat actief" blijft bovenaan staan en krijgt de knop die de dialoog opent. Dit is de harde eis van deze indeling: een verse installatie heeft geen certificaat, en de pagina is de enige plek waar je er een kiest. Zie §4a2 en de klem van 0.0.3

  • Het activiteitenlog over de volle breedte

  • "Setting up your wallet" dichtgeklapt met details/summary, en compacter

  • Twee kopieerknoppen in plaats van één per clientregel, met de wallets gegroepeerd onder de vorm die ze willen. Niet één platte lijst naast twee losse knoppen: dan is het adres er nog wel, maar niet meer bij welke wallet welk adres hoort. Bron blijft Referenties/Clients.md §4

  • Opruimen wat vervalt: de statustegels hoeven niet meer mee te rekken met hun buur, en het logblok en de certificaatlijst hoeven niet meer samen te groeien. Dat laatste was de hele inhoud van 0.0.13

  • Na afloop op mobiel nakijken, net als bij 0.0.10. De leesvolgorde in de HTML blijft de bedoelde volgorde, zonder order in de CSS

Geblokkeerd / wacht op

  • Niets. De afhankelijkheid van Configuratie is vervallen, zie PLAN.md