#224

feat(recon): add Subdomains by Jsmon as a passive subdomain source

Openencodedguywants to merge intofrom

Summary

Integrates Subdomains by Jsmon — a passive subdomain intelligence API with 5.4B+ subdomains — as a new source in the domain-discovery fan-out, alongside crt.sh, HackerTarget, Subfinder, Amass and Knockpy.

  • query_jsmon() in domain_recon.py mirrors the query_hackertarget pattern: per-source circuit breaker, KeyPool rotation, scope filter, max-results cap, dict-style {subdomain: {"jsmon"}} return for graph source attribution
  • Full settings cascade: Prisma (jsmonEnabled, jsmonMaxResults, jsmonApiKey) → Python DEFAULT_SETTINGS → fetch mapping → registry.yaml → registry.json → frontend toggle in SubdomainDiscoverySection
  • API key via UserSettings.jsmonApiKey (global per-user, not per-project), with rotation support, import/export, masking, and NOT_PROBED entry (no usage endpoint)
  • internal-network preset disables jsmon (no public OSINT for RFC1918 targets)
  • Graph schema updated: "jsmon" in Subdomain .source values
  • Preset schema: Zod + RECON_PARAMETER_CATALOG entries for AI presets
  • 12 unit tests (test_jsmon_source.py): 200/401/429/404/network-error, scope filter, max cap, disabled/no-key skip — all offline via mocked requests.Session

Skills / contracts followed

  • recon-tool-integration (enrichment _isolated contract, graph completeness, preset catalog)
  • project-settings-cascade (Prisma + Python + registry + frontend)
  • graph-db-writes (source value addition to schema_sections.md)

How to get a free API key

  1. Visit https://subdomains.jsmon.sh
  2. Register — the free tier gives 3 queries/day and up to 100 results per query
  3. Paste the key in Settings → API Keys → Jsmon Subdomains API Key

Defaults

  • Enabled by default (jsmonEnabled: true), but no-ops without an API key — zero impact on existing scans
  • jsmonMaxResults: 5000 (stealth ceiling: 100)

Subsystems touched

SubsystemFiles
Source modulerecon/main_recon_modules/domain_recon.py
Settingsrecon/project_settings.py, recon_settings/registry.yaml, recon_settings/registry.json
Prismawebapp/prisma/schema.prisma
FrontendSubdomainDiscoverySection.tsx, inputLogicTooltips.tsx
Preset schemarecon-preset-schema.ts
Hardcoded presetsinternal-network.ts
API keysapiKeysTemplate.ts, rotationTools.ts, apiUsage/registry.ts
User settings routewebapp/src/app/api/users/[id]/settings/route.ts
Graph schemagraph_db/schema_sections.md
Build artifactwebapp/src/lib/reconSettings/registry.json
Testsrecon/tests/test_jsmon_source.py
Test countsapiKeysTemplate.test.ts

Steps for maintainer / CI

I did not run Docker, Prisma, typecheck or the test harness (scope-limited to file edits).

  • python3 recon_settings/build.py — registry.json was hand-edited (PyYAML unavailable); re-running build.py will produce the canonical output and update the roe_parse_prompt.py SHA-256 digest
  • docker compose exec webapp npx prisma db push — apply the two new Project columns + one UserSettings column
  • docker compose exec webapp npx tsc --noEmit — typecheck
  • ./redamon.sh test unit — full unit gate

🤖 Generated with Claude Code