diff --git a/docs/STORAGE_SCHEMA.md b/docs/STORAGE_SCHEMA.md index e75b3ff..4779a9f 100644 --- a/docs/STORAGE_SCHEMA.md +++ b/docs/STORAGE_SCHEMA.md @@ -36,7 +36,9 @@ locale du navigateur et conservent les dix fichiers `sokkog-global-YYYY-MM-DD.js les plus récents. La vérification au démarrage ne demande pas de permission et ne crée pas les jours manquants lorsque l'application était fermée. Une nouvelle sauvegarde automatique est ignorée si son contenu est identique à la version la -plus récente, en excluant uniquement l'horodatage d'export. +plus récente, en excluant uniquement l'horodatage d'export. Si le navigateur ne +conserve pas l'autorisation du dossier entre deux sessions, l'interface propose +une réautorisation explicite ; le démarrage n'ouvre aucune demande de permission. Entrée type dans `modules` : diff --git a/tests/auto-backup.test.mjs b/tests/auto-backup.test.mjs index e48d5c8..b42da0b 100644 --- a/tests/auto-backup.test.mjs +++ b/tests/auto-backup.test.mjs @@ -94,13 +94,17 @@ test("manual backup replaces the day and retains ten non-consecutive versions", assert.equal(directory.files.get("notes.json"), "old"); }); -test("permission failure prevents export and cleanup", async () => { - const directory = new FakeDirectory(); - directory.permission = "prompt"; - let generated = false; - const result = await saveBackup({ directoryHandle: directory, generateJson: async () => { generated = true; return "{}"; } }); - assert.equal(result.reason, "permission"); - assert.equal(generated, false); +test("missing permission never opens a prompt or starts an export", async () => { + for (const permission of ["prompt", "denied"]) { + const directory = new FakeDirectory(); + directory.permission = permission; + directory.requestPermission = () => { throw new Error("Permission popup must require user interaction"); }; + let generated = false; + const result = await saveBackup({ directoryHandle: directory, generateJson: async () => { generated = true; return "{}"; } }); + assert.equal(result.reason, "permission"); + assert.equal(result.permission, permission); + assert.equal(generated, false); + } }); test("cleanup failure does not invalidate a successfully written backup", async () => { diff --git a/tests/helpers/data-validation.mjs b/tests/helpers/data-validation.mjs index 512b863..427ea18 100644 --- a/tests/helpers/data-validation.mjs +++ b/tests/helpers/data-validation.mjs @@ -233,6 +233,7 @@ export function validateSiteContent(site) { "toolboxes.autoBackup.chooseFolder", "toolboxes.autoBackup.changeFolder", "toolboxes.autoBackup.reauthorize", + "toolboxes.autoBackup.permissionRequired", "toolboxes.autoBackup.saveNow", "toolboxes.autoBackup.noFolder", "toolboxes.autoBackup.never", diff --git a/website/public/data/site.json b/website/public/data/site.json index 70c204b..5fcef3c 100644 --- a/website/public/data/site.json +++ b/website/public/data/site.json @@ -1829,6 +1829,7 @@ "chooseFolder": "Choisir un dossier", "changeFolder": "Changer de dossier", "reauthorize": "Réautoriser l’accès", + "permissionRequired": "L’accès au dossier doit être réautorisé pour reprendre les sauvegardes. Utilisez « Réautoriser l’accès » ci-dessous.", "saveNow": "Sauvegarder maintenant", "noFolder": "Aucun dossier", "never": "Jamais", diff --git a/website/src/components/ToolboxModals.jsx b/website/src/components/ToolboxModals.jsx index 64e0a21..affe521 100644 --- a/website/src/components/ToolboxModals.jsx +++ b/website/src/components/ToolboxModals.jsx @@ -118,10 +118,11 @@ export function AutoBackupModal({ backup, content, onClose }) {