16 KiB
Remote Client Shares V1.1 Design
Status
Dit document beschrijft de V1.1-doelscope voor Remote Client Shares.
Per huidige repositorystatus valt de beschreven V1.1 read-mostly scope onder afgeronde implementatie van:
- client registry
- browse via
/Clients - file info
- tekstpreview
- eenvoudige image preview
- download
De expliciet niet in V1.1 opgenomen onderdelen hieronder blijven buiten scope en vormen in dit document geen aparte vervolgfase.
Doel
Een gebruiker van WebManager moet naast de bestaande server-side storage-roots ook een beperkte set lokale mappen van zijn eigen client-Mac kunnen benaderen, zonder de hele homefolder bloot te geven.
Voorbeelden van toegestane client-shares:
DownloadsMoviesPictures
De oplossing moet:
- simpel blijven
- veilig blijven
- de bestaande storage-workflow niet breken
- WebManager niet laten vastlopen als een remote helper-agent offline is
Kernbeslissingen voor V1.1
Deze beslissingen liggen in V1.1 vast.
- Remote client shares worden niet opgenomen in
root_aliases. /Clientswordt een aparte virtuele bron naast/Volumes.- Remote paden lopen niet door de bestaande lokale filesystem-resolutie.
client_idis intern de enige leidende identiteit.display_nameis alleen voor UI-weergave.- De agent werkt alleen met
share key + relatief pad. - Alle agent-calls vereisen authenticatie, niet alleen registratie.
- Offline agents mogen alleen hun eigen subtree beïnvloeden, nooit de rest van de app.
- V1 blijft read-mostly: registry, browse, info, preview, download.
Waarom niet als gewone root alias
De huidige backend gaat uit van server-side whitelisted filesystem roots.
Dat model werkt voor:
/Volumes/...- gemounte server storage
- container-side toegankelijke paden
Dat model werkt niet goed voor:
- de lokale schijf van de browsergebruiker
- een remote Mac die buiten de server draait
- clients die offline kunnen zijn
- clients die dynamische IP-adressen hebben
Daarom mogen remote client shares niet in hetzelfde model worden gestopt als root_aliases.
Scope V1.1
In scope
- beperkte client-shares:
Downloads,Movies,Pictures - lokale helper-agent op macOS
- agent registratie in WebManager
- heartbeat/status tracking
- virtuele
Clientsbron in de WebUI - browse van remote shares
- bestand-info
- tekstpreview
- image preview waar triviaal
- download van bestanden
- nette offline-afhandeling
Expliciet niet in V1.1
- hele homefolder
- willekeurige custom paths buiten de toegestane sharelijst
- shell/subprocess execution
- rename
- mkdir
- delete
- upload naar remote share
- bookmarks voor
/Clients/... - startup paths voor
/Clients/... - cross-source copy of move
- complete taakrunner-integratie zoals server copy/move tasks
- automatische LAN discovery
- multi-user auth met OS user mapping
Status:
- deze lijst blijft expliciet uitgesloten van V1.1
- dit document definieert hiervoor geen Phase 4 of andere vervolgfase
Gewenste gebruikerservaring
In de WebUI komt naast server-storage een extra virtuele bron:
/Volumes/Clients
Onder /Clients ziet de gebruiker geregistreerde clients, bijvoorbeeld:
MacBook Pro van JaniMac Woonkamer
Onder een client ziet de gebruiker alleen de toegestane shares:
DownloadsMoviesPictures
Voor de gebruiker kan dat eruitzien als:
/Clients/MacBook-Pro-van-Jan/Downloads/Clients/MacBook-Pro-van-Jan/Movies/Clients/MacBook-Pro-van-Jan/Pictures
Maar intern mag routing niet op display_name leunen.
Intern moet WebManager werken met een stabiele client-identiteit en een mappinglaag:
client_idvoor routing en opslagdisplay_namevoor weergave- optioneel een afgeleide slug voor browse-url-presentatie
Architectuuroverzicht
Er zijn drie componenten.
1. WebManager backend
Verantwoordelijk voor:
- registry van bekende remote clients
- status- en heartbeat-tracking
- virtuele browse-root
Clients - proxying van requests naar agents
- timeouts en foutafhandeling
- scheiding tussen local-source en remote-source afhandeling
2. WebUI frontend
Verantwoordelijk voor:
- tonen van
Clientsals extra bron - navigeren binnen client/share paden
- offline status tonen
- requests afvuren naar gewone WebManager backend-routes
3. Remote helper-agent op macOS
Verantwoordelijk voor:
- toegang tot vaste lokale shares
- strikte padvalidatie binnen die shares
- simpele browse/info/read/download endpoints
- zichzelf registreren bij WebManager
- heartbeat sturen
- auth afdwingen op alle agent-endpoints
Bereikbaarheidsmodel
Dit is de eerste harde productbeslissing.
V1.1-keuze
V1.1 gaat uit van een omgeving waarin WebManager de agent rechtstreeks kan bereiken.
Dat betekent praktisch:
- dezelfde LAN
- of een expliciet configureerbaar agent-endpoint
- of een deployment waar server en client netwerkmatig direct verbonden zijn
Waarom deze keuze
Dit is het simpelste model dat functioneel klopt zonder reverse tunnels, websockets als transportlaag, of extra relay-infrastructuur.
Wat V1.1 niet probeert op te lossen
Deze versie garandeert niet dat een agent achter willekeurige NAT/firewall altijd bereikbaar is.
Dus:
- self-registration blijft het discoverymodel
- direct bereikbare agent-endpoint blijft het V1-transportmodel
- reverse-connect of tunnelmodellen zijn uitgesteld
Fallback
Een handmatige endpoint override blijft toegestaan als operationele fallback, bijvoorbeeld:
http://192.168.1.25:8765
Maar dat is geen hoofdmodel en geen productbelofte.
Hoe de remote agent bekend wordt in WebManager
Gekozen model: agent registreert zichzelf
De agent meldt zichzelf actief aan bij WebManager. Niet andersom.
Dat betekent:
- geen handmatig client-IP nodig als hoofdmodel
- geen server-naar-client discovery nodig
- geen afhankelijkheid van LAN-broadcasting
- geen probleem als het client-IP wisselt, zolang het geregistreerde endpoint actueel is
Registratiestroom
Bij starten van de agent:
- de agent leest lokale config
- de agent bepaalt:
client_iddisplay_namesharesendpoint
- de agent registreert zich bij WebManager
- WebManager slaat client-record op of werkt het bij
- de agent stuurt periodieke heartbeats
Benodigde velden bij registratie
Voorstel:
{
"client_id": "f4b2c8f8-2b1b-4d89-9ed2-8d6d7b1f3abc",
"display_name": "MacBook Pro van Jan",
"platform": "macos",
"agent_version": "1.1.0",
"endpoint": "http://192.168.1.25:8765",
"shares": [
{ "key": "downloads", "label": "Downloads" },
{ "key": "movies", "label": "Movies" },
{ "key": "pictures", "label": "Pictures" }
]
}
Backend bewaart per client
client_iddisplay_nameplatformagent_versionendpointshareslast_seenstatuslast_errorreachable_at- eventueel
registration_token_id
Heartbeat
De agent stuurt elke 15-30 seconden een heartbeat.
Bijvoorbeeld:
{
"client_id": "f4b2c8f8-2b1b-4d89-9ed2-8d6d7b1f3abc",
"agent_version": "1.1.0"
}
Statusmodel
Deze velden moeten logisch gescheiden blijven:
last_seenLaatste succesvolle heartbeat van de agent.statusAfgeleide UI-status, bijvoorbeeldonlineofoffline.last_errorLaatste connect- of browsefout richting agent.reachable_atLaatste moment waarop een directe agent-call echt succesvol was.
Belangrijk:
- een heartbeat bepaalt niet automatisch dat elke browse-call werkt
- een enkele browse-timeout mag niet blind
last_seenoverschrijven - status mag niet gaan flappen op basis van één los incident
Aanbevolen statusregels
onlinealslast_seenrecent isofflineals heartbeat-timeout overschreden is- extra foutdetails via
last_error - optioneel UI-label zoals
online with recent errorslater, maar niet nodig in V1.1
Authenticatie en beveiliging
Backend registratie-auth
Registratie vereist een bearer token.
Bijvoorbeeld:
Authorization: Bearer <registration-token>
Agent endpoint-auth
Alle agent-calls vereisen authenticatie. Niet alleen registratie.
Dus ook:
/health/api/list/api/info/api/read/api/download
moeten beschermd zijn.
V1.1 minimum
Voor V1.1 volstaat een eenvoudige gedeelde agent-token, bijvoorbeeld:
- WebManager bewaart een secret per client of per installatie
- backend stuurt dat token mee op elke agent-call
- agent weigert requests zonder geldig token
Voorbeeld:
Authorization: Bearer <agent-access-token>
Niet doen in V1.1
- open agent-HTTP API zonder auth
- browse/download endpoints publiek bereikbaar maken op het LAN
Virtueel padmodel
Remote client shares krijgen een aparte namespace.
Voorstel voor de gebruikersweergave:
/Clients/Clients/<client-display>/Clients/<client-display>/<share-label>/Clients/<client-display>/<share-label>/subdir/file.ext
Intern moet de backend dit mappen naar:
client_idshare_key- relatief share-pad
Belangrijk:
- dit zijn logische WebManager-paden
- het zijn geen echte lokale backend filesystem-paden
- ze mogen niet door de bestaande lokale
PathGuardresolved worden
Consequentie voor de codebasis
/Clients/... moet vroeg in routing worden onderschept door een aparte browse- of source-facade.
Dus:
- niet de lokale
PathGuarduitbreiden tot remote sources - niet overal
if remotein bestaande lokale services strooien - wel een duidelijke scheiding tussen local source en remote source
Share-validatie in de agent
De agent werkt niet met vrije absolute paden.
De agent heeft een vaste share-map, bijvoorbeeld:
{
"downloads": "/Users/jan/Downloads",
"movies": "/Users/jan/Movies",
"pictures": "/Users/jan/Pictures"
}
Een request bevat dan:
share = downloadspath = Some/Subdir/file.txt
Niet:
/Users/jan/...
Validatieregels
- onbekende
shareweigeren ..weigeren- pad resolven binnen de gekozen share-root
- symlink escape blokkeren
- alleen toegestane bestandshandelingen toestaan
Read, preview en download limieten
V1.1 moet resource-grenzen expliciet vastleggen.
Tekstpreview
- maximum grootte voor tekstpreview vastleggen
- voorstel: zelfde orde als huidige server-side preview/edit-limieten, of kleiner
- grote tekstbestanden niet volledig in memory laden voor preview
Binary versus text
- agent moet tekstpreview alleen teruggeven voor ondersteunde teksttypes
- binaire content mag niet per ongeluk als tekst in JSON-responses worden gepusht
Download
- downloads moeten gestreamd worden
- geen volledige bestand-buffering in memory
Image preview
- alleen triviale image preview in V1.1
- geen zware thumbnail-pipeline in deze fase
Offline gedrag
Dit is een harde eis.
WebManager mag niet vastlopen als de agent niet draait.
Backendregels
- alle agent-calls krijgen korte timeouts, bijvoorbeeld 1-3 seconden
- connect- of timeoutfouten worden vertaald naar nette app-fouten
- offline agent blokkeert nooit globale pagina-initialisatie
- browse- en file-fouten blijven lokaal tot betreffende request
Frontendregels
/Clientsmag laden, ook als sommige clients offline zijn- offline clients mogen zichtbaar blijven in de lijst
- browsen in offline subtree toont foutmelding
- andere panes blijven bruikbaar
- geen endless spinner
API-ontwerp
1. Backend registry endpoints
POST /api/clients/register
Registreert of update een remote agent.
POST /api/clients/heartbeat
Werkt last_seen bij.
GET /api/clients
Geeft bekende clients terug met:
client_iddisplay_namestatuslast_seenlast_errorshares
2. Backend browse facade voor UI
De frontend blijft praten met gewone WebManager-routes.
GET /api/browse?path=/Clients
Geeft alle bekende clients terug als directories.
GET /api/browse?path=/Clients/<client>/
Geeft shares van die client terug als directories.
GET /api/browse?path=/Clients/<client>/<share>/...
Backend vertaalt dit naar een agent-call.
Belangrijk:
- browse facade bepaalt eerst of pad onder
/Clientsvalt - alleen niet-remote paden mogen daarna naar bestaande lokale browse-paths
3. Agent endpoints
Eenvoudig houden. Geen shell.
GET /health
Gezondheidscheck met auth.
GET /api/list?share=downloads&path=subdir
Directory-inhoud binnen een share.
GET /api/info?share=downloads&path=file.txt
Metadata.
GET /api/read?share=downloads&path=file.txt
Tekstpreview.
GET /api/download?share=downloads&path=file.txt
Gestreamde download.
Haalbaarheid
Goed haalbaar in V1.1
- client registry
- heartbeat online/offline
- virtuele
Clientsroot - browse
- file info
- tekstpreview
- eenvoudige image preview
- gestreamde download
Bewust uitgesteld
- rename
- mkdir
- delete
- upload
- bookmarks/startup paths
- cross-source copy
- cross-source move
- unified history
- task-runner integratie
Veranderingen per gebied
Backend
Nieuwe onderdelen:
- client registry repository
- client registry service
- routes voor register/heartbeat/list
- browse/source facade voor
Clients/... - agent HTTP client met harde timeouts en auth
Bestaande onderdelen die waarschijnlijk geraakt worden:
- routes_browse.py
Om
/Clientsvroeg te routeren. - dependencies.py Voor nieuwe registry- en agent-services.
- app/main.py Voor nieuwe routers.
Liever niet verbreden:
- path_guard.py Deze hoort lokaal filesystemgericht te blijven.
- file_ops_service.py Deze service is nu server-filesystemgericht en moet niet vervuild raken met remote transportlogica.
Frontend
Waarschijnlijk aanpassen:
- app.js
Voor:
- extra virtuele root
- render van clients en shares
- offline status
- source-aware browse/view/download/info flows
- index.html Alleen als extra statuslabels of clientindicatoren nodig zijn
Remote agent
Te baseren op:
Maar vereenvoudigd:
- geen shell command endpoint
- geen hele home-root
- alleen
share key + relatief pad - registratie en heartbeat toevoegen
- auth afdwingen op alle endpoints
Minimale agent-config
Voorstel lokaal configbestand:
{
"webmanager_base_url": "https://webmanager.example.com",
"registration_token": "registration-secret",
"agent_access_token": "agent-secret",
"client_id": "f4b2c8f8-2b1b-4d89-9ed2-8d6d7b1f3abc",
"display_name": "MacBook Pro van Jan",
"shares": {
"downloads": "/Users/jan/Downloads",
"movies": "/Users/jan/Movies",
"pictures": "/Users/jan/Pictures"
},
"listen_host": "0.0.0.0",
"listen_port": 8765,
"public_endpoint": "http://192.168.1.25:8765"
}
Opmerking:
public_endpointis het endpoint dat WebManager gebruiktlisten_hostenpublic_endpointhoeven niet identiek te zijn
Open keuzes die bewust zijn uitgesteld
Deze keuzes zijn echt later werk, niet meer V1.1:
- reverse-connect of tunnelmodel
- cross-source copy
- cross-source move
- bookmarks/startup paths voor
/Clients/... - write-acties op remote shares
- sterkere pairing of key rotation
Beslisadvies
Aanbevolen implementatievolgorde voor V1.1:
- agent registry + heartbeat
- virtuele
Clientsroot in browse - online/offline status met gescheiden statusvelden
- browse/info/preview/download voor remote shares
Niet in V1.1:
- write-acties
- bookmarks/startup paths
- cross-source flows
Samenvatting
De juiste V1.1-richting is:
- geen hele homefolder
- wel beperkte shares zoals
Downloads,Movies,Pictures - remote helper-agent op macOS
- agent registreert zichzelf bij WebManager
- WebManager bewaart
client_id-geleide registry en status /Clientswordt een aparte virtuele bron- remote paden blijven buiten lokale filesystem services
- alle agent-calls vereisen auth
- offline agents mogen nooit de rest van WebManager verstoren
Dit model is haalbaar, beperkt in scope, en houdt de bestaande lokale storage-architectuur schoon.