fix(export): één download per webexport, en alleen melden wat we weten (#1902) #1906
No reviewers
Labels
No labels
accepted
bug
declined
docs
duplicate
enhancement
good first issue
in-progress
needs-info
privacy
security
triage
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
LibreKAT/Ocideck!1906
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/webdownload-succesmelding-1902"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #1902.
Wat er mis was
Op web is elke uitgang een browserdownload. De app las "er viel geen
uitzondering" als succes, en dat is geen bewijs:
FilePicker.saveFilegeeft opweb altijd
nullterug, ook wanneer het goed ging. Vier paden melddendaardoor onvoorwaardelijk succes — deck-export, documentexport,
.ocideck-pakketen auditdossier.
De scherpste vorm zat bij een geredigeerde export. Die bood drie bestanden
achter elkaar aan (rapport, commitments, verificatiesleutels), en browsers
houden de tweede automatische download op rij tegen. De auteur hield een
geredigeerd rapport over — zonder iets om ook maar één redactie mee na te
trekken — en las "geëxporteerd naar". Dat is precies wat de comment in
export_service.dartwilde voorkomen.Wat er nu gebeurt
lib/services/download_delivery.dart.Eén bestand gaat als zichzelf; meer dan één gaat als één ZIP, genoemd naar het
hoofdbestand plus
.zip. Dat geldt ook voor de sessie-export, die per dia eenbestand aanbood.
plaats van geëxporteerd naar. De pagina kan niet zien of het bestand in de
downloadmap aankwam — een download-anker meldt niets terug — en die grens hoort
in de tekst te staan, niet alleen in de code.
ExportFailure.downloadNotStartedvoor de deck-export (de dienst levert de reden, de schil de zin — #576),
nullvoor documentexport, pakket en dossier, met een melding in de schil. De
sessie-export onderscheidt nu ook afbreken van mislukken: alleen het tweede
krijgt een melding.
deliverAsDownloadstaat tussen deartefact-primitieven van
check_audience_boundary. Daardoor kwamdownloadDeckAsFileboven water: dat liep viadownloadTextFile, wat geenprimitief was, dus was er nooit gevraagd aan welke kant van de projectiegrens
het stond. Nu geregistreerd als
source.Hoe het bewezen is
Twaalf nieuwe toetsen plus twee bij
export_failure_text. De hele webtak lagbuiten bereik van de suite (
kIsWebis op de VM altijdfalse); twee@visibleForTesting-haken maken hem meetbaar — de download-sink en deplatformtak.
Rood geproefd door de afleverlaag terug te zetten op het oude gedrag (elk bestand
apart, succes ongeacht de uitkomst): vier toetsen vallen om, op precies de twee
claims uit het issue — drie downloads in plaats van één, en een export die succes
meldt terwijl er niets vertrok.
Meegekomen
make checkviel op drie plafonds; alle drie opgelost door te splitsen, nietdoor de basislijn te verhogen:
ExportFormat/ExportResultnaarlib/services/export_result.dart(data, geendienst) —
export_service.dart515 → 450 regels, plafond mee omlaag naar 485.ExportService.exportnaar een top-level functie —131 → 116 regels.
_flatMembersen de twee bestandsnaam-helpers uitFileServicenaartop-level; de naamexpressie stond op drie plekken letterlijk uitgeschreven.
deliversByDownloadtelt mee als platformpoort incheck_conventions(deproductiewaarde ís
kIsWeb; alleen een test kan hem omzetten).Documentatie
USER_GUIDE zei dat de twee manifestbestanden op web "in dezelfde downloadmap"
belanden — precies wat er niet gebeurde. Bijgewerkt in USER_GUIDE, FILE_FORMAT en
hun nl-varianten, met de reden erbij. Drie nieuwe l10n-strings, 31 talen.
Twee dingen die het issue niet noemde
Die tweede is de vervelendste: hij bewaarde de nonce ná de export, en de
comment daar zegt met zoveel woorden dat dat pas mag als het verzoek de deur
uit is — anders blijft er een nonce achter voor een verzoek dat nooit
verstuurd is. Na deze PR staat er in
lib/geen enkeleFilePicker.saveFile-aanroep meer.if (dart.library.html)is onwaar voor dart2wasm. Nagemeten in de glue-modulevan een echte
--wasm-build: metdart.library.htmlstaat.downloader0× in en
revokeObjectURL1×, metdart.library.js_interop1× en 2×. Deankercode was daar dus werkelijk weg. Wasm is nog geen bouwdoel (#1734); dit
is precies de val die dat later stil zou maken.
Bewaker
Dit raakt een publieke belofte (de bewoording in de interface en twee
documenten) en de vorm waarin het werk van de gebruiker aankomt, dus de
bewaker heeft ernaar gekeken.
besturingssysteem uitpakt; de leden erin zijn onveranderd (
.pdf,-redactie.json,.md). Geen OciDeck-specifieke omhulling, geen nieuwepartij om te vertrouwen —
archivezat er al in en het pakken gebeurt in detab zelf.
.md? Onaangeraakt. Dit is uitsluitend de afleverweg.openen.
De botsing, hardop: gemak tegen integriteit. Eén los
.pdfis prettiger daneen ZIP die je moet uitpakken. Daarom gaat één bestand nog steeds als zichzelf —
alleen bij meer dan één wordt het een ZIP. Daar wint integriteit: de vorige vorm
liet het redactiemanifest stilzwijgend achter, en dan is een geredigeerd rapport
niet meer na te trekken. Veiligheid staat op 1. Ik zou van gedachten
veranderen zodra browsers meerdere bestanden kunnen afleveren mét een
betrouwbare uitslag per bestand; dan is los beter dan een ZIP.
De bewoording is waarde 4: "geëxporteerd naar" beweerde meer dan de pagina kan
weten. De nieuwe zin is zwakker en waar.
Niet meegenomen
Dat de multi-download-poort van de browser dit werkelijk triggert is niet in
een echte browser nagemeten; de repro-stappen staan in #1902. De code-analyse
staat wel vast, en de reparatie is hoe dan ook de goede kant op: één download kan
die poort niet raken.
🤖 Generated with Claude Code
dfe4e8530b330842ca35