Add Nextcloud (WebDAV) as a file source #31

Merged
brenno merged 1 commit from feat/nextcloud-webdav-source into main 2026-06-29 20:45:13 +00:00
Owner

Wat

Nextcloud (WebDAV) als bestandsbron: bladeren door een map op je Nextcloud, .ocideck-pakketten of Marp .md-decks openen, en een deck terugschrijven — als .ocideck-pakket of als platte .md + assetmappen.

Hoe te gebruiken

  • Instellen: Settings → Nextcloud (server-URL, gebruikersnaam, app-wachtwoord, optionele submap) met een Verbinding testen-knop.
  • Openen: welkomstscherm of -menu → Openen vanaf Nextcloud.
  • Opslaan: -menu → Opslaan naar Nextcloud (keuze: pakket of platte bestanden).

Veiligheid

  • App-wachtwoord versleuteld in de OS-keychain (flutter_secure_storage via SecretStore), nooit in het prefs-bestand; alleen URL/gebruiker/submap/trust-vlag in prefs.
  • Een privé/LAN-server is alleen bereikbaar na het vinkje Vertrouwde interne server (NetGuard.safeResolveTrusted); deck-geleverde URL's blijven door de SSRF-guard geblokkeerd. Host wordt geresolved en de socket gepind.
  • Downloads lopen door dezelfde geharde pipeline (importPackageBytes/importMarkdownBytesopenFileByPath-gate) met dezelfde grootte-/zip-limieten. Terugschrijven hergebruikt buildPackageBytes/buildPackageMembers.
  • WebDAV volgt geen redirects, begrenst de PROPFIND-respons en het aantal entries, en houdt remote-paden binnen de wortel (uriFor weigert ..); listing-entries met traversal-segment worden weggefilterd.

Foutafhandeling

  • Keychain-schrijffouten worden afgevangen (geen onafgevangen async-exceptie); het wachtwoord wordt alleen geschreven bij een echte wijziging of identiteitswissel, zodat een snelle Opslaan vóór de async keychain-load het niet leegt.

Tests & docs

  • Nieuwe UI-strings in alle 7 talen (l10n-test groen).
  • test/webdav_source_test.dart: pad-containment, PROPFIND-parsing (incl. traversal-filter), keychain-sleutelnormalisatie, afgevangen keychain-fout, SSRF-opt-in.
  • flutter analyze schoon; volledige suite (829 tests) groen; macOS debug-build slaagt (keychain-plugin via CocoaPods).
  • Docs bijgewerkt: README, CHANGELOG, USER_GUIDE, SECURITY, ARCHITECTURE.

Nog niet meegenomen

  • Afbeelding-invoegen vanaf Nextcloud: de browser heeft een image-modus, maar die is nog niet aan een editor-knop gekoppeld (deck openen/opslaan is volledig bedraad).

🤖 Generated with Claude Code

