Files
mixandClaude Opus 5.5 49c872f836 backup-reauth: the account password before a backup or an export
Agreed with the owner on 2026-10-13, taken up on 2026-10-16 ("Да"); the
mockup is 1888dce. Both secret downloads - the full backup on Server ›
Backup and a domain's export on its settings - ask for "Your account
password": reauth (handlers_backup.go) checks the signed-in user's own
password with bcrypt, as a password change does, under the same limiter
(auth.AllowPasswordChange: ten in fifteen minutes per user, shared with the
Account form). A wrong or missing one is 401 on the same page with "Your
account password is incorrect.", logged; nothing is sent. The import and
the selfpost-backup CLI are not asked.

Also, the owner's phone screenshot of 2026-10-16 ("кнопка выбора файла не
такая, как в макете. Это косяк?"): the import's file field was a bare
<input type="file"> drawn by the browser ("Browse…"), where the mockup has
Bulma's .file - "Choose a file…" and the name chosen. The template now
follows the mockup; panel.js writes the name into .file-name on change and
at load (testdata/filename_test.js, run by TestPanelJS). No other file
field exists.

Tests: TestSecretDownloadsAskForTheAccountPassword (missing, wrong, right,
the limiter), the export refusals of the settings page with the password,
cmd/panel's restore tests and e2e's backups with it, e2e's refusal of a
backup without and with a wrong password. go vet + go test (26 packages)
and make e2e on the test server for this tree.

Docs: security.md § Backup and domain export, guide § Full backup and
restore, help (word for word with the mockup); CHANGELOG [Unreleased];
roadmap row done.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 22:39:13 +03:00

51 lines
1.9 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// The name of the file chosen in a Bulma .file field is written into its
// .file-name (the import of a domain on Server › Backup): on change, and at
// load for a page the browser restored with a file still chosen. Run by
// TestPanelJS (paneljs_test.go): node filename_test.js <panel.js>. Exits
// non-zero with what went wrong.
"use strict";
const fs = require("fs");
const vm = require("vm");
const failures = [];
function check(cond, what) {
if (!cond) failures.push(what);
}
const listeners = {};
const label = { textContent: "No file chosen" };
const box = { querySelector: (sel) => (sel === ".file-name" ? label : null) };
const input = {
files: [],
matches: (sel) => sel === "input.file-input",
closest: (sel) => (sel === ".file" ? box : null),
};
const document = {
hidden: false,
addEventListener: (type, fn) => (listeners[type] = listeners[type] || []).push(fn),
body: { addEventListener() {} },
getElementById: () => null,
querySelectorAll: (sel) => (sel === "input.file-input" ? [input] : []),
};
vm.runInNewContext(fs.readFileSync(process.argv[2], "utf8"), {
document, window: { addEventListener() {} }, htmx: { config: {}, ajax() {} }, setTimeout, clearTimeout, Date, Object, Math, console,
});
const fire = (type, ev) => (listeners[type] || []).forEach((fn) => fn(ev));
input.files = [{ name: "example.org.spde" }];
fire("change", { target: input });
check(label.textContent === "example.org.spde", `after choosing a file the name reads ${JSON.stringify(label.textContent)}`);
input.files = [];
fire("change", { target: input });
check(label.textContent === "No file chosen", `after clearing the choice the name reads ${JSON.stringify(label.textContent)}`);
input.files = [{ name: "restored.json" }];
fire("DOMContentLoaded", {});
check(label.textContent === "restored.json", `a restored page shows ${JSON.stringify(label.textContent)}`);
if (failures.length) {
console.error(failures.join("\n"));
process.exit(1);
}