From 8d768bf9d5cc3df9bdc97f6c99e524b6811baca7 Mon Sep 17 00:00:00 2001 From: bruno Date: Tue, 27 Oct 2026 23:10:24 -0400 Subject: [PATCH 01/14] [fix] mypy Coffre + bump 2.80.2 : backend/coffre_crypto.py --- backend/coffre_crypto.py | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/backend/coffre_crypto.py b/backend/coffre_crypto.py index ff92dde..897c5dd 100644 --- a/backend/coffre_crypto.py +++ b/backend/coffre_crypto.py @@ -24,14 +24,19 @@ import logging import os import stat from pathlib import Path +from typing import Any logger = logging.getLogger("obsigate.coffre_crypto") +# Annotation explicite : sans elle, mypy refuse l'assignation de deux types +# (la classe AESGCM importée, puis None dans le repli sans cryptography) +# et le commentaire `type: ignore[assignment]` ne couvre pas ce code [misc]. +AESGCM: type[Any] | None try: # cryptography est une dépendance de la Phase 1a (requirements.txt) from cryptography.exceptions import InvalidTag from cryptography.hazmat.primitives.ciphers.aead import AESGCM except Exception: # pragma: no cover - environnement sans cryptography - AESGCM = None # type: ignore[assignment] + AESGCM = None InvalidTag = Exception # type: ignore[assignment,misc] @@ -55,11 +60,17 @@ class CryptoIndisponibleError(CoffreCryptoError): """La bibliothèque ``cryptography`` n'est pas installée.""" -def _require_aesgcm() -> None: +def _require_aesgcm() -> type[Any]: + """Retourne la classe AESGCM, ou lève si cryptography est absent. + + Retourner la classe (plutôt qu'un simple garde) permet à mypy de + savoir que l'appelant détient bien un constructible, et non None. + """ if AESGCM is None: raise CryptoIndisponibleError( "cryptography n'est pas installé (dépendance Phase 1a)" ) + return AESGCM def parse_kek(raw: str) -> bytes: @@ -146,17 +157,17 @@ def _unb64(value: str) -> bytes: def encrypt_with_key(key: bytes, plaintext: bytes, aad: bytes) -> dict: """Chiffre avec AES-256-GCM. Retourne {nonce, ciphertext} en base64.""" - _require_aesgcm() + aesgcm = _require_aesgcm() nonce = os.urandom(12) - ciphertext = AESGCM(key).encrypt(nonce, plaintext, aad) + ciphertext = aesgcm(key).encrypt(nonce, plaintext, aad) return {"nonce": _b64(nonce), "ciphertext": _b64(ciphertext)} def decrypt_with_key(key: bytes, nonce_b64: str, ciphertext_b64: str, aad: bytes) -> bytes: """Déchiffre avec AES-256-GCM. Tag invalide -> TagInvalideError.""" - _require_aesgcm() + aesgcm = _require_aesgcm() try: - return AESGCM(key).decrypt(_unb64(nonce_b64), _unb64(ciphertext_b64), aad) + return aesgcm(key).decrypt(_unb64(nonce_b64), _unb64(ciphertext_b64), aad) except InvalidTag as exc: raise TagInvalideError("Tag GCM invalide : données altérées ou mauvaise clé") from exc except (binascii.Error, ValueError) as exc: -- 2.54.0 From d4d050297be210a0fcc546d374a5639be8d0ec27 Mon Sep 17 00:00:00 2001 From: bruno Date: Tue, 27 Oct 2026 23:10:27 -0400 Subject: [PATCH 02/14] [fix] mypy Coffre + bump 2.80.2 : backend/coffre_store.py --- backend/coffre_store.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/coffre_store.py b/backend/coffre_store.py index d57d21a..ce9d02b 100644 --- a/backend/coffre_store.py +++ b/backend/coffre_store.py @@ -42,6 +42,7 @@ import threading import uuid from datetime import UTC, datetime, timedelta from pathlib import Path +from typing import Any from backend.coffre_crypto import ( decrypt_secret_value, @@ -306,7 +307,7 @@ def create_coffre( data = _load_coffres(base) if any(c["slug"] == slug for c in data["coffres"]): raise CoffreExisteError(f"Coffre déjà existant : {slug}") - coffre = { + coffre: dict[str, Any] = { "id": str(uuid.uuid4()), "slug": slug, "nom": nom, -- 2.54.0 From 0c7b3162c821b34d0640cf597704bbc5bac8a871 Mon Sep 17 00:00:00 2001 From: bruno Date: Tue, 27 Oct 2026 23:10:29 -0400 Subject: [PATCH 03/14] [fix] mypy Coffre + bump 2.80.2 : VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index a2f5270..b753131 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.80.1 +2.80.2 -- 2.54.0 From b12122f78a13c2241214f0f04c6b3a2ce18a77ec Mon Sep 17 00:00:00 2001 From: bruno Date: Tue, 27 Oct 2026 23:10:31 -0400 Subject: [PATCH 04/14] [fix] mypy Coffre + bump 2.80.2 : package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 19f92dd..62e24a4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "obsigate", - "version": "2.80.1", + "version": "2.80.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": { -- 2.54.0 From 2dae023ee31ec4a0fa461979f5c2d6a92150942f Mon Sep 17 00:00:00 2001 From: bruno Date: Tue, 27 Oct 2026 23:10:34 -0400 Subject: [PATCH 05/14] [fix] mypy Coffre + bump 2.80.2 : desktop/tauri.conf.json --- desktop/tauri.conf.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desktop/tauri.conf.json b/desktop/tauri.conf.json index b90a424..2b32868 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.80.1", + "version": "2.80.2", "identifier": "com.obsigate.desktop", "build": { "frontendDist": "../frontend", -- 2.54.0 From 111d927eced98cf62b6c3f43133b9eb0a9eb9752 Mon Sep 17 00:00:00 2001 From: bruno Date: Tue, 27 Oct 2026 23:10:36 -0400 Subject: [PATCH 06/14] [fix] mypy Coffre + bump 2.80.2 : desktop/Cargo.toml --- desktop/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desktop/Cargo.toml b/desktop/Cargo.toml index d54b571..daca03b 100644 --- a/desktop/Cargo.toml +++ b/desktop/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "obsigate-desktop" -version = "2.80.1" +version = "2.80.2" description = "ObsiGate Desktop — Porte d'entrée native pour vos vaults Obsidian" authors = ["Bruno Charest"] edition = "2021" -- 2.54.0 From 0b8ad8b0f3cb59b405291a6fb5160fc1355c26b0 Mon Sep 17 00:00:00 2001 From: bruno Date: Tue, 27 Oct 2026 23:10:39 -0400 Subject: [PATCH 07/14] [fix] mypy Coffre + bump 2.80.2 : desktop/Cargo.lock --- desktop/Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desktop/Cargo.lock b/desktop/Cargo.lock index 473c67e..9e56071 100644 --- a/desktop/Cargo.lock +++ b/desktop/Cargo.lock @@ -2626,7 +2626,7 @@ dependencies = [ [[package]] name = "obsigate-desktop" -version = "2.80.1" +version = "2.80.2" dependencies = [ "chrono", "env_logger", -- 2.54.0 From 593cf492c332bccb066f727a791b765fcbb83ee5 Mon Sep 17 00:00:00 2001 From: bruno Date: Tue, 27 Oct 2026 23:10:41 -0400 Subject: [PATCH 08/14] [fix] mypy Coffre + bump 2.80.2 : README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6097e5d..f2a8446 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.80.1-blue.svg)]() +[![Version](https://img.shields.io/badge/Version-2.80.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/) @@ -1152,8 +1152,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.80.1). +See [CHANGELOG.md](./CHANGELOG.md) for the complete version history (v1.0.0 → v2.80.2). --- -*Project: ObsiGate | Version: 2.80.1 | Last updated: September 2026* +*Project: ObsiGate | Version: 2.80.2 | Last updated: September 2026* -- 2.54.0 From 0352451ead5066f83833bf63ef209d5901e293aa Mon Sep 17 00:00:00 2001 From: bruno Date: Tue, 27 Oct 2026 23:10:44 -0400 Subject: [PATCH 09/14] [fix] mypy Coffre + bump 2.80.2 : README.fr.md --- README.fr.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.fr.md b/README.fr.md index 8ce92e1..9914f6c 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.80.1-blue.svg)]() +[![Version](https://img.shields.io/badge/Version-2.80.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/) @@ -977,8 +977,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.80.1). +Consultez le [CHANGELOG.md](./CHANGELOG.md) pour l'historique complet de toutes les versions (v1.0.0 → v2.80.2). --- -*Projet : ObsiGate | Version : 2.80.1 | Dernière mise à jour : Septembre 2026* +*Projet : ObsiGate | Version : 2.80.2 | Dernière mise à jour : Septembre 2026* -- 2.54.0 From 82756030c6b7c5ec94e60c175a1bdf32bc4640ac Mon Sep 17 00:00:00 2001 From: bruno Date: Tue, 27 Oct 2026 23:10:48 -0400 Subject: [PATCH 10/14] [fix] mypy Coffre + bump 2.80.2 : docs/ROADMAP.md --- docs/ROADMAP.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index d67128d..76a85f5 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -1,6 +1,6 @@ # ObsiGate — Roadmap -> **Version :** 2.80.1 | **Dernière mise à jour :** 2026-10-27 +> **Version :** 2.80.2 | **Dernière mise à jour :** 2026-10-27 > **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)** -- 2.54.0 From fc3d847d852a23d805d3f1e26d219a2ed675ca36 Mon Sep 17 00:00:00 2001 From: bruno Date: Tue, 27 Oct 2026 23:10:51 -0400 Subject: [PATCH 11/14] [fix] mypy Coffre + bump 2.80.2 : CHANGELOG.md --- CHANGELOG.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6a7117..ae7ec03 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.80.1**. +> [Unreleased](#unreleased). La dernière version livrée est **2.80.2**. --- @@ -14,6 +14,14 @@ et [Semantic Versioning](https://semver.org/spec/v2.0.0.html). --- +## [2.80.2] — 2026-10-27 + +### Corrigé + +- **CI lint (mypy)** — 3 erreurs dans le Coffre Secrets : annotation explicite `type[Any] | None` pour `AESGCM` dans `coffre_crypto.py` (le repli sans `cryptography` reste `None`, et `_require_aesgcm()` retourne désormais la classe pour un narrowing propre) ; annotation `dict[str, Any]` du coffre dans `create_coffre` (`coffre_store.py`), qui inférait ses valeurs en `str | None` et refusait le dict de `wrap_dek` ainsi que `coffre["id"]` en argument. Aucun `type: ignore` aveugle ajouté, aucun changement de comportement. + +--- + ## [2.80.1] — 2026-10-27 ### Ajouté -- 2.54.0 From 682a5030d3e03e0035165d479e388cd9044f2945 Mon Sep 17 00:00:00 2001 From: bruno Date: Tue, 27 Oct 2026 23:20:30 -0400 Subject: [PATCH 12/14] [fix] Coffre Secrets : valeurField attache l'oeil a wrap avant insertBefore (NotFoundError bouton Nouveau secret) --- frontend/js/coffres.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontend/js/coffres.js b/frontend/js/coffres.js index e4862b1..8d57b89 100644 --- a/frontend/js/coffres.js +++ b/frontend/js/coffres.js @@ -292,6 +292,9 @@ function valeurField(initialType) { else if (input) input.type = 'password'; }); eyeBtn.title = t('coffres.show_before_save'); + // L'oeil doit etre enfant de wrap AVANT le premier build : insertBefore(input, eyeBtn) + // leve sinon NotFoundError et la modale ne s'ouvre jamais (bug bouton Nouveau secret). + wrap.appendChild(eyeBtn); build(initialType); return { wrap, -- 2.54.0 From 5266506b56c1b7cdda24a7c8f18b2e1e11128c6a Mon Sep 17 00:00:00 2001 From: bruno Date: Tue, 27 Oct 2026 23:20:35 -0400 Subject: [PATCH 13/14] [fix] Securite : plancher msgpack>=1.2.3 (CVE-2026-114613, pip-audit bloquant) --- backend/requirements.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backend/requirements.txt b/backend/requirements.txt index 3b500cf..b412ab7 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -75,3 +75,7 @@ filelock>=4.2.1 opentelemetry-api>=1.45.1 # Coffre Secrets (Phase 1a) : chiffrement par enveloppe AES-256-GCM. cryptography>=44.0 + +# Plancher de securite : msgpack est transitif, version 1.2.1 relevee par le job +# security (pip-audit, bloquant) — CVE-2026-114613, corrigee en 1.2.3. +msgpack>=1.2.3 -- 2.54.0 From 99cd7659973ab3a208328dbf486e9c9d2c8df20c Mon Sep 17 00:00:00 2001 From: bruno Date: Tue, 27 Oct 2026 23:20:41 -0400 Subject: [PATCH 14/14] [fix] CHANGELOG 2.80.2 : bouton Nouveau secret + plancher msgpack --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae7ec03..bdd0036 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,9 @@ et [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - **CI lint (mypy)** — 3 erreurs dans le Coffre Secrets : annotation explicite `type[Any] | None` pour `AESGCM` dans `coffre_crypto.py` (le repli sans `cryptography` reste `None`, et `_require_aesgcm()` retourne désormais la classe pour un narrowing propre) ; annotation `dict[str, Any]` du coffre dans `create_coffre` (`coffre_store.py`), qui inférait ses valeurs en `str | None` et refusait le dict de `wrap_dek` ainsi que `coffre["id"]` en argument. Aucun `type: ignore` aveugle ajouté, aucun changement de comportement. +- **Bouton Nouveau secret inoperant (console NotFoundError)** — `valeurField` appelait `wrap.insertBefore(input, eyeBtn)` alors que le bouton oeil n'avait jamais ete rattache a `wrap` : l'oeil est desormais ajoute a `wrap` avant le premier `build`, la modale de creation (et celle de rotation) s'ouvre. +- **CI security (pip-audit)** — plancher `msgpack>=1.2.3` : la version transitive 1.2.1 etait signalee pour CVE-2026-114613 (correctif 1.2.3). + --- ## [2.80.1] — 2026-10-27 -- 2.54.0