diff --git a/Docs/Plannen/Actief/008-Umbrelapp/OPEN.md b/Docs/Plannen/Actief/008-Umbrelapp/OPEN.md index d923299..540318f 100644 --- a/Docs/Plannen/Actief/008-Umbrelapp/OPEN.md +++ b/Docs/Plannen/Actief/008-Umbrelapp/OPEN.md @@ -82,13 +82,32 @@ proxy met een eigen domein is wat Electrum Gate al doet. Beide veranderen dit van "een vlag omzetten" in een eigen ontwerpvraag. + **Richting van de gebruiker, 28-08-2026:** een certificaat op een eigen subdomein, en Zoraxy dat die + naam doorzet naar de relay op de interne poort. Dat is dezelfde weg die Electrum Gate al gebruikt, dus + het is bekend terrein en geen nieuw bouwwerk. Twee dingen die daarbij vastliggen: + + - **Zoraxy moet de WebSocket-upgrade doorlaten.** Dit is geen gewone HTTP-site; alles loopt over één + opgewaardeerde verbinding, en bij de meeste reverse proxies is dat een schakelaar per host. Staat die + uit, dan lijkt het beeld op dat van vanochtend: een server die leeft en een cliënt die niets doet. De + handshake-curl uit [PLAN.md](PLAN.md) §6a stap 3 is dan de test, met de publieke naam in plaats van + het IP; + - **TLS lost punt 8 niet op, het maakt het dringender.** Een certificaat regelt versleuteling en + waarschijnlijk iOS, maar niet wie er mag schrijven. Achter een publieke naam is de kale relay vanaf + het internet bereikbaar zonder enige toegangscontrole. De kale relay op een LAN is iets anders dan de + kale relay op een publiek subdomein. + **Goedkoopste volgende meting, en die kost niets:** op de telefoon controleren of de synchronisatie überhaupt aangaat en of het apparaat om een bevestiging vraagt. Is het antwoord nee, dan is TLS niet de verdachte en zou een certificaat niets opgelost hebben. **Moment:** nadat de verbouwing staat; de desktop werkt en dat is genoeg om verder te bouwen · **Eigenaar:** gebruiker -8. **Welke limiter komt er op de kale relay?** +8. **Welke limiter komt er op de kale relay?** - **beslist op 28-08-2026: weg 1, de relay uitbreiden via + `createRelay`.** Het ontwerp staat in [PLAN.md](PLAN.md) §4g en bleek veel kleiner dan hieronder + aangenomen: het zijn twee terugroepfuncties en geen eigen relay. De gebruiker breidde het uit met een + schakelaar voor nieuwe eigenaars en het wissen van data per eigenaar. Het geheime pad uit de vierde weg + is bewust niet genomen. De rest van dit punt blijft staan als onderbouwing tot de verbouwing er is. + Nieuw op 27-08-2026, uit de richting in punt 6. Dit is de vraag die met "kaal gaan" meekomt en die je niet kunt uitstellen tot na de verbouwing, want hij bepaalt of er een eigen image nodig blijft. @@ -134,7 +153,11 @@ **Moment:** als fase 4 helemaal af is, dus als bewezen is dat er iets te delen valt · **Eigenaar:** gebruiker -2. **Komt er een statuspagina?** +2. **Komt er een statuspagina?** - **beslist op 28-08-2026: ja, en achter de umbrelOS-inlog.** De + poortindeling gaat om: de pagina komt op de app-proxy mét inlog, de relay op een eigen gepubliceerde + poort waar Zoraxy naartoe wijst. Daarmee vervalt het bezwaar hieronder, want de pagina ligt dan wél + achter een grens. Zie [PLAN.md](PLAN.md) §4h. + Electrum Gate heeft er een en die bleek in de praktijk het nuttigste deel van die app. Hier zou dat kunnen: draait de relay, hoe groot is de database, wanneer was de laatste synchronisatie, en is er een eigenaar geregistreerd. Dat laatste is meer dan gemak, want het is precies waar het stil kan misgaan. diff --git a/Docs/Plannen/Actief/008-Umbrelapp/PLAN.md b/Docs/Plannen/Actief/008-Umbrelapp/PLAN.md index c148247..f9153b0 100644 --- a/Docs/Plannen/Actief/008-Umbrelapp/PLAN.md +++ b/Docs/Plannen/Actief/008-Umbrelapp/PLAN.md @@ -33,6 +33,12 @@ Alles hieronder rust op [Upstream-evolu-relay.md](../../../Referenties/Upstream- feiten met bron-URL per stuk staan. De vorm van een Umbrel-app staat in [Umbrel-appstore-spec.md](../../../Referenties/Umbrel-appstore-spec.md). +> **Let op de tweedeling in deze paragraaf.** §4a tot en met §4f beschrijven het pakket **zoals het op +> 25-08-2026 gebouwd is**, met de relay van Trezor, een Postgres en de quota-manager. Dat pakket gaat eruit: +> de proef van 28-08 (§6a) bewees dat de kale Evolu-relay werkt, en §4g en §4h beschrijven wat ervoor in de +> plaats komt. De oude paragrafen blijven staan tot de verbouwing gedaan is, want ze leggen uit waaróm er +> iets weggaat; daarna verdwijnen ze. + ### 4a. Drie containers, twee images De relay en de quota-manager komen uit **dezelfde** image met een ander `command`: bovenstrooms is het één @@ -111,6 +117,70 @@ Voorlopig blijft die tag lokaal, op verzoek van de gebruiker: dat is de kortste die je kunt proberen. Compose haalt niets op zolang de image lokaal bestaat, dus dezelfde regel werkt later ook als de tag naar een register wijst. Waar dat register komt te staan is [OPEN.md](OPEN.md) punt 1. +### 4g. De limiter is niet een eigen relay maar twee functies + +Beslist op 28-08-2026 door de gebruiker, na de geslaagde proef. De feiten met bron staan in +[Upstream-evolu-relay.md](../../../Referenties/Upstream-evolu-relay.md) §8. + +`createRelay` uit `@evolu/nodejs` neemt twee terugroepfuncties: `isOwnerAllowed(ownerId)` en +`isOwnerWithinQuota(ownerId, requiredBytes)`. **Trezor doet precies dit en niets meer**; hun hele +quota-manager met Postgres bestaat alleen om de tabel te vullen die die twee functies raadplegen. Wij +vullen ze met eigen logica en houden verder alles van bovenstrooms. Er wordt dus **geen relay nagebouwd en +niets van Evolu aangepast**. + +De logica die erin komt, zoals de gebruiker hem formuleerde: + +- **de eerste eigenaar die zich meldt, wordt de eigenaar.** Geen id intikken, want Suite toont je `OwnerId` + nergens; +- **een schakelaar die bepaalt of er nog nieuwe eigenaars bij mogen.** Dit is wat de leer-variant bruikbaar + maakt in een huishouden: openzetten, tweede apparaat koppelen, weer dichtzetten; +- **data per eigenaar wissen**, zodat een verkeerd geleerde eigenaar geen herinstallatie kost. + +**De prijs die we hiermee accepteren:** de bouwstap en het eigen register komen terug, want dit vraagt een +eigen image. Wat níet terugkomt is de Postgres, het wachtwoord en het onderhoud aan andermans schema. Het +bouwrecept in `tools/evolu-relay/` blijft dus bestaan, maar het bouwt straks niet meer de repo van Trezor; +het bouwt een klein eigen programma tegen `@evolu/nodejs`. + +**Twee dingen om niet over te slaan.** De gepubliceerde image zet `isOwnerWithinQuota` op **1 MB per +eigenaar** en laat `isOwnerAllowed` weg. Nemen wij die grens over zonder erbij na te denken, dan stopt het +synchroniseren zodra de labelgeschiedenis daar tegenaan loopt, en dat merk je pas als het gebeurt. En de +allowlist is **staat**: die hoort onder `${APP_DATA_DIR}/data/`, naast de relay-database en niet erin. + +**Wat er bewust níet in gaat: een geheim pad in de URL.** De cliënt neemt een pad in de relay-URL letterlijk +over, dus Zoraxy had alleen een onraadbaar pad kunnen doorlaten. Dat is een laag vóór de relay in plaats van +erin, en het is met één proxyregel alsnog toe te voegen. De gebruiker ziet er geen reden voor nu de +allowlist er komt, en dat klopt: het beschermt tegen hetzelfde, alleen eerder in de keten. + +### 4h. De poorten omgedraaid: pagina achter de inlog, relay ernaast + +Beslist op 28-08-2026, en het draait §4c om. Daar stond de relay achter de app-proxy met de inlog uit, en +dat maakte een statuspagina onmogelijk zonder die pagina net zo bloot te leggen. + +De nieuwe indeling volgt het patroon dat Electrum Gate in deze repo al gebruikt: + +- **de pagina achter `app_proxy`, met de umbrelOS-inlog gewoon aan.** Dat is de app-tegel op het dashboard; +- **de relay op een eigen `ports:`-regel**, waar Zoraxy met TLS op een eigen subdomein naartoe wijst. + +Suite ziet daarmee nooit een inlogpagina en de pagina is nooit onbeschermd. Dat lost open punt 2 op zonder +de tweede poort die daar als bezwaar stond, want die tweede poort is er toch al. + +**Zoraxy moet de WebSocket-upgrade doorlaten**, anders lijkt het beeld op dat van 28-08: een server die +leeft en een cliënt die niets doet. De handshake-curl uit §6a stap 3 is de test. + +**De pagina volgt hetzelfde ontwerpsysteem als Electrum Gate**, aangewezen door de gebruiker op +28-08-2026: `HomeGit/Docs/website-design-system.html`. Dat is geen kwestie van smaak maar van herkenning, +want de twee apps staan straks naast elkaar op hetzelfde dashboard. Electrum Gate neemt die tokens +letterlijk over (`data-theme` maal `data-accent`, dezelfde accentkleur) en dat is het vertrekpunt. **Eén +ding niet overnemen uit het bronbestand: de verwijzing naar Google Fonts.** De pagina van Electrum Gate +heeft die bewust niet, en een app op een Umbrel hoort niet stuk te gaan of te vertragen op een lettertype +dat van buiten moet komen. + +**De pagina praat niet met Docker.** Dezelfde regel als bij Electrum Gate: geen socket. De pagina en het +relay-proces delen een map onder `${APP_DATA_DIR}/data/`, en een knop op de pagina zet daar een vlagbestand +neer dat het relay-proces oppakt. Dat geldt zowel voor de schakelaar als voor het wissen: het wissen raakt +de SQLite van de relay, en dat hoort het proces te doen dat die database bezit, niet een tweede container +die er langszij in schrijft. + ## 5. Raakvlakken - **Proefopstelling** leverde alle feiten waarop §4 rust, en heeft nog twee open vragen die dit plan raken: diff --git a/Docs/Plannen/Actief/008-Umbrelapp/PROGRESS.md b/Docs/Plannen/Actief/008-Umbrelapp/PROGRESS.md index 9229d7b..df4d8c6 100644 --- a/Docs/Plannen/Actief/008-Umbrelapp/PROGRESS.md +++ b/Docs/Plannen/Actief/008-Umbrelapp/PROGRESS.md @@ -20,7 +20,13 @@ daar wel, valideert op `http(s)://` en onthoudt zijn waarde, maar de app doet ge verbindingspoging. Het vermoeden is TLS; dat is niet gemeten en het is duur, want een certificaat voor een LAN-adres bestaat niet. -**Geraakt:** alleen documentatie van dit plan. **Tests:** niet van toepassing. +**Het ontwerp van de limiter en de pagina staat er ook**, en de limiter bleek veel kleiner dan +**Bereikbaarheid** §4b aannam: `createRelay` neemt twee terugroepfuncties, en Trezor doet zelf niets +anders. De poorten gaan om, zodat de pagina achter de umbrelOS-inlog kan en Zoraxy met TLS naar de relay +wijst. De gebruiker heeft de oude installatie weggehaald; die wordt niet geüpdatet maar opnieuw gebouwd. + +**Geraakt:** documentatie van dit plan plus `Referenties/Upstream-evolu-relay.md` §8. **Tests:** niet van +toepassing. ## 27-08-2026 - richting gekozen: kaal, met een limiter en een pagina erop diff --git a/Docs/Plannen/Actief/008-Umbrelapp/TAKEN.md b/Docs/Plannen/Actief/008-Umbrelapp/TAKEN.md index d99b8dd..605c867 100644 --- a/Docs/Plannen/Actief/008-Umbrelapp/TAKEN.md +++ b/Docs/Plannen/Actief/008-Umbrelapp/TAKEN.md @@ -26,27 +26,46 @@ Nu de desktop bewijst dat de relay in orde is, is dit een schone vraag geworden: het ligt aan de app of aan het platform, niet aan ons. Zonder antwoord werkt de app alleen op de desktop, en dat scheelt voor de waarde van dit hele plan -- [ ] **Pas daarna beslissen wat er met het huidige pakket gebeurt.** Werkt de kale relay, dan wordt dit - één container op een gepubliceerde image en vervallen de Postgres en het wachtwoord. Werkt hij niet, - dan is de limietenrij met de hand zetten de enige weg vooruit +- [x] **Besloten wat er met het huidige pakket gebeurt (28-08-2026): het gaat eruit.** De relay van Trezor, + de quota-manager en de Postgres vervallen. Wat ervoor in de plaats komt staat in [PLAN.md](PLAN.md) + §4g en §4h +- [x] **De limiter gekozen (28-08-2026): weg 1, uitbreiden via `createRelay`.** Dat bleek veel kleiner dan + **Bereikbaarheid** §4b aannam: het zijn twee terugroepfuncties, `isOwnerAllowed` en + `isOwnerWithinQuota`, en Trezor doet zelf niets anders. De gebruiker breidde het ontwerp uit met een + schakelaar voor nieuwe eigenaars en met wissen per eigenaar. Zie [OPEN.md](OPEN.md) punt 8 +- [x] **De vraag of het databaseschema zichzelf aanmaakt is vervallen.** Hij ging over het pakket dat eruit + gaat, en de kale relay maakt zijn database bij de start zelf aan; dat is op 28-08-2026 gezien - **De richting is al gekozen op 27-08-2026: kaal, met een eigen limiter erop en de statuspagina - erbij.** Zie [OPEN.md](OPEN.md) punt 6, 8 en 2. Wat daarbij vastligt en makkelijk verkeerd onthouden - wordt: de kale relay heeft géén toegangscontrole, dus de limiter is geen extraatje maar de vervanging - van de enige bescherming die er vandaag is. En de quota-manager die er nu in zit is daarvoor niet te - hergebruiken: die schrijft in Trezor's limietentabel, en die tabel bestaat straks niet meer +## Fase 5 - De verbouwing naar de kale relay - **Een eigen image blijft daardoor waarschijnlijk nodig**, want de meest voor de hand liggende limiter - breidt de relay uit via `createRelay`. Dat is geen obstakel: de gebruiker meldde op 27-08-2026 dat de - broncode nog op zijn Umbrel staat, dus opnieuw bouwen en naar het eigen Gitea-register duwen kan - gewoon. De bouwstap en het register vervallen dus mogelijk tóch niet; de Postgres en het wachtwoord - wel +Nog niets van begonnen. De volgorde is bewust: eerst het programma dat de limiter draagt, dan de app +eromheen, want de compose hangt af van wat dat programma nodig heeft. -- [ ] **De limiter kiezen uit de drie wegen van Bereikbaarheid §4b**, met de leer-variant erbij: de eerste - eigenaar die verbindt wordt toegelaten, de rest geweigerd, met een wisknop op de statuspagina. Zie - [OPEN.md](OPEN.md) punt 8. **Pas nadat de proef geslaagd is** -- [ ] **In de logs van de relay kijken of het databaseschema zichzelf aanmaakt.** Alleen nog nuttig als het - huidige pakket blijft: `sudo docker logs whatsnext-evolu-relay_relay_1` +- [ ] **Het eigen relay-programma schrijven.** Een klein Node-project dat `createRelay` uit `@evolu/nodejs` + aanroept met onze twee functies. Niets van Evolu aanpassen en niets nabouwen. Zie [PLAN.md](PLAN.md) + §4g en [Upstream-evolu-relay.md](../../../Referenties/Upstream-evolu-relay.md) §8 +- [ ] **Bewust een getal kiezen voor `isOwnerWithinQuota`.** De gepubliceerde image staat op 1 MB per + eigenaar. Overnemen zonder nadenken betekent dat het synchroniseren stilvalt zodra de + labelgeschiedenis daar tegenaan loopt +- [ ] **De allowlist als staat onder `${APP_DATA_DIR}/data/`**, naast de relay-database en niet erin, met + een `.gitkeep` voor de map +- [ ] **Wissen per eigenaar laten doen door het relay-proces zelf**, aangestuurd met een vlagbestand vanaf + de pagina. Geen tweede container die langszij in de SQLite schrijft, en geen Docker-socket +- [ ] **`tools/evolu-relay/build.sh` omschrijven:** niet meer de repo van Trezor bouwen maar het eigen + programma. De pin blijft, en met de pin mee gaat `version` in het manifest omhoog +- [ ] **De compose omzetten:** pagina achter `app_proxy` met de inlog aan, relay op een eigen `ports:`. + Postgres, wachtwoord en quota-manager eruit. Zie [PLAN.md](PLAN.md) §4h +- [ ] **De statuspagina bouwen**, met de pagina en de agent van Electrum Gate als vertrekpunt en met + hetzelfde ontwerpsysteem (`HomeGit/Docs/website-design-system.html`), maar zonder de Google + Fonts-verwijzing daaruit. Toont of de relay draait, welke eigenaars bekend en toegelaten zijn, de + omvang van de database en het laatste schrijfmoment. Draagt de schakelaar voor nieuwe eigenaars en de + wisknop per eigenaar +- [ ] **De app opnieuw installeren in plaats van updaten.** De gebruiker heeft de oude installatie op + 28-08-2026 weggehaald; dat is ook de nette weg, want niet elk bestand bereikt een bestaande + installatie via een update +- [ ] **Zoraxy inrichten** op het eigen subdomein met TLS, doorverwijzend naar de relay-poort, met de + WebSocket-upgrade aan. Testen met de handshake-curl uit [PLAN.md](PLAN.md) §6a stap 3, met de + publieke naam in plaats van het IP. **Eigenaar: gebruiker** ## Fase 1 - De app-map diff --git a/Docs/Referenties/Upstream-evolu-relay.md b/Docs/Referenties/Upstream-evolu-relay.md index 0c1757d..2aacabc 100644 --- a/Docs/Referenties/Upstream-evolu-relay.md +++ b/Docs/Referenties/Upstream-evolu-relay.md @@ -69,6 +69,20 @@ klopt. Suite gebruikt `@evolu/web@3.0.0-next.1` **met een eigen patch** in `.yar in minuten te weerleggen: `docker run --rm -p 4000:4000 docker.io/evoluhq/relay:latest`, Suite ernaartoe wijzen, label maken. +**4. De relay-URL bevat een pad, en de cliënt gebruikt hem letterlijk.** Toegevoegd 28-08-2026 uit +`suite-common/suite-sync/src/relay/relayUrl.test.ts`. Hun eigen standaardwaarden zijn +`https://suite-sync.trezor.io/evolu/` en lokaal `http://127.0.0.1:4000/evolu/`: de relay van Trezor hangt +dus achter een pad, en een eigen URL wordt overgenomen zoals hij is. De kale Evolu-relay luistert op de +wortel; dat is gemeten met `http://10.0.0.11:4000` zonder pad. + +**Dat opent een goedkope toegangscontrole die in geen van de drie wegen van Bereikbaarheid §4b stond:** een +onraadbaar pad in de URL, afgedwongen door de reverse proxy die er toch al staat. Geen eigen image, geen +regel code. + +**En het verklaart de foutmelding op iOS.** De URL wordt gevalideerd met een `.url()`-regel uit yup +(`relayServerSettings.ts`), en die accepteert `ws://` niet. "Enter a valid url" ging dus over het schema en +niet over het adres. + Dat het huidige pakket de zware variant bevat is geen fout maar het gevolg van de volgorde waarin het gevonden is: de laag van Trezor was eerder zichtbaar dan de laag eronder. @@ -287,3 +301,48 @@ Twee waarschuwingen bij die bron. Het meeste hierboven komt uit **`suite-native` desktopversie kan andere instellingen op een andere plek hebben, en dat is niet nagekeken. En het is een kloon op een moment in de tijd: bij twijfel de datum van die kloon opzoeken voordat je er een conclusie op bouwt. + +## 8. De uitbreidpunten van de kale relay + +Nagetrokken 28-08-2026 in de broncode van `evoluhq/evolu`, nadat de proef bewees dat de kale relay bruikbaar +is. Dit is wat een eigen limiter mogelijk maakt, en het is aanzienlijk minder werk dan **Bereikbaarheid** +§4b aannam. + +**Er wordt geen relay nagebouwd; er worden twee functies meegegeven.** `createRelay` uit `@evolu/nodejs` +heeft deze vorm: + +```ts +createRelay({ port = 443, name, isOwnerAllowed, isOwnerWithinQuota }): Task +``` + +`isOwnerAllowed(ownerId)` beslist of een eigenaar er überhaupt in mag, `isOwnerWithinQuota(ownerId, +requiredBytes)` of een schrijfactie past. Beide zijn asynchroon. De opslag wordt intern gemaakt met +`createRelaySqliteStorage(deps)({ isOwnerWithinQuota })`, dus SQLite, en `createRelayDeps()` levert de +driver. + +**Trezor doet exact dit en niets meer.** Hun `createEvoluRelay.ts` roept de relay aan met die twee +functies, en beide kijken in hun limietentabel via `getLimitsForOwner()`. De hele quota-manager plus +Postgres bestaat dus alleen om die tabel te vullen. Dat is het bewijs dat ons pakket met dezelfde twee +haken hetzelfde kan zonder die machinerie. + +**De gepubliceerde image vult ze zelf al deels in**, en dat is een valstrik om te kennen. In +`apps/relay/src/index.ts` staat `isOwnerAllowed` **uitgecommentarieerd** (dus iedereen mag erin) en +`isOwnerWithinQuota` op **1 MB per eigenaar**. Dat is geen theorie maar de image die wij draaien: + +- **een kale relay is niet volledig ongelimiteerd.** Er zit een bovengrens op wat één eigenaar kan + wegschrijven, en dat dempt misbruik als gratis opslag meer dan gedacht; +- **maar 1 MB is ook een plafond voor de échte gebruiker.** Loopt de labelgeschiedenis daar tegenaan, dan + stopt het synchroniseren, en dat merk je pas als het gebeurt. Wie zelf een relay bouwt, kiest dat getal + dus bewust. + +De relay zet zijn data in een map `data` naast het programma (`mkdirSync` plus `process.chdir`), en dat is +het volume `/app/data` uit de image. In de database zitten onder meer `evolu_message` en `evolu_history`, en +`ownerId` is een systeemkolom. **Data per eigenaar wissen is daarmee mogelijk maar het is schrijven in +andermans schema**, met dezelfde bezwaren als bij Trezor's limietentabel. + +Bronnen, geraadpleegd 28-08-2026: + +- [`packages/nodejs/src/local-first/Relay.ts`](https://raw.githubusercontent.com/evoluhq/evolu/main/packages/nodejs/src/local-first/Relay.ts) +- [`apps/relay/src/index.ts`](https://raw.githubusercontent.com/evoluhq/evolu/main/apps/relay/src/index.ts) +- [`src/evoluRelay/createEvoluRelay.ts`](https://raw.githubusercontent.com/trezor/trezor-suite-sync/main/src/evoluRelay/createEvoluRelay.ts) van Trezor +- [evolu.dev/docs/relay](https://www.evolu.dev/docs/relay) en [evolu.dev/docs/evolu-server](https://www.evolu.dev/docs/evolu-server)