fix: coller du menu contextuel tableur muet + planchers sécurité CI (BUG-108)
BUG-108 — closeContextMenu() retirait le nœud du menu AVANT de déférencer _menu : le retrait émet focusout en synchrone (le menu tient le focus), qui rappelle closeContextMenu() ; le second remove() sur un nœud démonté lève NotFoundError et avorte le handler de l'action « Coller » du viewer — le coller par menu contextuel était silencieusement mort (régression de la fermeture au focus #179, reproduite par l'E2E « coller une plage », CI #850→#854). Déférencement avant retrait. Sécurité CI (job security, run #853) : - plancher multidict>=6.9.1 (CVE-2026-104874 ; 6.7.x préinstallée dans la toolcache de l'image du runner, même piège « already satisfied » que pypdf BUG-093) + entrée dans le garde-fou TestDependencySecurityFloors ; - exception documentée CVE-2026-85394 (python-jose, AUCUN correctif upstream) : non atteignable ici, jwt.decode passe toujours algorithms=["HS256"] avec un secret symétrique serveur — jamais de clé publique comme clé HMAC. Vérifié : E2E -g « coller une plage » 1/1 ; xlsx-menus 11/11, xlsx-formula 14/14, ai 100/100, ai-quick-actions 13/13 ; pytest 1586 passés ; ruff/mypy 0 erreur ; ISSUES_TODOLIST + CHANGELOG à jour.
This commit is contained in:
+10
-1
@@ -181,13 +181,22 @@ jobs:
|
|||||||
# pypdf>=6.16.1 (BUG-093).
|
# pypdf>=6.16.1 (BUG-093).
|
||||||
# CVE-2026-97687 / CVE-2026-97688 / CVE-2026-97689 (urllib3 2.7.0)
|
# CVE-2026-97687 / CVE-2026-97688 / CVE-2026-97689 (urllib3 2.7.0)
|
||||||
# corrigés par le plancher urllib3>=2.8.0.
|
# corrigés par le plancher urllib3>=2.8.0.
|
||||||
|
# CVE-2026-104874 (multidict 6.7.x) corrigé par le plancher
|
||||||
|
# multidict>=6.9.1 (transitive aiohttp/yarl ; 6.7.x est dans la
|
||||||
|
# toolcache de l'image du runner — même piège « already satisfied »).
|
||||||
|
# CVE-2026-85394 (python-jose ≤3.5.0, forgery HS256 par clé publique
|
||||||
|
# DER passée comme secret HMAC) : AUCUN correctif upstream (projet
|
||||||
|
# sans release depuis 2025). Non atteignable dans ObsiGate :
|
||||||
|
# jwt.decode passe toujours algorithms=["HS256"] et un secret
|
||||||
|
# symétrique serveur (backend/auth/jwt_handler.py,
|
||||||
|
# backend/mcp/confirmations.py) — jamais une clé publique comme clé.
|
||||||
# Ces planchers doivent rester *au-dessus* des versions préinstallées
|
# Ces planchers doivent rester *au-dessus* des versions préinstallées
|
||||||
# dans la toolcache de l'image du runner : en dessous, pip répond
|
# dans la toolcache de l'image du runner : en dessous, pip répond
|
||||||
# « already satisfied » et n'aligne jamais (c'est exactement ce qui a
|
# « already satisfied » et n'aligne jamais (c'est exactement ce qui a
|
||||||
# fait échouer ce job). Le garde-fou tests/test_ci_workflow.py::
|
# fait échouer ce job). Le garde-fou tests/test_ci_workflow.py::
|
||||||
# TestDependencySecurityFloors verrouille ces planchers.
|
# TestDependencySecurityFloors verrouille ces planchers.
|
||||||
# NOTE runner Gitea Act (BUG-083) : aucun `#` dans le `run:`.
|
# NOTE runner Gitea Act (BUG-083) : aucun `#` dans le `run:`.
|
||||||
run: pip-audit --ignore-vuln PYSEC-2026-1325
|
run: pip-audit --ignore-vuln PYSEC-2026-1325 --ignore-vuln CVE-2026-85394
|
||||||
|
|
||||||
# ── Docker build ──────────────────────────────────────────────────
|
# ── Docker build ──────────────────────────────────────────────────
|
||||||
build:
|
build:
|
||||||
|
|||||||
+16
-1
@@ -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).
|
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
|
> **En cours de développement** : les changements à venir sont listés dans la section
|
||||||
> [Unreleased](#unreleased). La dernière version livrée est **2.53.2**.
|
> [Unreleased](#unreleased). La dernière version livrée est **2.53.3**.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -14,6 +14,21 @@ et [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## [2.53.3] — 2026-10-07
|
||||||
|
|
||||||
|
### Corrigé
|
||||||
|
|
||||||
|
- **BUG-108 - Tableur : « Coller » du menu contextuel muet**
|
||||||
|
- `closeContextMenu()` retirait le nœud du menu **avant** de déférencer
|
||||||
|
`_menu` : retirer le menu portant le focus émet un `focusout` synchrone
|
||||||
|
qui rappelle la fonction, et le second `remove()` sur un nœud déjà
|
||||||
|
démonté lève `NotFoundError` — le handler de l'action « Coller » du
|
||||||
|
viewer est avorté avant son exécution (régression de la fermeture au
|
||||||
|
focus #179 ; reproduite par l'E2E « coller une plage », CI #850-#854).
|
||||||
|
Déférencement avant retrait ; l'E2E passe après correctif.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## [2.53.2] — 2026-10-07
|
## [2.53.2] — 2026-10-07
|
||||||
|
|
||||||
### Modifié
|
### Modifié
|
||||||
|
|||||||
+3
-3
@@ -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.
|
**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.
|
||||||
|
|
||||||
[]()
|
[]()
|
||||||
[](https://opensource.org/licenses/MIT)
|
[](https://opensource.org/licenses/MIT)
|
||||||
[](https://www.docker.com/)
|
[](https://www.docker.com/)
|
||||||
[](https://www.python.org/)
|
[](https://www.python.org/)
|
||||||
@@ -976,8 +976,8 @@ Ce projet est sous licence **MIT** — voir le fichier [LICENSE](LICENSE) pour l
|
|||||||
|
|
||||||
## 📝 Changelog
|
## 📝 Changelog
|
||||||
|
|
||||||
Consultez le [CHANGELOG.md](./CHANGELOG.md) pour l'historique complet de toutes les versions (v1.0.0 → v2.53.2).
|
Consultez le [CHANGELOG.md](./CHANGELOG.md) pour l'historique complet de toutes les versions (v1.0.0 → v2.53.3).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*Projet : ObsiGate | Version : 2.53.2 | Dernière mise à jour : Septembre 2026*
|
*Projet : ObsiGate | Version : 2.53.3 | Dernière mise à jour : Septembre 2026*
|
||||||
|
|||||||
@@ -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.
|
**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.
|
||||||
|
|
||||||
[]()
|
[]()
|
||||||
[](https://opensource.org/licenses/MIT)
|
[](https://opensource.org/licenses/MIT)
|
||||||
[](https://www.docker.com/)
|
[](https://www.docker.com/)
|
||||||
[](https://www.python.org/)
|
[](https://www.python.org/)
|
||||||
@@ -1151,8 +1151,8 @@ This project is licensed under the **MIT License** - see the [LICENSE](LICENSE)
|
|||||||
|
|
||||||
## 📝 Changelog
|
## 📝 Changelog
|
||||||
|
|
||||||
See [CHANGELOG.md](./CHANGELOG.md) for the complete version history (v1.0.0 → v2.53.2).
|
See [CHANGELOG.md](./CHANGELOG.md) for the complete version history (v1.0.0 → v2.53.3).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*Project: ObsiGate | Version: 2.53.2 | Last updated: September 2026*
|
*Project: ObsiGate | Version: 2.53.3 | Last updated: September 2026*
|
||||||
|
|||||||
@@ -39,3 +39,8 @@ reportlab>=4.0
|
|||||||
pillow>=10.0
|
pillow>=10.0
|
||||||
# Plancher urllib3 >= 2.8.0 (CVE-2026-97687, CVE-2026-97688, CVE-2026-97689)
|
# Plancher urllib3 >= 2.8.0 (CVE-2026-97687, CVE-2026-97688, CVE-2026-97689)
|
||||||
urllib3>=2.8.0
|
urllib3>=2.8.0
|
||||||
|
# Plancher de sécurité (CVE-2026-104874, fix 6.9.1) : multidict est transitive
|
||||||
|
# (aiohttp/yarl). 6.7.x est la version pré-installée dans la toolcache de
|
||||||
|
# l'image du runner — sans plancher, pip répond « already satisfied » et
|
||||||
|
# n'aligne jamais (même piège que pypdf, BUG-093).
|
||||||
|
multidict>=6.9.1
|
||||||
|
|||||||
Generated
+1
-1
@@ -2626,7 +2626,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "obsigate-desktop"
|
name = "obsigate-desktop"
|
||||||
version = "2.53.2"
|
version = "2.53.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "obsigate-desktop"
|
name = "obsigate-desktop"
|
||||||
version = "2.53.2"
|
version = "2.53.3"
|
||||||
description = "ObsiGate Desktop — Porte d'entrée native pour vos vaults Obsidian"
|
description = "ObsiGate Desktop — Porte d'entrée native pour vos vaults Obsidian"
|
||||||
authors = ["Bruno Charest"]
|
authors = ["Bruno Charest"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/nicedoc/obsigate/main/desktop/tauri.conf.schema.json",
|
"$schema": "https://raw.githubusercontent.com/nicedoc/obsigate/main/desktop/tauri.conf.schema.json",
|
||||||
"productName": "ObsiGate",
|
"productName": "ObsiGate",
|
||||||
"version": "2.53.2",
|
"version": "2.53.3",
|
||||||
"identifier": "com.obsigate.desktop",
|
"identifier": "com.obsigate.desktop",
|
||||||
"build": {
|
"build": {
|
||||||
"frontendDist": "../frontend",
|
"frontendDist": "../frontend",
|
||||||
|
|||||||
@@ -214,7 +214,8 @@ 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-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-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-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 |
|
| *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` : les deux marqueurs obligatoires) + lancement OK (fenêtre unique, boot normal) ; dépôt réel à valider par l'utilisateur |
|
||||||
|
| *BUG-108* | Tableur : le « Coller » du menu contextuel ne fait rien (copier-coller par menu muet) | 🟢 corrigé | P1 | 📱 frontend | IA | `frontend/js/xlsx/context-menu.js` (`closeContextMenu`) | Ouvrir un `.xlsx`, clic droit « Copier » sur une plage, clic droit cible puis « Coller » → rien n'est collé (le menu se ferme sans action) | `closeContextMenu()` retirait le nœud du DOM **avant** de remettre `_menu` à `null` : retirer le menu qui tient le focus émet `focusout` en synchrone, qui rappelle `closeContextMenu()` → second `remove()` sur un nœud déjà démonté → `NotFoundError` qui avorte le handler de l'action « Coller » du viewer. Introduit par #179 (fermeture au focus). Correctif : `_menu = null` avant `menu.remove()` | Reproduit en local sur HEAD (e2e « coller une plage » : attendu `Date`, obtenu la valeur datée) puis vert après fix : E2E `-g "coller une plage"` 1/1, `xlsx-menus` 11/11, `ai-quick-actions` 13/13 |
|
||||||
| | | | | | | | | | |
|
| | | | | | | | | | |
|
||||||
### TODOs techniques (améliorations / nouvelles tâches)
|
### TODOs techniques (améliorations / nouvelles tâches)
|
||||||
|
|
||||||
@@ -326,6 +327,7 @@ Avant de corriger quoi que ce soit, un agent IA doit :
|
|||||||
| 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-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-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é |
|
| 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é |
|
||||||
|
| 2026-10-07 | BUG-108 | Correction | `frontend/js/xlsx/context-menu.js` | **BUG-108 — « Coller » du menu contextuel du tableur muet** : `closeContextMenu()` faisait `menu.remove()` **avant** `_menu = null` ; retirer le menu portant le focus émet `focusout` synchrone qui rappelle `closeContextMenu()`, le second `remove()` sur un nœud démonté lève `NotFoundError` et avorte le handler de l'action avant son exécution (introduit par la fermeture au focus #179). Reproduit par l'E2E `xlsx-viewer.spec.js` « coller une plage » (CI #850→#854). Correctif : déférencer avant de retirer. | 🟢 corrigé |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
# ObsiGate — Roadmap
|
# ObsiGate — Roadmap
|
||||||
|
|
||||||
> **Version :** 2.53.2 | **Dernière mise à jour :** 2026-10-07
|
> **Version :** 2.53.3 | **Dernière mise à jour :** 2026-10-07
|
||||||
> **Ce fichier ne contient que le travail à venir** (🔵 En cours + ⚪ Backlog) et un index compact
|
> **Ce fichier ne contient que le travail à venir** (🔵 En cours + ⚪ Backlog) et un index compact
|
||||||
> vers les fonctionnalités livrées.
|
> vers les fonctionnalités livrées.
|
||||||
> - **Méthode de livraison à appliquer pour toute tâche : [DELIVERY_WORKFLOW.md](./DELIVERY_WORKFLOW.md)**
|
> - **Méthode de livraison à appliquer pour toute tâche : [DELIVERY_WORKFLOW.md](./DELIVERY_WORKFLOW.md)**
|
||||||
|
|||||||
@@ -17,10 +17,14 @@ let _openedAt = 0;
|
|||||||
let _dismissBound = false;
|
let _dismissBound = false;
|
||||||
|
|
||||||
export function closeContextMenu() {
|
export function closeContextMenu() {
|
||||||
if (_menu) {
|
// BUG-108: drop the reference BEFORE touching the DOM — removing a menu
|
||||||
_menu.remove();
|
// that holds the focus fires blur/focusout synchronously, which re-enters
|
||||||
_menu = null;
|
// this very function; the second remove() on the mid-flight node throws
|
||||||
}
|
// NotFoundError and aborts the caller's click handler before its action
|
||||||
|
// runs (contextual « Coller » silently dead, e2e xlsx-viewer A5).
|
||||||
|
const menu = _menu;
|
||||||
|
_menu = null;
|
||||||
|
if (menu) menu.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isContextMenuOpen() {
|
export function isContextMenuOpen() {
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "obsigate",
|
"name": "obsigate",
|
||||||
"version": "2.53.2",
|
"version": "2.53.3",
|
||||||
"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.",
|
"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",
|
"main": "patch.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
|
|||||||
@@ -255,6 +255,7 @@ class TestDependencySecurityFloors:
|
|||||||
# BUG-095 : 2.13.0 a son propre advisory (CVE-2026-102274, fix 2.14.0).
|
# BUG-095 : 2.13.0 a son propre advisory (CVE-2026-102274, fix 2.14.0).
|
||||||
"pyjwt": (2, 14, 0), # PYSEC-2026-178 (2.13.0) puis CVE-2026-102274 (2.14.0)
|
"pyjwt": (2, 14, 0), # PYSEC-2026-178 (2.13.0) puis CVE-2026-102274 (2.14.0)
|
||||||
"urllib3": (2, 8, 0), # CVE-2026-97687, CVE-2026-97688, CVE-2026-97689 (fix 2.8.0)
|
"urllib3": (2, 8, 0), # CVE-2026-97687, CVE-2026-97688, CVE-2026-97689 (fix 2.8.0)
|
||||||
|
"multidict": (6, 9, 1), # CVE-2026-104874 (fix 6.9.1 ; 6.7.x toolcache runner)
|
||||||
}
|
}
|
||||||
|
|
||||||
def test_security_floors_are_declared(self):
|
def test_security_floors_are_declared(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user