Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ad8eaac71 |
+14
-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).
|
||||
|
||||
> **En cours de développement** : les changements à venir sont listés dans la section
|
||||
> [Unreleased](#unreleased). La dernière version livrée est **2.16.4**.
|
||||
> [Unreleased](#unreleased). La dernière version livrée est **2.16.5**.
|
||||
|
||||
---
|
||||
|
||||
@@ -14,6 +14,19 @@ et [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
---
|
||||
|
||||
## [2.16.5] — 2026-09-22
|
||||
|
||||
### Corrigé
|
||||
|
||||
- **BUG-071 (complément) - spec E2E mobile de la page Configurations** :
|
||||
`tests/e2e/config-mobile.spec.js` (nouveau, projet `chromium-mobile`,
|
||||
ignoré en `chromium-desktop` comme `mobile-editor.spec.js`) : le hamburger
|
||||
révèle le sommaire, le choix d'une section y défile + lien actif + repli
|
||||
auto, aucun débordement horizontal à 393px. Vérifié en local contre
|
||||
l'instance de test (port 2029, auth désactivée) : 3/3.
|
||||
|
||||
---
|
||||
|
||||
## [2.16.4] — 2026-09-22
|
||||
|
||||
### Corrigé
|
||||
|
||||
+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.
|
||||
|
||||
[]()
|
||||
[]()
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
[](https://www.docker.com/)
|
||||
[](https://www.python.org/)
|
||||
@@ -927,8 +927,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.16.4).
|
||||
Consultez le [CHANGELOG.md](./CHANGELOG.md) pour l'historique complet de toutes les versions (v1.0.0 → v2.16.5).
|
||||
|
||||
---
|
||||
|
||||
*Projet : ObsiGate | Version : 2.16.4 | Dernière mise à jour : Juin 2026*
|
||||
*Projet : ObsiGate | Version : 2.16.5 | Dernière mise à jour : Juin 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.
|
||||
|
||||
[]()
|
||||
[]()
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
[](https://www.docker.com/)
|
||||
[](https://www.python.org/)
|
||||
@@ -1096,8 +1096,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.16.4).
|
||||
See [CHANGELOG.md](./CHANGELOG.md) for the complete version history (v1.0.0 → v2.16.5).
|
||||
|
||||
---
|
||||
|
||||
*Project: ObsiGate | Version: 2.16.4 | Last updated: May 2026*
|
||||
*Project: ObsiGate | Version: 2.16.5 | Last updated: May 2026*
|
||||
|
||||
Generated
+1
-1
@@ -2626,7 +2626,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "obsigate-desktop"
|
||||
version = "2.16.4"
|
||||
version = "2.16.5"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"env_logger",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "obsigate-desktop"
|
||||
version = "2.16.4"
|
||||
version = "2.16.5"
|
||||
description = "ObsiGate Desktop — Porte d'entrée native pour vos vaults Obsidian"
|
||||
authors = ["Bruno Charest"]
|
||||
edition = "2021"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/nicedoc/obsigate/main/desktop/tauri.conf.schema.json",
|
||||
"productName": "ObsiGate",
|
||||
"version": "2.16.4",
|
||||
"version": "2.16.5",
|
||||
"identifier": "com.obsigate.desktop",
|
||||
"build": {
|
||||
"frontendDist": "../frontend",
|
||||
|
||||
@@ -179,7 +179,7 @@ Avant de corriger quoi que ce soit, un agent IA doit :
|
||||
| *BUG-068* | Configuration — section « 🔒 Sécurité du compte » inachevée : boutons hors thème, QR code invisible, fiabilité des fonctions à valider | 🟢 corrigé | P1 | 📱 frontend + ⚙️ backend | IA | `frontend/js/auth.js`, `frontend/style.css`, `backend/auth/router.py` | Configuration → 🔒 Sécurité du compte | `frontend/style.css` (+`config-btn-primary`/`danger` thème), `backend/auth/router.py` (`qr_data_url` segno local), `frontend/js/auth.js` (QR local + fallback, recovery WebAuthn, carte mot de passe, escapeHtml labels), locales FR/EN, `backend/requirements.txt` (+segno) ; tests `tests/test_mfa.py` (+1) + `tests/frontend/mfa-settings.test.mjs` (nouveau, 9) | pytest 1241 passed / 6 skipped, ruff 0, mypy 0, frontend unit + validate-imports verts |
|
||||
| *BUG-069* | Login 2FA bloqué sans erreur : après user+pwd corrects, la page de login reste affichée et le challenge MFA n'apparaît jamais | 🟢 corrigé | P0 | 📱 frontend | IA | `frontend/js/auth.js`, `frontend/index.html` | Activer 2FA → logout → login (bon user+pwd) | `frontend/js/auth.js` (`showMfaChallenge` → `.login-card` + erreur `mfa.challenge_unavailable` si montage impossible), locales FR/EN ; tests `tests/frontend/mfa-settings.test.mjs` (+2) | Reproduit au navigateur avant correctif (challenge jamais affiché), vérifié après : challenge affiché, code erroné → erreur, code valide (200) → app ; frontend mfa-settings 11/11, unit + validate-imports verts |
|
||||
| *BUG-070* | Activation clé physique WebAuthn impossible : « Validation du credential WebAuthn échouée » à chaque tentative | 🟢 corrigé | P0 | ⚙️ backend | IA | `backend/auth/webauthn_mfa.py`, `backend/auth/router.py` | Config → Sécurité → Ajouter une clé → cérémonie navigateur → 400 | `resolve_relying_party()` (rp_id/origines dérivés de la requête, config explicite prioritaire, forwarded si TRUST_PROXY) sur les 4 endpoints ; challenges multiples (5 derniers) acceptés ; `.env.example` ; tests `tests/test_webauthn.py` (+8) | Logs : origin `http://localhost:2020` rejetée + challenge mismatch au retry. Vérifié navigateur (authentificateur virtuel CDP) : register 200 + clé listée, clé de test retirée (admin de nouveau TOTP seul) ; pytest 1249 passed, ruff/mypy 0 |
|
||||
| *BUG-071* | Configuration « Configurations » inutilisable en mode mobile : sommaire masqué sans bouton d'accès, navigation par ancre sans JS, grilles 2 colonnes et rangées d'ajout qui débordent (≤768px) | 🟢 corrigé | P1 | 📱 frontend | IA | `frontend/index.html`, `frontend/js/config.js`, `frontend/js/i18n.js`, `frontend/style.css`, `frontend/locales/{fr,en}.json` | Mobile (≤768px) : ouvrir Configurations → aucun sommaire ni moyen d'atteindre une section ; champs « Clés IA » / jetons / webhooks débordent | `index.html` (+`#config-hamburger` `.help-hamburger`, `config.toc_toggle` FR/EN) ; `config.js` (toggle, scroll doux + actif + repli auto mobile, reset à l'ouverture) ; `i18n.js` (`data-i18n-attr` multi-paires `;`) ; `style.css` (bloc mobile `#config-modal` : sommaire haut 46vh, grilles 1fr, add-rows wrap + `!important`, items wrap, 44px) ; tests `tests/frontend/config-mobile.test.mjs` (nouveau, 11) + CI | pytest 1249 passed / 6 skipped, ruff 0, mypy 0, validate-imports 39 modules, unit 10/10, JSDOM ai 93/93 + sidebar 6/6 + mobile 35/35 + ai-keys 7/7 |
|
||||
| *BUG-071* | Configuration « Configurations » inutilisable en mode mobile : sommaire masqué sans bouton d'accès, navigation par ancre sans JS, grilles 2 colonnes et rangées d'ajout qui débordent (≤768px) | 🟢 corrigé | P1 | 📱 frontend | IA | `frontend/index.html`, `frontend/js/config.js`, `frontend/js/i18n.js`, `frontend/style.css`, `frontend/locales/{fr,en}.json` | Mobile (≤768px) : ouvrir Configurations → aucun sommaire ni moyen d'atteindre une section ; champs « Clés IA » / jetons / webhooks débordent | `index.html` (+`#config-hamburger` `.help-hamburger`, `config.toc_toggle` FR/EN) ; `config.js` (toggle, scroll doux + actif + repli auto mobile, reset à l'ouverture) ; `i18n.js` (`data-i18n-attr` multi-paires `;`) ; `style.css` (bloc mobile `#config-modal` : sommaire haut 46vh, grilles 1fr, add-rows wrap + `!important`, items wrap, 44px) ; tests `tests/frontend/config-mobile.test.mjs` (nouveau, 11) + CI ; E2E `tests/e2e/config-mobile.spec.js` (nouveau, 3/3 projet chromium-mobile, ignoré en desktop) | pytest 1249 passed / 6 skipped, ruff 0, mypy 0, validate-imports 39 modules, unit 10/10, JSDOM ai 93/93 + sidebar 6/6 + mobile 35/35 + ai-keys 7/7 |
|
||||
| | | | | | | | | | | |
|
||||
|
||||
### TODOs techniques (améliorations / nouvelles tâches)
|
||||
@@ -257,6 +257,7 @@ Avant de corriger quoi que ce soit, un agent IA doit :
|
||||
| 2026-09-23 | BUG-069 | Correction | `frontend/js/auth.js`, `frontend/locales/{fr,en}.json`, `tests/frontend/mfa-settings.test.mjs`, `CHANGELOG.md`, `docs/ISSUES_TODOLIST.md` | **BUG-069** : login 2FA bloqué sans erreur — après user+pwd corrects, `showMfaChallenge` cherchait `.login-box` (inexistant dans `index.html`, marquage réel `#login-screen > .login-card`) et faisait un `return` silencieux : page de login figée, aucune erreur. Correctif : montage dans `.login-card` (repli `#login-screen`) + erreur visible `mfa.challenge_unavailable` (FR/EN) si le point de montage manque. **Reproduit au navigateur** (Playwright, instance Docker `obsigate-test`, compte jetable avec TOTP) : avant → challenge jamais affiché ; après → challenge affiché, code erroné → erreur, code valide (verify 200) → app. Tests : `mfa-settings.test.mjs` 11/11 (+2 ancrage DOM), unit 10/10, validate-imports 39 modules. | 🟢 corrigé (en attente vérif utilisateur) |
|
||||
| 2026-09-23 | BUG-070 | Correction | `backend/auth/webauthn_mfa.py`, `backend/auth/router.py`, `.env.example`, `tests/test_webauthn.py`, `CHANGELOG.md`, `docs/ISSUES_TODOLIST.md` | **BUG-070** : activation WebAuthn rejetée en 400. (1) Défauts `localhost` sans port → `resolve_relying_party()` dérive rp_id/origines de la requête (config explicite prioritaire, forwarded sous TRUST_PROXY), appliqué aux endpoints register + login. (2) Challenge single-use → 5 derniers conservés, vérification contre le challenge de la cérémonie en cours. **Vérifié au navigateur** (authentificateur virtuel CDP, instance Docker) : register 200, clé listée, clé de test retirée. Tests : `test_webauthn.py` 19/19 (+8), suite complète 1249 passed / 6 skipped, ruff/mypy 0. | 🟢 corrigé (en attente vérif utilisateur) |
|
||||
| 2026-09-23 | BUG-071 | Correction | `frontend/index.html`, `frontend/js/config.js`, `frontend/js/i18n.js`, `frontend/style.css`, `frontend/locales/{fr,en}.json`, `tests/frontend/config-mobile.test.mjs` (nouveau), `.gitea/workflows/ci.yml`, `CHANGELOG.md`, `docs/ISSUES_TODOLIST.md` | **BUG-071** : page « Configurations » inutilisable en mobile. (1) `#config-nav` masquée sous 768px sans toggle → hamburger `#config-hamburger` ajouté à l'en-tête (`.help-hamburger`, libellé `config.toc_toggle` FR/EN). (2) Ancres brutes sans JS → interception en `config.js` (scroll doux, lien actif, repli auto mobile, reset à l'ouverture). (3) Débordements 360px → bloc CSS mobile `#config-modal` (sommaire haut 46vh, grilles 1fr, add-rows wrap + largeurs inline neutralisées, items wrap, cibles 44px). `data-i18n-attr` multi-paires (`;`). Vérifié : `config-mobile.test.mjs` 11/11 (nouveau, au CI), pytest 1249 passed / 6 skipped, ruff/mypy 0, validate-imports 39 modules, unit 10/10, JSDOM ai 93/93 + ai-sidebar 6/6 + sidebar-filters 8/8 + mobile-editor 35/35 + config-ai-keys 7/7. | 🟢 corrigé (en attente vérif utilisateur) |
|
||||
| 2026-09-23 | BUG-071 (complément E2E) | Test | `tests/e2e/config-mobile.spec.js` (nouveau), `CHANGELOG.md`, `docs/ISSUES_TODOLIST.md` | **BUG-071 (complément E2E)** : spec Playwright mobile (convention `mobile-editor.spec.js` : `test.skip` hors viewport ≤768px, donc inactive sur le projet `chromium-desktop` du CI). Vérifié en local sur l'instance de test (port 2029, auth désactivée) : hamburger → sommaire, sélection → scroll + actif + repli, 0 débordement horizontal à 393px (3/3 `chromium-mobile`, 3 ignorés en desktop) ; suite `mobile-editor.spec.js` intacte (3/3). | 🟢 corrigé (en attente vérif utilisateur) |
|
||||
|
||||
---
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# ObsiGate — Roadmap
|
||||
|
||||
> **Version :** 2.16.4 | **Dernière mise à jour :** 2026-09-22
|
||||
> **Version :** 2.16.5 | **Dernière mise à jour :** 2026-09-22
|
||||
> **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)**
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "obsigate",
|
||||
"version": "2.16.4",
|
||||
"version": "2.16.5",
|
||||
"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": {
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* E2E tests for the Configurations modal on mobile (BUG-071).
|
||||
*
|
||||
* Runs only under the `chromium-mobile` Playwright project (viewport ≤ 768px);
|
||||
* skipped on the desktop project that the CI job executes — same convention
|
||||
* as mobile-editor.spec.js.
|
||||
*
|
||||
* Covered:
|
||||
* - the TOC hamburger (#config-hamburger) is visible and reveals #config-nav,
|
||||
* which is hidden by default on mobile;
|
||||
* - picking a TOC entry scrolls to the section, marks the link active and
|
||||
* collapses the nav;
|
||||
* - the modal content does not overflow horizontally at 393px.
|
||||
*
|
||||
* Run:
|
||||
* npx playwright test tests/e2e/config-mobile.spec.js --project=chromium-mobile
|
||||
* (ObsiGate listening on http://localhost:2029, auth disabled)
|
||||
*/
|
||||
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
const MOBILE_MAX_WIDTH = 768;
|
||||
|
||||
async function boot(page) {
|
||||
await page.goto('/');
|
||||
await page.waitForSelector('#app:not(.hidden)', { timeout: 15000 });
|
||||
await expect(page.locator('#header-menu-btn')).toBeVisible({ timeout: 15000 });
|
||||
}
|
||||
|
||||
async function openConfigModal(page) {
|
||||
await page.locator('#header-menu-btn').click();
|
||||
await page.locator('#config-open-btn').click();
|
||||
await expect(page.locator('#config-modal.active')).toBeVisible();
|
||||
}
|
||||
|
||||
test.describe('Configurations modal on mobile (BUG-071)', () => {
|
||||
test('hamburger reveals the table of contents', async ({ page, viewport }) => {
|
||||
test.skip((viewport?.width ?? 0) > MOBILE_MAX_WIDTH, 'Mobile viewport required');
|
||||
await boot(page);
|
||||
await openConfigModal(page);
|
||||
|
||||
// TOC hidden by default on mobile, hamburger visible.
|
||||
await expect(page.locator('#config-hamburger')).toBeVisible();
|
||||
await expect(page.locator('#config-nav')).toBeHidden();
|
||||
|
||||
await page.locator('#config-hamburger').click();
|
||||
await expect(page.locator('#config-nav')).toBeVisible();
|
||||
});
|
||||
|
||||
test('picking a section scrolls to it and collapses the nav', async ({ page, viewport }) => {
|
||||
test.skip((viewport?.width ?? 0) > MOBILE_MAX_WIDTH, 'Mobile viewport required');
|
||||
await boot(page);
|
||||
await openConfigModal(page);
|
||||
|
||||
await page.locator('#config-hamburger').click();
|
||||
const link = page.locator('#config-nav a[href="#cfg-tokens"]');
|
||||
await expect(link).toBeVisible();
|
||||
await link.click();
|
||||
|
||||
// Nav collapses on mobile after selection…
|
||||
await expect(page.locator('#config-nav')).toBeHidden();
|
||||
// …the link is marked active…
|
||||
await expect(link).toHaveClass(/active/);
|
||||
// …and the section scrolls into view inside the modal (smooth scroll:
|
||||
// poll for the settled position instead of racing the animation).
|
||||
await expect
|
||||
.poll(
|
||||
async () => {
|
||||
const box = await page.locator('#cfg-tokens').boundingBox();
|
||||
const modalBox = await page.locator('#config-modal').boundingBox();
|
||||
if (!box || !modalBox) return Number.POSITIVE_INFINITY;
|
||||
return box.y - (modalBox.y + modalBox.height);
|
||||
},
|
||||
{ timeout: 8000 },
|
||||
)
|
||||
.toBeLessThanOrEqual(0);
|
||||
});
|
||||
|
||||
test('no horizontal overflow at 393px', async ({ page, viewport }) => {
|
||||
test.skip((viewport?.width ?? 0) > MOBILE_MAX_WIDTH, 'Mobile viewport required');
|
||||
await boot(page);
|
||||
await openConfigModal(page);
|
||||
|
||||
for (const section of ['#cfg-ai', '#cfg-tokens', '#cfg-webhooks', '#cfg-partages-publics']) {
|
||||
await page.locator('#config-hamburger').click();
|
||||
await page.locator(`#config-nav a[href="${section}"]`).click();
|
||||
}
|
||||
const overflow = await page.evaluate(() => {
|
||||
const scroller = document.getElementById('config-scroll');
|
||||
return scroller.scrollWidth - scroller.clientWidth;
|
||||
});
|
||||
expect(overflow).toBeLessThanOrEqual(1);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user