feat(share) : explorateur de partage Windows (SMB) + viewer #8

Merged
matthieu merged 23 commits from feat/share-explorer-impl into develop 2026-06-12 13:52:41 +00:00
Owner

Objectif

Donner accès depuis Lesstime à un partage de fichiers Windows (SMB) : explorateur façon Drive, viewer de documents (image/PDF/texte), et configuration admin activable + testable.

Backend

  • Entité ShareConfiguration (singleton, mot de passe chiffré via TokenEncryptor) + migration share_configuration.
  • Service\Share\ : interface FileSourceSmbFileSource (icewind/smb), SharePathResolver anti path-traversal (testé unitairement).
  • API Platform : GET/PUT /api/settings/share + POST /api/settings/share/test (ROLE_ADMIN).
  • Controllers /api/share/status|browse|download (IS_AUTHENTICATED_FULLY, priority:1).

Frontend (Nuxt)

  • Services + DTO, composable useShareStatus, onglet admin AdminShareTab, lien sidebar conditionnel.
  • Viewer SharedFilePreview (image/PDF/texte, PDF via iframe natif), page explorateur documents.vue, i18n FR.

Sécurité

  • Download : allowlist inline (images hors SVG + PDF), reste forcé en attachment, en-tête X-Content-Type-Options: nosniff.
  • Messages d'erreur SMB masqués côté browse/download.

Problèmes interceptés & corrigés pendant la revue

  • Migration : SERIAL + DEFAULT FALSE générés à la main → drift de schéma. Corrigé en GENERATED BY DEFAULT AS IDENTITY (convention projet), schéma re-synchronisé (dev + test).
  • Lockfile npm vs yarn : un yarn add avait créé un yarn.lock parasite et désynchronisé node_modules (suppression d'izitoast, build cassé). Le projet est npm-canonique (package-lock.json, npm ci en prod) : yarn.lock retiré, lock npm resynchronisé.
  • Dépendance inutile : vue-pdf-embed finalement retiré (le viewer rend le PDF via <iframe> natif, plus robuste — évite la config worker pdf.js).
  • Bug de shadowing : documents.vue définissait une fonction locale navigateTo masquant celle de Nuxt → le garde-fou « partage désactivé → redirection accueil » était cassé. Renommé openPath.
  • 🔴 XSS (revue sécurité finale) : un fichier HTML pouvait être servi inline (seul le SVG était protégé). Durci via allowlist inline + nosniff.

Tests / vérifs

  • 86 tests PHPUnit verts (path-traversal, sécurité settings/browse). Build front OK. php-cs-fixer propre.

À faire au déploiement prod

  • Rebuild image prod lesstime-app avec smbclient, jouer la migration en prod, vérifier ENCRYPTION_KEY, puis saisir/activer la config SMB en admin.
## Objectif Donner accès depuis Lesstime à un partage de fichiers Windows (SMB) : explorateur façon Drive, viewer de documents (image/PDF/texte), et configuration admin activable + testable. ## Backend - Entité `ShareConfiguration` (singleton, mot de passe chiffré via TokenEncryptor) + migration `share_configuration`. - `Service\Share\` : interface `FileSource` → `SmbFileSource` (icewind/smb), `SharePathResolver` anti path-traversal (testé unitairement). - API Platform : `GET/PUT /api/settings/share` + `POST /api/settings/share/test` (ROLE_ADMIN). - Controllers `/api/share/status|browse|download` (IS_AUTHENTICATED_FULLY, priority:1). ## Frontend (Nuxt) - Services + DTO, composable `useShareStatus`, onglet admin `AdminShareTab`, lien sidebar conditionnel. - Viewer `SharedFilePreview` (image/PDF/texte, PDF via iframe natif), page explorateur `documents.vue`, i18n FR. ## Sécurité - Download : allowlist inline (images hors SVG + PDF), reste forcé en attachment, en-tête `X-Content-Type-Options: nosniff`. - Messages d'erreur SMB masqués côté browse/download. ## Problèmes interceptés & corrigés pendant la revue - **Migration** : `SERIAL` + `DEFAULT FALSE` générés à la main → drift de schéma. Corrigé en `GENERATED BY DEFAULT AS IDENTITY` (convention projet), schéma re-synchronisé (dev + test). - **Lockfile npm vs yarn** : un `yarn add` avait créé un `yarn.lock` parasite et désynchronisé `node_modules` (suppression d'`izitoast`, build cassé). Le projet est **npm-canonique** (`package-lock.json`, `npm ci` en prod) : `yarn.lock` retiré, lock npm resynchronisé. - **Dépendance inutile** : `vue-pdf-embed` finalement retiré (le viewer rend le PDF via `<iframe>` natif, plus robuste — évite la config worker pdf.js). - **Bug de shadowing** : `documents.vue` définissait une fonction locale `navigateTo` masquant celle de Nuxt → le garde-fou « partage désactivé → redirection accueil » était cassé. Renommé `openPath`. - **🔴 XSS (revue sécurité finale)** : un fichier HTML pouvait être servi `inline` (seul le SVG était protégé). Durci via allowlist inline + `nosniff`. ## Tests / vérifs - 86 tests PHPUnit verts (path-traversal, sécurité settings/browse). Build front OK. php-cs-fixer propre. ## À faire au déploiement prod - Rebuild image prod `lesstime-app` **avec smbclient**, jouer la migration en prod, vérifier `ENCRYPTION_KEY`, puis saisir/activer la config SMB en admin.
matthieu added 17 commits 2026-06-03 15:53:57 +00:00
- Ajout vue-pdf-embed@2.1.4
- DTO share.ts (FileEntry, Breadcrumb, ShareBrowseResult, ShareStatus, ShareSettings, ShareSettingsWrite, ShareTestResult)
- Service share.ts (browse, getStatus, getDownloadUrl)
- Service share-settings.ts (getSettings, saveSettings, testConnection)
matthieu added 4 commits 2026-06-12 13:31:41 +00:00
matthieu added 1 commit 2026-06-12 13:50:08 +00:00
Endpoint GET /api/share/search?q= parcourant tout le partage en largeur
(garde-fous 200 résultats / 2000 dossiers). Le champ de l'explorateur
déclenche une recherche globale debouncée dès 2 caractères (filtre local
en deçà), avec affichage du dossier parent de chaque résultat.
matthieu added 1 commit 2026-06-12 13:52:37 +00:00
matthieu merged commit 7f20c2ae13 into develop 2026-06-12 13:52:41 +00:00
matthieu deleted branch feat/share-explorer-impl 2026-06-12 13:52:47 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: MALIO-DEV/Lesstime#8