Skip to content

v0.1.11 — Upload without base64 (ticket flow)

Choose a tag to compare

@marselsel marselsel released this 13 Aug 10:22
· 10 commits to main since this release

Upload a receipt without pushing its bytes through the model context. Based on the contribution by @gutencoder (#34, merged as #38); the server-side URL-fetch tool from that PR was intentionally held back (see the CHANGELOG Security note).

Added

  • create-upload-ticket / get-upload-result (drafts tier): a short-lived (15 min), single-use ticket with a browser drag-and-drop URL and a ready-to-run curl command. Bytes go client → server → Lexware; the model only sees the file id. Filenames travel as X-Filename-B64 (base64url of the UTF-8 bytes), so umlauts, dashes, quotes and emoji survive.
  • SERVER_URL (or OAUTH_RESOURCE) now applies in every auth mode — upload links are built from it; static-token deployments behind a real domain no longer hand out loopback links.

Security & hardening

  • The /upload/:ticket route mounts only when the drafts capability is enabled; the ticket page is served no-store + nosniff + frame-denied.
  • One buffering body per ticket at a time; invalid/expired/used tickets are rejected before any body is read; gzip framing refused (inflate: false).
  • Operator credential failures (Lexware 401/403) answered as generic 502 to the unauthenticated uploader; unknown-outcome transport failures name the duplicate risk.
  • upload-file-from-url deferred: its DNS-rebinding TOCTOU is moot for the built-in Microsoft allow-list but live for custom allow-lists; it returns only with connection-level IP pinning, disabled by default.

Notes

  • The ticket store is in-process — a single-instance feature (documented in the CHANGELOG).
  • 250 tests, including an end-to-end test that executes the emitted curl command against the live routes.

Full details in CHANGELOG.md.