From 4e4aeb4b6d89bf48b2ed1745195913af36e3d015 Mon Sep 17 00:00:00 2001 From: Ramon Date: Sun, 19 Jul 2026 13:31:10 +0200 Subject: [PATCH] feat: exporteren van vers-gegenereerde wachtwoorden als CSV (v0.4.30-beta) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - "Exporteer als CSV"-knop toegevoegd aan het bestaande multireset- resultatenscherm (klas-wachtwoorden resetten in de School-navigator), naast de bestaande "kopieer alles"-knop. - BELANGRIJKE BEPERKING, bewust zo: dit exporteert alleen wat op dit scherm al staat (net-gegenereerde wachtwoorden). Wachtwoorden worden na het zetten nergens leesbaar bewaard (alleen gehashet in de database) - er is dus geen "haal wachtwoorden van bestaande accounts op"-mogelijkheid en die komt er ook niet. - CSV bevat gebruikersnaam (het echte inlogveld) naast de naam, ook al toont het scherm zelf alleen de naam - zonder gebruikersnaam is een uitdeelvel niet bruikbaar om mee in te loggen. - Hergebruikt de csvValue()/downloadCsv()-helpers uit de vorige resultaten-exportfeature (v0.4.29-beta) - eerste echte tweede gebruiker, dus die keuze om ze lokaal in admin.js te houden i.p.v. te verplaatsen was terecht. - Geverifieerd met de volledige testsuite (112/112) en een live browserdoorloop: klas-wachtwoorden resetten (dubbele bevestigingsklik) → CSV-download met correcte escaping van een leerlingnaam met komma én aanhalingsteken. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_014EPxzBVRXZZnBPvSAaPAbJ --- VERSION | 2 +- public/js/admin.js | 16 ++++++++++++++++ public/js/core.js | 4 +++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index c91d8a6..96ea3ee 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.29-beta \ No newline at end of file +0.4.30-beta \ No newline at end of file diff --git a/public/js/admin.js b/public/js/admin.js index 8df4c2a..f9ef761 100644 --- a/public/js/admin.js +++ b/public/js/admin.js @@ -615,6 +615,22 @@ copyAll.type = "button"; copyAll.addEventListener("click", e=>{ e.preventDefault(); copyText(copyAll, all); }); box.appendChild(copyAll); + /* export als uitdeelvel - alleen mogelijk zolang dit scherm openstaat: de + wachtwoorden zijn hierna nergens meer in leesbare vorm te achterhalen + (alleen het gehashte wachtwoord blijft in de database), dus dit is + bewust "exporteer wat nu net gegenereerd is", niet "haal wachtwoorden + van bestaande accounts op". Gebruikersnaam (het echte inlog-veld) staat + er wél bij, ook al toont de schermlijst hierboven alleen de naam. */ + const exportBtn = h("button","am-btn", T("amExportCsv")); + exportBtn.type = "button"; + exportBtn.addEventListener("click", e=>{ + e.preventDefault(); + const header = [T("amExportColPupil"), T("amExportColUsername"), T("amResultPw")]; + const rows = [header, ...resetResults.entries.map(en=>[en.displayName, en.username, en.password])]; + const safeName = resetResults.title.replace(/[^a-z0-9]+/gi, "-"); + downloadCsv(`${safeName}.csv`, rows); + }); + box.appendChild(exportBtn); const list = h("div","am-reset-list"); resetResults.entries.forEach(en=>{ const row = h("div","am-reset-row"); diff --git a/public/js/core.js b/public/js/core.js index 94c4377..5e72a79 100644 --- a/public/js/core.js +++ b/public/js/core.js @@ -2,7 +2,7 @@ "use strict"; /* version — shown until /api/version resolves (or if the fetch fails, e.g. offline). Kept in sync by hand with the VERSION file at the repo root on every release. */ -const VERSION = "0.4.29-beta"; +const VERSION = "0.4.30-beta"; (function(){ const tag = document.getElementById("verTag"); tag.textContent = "v"+VERSION; @@ -352,6 +352,7 @@ const I18N = { amExportClass:"Exporteren per klas", amExportCsv:"Exporteer als CSV", amPickClassHint:"Kies eerst een klas.", amExportColPupil:"Leerling", amExportColWidget:"Widget", amExportColAttempts:"Pogingen", amExportColCorrect:"Goed", amExportColStars:"Sterren", amExportColDate:"Datum", + amExportColUsername:"Gebruikersnaam", amExportDone:"Export gedownload ✓", amConfirmDel:"Weet je zeker dat je deze gebruiker wilt verwijderen?", amCopy:"kopieer", amCopyAll:"kopieer alles", @@ -690,6 +691,7 @@ const I18N = { amExportClass:"Export by class", amExportCsv:"Export as CSV", amPickClassHint:"Pick a class first.", amExportColPupil:"Pupil", amExportColWidget:"Widget", amExportColAttempts:"Attempts", amExportColCorrect:"Correct", amExportColStars:"Stars", amExportColDate:"Date", + amExportColUsername:"Username", amExportDone:"Export downloaded ✓", amConfirmDel:"Are you sure you want to delete this user?", amCopy:"copy", amCopyAll:"copy all",