diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f9f636..0bc4d71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ Format basé sur [Keep a Changelog](https://keepachangelog.com/fr/1.1.0/), et [Semantic Versioning](https://semver.org/spec/v2.0.0.html). > **En cours de développement** : les changements à venir sont listés dans la section -> [Unreleased](#unreleased). La dernière version livrée est **2.50.1**. +> [Unreleased](#unreleased). La dernière version livrée est **2.50.2**. --- @@ -14,6 +14,10 @@ et [Semantic Versioning](https://semver.org/spec/v2.0.0.html). --- +## [2.50.2] — 2026-10-02 + +--- + ## [2.50.1] — 2026-10-02 ### Corrigé @@ -23,6 +27,12 @@ et [Semantic Versioning](https://semver.org/spec/v2.0.0.html). généré par FastAPI et jamais noncé — `SecurityHeadersMiddleware` injecte désormais le nonce dans le HTML de `/docs` et `/redoc` (helper existant `inject_csp_nonce`, corps ré-encodé gzip), avec 3 tests de non-régression. +- **BUG-107 — drag & drop de fichiers inutilisable sur desktop** : Tauri/wry + remplaçait le gestionnaire de drag & drop du WebView2 par le sien (aucun + événement natif écouté) — les dépôts depuis l'Explorateur n'atteignaient + jamais la page. La fenêtre est désormais créée en code (`create: false`) avec + `disable_drag_drop_handler()` : le HTML5 drag & drop (#89) fonctionne comme + sur le web, avec un garde-fou de test. --- diff --git a/README.fr.md b/README.fr.md index 24f12ef..63bed0f 100644 --- a/README.fr.md +++ b/README.fr.md @@ -4,7 +4,7 @@ **Porte d'entrée web ultra-léger pour vos vaults Obsidian** — Accédez, naviguez et recherchez dans toutes vos notes Obsidian depuis n'importe quel appareil via une interface web moderne et responsive. -[![Version](https://img.shields.io/badge/Version-2.50.1-blue.svg)]() +[![Version](https://img.shields.io/badge/Version-2.50.2-blue.svg)]() [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Docker](https://img.shields.io/badge/Docker-Ready-blue.svg)](https://www.docker.com/) [![Python](https://img.shields.io/badge/Python-3.11+-green.svg)](https://www.python.org/) @@ -976,8 +976,8 @@ Ce projet est sous licence **MIT** — voir le fichier [LICENSE](LICENSE) pour l ## 📝 Changelog -Consultez le [CHANGELOG.md](./CHANGELOG.md) pour l'historique complet de toutes les versions (v1.0.0 → v2.50.1). +Consultez le [CHANGELOG.md](./CHANGELOG.md) pour l'historique complet de toutes les versions (v1.0.0 → v2.50.2). --- -*Projet : ObsiGate | Version : 2.50.1 | Dernière mise à jour : Septembre 2026* +*Projet : ObsiGate | Version : 2.50.2 | Dernière mise à jour : Septembre 2026* diff --git a/README.md b/README.md index 8c475c4..ff02310 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ **Ultra-light web gateway for your Obsidian vaults** — Access, browse, and search all your Obsidian notes from any device via a modern, responsive web interface. -[![Version](https://img.shields.io/badge/Version-2.50.1-blue.svg)]() +[![Version](https://img.shields.io/badge/Version-2.50.2-blue.svg)]() [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Docker](https://img.shields.io/badge/Docker-Ready-blue.svg)](https://www.docker.com/) [![Python](https://img.shields.io/badge/Python-3.11+-green.svg)](https://www.python.org/) @@ -1151,8 +1151,8 @@ This project is licensed under the **MIT License** - see the [LICENSE](LICENSE) ## 📝 Changelog -See [CHANGELOG.md](./CHANGELOG.md) for the complete version history (v1.0.0 → v2.50.1). +See [CHANGELOG.md](./CHANGELOG.md) for the complete version history (v1.0.0 → v2.50.2). --- -*Project: ObsiGate | Version: 2.50.1 | Last updated: September 2026* +*Project: ObsiGate | Version: 2.50.2 | Last updated: September 2026* diff --git a/VERSION b/VERSION index 895eb8a..555bd6c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.50.1 +2.50.2 diff --git a/desktop/Cargo.lock b/desktop/Cargo.lock index 9e26270..2f7fef7 100644 --- a/desktop/Cargo.lock +++ b/desktop/Cargo.lock @@ -2626,7 +2626,7 @@ dependencies = [ [[package]] name = "obsigate-desktop" -version = "2.50.1" +version = "2.50.2" dependencies = [ "chrono", "env_logger", diff --git a/desktop/Cargo.toml b/desktop/Cargo.toml index 7e82196..da9de37 100644 --- a/desktop/Cargo.toml +++ b/desktop/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "obsigate-desktop" -version = "2.50.1" +version = "2.50.2" description = "ObsiGate Desktop — Porte d'entrée native pour vos vaults Obsidian" authors = ["Bruno Charest"] edition = "2021" diff --git a/desktop/src/main.rs b/desktop/src/main.rs index 94e435f..43bbf1d 100644 --- a/desktop/src/main.rs +++ b/desktop/src/main.rs @@ -48,6 +48,7 @@ fn pick_free_port() -> u16 { #[cfg(target_os = "windows")] use std::os::windows::process::CommandExt; use tauri::Manager; +use tauri::webview::WebviewWindowBuilder; // ── State ─────────────────────────────────────────────────────────────────── @@ -624,6 +625,19 @@ fn main() { list_dirs, ]) .setup(move |app| { + // BUG-107 / #89 — HTML5 drag & drop des fichiers : Tauri installe + // son propre IDropTarget par-dessus celui du WebView2 (wry : + // « find the WebView2 window and override! ») et aucun événement + // natif n'est écouté ici → les glisser-déposer depuis + // l'Explorateur n'atteignaient jamais la page. La fenêtre est donc + // créée manuellement (`create: false` dans tauri.conf.json) avec + // le handler désactivé : la page reçoit les drops comme sur le web. + let window_config = app.config().app.windows[0].clone(); + WebviewWindowBuilder::from_config(app, &window_config) + .expect("fenêtre principale (tauri.conf.json)") + .disable_drag_drop_handler() + .build()?; + // Build native menu bar (File / Edit / Help) let _ = build_native_menu(app); @@ -1205,4 +1219,24 @@ mod tests { } assert!(seen > 0, "aucun invoke('…') trouvé dans frontend/js"); } + + /// BUG-107 : la fenêtre est créée en code (`create: false`) avec le + /// handler de drag & drop de Tauri désactivé. Si l'un des deux manque, + /// wry réinstalle son IDropTarget par-dessus celui du WebView2 et les + /// glisser-déposer de fichiers depuis l'Explorateur n'atteignent plus la + /// page (#89 fonctionnait uniquement sur le web). + #[test] + fn test_window_created_without_tauri_drag_drop_handler() { + let dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR")); + let conf = fs::read_to_string(dir.join("tauri.conf.json")).unwrap(); + assert!( + conf.contains("\"create\": false"), + "tauri.conf.json : la fenêtre doit être créée en code (create: false)" + ); + let main_src = fs::read_to_string(dir.join("src/main.rs")).unwrap(); + assert!( + main_src.contains("disable_drag_drop_handler()"), + "main.rs : disable_drag_drop_handler() manquant — drag & drop bloqué" + ); + } } diff --git a/desktop/tauri.conf.json b/desktop/tauri.conf.json index ec7f5f5..1253f7d 100644 --- a/desktop/tauri.conf.json +++ b/desktop/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://raw.githubusercontent.com/nicedoc/obsigate/main/desktop/tauri.conf.schema.json", "productName": "ObsiGate", - "version": "2.50.1", + "version": "2.50.2", "identifier": "com.obsigate.desktop", "build": { "frontendDist": "../frontend", @@ -13,6 +13,7 @@ "withGlobalTauri": true, "windows": [ { + "create": false, "title": "ObsiGate", "width": 1200, "height": 800, diff --git a/docs/ISSUES_TODOLIST.md b/docs/ISSUES_TODOLIST.md index 330d861..793f217 100644 --- a/docs/ISSUES_TODOLIST.md +++ b/docs/ISSUES_TODOLIST.md @@ -214,6 +214,7 @@ Avant de corriger quoi que ce soit, un agent IA doit : | *BUG-104* | Desktop : toutes les commandes Tauri invoquées depuis la page backend (`http://127.0.0.1`) rejetées « not allowed by ACL » — le bouton « Choisir mon dossier » du wizard ne fait rien | 🟢 corrigé | P1 | 🖥️ desktop | IA | `desktop/permissions/commands.toml` (nouveau), `desktop/capabilities/default.json`, `desktop/build.rs` | Installeur 2.49.2 : clic sur « Choisir mon dossier » → aucune fenêtre ; console `[desktop] invoke(pick_vault_folder) failed: Command … not allowed by ACL` (capturée via CDP, WebView2 `--remote-debugging-port`) | Manifeste de permissions applicatives créé (`allow-app-commands`, 19 commandes) et référencé par la capability : Tauri v2 ACL gate toute commande invoquée depuis une origine *remote*, y compris celles de l'`invoke_handler` | `cargo test` 25 passed (nouveau garde-fou `test_frontend_invokes_are_acl_allowed`) + vérif live CDP : `get_version`→2.49.2, clic → fenêtre native « Select Folder », parcours complet ajout de vault terminé | | *BUG-105* | Desktop : crash 2-15 s après l'ouverture de la fenêtre (`APPCRASH c0000374`, heap corruption détectée dans ntdll) — absent de v2.0.0, apparu en 2.49.2 | 🟢 corrigé | P1 | 🖥️ desktop | IA | `desktop/src/jumplist.rs` (`set_link_title`) | Installeur 2.49.2 : fenêtre visible quelques secondes puis fermeture (3/3), Event Log Windows `APPCRASH obsigate-desktop.exe … c0000374`, rien dans stderr | `set_link_title` (#77) construisait un `PROPVARIANT VT_LPWSTR` pointant un buffer heap Rust et le confiait au property store du shell, qui le libère avec l'allocateur Windows → corruption du tas ; fonction supprimée (`SetDescription` fournit déjà le libellé) | Bisect 3 états (jumplist off = stable, titre off = stable, d'origine = crash) ; run 9 min sans crash + sortie propre `EXIT=0`, zéro événement WER (avant : 3 crashes ≤20 s) | | *BUG-106* | Page blanche sur `/docs` (Swagger UI) : la CSP `script-src` sans `unsafe-inline` (#87 T5c) refuse le script inline d'init de FastAPI, jamais noncé | 🟢 corrigé | P1 | ⚙️ backend | IA | `backend/main.py` (`SecurityHeadersMiddleware`) | Ouvrir `https://og.dracodev.net/docs` : HTML servi (200) mais aucune UI, console `Refused to execute inline script … Content Security Policy` | Injection du nonce dans le HTML de `/docs` et `/redoc` depuis le middleware, via le helper existant `inject_csp_nonce` ; corps décompressé/recompressé (GZipMiddleware est plus proche de la route) | `pytest tests/test_csp_nonce.py` (3 tests ajoutés : nonce sur `/docs`, `/redoc` sans injection, regex sur bundle externe) + 45 passed sur les 3 suites sécurité ; ruff/mypy 0 | +| *BUG-107* | Drag & drop de fichiers depuis l'Explorateur inutilisable sur desktop : Tauri/wry pose son propre `IDropTarget` par-dessus de celui du WebView2 et aucun événement natif n'est écouté — #89 ne fonctionnait que sur le web | 🟢 corrigé | P1 | 🖥️ desktop | IA | `desktop/tauri.conf.json` (`create: false`), `desktop/src/main.rs` (`WebviewWindowBuilder::…disable_drag_drop_handler`) | App desktop : glisser un fichier de l'Explorateur sur la fenêtre → aucun survol, aucun dépôt — les gestionnaires HTML5 de `dragdrop.js` ne sont jamais déclenchés | Création manuelle de la fenêtre avec `disable_drag_drop_handler()` (doc Tauri : « required to use HTML5 drag and drop APIs on the frontend on Windows ») ; `create: false` évite la double création par la boucle Tauri | `cargo test` 26 passed (nouveau garde-fou `test_window_created_without_tauri_drag_drop_handler`) + lancement OK (fenêtre unique, boot normal) ; dépôt réel à valider par l'utilisateur | | | | | | | | | | | | ### TODOs techniques (améliorations / nouvelles tâches) @@ -324,6 +325,7 @@ Avant de corriger quoi que ce soit, un agent IA doit : | 2026-10-02 | BUG-104 | Correction | `desktop/permissions/commands.toml` (nouveau), `desktop/capabilities/default.json`, `desktop/build.rs` | **BUG-104 — commandes Tauri rejetées par l'ACL depuis la page backend** : la fenêtre redirige vers `http://127.0.0.1:`, origine *remote* pour Tauri v2, et aucune commande applicative n'était déclarée → `Command … not allowed by ACL` sur `pick_vault_folder`, `get_wizard_state`, etc. ; les erreurs sont avalées par `desktop.js:invoke()` → bouton du wizard silencieusement inopérant depuis #77. Correctif : manifeste `desktop/permissions/commands.toml` (`allow-app-commands`, 19 commandes) référencé par la capability + `rerun-if-changed=permissions` dans `build.rs`. Vérifié : `cargo test` 25 passed (nouveau garde-fou ACL), CDP live : `get_version` OK, clic → fenêtre native « Select Folder », ajout de vault complété de bout en bout. | 🟢 corrigé | | 2026-10-02 | BUG-105 | Correction | `desktop/src/jumplist.rs` | **BUG-105 — crash heap (c0000374) à l'ouverture du desktop** : `set_link_title` (#77) passait un `PROPVARIANT VT_LPWSTR` pointant un buffer heap Rust au property store du shell, qui le libère avec l'allocateur Windows → `STATUS_HEAP_CORRUPTION` détectée dans ntdll ≤20 s après le lancement (3/3, Event Log WER, même empreinte de pile). Fonction supprimée : le libellé des entrées vient de `SetDescription`. Vérifié : bisect sur 3 états de build, run 9 min `EXIT=0`, zéro événement WER. | 🟢 corrigé | | 2026-10-02 | BUG-106 | Correction | `backend/main.py`, `tests/test_csp_nonce.py` | **BUG-106 — page blanche sur /docs** : la CSP `#87 T5c` (`script-src` sans `unsafe-inline`, nonce frais par réponse) s'applique aussi aux pages générées par FastAPI (`/docs`, `/redoc`) dont le balisage n'est jamais passé par `inject_csp_nonce` → le navigateur refusait le script inline `SwaggerUIBundle(…)`, la div restait vide. `SecurityHeadersMiddleware` injecte désormais le nonce dans ce HTML avec le helper existant ; le corps est décompressé/recompressé car `SSESafeGZipMiddleware` est plus proche de la route (les réponses arrivent gunzippées). `/redoc` n'a aucun script inline (bundle jsdelivr seul, couvert par `script-src`) — vérifié tel quel. Vérifié : `test_docs_inline_script_nonced`, `test_redoc_served_with_csp`, `test_docs_external_bundle_not_nonced` + 45 passed sur les 3 suites sécurité, ruff/mypy 0. | 🟢 corrigé | +| 2026-10-02 | BUG-107 | Correction | `desktop/tauri.conf.json`, `desktop/src/main.rs` | **BUG-107 — drag & drop de fichiers inutilisable sur desktop** : Tauri/wry installe son propre `IDropTarget` par-dessus de celui du WebView2 (source wry : « Enumerate child windows to find the WebView2 window and override! ») et aucun événement natif n'était écouté → les glisser-déposer depuis l'Explorateur n'atteignaient jamais les gestionnaires HTML5 de `dragdrop.js` (#89 marchait donc uniquement sur le web). Correctif : la doc Tauri est explicite — `disable_drag_drop_handler()` « is required to use HTML5 drag and drop APIs on the frontend on Windows » ; la fenêtre est créée en code (`create: false` dans `tauri.conf.json`, boucle Tauri qui saute les fenêtres non auto-créées) via `WebviewWindowBuilder::from_config(...).disable_drag_drop_handler()`. Vérifié : `cargo test` 26 passed (nouveau garde-fou `test_window_created_without_tauri_drag_drop_handler` : les deux marqueurs obligatoires), lancement de l'app OK (fenêtre unique, boot log normal) ; glisser-déposer réel à valider par l'utilisateur. | 🟢 corrigé | --- diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 1ef4632..9bd64e3 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -1,6 +1,6 @@ # ObsiGate — Roadmap -> **Version :** 2.50.1 | **Dernière mise à jour :** 2026-10-02 +> **Version :** 2.50.2 | **Dernière mise à jour :** 2026-10-02 > **Ce fichier ne contient que le travail à venir** (🔵 En cours + ⚪ Backlog) et un index compact > vers les fonctionnalités livrées. > - **Méthode de livraison à appliquer pour toute tâche : [DELIVERY_WORKFLOW.md](./DELIVERY_WORKFLOW.md)** diff --git a/package.json b/package.json index 1235bf0..14a5af0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "obsigate", - "version": "2.50.1", + "version": "2.50.2", "description": "**Porte d'entrée web ultra-léger pour vos vaults Obsidian** — Accédez, naviguez et recherchez dans toutes vos notes Obsidian depuis n'importe quel appareil via une interface web moderne et responsive.", "main": "patch.js", "directories": {