PDF.js's signature dialog saved every signature in localStorage under pdfjs.signature, "save" ticked on every open, for this origin rather than for a bau-pm user. Measured on v0.1.0: a typed and an uploaded signature were offered to a fresh page on the same browser, the way the next person on a shared tablet would get it, a Redmine logout included. Another browser profile saw nothing; the server never had anything. The glue's fifth duty, in every window before PDF.js's modules: delete the store (a device that saved signatures loses them on its first visit), refuse writes to that key, hold the save box unticked through a property on the element and hide it, and hide the dialog's Bild tab and its file picker, so a scanned signature never enters the dialog. test/signatures.mjs is the second gate, in CI and the release workflow: a browser seeded with a real saved entry (captured from v0.1.0's own store) is offered none, the dialog shows neither the box nor the tab, a typed signature is placed and not stored, a fresh page is offered nothing. Fed v0.1.0: 9 findings, exit 1. Against this image: 0, and the zero-host gate drove 117 tool pages with nothing leaving the origin. A signed PDF still exports with the signature on the page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
43 lines
4.2 KiB
Markdown
43 lines
4.2 KiB
Markdown
# Changelog
|
|
|
|
All notable changes to this project are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
|
## [Unreleased]
|
|
|
|
### Security
|
|
|
|
- The signing tool keeps no signature on the device (issue #1, bau-pm BAU-260). PDF.js's signature dialog saved every signature in the browser's `localStorage`, with *Unterschrift speichern* ticked by default, for this address rather than for a bau-pm user, so the next person on a shared tablet or site office PC was offered the previous one's signature, typed, drawn or traced from an uploaded image, and logging out of bau-pm did not clear it. Every page now deletes that store and refuses its writes, and the dialog's save box is held unticked and hidden. Signatures a device saved before are deleted on its first visit after the update.
|
|
|
|
### Removed
|
|
|
|
- The *Bild* tab of the signing dialog, and its file picker: a scanned signature no longer enters the tool. Signing means typing or drawing it.
|
|
|
|
### Added
|
|
|
|
- A second gate, `test/signatures.mjs`, in CI and in the release workflow: nothing saved before is offered, nothing signed is stored, a fresh page is offered nothing, and the dialog shows neither the save box nor the image tab. Fed v0.1.0 it fails with 9 findings.
|
|
|
|
## [0.1.1] - 2026-10-24
|
|
|
|
The same BentoPDF on current packages. Nothing in this repository's own code changed; what changed is that a build no longer ships whatever base image the runner happened to have cached, so this image carries nginx 1.31.8 where v0.1.0 carried 1.31.6. Out of bau-pm's v0.22.3 security review.
|
|
|
|
### Security
|
|
|
|
- The CI and release builds pull their base images fresh (`docker build --pull`). Both bases are floating tags, so what shipped was whatever the runner had cached: v0.1.0 went out with nginx 1.31.6 while the tag had already moved to 1.31.8, past five October CVEs. None of the five is reachable in a static file server configured like this one, which is why this is the fix rather than a pin. From bau-pm's v0.22.3 security review, finding 41 (bau-pm BAU-191). **A release is what applies it** - the running image does not change until one is cut.
|
|
|
|
### Changed
|
|
|
|
- The image is built on the current `node:20-alpine` and `nginx-unprivileged:alpine-slim`, which is where the operating-system packages under BentoPDF come from. BentoPDF itself is unchanged: still v2.8.8 at the same pinned commit, the same vendored modules at the same integrity hashes, the same two tools disabled.
|
|
|
|
## [0.1.0] - 2026-10-10
|
|
|
|
The first release: BentoPDF v2.8.8 for bau-pm, about 120 PDF tools that run in the browser and talk to no third party, with the hand-off that brings a PDF from bau-pm into a tool and the result back.
|
|
|
|
### Added
|
|
|
|
- BentoPDF v2.8.8 built from source at its pinned commit with BentoPDF's air-gapped build options: Simple Mode, German by default, every module served from the image's own `/wasm/`, the CORS proxy off.
|
|
- The CDN modules vendored and checked against `vendor.lock` (PyMuPDF, Ghostscript, CoherentPDF, Tesseract with German, French, Italian and English, the OCR font, the PDF editor's Latin, Arabic and Hebrew fallback fonts). Ghostscript is served as its whole package with `gs.js` and `gs.wasm` linked at its root, because BentoPDF's own loader and PyMuPDF's wrapper expect the two different layouts (upstream's air-gap layout left `pdf-to-docx` with a 404).
|
|
- A Content-Security-Policy without any host, `img-src` included; the build fails if one survives.
|
|
- `digital-sign-pdf` and `timestamp-pdf` disabled: both need a third party by design.
|
|
- The hand-off glue on every page: a source link (AGPL), the hand-in of a file from bau-pm through a one-minute cookie into the tab's `sessionStorage`, confirmed by the tool's own reaction and retried while it has none (BentoPDF attaches its listener late, and its service worker made the glue win that race), the hand-back of a result caught in every window, the viewer's frame included, and waiting for the hand-off's details when a save comes before them, and the signing tool's flatten switch locked on.
|
|
- The zero-host gate (`test/zero-hosts.mjs`) over every tool page, in CI and in the release workflow.
|