Skip to content

feat(security): wire port-scan queue + SSE realtime feedback - #82

Merged
ralyodio merged 1 commit into
masterfrom
wire-port-scan-producer
Jul 6, 2026
Merged

ralyodio merged 1 commit into
masterfrom
wire-port-scan-producer

Conversation

@ralyodio

@ralyodio ralyodio commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Fixes scans stuck in queued with no feedback. The UI wrote a port_scans row but nothing bridged it to the prober, and the page never updated.

The missing middle (now built)

UI Run → requestPortScan (insert queued, returns scanId)
  client opens EventSource → /projects/[id]/security/stream?scanId=…   (SSE push)
worker sweep (5s): queued → enqueue BullMQ "prober" job → running
  droplet prober scans → returns result → worker reconciles → done + findings
SSE streams each status change to the browser; closes on done/failed

Changes

  • lib/prober-queue.ts — enqueues queued rows to the prober BullMQ queue (jobId = scan id, idempotent), then reconciles finished jobs: reads the job's return value and writes port_scans → done (+ open_ports) and upserts port_findings (severity by port; DB/cache/admin ports = high). Times out stuck scans. Parses REDIS_URL into bullmq connection options (no direct ioredis import → avoids the bundled-ioredis type clash).
  • worker/index.ts — portScanSweep on a 5s interval + startup; no-ops when REDIS_URL is unset.
  • SSE route app/(app)/projects/[id]/security/stream/route.ts — auth'd text/event-stream; polls the DB server-side and pushes status/done events; 5-min cap; closes on client abort.
  • request-scan-button.tsx — opens the stream on Run, resumes an in-flight scan on page load, shows a live status pill, router.refresh() on completion.
  • requestPortScan returns scanId; added bullmq/ioredis deps.

Realtime path uses SSE (server push) per request; the web tier needs no Redis connection (the worker owns Redis).

Root + worker tsc --noEmit both pass. Depends on the prober droplet running (deploy-prober is green) and REDIS_URL set on the crawlproof.com service (done).

🤖 Generated with Claude Code

Scans were stuck in 'queued' because nothing bridged the port_scans table to
the prober. This adds the Railway producer side and realtime UI feedback:

- lib/prober-queue.ts: enqueue queued rows to the 'prober' BullMQ queue, then
  reconcile finished jobs back to the DB (status done/failed + port_findings).
  Parses REDIS_URL into bullmq connection opts (no direct ioredis import).
- worker/index.ts: portScanSweep on a 5s interval (+ startup), no-ops without
  REDIS_URL.
- SSE route /projects/[id]/security/stream: pushes status changes (queued →
  running → done/failed) + findings to the browser via EventSource.
- request-scan-button.tsx: opens the stream on Run and resumes an in-flight
  scan on load; live status pill; router.refresh() on completion.
- requestPortScan returns scanId; add bullmq/ioredis deps.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown

vu1nz Security Review

0 finding(s) in PR #?

No security issues found.

@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedioredis@​5.11.19410010092100

View full report

@ralyodio
ralyodio merged commit 85494ad into master Jul 6, 2026
8 checks passed
@ralyodio
ralyodio deleted the wire-port-scan-producer branch July 6, 2026 19:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant