Skip to content

v0.2.3 — Events, QR codes, sqlx 0.8 security upgrade

Choose a tag to compare

@ChronoCoders ChronoCoders released this 02 Oct 23:05
· 11 commits to main since this release

New features

/events — global event log

  • GET /v1/events?product_id=&event_type=&anchor_status=&limit=&offset= — paginated event listing scoped to the authenticated brand. All filters compose with AND.
  • db::events::list_by_brand_filtered uses QueryBuilder<Postgres> for conditional WHERE clauses. Limit clamped to [1, 200], default 50.
  • Frontend /events page (client component) — Product / Type / Anchor-status dropdown filters with reset, paginated table, links to product detail.

/qr-codes — per-product QR codes

  • GET /v1/products/:id/qr — returns a PNG QR encoding the public verification URL (PUBLIC_BASE_URL/verify/:id). 512×512 minimum, quiet zone enabled, Cache-Control: private, max-age=3600.
  • Tenant-scoped via db::products::get_by_id_for_brand — a brand can't fetch QR codes for products it doesn't own.
  • Frontend /qr-codes page — grid of cards, browser fetches each QR via the same-origin Next.js proxy, Download PNG link uses the HTML download attribute with filename genuflow-<product_id>.png.
  • New env var PUBLIC_BASE_URL (default http://localhost:3000) wired through AppState, .env.example, and docker-compose.yml.

Split-screen auth

  • /login and /register get a two-column layout at md+: marketing copy on the left (DM Serif hero, accent-colored anchored, three-bullet value prop, BSL footer), form panel on the right.
  • Mobile (<md) stays single-column with the wordmark above the form. Forms themselves are unchanged.
  • All visual changes live in components/auth-shell.tsx — page-level code untouched.

Security

sqlx 0.7.4 → 0.8.6 upgrade

  • Closes RUSTSEC-2024-0363 — binary protocol misinterpretation in sqlx 0.7.x. Priority fix.
  • Side benefit: the chronic sqlx-postgres v0.7.4 future-incompat-report warning that trailed every clippy run for the prior six commits is gone.
  • Breaking changes encountered: one, config-only. The runtime-tokio feature in sqlx 0.8 no longer implies a TLS backend; you must pick tls-rustls or tls-native-tls explicitly. We chose tls-rustls (pure-Rust, no system OpenSSL needed in the Docker slim base). Zero source-code changes were required across common, db, anchor, or api — the runtime query API (sqlx::query, sqlx::query_as::<_, T>, QueryBuilder, FromRow, Type, migrate!) is binary-compatible for our usage.
  • cargo clippy --workspace -- -D warnings clean (zero warnings, zero notes).

Audit results

cargo audit against the post-upgrade Cargo.lock:

  • rsa 0.9.10 (RUSTSEC-2023-0071, medium 5.9) — present pre-upgrade and post-upgrade. Path: rsa → sqlx-mysql → sqlx-macros-core → sqlx-macros → sqlx. Compile-time-only: the macros crate uses sqlx-mysql for cross-backend prepared-statement validation; that code is not linked into the runtime binary. No exploitable path through Genuflow — the Marvin Attack requires a TLS-server role that this code never plays. Upstream has no fixed release yet. Documented as a known carryover.
  • 3 unmaintained/unsound warnings on derivative, paste, lru — all reached through alloy 0.3. Will clear when alloy bumps to 0.4+. Tracked separately, not blocking.

No new vulnerabilities introduced by the sqlx bump.

Operational

  • docker compose up -d now requires no manual env tweaks for the QR codes feature; PUBLIC_BASE_URL defaults via ${VAR:-http://localhost:3000}.
  • Sidebar nav adds "Events" and "QR codes" entries.
  • No new migrations.

Verification

  • cargo clippy --workspace --all-targets -- -D warnings ✓
  • cargo audit — 1 finding, documented above, accepted carryover.
  • tsc --noEmit ✓
  • next build — 14 routes generated cleanly (/events and /qr-codes joined the bundle).