Applies stash@{0} (WIP on d3611a8, previously untouched) — package.json
dependency bump plus two <head> additions to public/index.html for SEO
(canonical URL) and self-hosted Umami analytics.
- node-whois was declared in package.json but required/imported nowhere
in the codebase (verified via repo-wide grep) -- pure dead weight that
was dragging in a critical arbitrary-code-execution chain (underscore
1.5.2 via optimist, CVSS 9.8). No fixed version exists upstream (latest
2.1.3 still depends on the same vulnerable optimist/underscore), so the
only real fix was removal. Zero behavior change since nothing called it.
- node-cron 3.0.3 -> 4.6.0: only real usage is two plain cron.schedule()
calls in src/features/hijack-alerts/retry-scheduler.ts and
src/features/aspa-adoption/scheduler.ts -- API unchanged, low risk.
4.6.0 has zero runtime deps (drops the vulnerable uuid transitive dep)
and ships its own TS types, so @types/node-cron was also removed to
avoid duplicate/conflicting type declarations.
- repository/bugs URLs in package.json corrected from the GitHub repo
(deleted 2026-07-14) to the actual Gitea repo.
12 -> 6 vulnerabilities (6 critical/1 high/5 moderate -> 2 critical/1
high/3 moderate). Remaining 6 are entirely in the vitest/vite/esbuild
dev-tooling chain (vite dev-server SSRF, GHSA-67mh-4wv8-2f99) -- not
production-exposed, and fixing requires a vitest 2.x -> 4.x major bump
that needs its own test-suite verification pass, not folded into this
commit.
tsc --noEmit confirms no new type errors from the node-cron/types
change (remaining TS6133 unused-var warnings in src/sources/*.ts are
pre-existing skeleton-source stubs, unrelated to this commit).
Merges the production-only changes (Izzy PDF export via puppeteer,
Adoption Tracker overlay, audit scripts, deploy/utility scripts) that
had been living as uncommitted edits directly on Erik since before the
2026-07-14 backend refactor, on top of current main.
4 real conflicts, resolved by keeping whichever side is actually
functional rather than picking a side mechanically:
- package.json / package-lock.json: trivial union, kept both the
refactor's pg/playwright deps and the snapshot's puppeteer dep;
lockfile regenerated via `npm install --package-lock-only` rather
than hand-edited
- server.js top-of-file: additive, kept both the localDb require
(backend refactor) and the puppeteer lazy-loader (PDF export)
- server.js /api/health aspa_adoption block: main referenced
`aspaAdoptionHistory`, a variable that is never declared anywhere
in this file (confirmed by grep) -- a pre-existing dead reference
that would throw if this code path ever ran. Kept the snapshot's
working `aspaAdoptionDailyHistory`/`roaStore.count` version, which
matches the live /api/health output from production. Also fixed
the identical bug in the neighboring .catch() fallback block a few
lines down (same undefined variable, not part of the conflict
itself -- pre-existing on main, same fix applied for consistency).
- server.js hijack-subscribe/webhooks section (186 lines): main's
side was just a 2-line comment ("Migrated to
src/features/hijack-subscribe/"). Kept the snapshot's actual
working implementation instead, because server.js does not
require() or import anything from src/features/ or dist/ anywhere
-- confirmed by grep. The "migration" only ever happened on the
src/features/ side; server.js's own HTTP routing was never wired
up to call into it.
IMPORTANT CAVEAT, found while investigating the above and NOT fixed
here: server.js still has 13 other "// Migrated to src/features/..."
comments (bgp-communities, irr-audit, asset-expand, rpki-history,
aspath, looking-glass, ix-matrix, submarine-cables, global-infra,
hijack-alerts (Fastify), changelog, rib, prefix-changes) where the
same thing is true -- the route implementation was deleted from
server.js and never replaced with a working call into src/features/.
These weren't touched by this merge (git didn't flag them as
conflicts, because production's snapshot never touched those
sections either -- only main changed them, by deleting them). If
this server.js is ever deployed as the new production file as-is,
those 13 endpoints will silently 404 or fall through, exactly like
the hijack-subscribe one would have if I'd taken main's side. This
is a pre-existing gap in the 2026-07-14 refactor (PR #1), unrelated
to the Izzy/Adoption Tracker work, and needs a deliberate decision
(wire server.js to src/features/, or confirm those routes are meant
to live on a different process/port entirely) before this branch
should be treated as deployable.
`node --check server.js` passes. Not deployed to Erik as part of
this commit -- Erik's currently-live server.js/public/index.html
are untouched.
Working tree was 3+ months ahead of git in uncommitted local edits, sitting
on a detached HEAD at d3611a8 (2026-04-09), never reconciled with main.
Committing as-is on its own branch, without touching main or the detached
HEAD, to stop these files existing only on this one server:
- public/index.html + server.js: PDF export add-on gated to client Izzy,
full Adoption Tracker overlay (ASPA + IPv6 tabs) -- neither exists
anywhere in git history on any branch until now
- audit/: daily/rotating audit scripts + email report sender, previously
untracked
- scripts/: tunnel-cleanup.sh, refresh-peeringdb.sh, previously untracked
- deploy-from-scp.sh, webhook-subs.json, hijack-alerts.json,
aspa-adoption-history.json: previously untracked runtime/deploy state
- public/public/: duplicate mirror of the HTML variants found alongside
the real public/ dir, preserved as found
No reconciliation with main attempted here -- that needs a deliberate pass,
not a side effect of a backup commit.
Adds real-time local BGP RIB data as a complement to external APIs
(RIPE Stat, bgproutes.io) which have rate limits and 15min+ delays.
- bio-rd-client.js: gRPC client for bio-routing/bio-rd RIS service
- LPM, Get, GetLonger, GetRouters, DumpRIB, ObserveRIB methods
- IPv4/IPv6 encoding as uint64 pair (bio.net format)
- Full BGP path decode: AS paths, communities, large communities
- Graceful fallback if RIS unavailable (null/empty returns)
- protos/: bio-rd proto definitions (ris, bgp, session, route, net)
- server.js: three new endpoints + WebSocket stream
- GET /api/rib/prefix — LPM + more-specifics via GetLonger
- GET /api/rib/routers — list BMP-monitored routers
- GET /api/rib/dump — full RIB dump with ASN filter + limit
- WS /ws/rib — live ObserveRIB stream (add/withdraw events)
- package.json: @grpc/grpc-js + @grpc/proto-loader dependencies