## Wat Nextcloud (WebDAV) als bestandsbron: bladeren door een map op je Nextcloud, `.ocideck`-pakketten of Marp `.md`-decks openen, en een deck terugschrijven — als `.ocideck`-pakket of als platte `.md` + assetmappen. ## Hoe te gebruiken - **Instellen**: *Settings → Nextcloud* (server-URL, gebruikersnaam, app-wachtwoord, optionele submap) met een **Verbinding testen**-knop. - **Openen**: welkomstscherm of `…`-menu → *Openen vanaf Nextcloud*. - **Opslaan**: `…`-menu → *Opslaan naar Nextcloud* (keuze: pakket of platte bestanden). ## Veiligheid - App-wachtwoord **versleuteld in de OS-keychain** (`flutter_secure_storage` via `SecretStore`), nooit in het prefs-bestand; alleen URL/gebruiker/submap/trust-vlag in prefs. - Een privé/LAN-server is alleen bereikbaar na het vinkje **Vertrouwde interne server** (`NetGuard.safeResolveTrusted`); deck-geleverde URL's blijven door de SSRF-guard geblokkeerd. Host wordt geresolved en de socket gepind. - Downloads lopen door dezelfde geharde pipeline (`importPackageBytes`/`importMarkdownBytes` → `openFileByPath`-gate) met dezelfde grootte-/zip-limieten. Terugschrijven hergebruikt `buildPackageBytes`/`buildPackageMembers`. - WebDAV volgt geen redirects, begrenst de PROPFIND-respons en het aantal entries, en houdt remote-paden binnen de wortel (`uriFor` weigert `..`); listing-entries met traversal-segment worden weggefilterd. ## Foutafhandeling - Keychain-schrijffouten worden afgevangen (geen onafgevangen async-exceptie); het wachtwoord wordt alleen geschreven bij een echte wijziging of identiteitswissel, zodat een snelle *Opslaan* vóór de async keychain-load het niet leegt. ## Tests & docs - Nieuwe UI-strings in alle 7 talen (l10n-test groen). - `test/webdav_source_test.dart`: pad-containment, PROPFIND-parsing (incl. traversal-filter), keychain-sleutelnormalisatie, afgevangen keychain-fout, SSRF-opt-in. - `flutter analyze` schoon; volledige suite (**829 tests**) groen; macOS debug-build slaagt (keychain-plugin via CocoaPods). - Docs bijgewerkt: README, CHANGELOG, USER_GUIDE, SECURITY, ARCHITECTURE. ## Nog niet meegenomen - Afbeelding-invoegen vanaf Nextcloud: de browser heeft een image-modus, maar die is nog niet aan een editor-knop gekoppeld (deck openen/opslaan is volledig bedraad). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Add Nextcloud (WebDAV) as a file source
Some checks failed
CI / Gate (Linux) · Format · Analyze · Coverage (pull_request) Has been cancelled
CI / Test (macos-latest) (pull_request) Has been cancelled
CI / Test (windows-latest) (pull_request) Has been cancelled
CI / Web hardening (pull_request) Has been cancelled
CI / Docs links (pull_request) Has been cancelled
CI / Gate (Linux) · Format · Analyze · Coverage (push) Waiting to run
CI / Test (macos-latest) (push) Waiting to run
CI / Test (windows-latest) (push) Waiting to run
CI / Web hardening (push) Waiting to run
CI / Docs links (push) Waiting to run
cf8ff62f03
Browse a folder on a Nextcloud/WebDAV server and open .ocideck packages or
Marp .md decks from it, and save a deck back as either a single .ocideck
package or a flat .md plus its asset folders.

- Configure under Settings -> Nextcloud (server URL, username, app password,
  optional subfolder) with a "Test connection" button.
- The app password is stored encrypted in the OS keychain
  (flutter_secure_storage via SecretStore), never in the prefs file; only
  URL/username/subfolder/trust flag live in the prefs domain.
- A private/LAN server is only reachable after ticking "Trusted internal
  server" (NetGuard.safeResolveTrusted); deck-supplied URLs stay blocked by
  the SSRF guard. Host is still resolved and the socket pinned.
- Downloads reuse the existing hardened pipeline: FileService.importPackageBytes
  / importMarkdownBytes -> TabsNotifier.openFileByPath security gate, with the
  same size/zip limits. Saving reuses buildPackageBytes / buildPackageMembers.
- WebDAV requests follow no redirects, cap the PROPFIND response and entry
  count, and contain remote paths to the configured root (uriFor rejects ..
  escapes); listing entries with a traversal segment are dropped.

Failure handling: keychain write errors are caught (no unhandled async throw),
and the settings dialog only writes the password when it actually changed or
the server identity changed, so a quick Save before the async keychain load
cannot blank it.

New UI strings are translated in all 7 languages. Tests cover path containment,
PROPFIND parsing (incl. traversal filtering), keychain-key normalisation, the
swallowed keychain error, and the trusted-server SSRF opt-in. Docs updated
(README, CHANGELOG, USER_GUIDE, SECURITY, ARCHITECTURE).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
brenno merged commit 7a5be80f41 into main 2026-06-29 20:45:13 +00:00
brenno deleted branch feat/nextcloud-webdav-source 2026-06-29 20:45:13 +00:00
Sign in to join this conversation.
No description provided.