voidaccess 2.0.1__tar.gz → 2.0.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. {voidaccess-2.0.1 → voidaccess-2.0.2}/PKG-INFO +1 -1
  2. {voidaccess-2.0.1 → voidaccess-2.0.2}/api/main.py +1 -1
  3. {voidaccess-2.0.1 → voidaccess-2.0.2}/export/__init__.py +2 -0
  4. {voidaccess-2.0.1 → voidaccess-2.0.2}/export/ioc_package.py +3 -47
  5. {voidaccess-2.0.1 → voidaccess-2.0.2}/export/sigma.py +58 -1
  6. {voidaccess-2.0.1 → voidaccess-2.0.2}/pyproject.toml +2 -2
  7. {voidaccess-2.0.1 → voidaccess-2.0.2}/voidaccess.egg-info/PKG-INFO +1 -1
  8. {voidaccess-2.0.1 → voidaccess-2.0.2}/voidaccess_cli/__init__.py +1 -1
  9. {voidaccess-2.0.1 → voidaccess-2.0.2}/voidaccess_cli/commands/export.py +53 -17
  10. {voidaccess-2.0.1 → voidaccess-2.0.2}/LICENSE +0 -0
  11. {voidaccess-2.0.1 → voidaccess-2.0.2}/README.md +0 -0
  12. {voidaccess-2.0.1 → voidaccess-2.0.2}/alembic.ini +0 -0
  13. {voidaccess-2.0.1 → voidaccess-2.0.2}/analysis/__init__.py +0 -0
  14. {voidaccess-2.0.1 → voidaccess-2.0.2}/analysis/opsec.py +0 -0
  15. {voidaccess-2.0.1 → voidaccess-2.0.2}/analysis/patterns.py +0 -0
  16. {voidaccess-2.0.1 → voidaccess-2.0.2}/analysis/temporal.py +0 -0
  17. {voidaccess-2.0.1 → voidaccess-2.0.2}/api/__init__.py +0 -0
  18. {voidaccess-2.0.1 → voidaccess-2.0.2}/api/auth.py +0 -0
  19. {voidaccess-2.0.1 → voidaccess-2.0.2}/api/errors.py +0 -0
  20. {voidaccess-2.0.1 → voidaccess-2.0.2}/api/routes/__init__.py +0 -0
  21. {voidaccess-2.0.1 → voidaccess-2.0.2}/api/routes/actors.py +0 -0
  22. {voidaccess-2.0.1 → voidaccess-2.0.2}/api/routes/admin.py +0 -0
  23. {voidaccess-2.0.1 → voidaccess-2.0.2}/api/routes/auth.py +0 -0
  24. {voidaccess-2.0.1 → voidaccess-2.0.2}/api/routes/entities.py +0 -0
  25. {voidaccess-2.0.1 → voidaccess-2.0.2}/api/routes/export.py +0 -0
  26. {voidaccess-2.0.1 → voidaccess-2.0.2}/api/routes/investigations.py +0 -0
  27. {voidaccess-2.0.1 → voidaccess-2.0.2}/api/routes/monitors.py +0 -0
  28. {voidaccess-2.0.1 → voidaccess-2.0.2}/api/routes/search.py +0 -0
  29. {voidaccess-2.0.1 → voidaccess-2.0.2}/api/routes/settings.py +0 -0
  30. {voidaccess-2.0.1 → voidaccess-2.0.2}/auth/__init__.py +0 -0
  31. {voidaccess-2.0.1 → voidaccess-2.0.2}/auth/token_blacklist.py +0 -0
  32. {voidaccess-2.0.1 → voidaccess-2.0.2}/config.py +0 -0
  33. {voidaccess-2.0.1 → voidaccess-2.0.2}/crawler/__init__.py +0 -0
  34. {voidaccess-2.0.1 → voidaccess-2.0.2}/crawler/dedup.py +0 -0
  35. {voidaccess-2.0.1 → voidaccess-2.0.2}/crawler/frontier.py +0 -0
  36. {voidaccess-2.0.1 → voidaccess-2.0.2}/crawler/spider.py +0 -0
  37. {voidaccess-2.0.1 → voidaccess-2.0.2}/crawler/utils.py +0 -0
  38. {voidaccess-2.0.1 → voidaccess-2.0.2}/data/__init__.py +0 -0
  39. {voidaccess-2.0.1 → voidaccess-2.0.2}/data/common_words_en.txt +0 -0
  40. {voidaccess-2.0.1 → voidaccess-2.0.2}/data/domain_stopwords_en.txt +0 -0
  41. {voidaccess-2.0.1 → voidaccess-2.0.2}/data/monitors.yaml +0 -0
  42. {voidaccess-2.0.1 → voidaccess-2.0.2}/data/seed_data.json.gz +0 -0
  43. {voidaccess-2.0.1 → voidaccess-2.0.2}/data/threat_gazetteer.json +0 -0
  44. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/__init__.py +0 -0
  45. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/migrations/__init__.py +0 -0
  46. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/migrations/env.py +0 -0
  47. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/migrations/versions/0001_initial_schema.py +0 -0
  48. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/migrations/versions/0002_add_investigation_status_column.py +0 -0
  49. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/migrations/versions/0002_add_missing_tables.py +0 -0
  50. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/migrations/versions/0003_add_canonical_value_and_entity_links.py +0 -0
  51. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/migrations/versions/0004_add_page_posted_at.py +0 -0
  52. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/migrations/versions/0005_add_extraction_method.py +0 -0
  53. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/migrations/versions/0006_add_monitor_alerts.py +0 -0
  54. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/migrations/versions/0007_add_actor_style_profiles.py +0 -0
  55. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/migrations/versions/0008_add_users_table.py +0 -0
  56. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/migrations/versions/0009_add_investigation_id_to_relationships.py +0 -0
  57. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/migrations/versions/0010_add_composite_index_entity_relationships.py +0 -0
  58. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/migrations/versions/0011_add_page_extraction_cache.py +0 -0
  59. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/migrations/versions/0013_add_graph_status.py +0 -0
  60. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/migrations/versions/0015_add_progress_fields.py +0 -0
  61. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/migrations/versions/0016_backfill_graph_status.py +0 -0
  62. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/migrations/versions/0017_add_user_api_keys.py +0 -0
  63. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/migrations/versions/0018_add_user_id_to_investigations.py +0 -0
  64. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/migrations/versions/0019_add_content_safety_log.py +0 -0
  65. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/migrations/versions/0020_add_entity_source_tracking.py +0 -0
  66. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/migrations/versions/0021_add_search_engine_stats.py +0 -0
  67. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/migrations/versions/0022_add_actor_profiles.py +0 -0
  68. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/migrations/versions/0023_add_investigation_metadata.py +0 -0
  69. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/migrations/versions/0024_add_investigation_step_metrics.py +0 -0
  70. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/migrations/versions/0025_add_cancellation_requested.py +0 -0
  71. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/migrations/versions/0026_add_entity_investigation_count.py +0 -0
  72. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/models.py +0 -0
  73. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/queries.py +0 -0
  74. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/search_engine_stats.py +0 -0
  75. {voidaccess-2.0.1 → voidaccess-2.0.2}/db/session.py +0 -0
  76. {voidaccess-2.0.1 → voidaccess-2.0.2}/export/_entity_loading.py +0 -0
  77. {voidaccess-2.0.1 → voidaccess-2.0.2}/export/misp.py +0 -0
  78. {voidaccess-2.0.1 → voidaccess-2.0.2}/export/relationships.py +0 -0
  79. {voidaccess-2.0.1 → voidaccess-2.0.2}/export/snort_export.py +0 -0
  80. {voidaccess-2.0.1 → voidaccess-2.0.2}/export/stix.py +0 -0
  81. {voidaccess-2.0.1 → voidaccess-2.0.2}/export/yara_export.py +0 -0
  82. {voidaccess-2.0.1 → voidaccess-2.0.2}/extractor/__init__.py +0 -0
  83. {voidaccess-2.0.1 → voidaccess-2.0.2}/extractor/confidence.py +0 -0
  84. {voidaccess-2.0.1 → voidaccess-2.0.2}/extractor/dependency_relationship.py +0 -0
  85. {voidaccess-2.0.1 → voidaccess-2.0.2}/extractor/entity_shape.py +0 -0
  86. {voidaccess-2.0.1 → voidaccess-2.0.2}/extractor/gazetteer.py +0 -0
  87. {voidaccess-2.0.1 → voidaccess-2.0.2}/extractor/identity.py +0 -0
  88. {voidaccess-2.0.1 → voidaccess-2.0.2}/extractor/llm_extract.py +0 -0
  89. {voidaccess-2.0.1 → voidaccess-2.0.2}/extractor/ner.py +0 -0
  90. {voidaccess-2.0.1 → voidaccess-2.0.2}/extractor/normalizer.py +0 -0
  91. {voidaccess-2.0.1 → voidaccess-2.0.2}/extractor/pipeline.py +0 -0
  92. {voidaccess-2.0.1 → voidaccess-2.0.2}/extractor/regex_patterns.py +0 -0
  93. {voidaccess-2.0.1 → voidaccess-2.0.2}/extractor/relationship_extract.py +0 -0
  94. {voidaccess-2.0.1 → voidaccess-2.0.2}/extractor/software_suppression.py +0 -0
  95. {voidaccess-2.0.1 → voidaccess-2.0.2}/fingerprint/__init__.py +0 -0
  96. {voidaccess-2.0.1 → voidaccess-2.0.2}/fingerprint/calibration.py +0 -0
  97. {voidaccess-2.0.1 → voidaccess-2.0.2}/fingerprint/profiler.py +0 -0
  98. {voidaccess-2.0.1 → voidaccess-2.0.2}/fingerprint/stylometry.py +0 -0
  99. {voidaccess-2.0.1 → voidaccess-2.0.2}/graph/__init__.py +0 -0
  100. {voidaccess-2.0.1 → voidaccess-2.0.2}/graph/builder.py +0 -0
  101. {voidaccess-2.0.1 → voidaccess-2.0.2}/graph/export.py +0 -0
  102. {voidaccess-2.0.1 → voidaccess-2.0.2}/graph/model.py +0 -0
  103. {voidaccess-2.0.1 → voidaccess-2.0.2}/graph/queries.py +0 -0
  104. {voidaccess-2.0.1 → voidaccess-2.0.2}/graph/visualize.py +0 -0
  105. {voidaccess-2.0.1 → voidaccess-2.0.2}/i18n/__init__.py +0 -0
  106. {voidaccess-2.0.1 → voidaccess-2.0.2}/i18n/detect.py +0 -0
  107. {voidaccess-2.0.1 → voidaccess-2.0.2}/i18n/query_expand.py +0 -0
  108. {voidaccess-2.0.1 → voidaccess-2.0.2}/i18n/translate.py +0 -0
  109. {voidaccess-2.0.1 → voidaccess-2.0.2}/monitor/__init__.py +0 -0
  110. {voidaccess-2.0.1 → voidaccess-2.0.2}/monitor/_db.py +0 -0
  111. {voidaccess-2.0.1 → voidaccess-2.0.2}/monitor/alerts.py +0 -0
  112. {voidaccess-2.0.1 → voidaccess-2.0.2}/monitor/config.py +0 -0
  113. {voidaccess-2.0.1 → voidaccess-2.0.2}/monitor/diff.py +0 -0
  114. {voidaccess-2.0.1 → voidaccess-2.0.2}/monitor/jobs.py +0 -0
  115. {voidaccess-2.0.1 → voidaccess-2.0.2}/monitor/scheduler.py +0 -0
  116. {voidaccess-2.0.1 → voidaccess-2.0.2}/pacing/__init__.py +0 -0
  117. {voidaccess-2.0.1 → voidaccess-2.0.2}/scraper/__init__.py +0 -0
  118. {voidaccess-2.0.1 → voidaccess-2.0.2}/scraper/scrape.py +0 -0
  119. {voidaccess-2.0.1 → voidaccess-2.0.2}/scraper/scrape_js.py +0 -0
  120. {voidaccess-2.0.1 → voidaccess-2.0.2}/scraper/tor_pool.py +0 -0
  121. {voidaccess-2.0.1 → voidaccess-2.0.2}/search/__init__.py +0 -0
  122. {voidaccess-2.0.1 → voidaccess-2.0.2}/search/circuit_breaker.py +0 -0
  123. {voidaccess-2.0.1 → voidaccess-2.0.2}/search/config.py +0 -0
  124. {voidaccess-2.0.1 → voidaccess-2.0.2}/search/engine_catalog.py +0 -0
  125. {voidaccess-2.0.1 → voidaccess-2.0.2}/search/query_builder.py +0 -0
  126. {voidaccess-2.0.1 → voidaccess-2.0.2}/search/search.py +0 -0
  127. {voidaccess-2.0.1 → voidaccess-2.0.2}/search/tor_isolation.py +0 -0
  128. {voidaccess-2.0.1 → voidaccess-2.0.2}/setup.cfg +0 -0
  129. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/__init__.py +0 -0
  130. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/actor_profiles.py +0 -0
  131. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/blockchain.py +0 -0
  132. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/breach_lookup.py +0 -0
  133. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/cache.py +0 -0
  134. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/cisa.py +0 -0
  135. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/data/__init__.py +0 -0
  136. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/data/onion_seeds.json +0 -0
  137. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/dns_enrichment.py +0 -0
  138. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/domain_reputation.py +0 -0
  139. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/email_reputation.py +0 -0
  140. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/engines.py +0 -0
  141. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/enrichment.py +0 -0
  142. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/github_scraper.py +0 -0
  143. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/gitlab_scraper.py +0 -0
  144. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/hash_reputation.py +0 -0
  145. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/historical_intel.py +0 -0
  146. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/infostealer.py +0 -0
  147. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/ip_reputation.py +0 -0
  148. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/nvd.py +0 -0
  149. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/paste_scraper.py +0 -0
  150. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/pastes.py +0 -0
  151. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/proxy_client.py +0 -0
  152. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/rss_scraper.py +0 -0
  153. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/seed_manager.py +0 -0
  154. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/seeds.py +0 -0
  155. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/shodan.py +0 -0
  156. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/telegram.py +0 -0
  157. {voidaccess-2.0.1 → voidaccess-2.0.2}/sources/virustotal.py +0 -0
  158. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_actor_extraction_gap.py +0 -0
  159. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_analysis_opsec.py +0 -0
  160. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_analysis_stylometry.py +0 -0
  161. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_analysis_temporal.py +0 -0
  162. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_api.py +0 -0
  163. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_api_monitors.py +0 -0
  164. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_blockchain.py +0 -0
  165. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_breach_lookup.py +0 -0
  166. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_cli_manifest.py +0 -0
  167. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_cli_proxy_config.py +0 -0
  168. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_community_detection_parity.py +0 -0
  169. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_confidence_calibration.py +0 -0
  170. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_config.py +0 -0
  171. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_consolidated_contracts.py +0 -0
  172. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_crawler.py +0 -0
  173. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_db.py +0 -0
  174. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_dependency_relationship.py +0 -0
  175. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_dns_enrichment.py +0 -0
  176. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_domain_reputation.py +0 -0
  177. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_email_reputation.py +0 -0
  178. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_entity_priority.py +0 -0
  179. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_extractor_llm_pipeline.py +0 -0
  180. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_filter_e2e_manual.py +0 -0
  181. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_filter_parser_manual.py +0 -0
  182. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_fingerprint.py +0 -0
  183. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_gazetteer.py +0 -0
  184. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_github_scraper.py +0 -0
  185. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_gitlab_scraper.py +0 -0
  186. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_graph.py +0 -0
  187. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_graph_integration.py +0 -0
  188. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_hash_reputation.py +0 -0
  189. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_heuristic_expansion.py +0 -0
  190. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_i18n.py +0 -0
  191. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_infostealer.py +0 -0
  192. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_ioc_package_export.py +0 -0
  193. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_ip_reputation.py +0 -0
  194. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_llm.py +0 -0
  195. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_llm_utils.py +0 -0
  196. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_model_singleton.py +0 -0
  197. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_monitor.py +0 -0
  198. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_monitor_integration.py +0 -0
  199. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_nvd.py +0 -0
  200. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_pacing.py +0 -0
  201. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_pacing_enrichment.py +0 -0
  202. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_pacing_quotas.py +0 -0
  203. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_pagination.py +0 -0
  204. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_paste_scraper.py +0 -0
  205. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_priority_score_cli_api_parity.py +0 -0
  206. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_proxy_client.py +0 -0
  207. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_ransomlook.py +0 -0
  208. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_regex_patterns.py +0 -0
  209. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_relationship_extract.py +0 -0
  210. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_requirement_bugs.py +0 -0
  211. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_rss_scraper.py +0 -0
  212. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_scrape_isolation.py +0 -0
  213. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_scrape_js.py +0 -0
  214. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_settings.py +0 -0
  215. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_sigma_export.py +0 -0
  216. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_snort_export.py +0 -0
  217. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_software_suppression.py +0 -0
  218. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_sources.py +0 -0
  219. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_sources_enrichment_new.py +0 -0
  220. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_stix_export.py +0 -0
  221. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_vector.py +0 -0
  222. {voidaccess-2.0.1 → voidaccess-2.0.2}/tests/test_yara_export.py +0 -0
  223. {voidaccess-2.0.1 → voidaccess-2.0.2}/utils/__init__.py +0 -0
  224. {voidaccess-2.0.1 → voidaccess-2.0.2}/utils/async_utils.py +0 -0
  225. {voidaccess-2.0.1 → voidaccess-2.0.2}/utils/content_dedup.py +0 -0
  226. {voidaccess-2.0.1 → voidaccess-2.0.2}/utils/content_safety.py +0 -0
  227. {voidaccess-2.0.1 → voidaccess-2.0.2}/utils/defang.py +0 -0
  228. {voidaccess-2.0.1 → voidaccess-2.0.2}/utils/encryption.py +0 -0
  229. {voidaccess-2.0.1 → voidaccess-2.0.2}/utils/enrichment_cache.py +0 -0
  230. {voidaccess-2.0.1 → voidaccess-2.0.2}/utils/entity_priority.py +0 -0
  231. {voidaccess-2.0.1 → voidaccess-2.0.2}/utils/investigation_metrics.py +0 -0
  232. {voidaccess-2.0.1 → voidaccess-2.0.2}/utils/ioc_freshness.py +0 -0
  233. {voidaccess-2.0.1 → voidaccess-2.0.2}/utils/user_keys.py +0 -0
  234. {voidaccess-2.0.1 → voidaccess-2.0.2}/vector/__init__.py +0 -0
  235. {voidaccess-2.0.1 → voidaccess-2.0.2}/vector/embedder.py +0 -0
  236. {voidaccess-2.0.1 → voidaccess-2.0.2}/vector/model_singleton.py +0 -0
  237. {voidaccess-2.0.1 → voidaccess-2.0.2}/vector/search.py +0 -0
  238. {voidaccess-2.0.1 → voidaccess-2.0.2}/vector/store.py +0 -0
  239. {voidaccess-2.0.1 → voidaccess-2.0.2}/voidaccess/__init__.py +0 -0
  240. {voidaccess-2.0.1 → voidaccess-2.0.2}/voidaccess/config.py +0 -0
  241. {voidaccess-2.0.1 → voidaccess-2.0.2}/voidaccess/llm.py +0 -0
  242. {voidaccess-2.0.1 → voidaccess-2.0.2}/voidaccess/llm_utils.py +0 -0
  243. {voidaccess-2.0.1 → voidaccess-2.0.2}/voidaccess.egg-info/SOURCES.txt +0 -0
  244. {voidaccess-2.0.1 → voidaccess-2.0.2}/voidaccess.egg-info/dependency_links.txt +0 -0
  245. {voidaccess-2.0.1 → voidaccess-2.0.2}/voidaccess.egg-info/entry_points.txt +0 -0
  246. {voidaccess-2.0.1 → voidaccess-2.0.2}/voidaccess.egg-info/requires.txt +0 -0
  247. {voidaccess-2.0.1 → voidaccess-2.0.2}/voidaccess.egg-info/top_level.txt +0 -0
  248. {voidaccess-2.0.1 → voidaccess-2.0.2}/voidaccess_cli/adapters/__init__.py +0 -0
  249. {voidaccess-2.0.1 → voidaccess-2.0.2}/voidaccess_cli/adapters/sqlite.py +0 -0
  250. {voidaccess-2.0.1 → voidaccess-2.0.2}/voidaccess_cli/browser.py +0 -0
  251. {voidaccess-2.0.1 → voidaccess-2.0.2}/voidaccess_cli/commands/__init__.py +0 -0
  252. {voidaccess-2.0.1 → voidaccess-2.0.2}/voidaccess_cli/commands/actors.py +0 -0
  253. {voidaccess-2.0.1 → voidaccess-2.0.2}/voidaccess_cli/commands/configure.py +0 -0
  254. {voidaccess-2.0.1 → voidaccess-2.0.2}/voidaccess_cli/commands/enrich.py +0 -0
  255. {voidaccess-2.0.1 → voidaccess-2.0.2}/voidaccess_cli/commands/investigate.py +0 -0
  256. {voidaccess-2.0.1 → voidaccess-2.0.2}/voidaccess_cli/commands/show.py +0 -0
  257. {voidaccess-2.0.1 → voidaccess-2.0.2}/voidaccess_cli/config.py +0 -0
  258. {voidaccess-2.0.1 → voidaccess-2.0.2}/voidaccess_cli/display.py +0 -0
  259. {voidaccess-2.0.1 → voidaccess-2.0.2}/voidaccess_cli/main.py +0 -0
  260. {voidaccess-2.0.1 → voidaccess-2.0.2}/voidaccess_cli/tor_detect.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: voidaccess
3
- Version: 2.0.1
3
+ Version: 2.0.2
4
4
  Summary: Dark web OSINT CLI — automated threat intelligence from query to report
5
5
  Author: VoidAccess
6
6
  License-Expression: MIT
@@ -332,7 +332,7 @@ async def _periodic_stuck_sweep() -> None:
332
332
  app = FastAPI(
333
333
  title="VoidAccess Intelligence API",
334
334
  description="VoidAccess: Dark Web Intelligence Platform",
335
- version="2.0.1",
335
+ version="2.0.2",
336
336
  docs_url="/docs",
337
337
  redoc_url="/redoc",
338
338
  lifespan=lifespan,
@@ -17,6 +17,7 @@ from export.misp import (
17
17
  from export.sigma import (
18
18
  entities_to_sigma_rules,
19
19
  export_sigma_rules,
20
+ render_sigma_rules,
20
21
  sigma_rule_to_yaml,
21
22
  )
22
23
  from export.yara_export import (
@@ -44,6 +45,7 @@ __all__ = [
44
45
  # sigma
45
46
  "entities_to_sigma_rules",
46
47
  "sigma_rule_to_yaml",
48
+ "render_sigma_rules",
47
49
  "export_sigma_rules",
48
50
  # yara
49
51
  "generate_yara_rules",
@@ -57,7 +57,7 @@ logger = logging.getLogger(__name__)
57
57
  # ---------------------------------------------------------------------------
58
58
 
59
59
  PACKAGE_FORMAT = "voidaccess-ioc-v1"
60
- PACKAGE_VERSION = "2.0.1"
60
+ PACKAGE_VERSION = "2.0.2"
61
61
  SNORT_SID_BASE = 9000001 # 9xxxxxx reserved for VoidAccess-generated rules
62
62
 
63
63
  # Map extractor upper-case entity types to the per-file bucket they belong to.
@@ -702,57 +702,13 @@ def _safe_misp_json(entities: list[Any], investigation_id: Any) -> str:
702
702
 
703
703
  def _safe_sigma_yml(entities: list[Any]) -> str:
704
704
  try:
705
- from export.sigma import entities_to_sigma_rules, sigma_rule_to_yaml
706
- # Sigma rules expect object-style entities (NormalizedEntity). When the
707
- # caller passes plain dicts, wrap them in a tiny adapter so Sigma can
708
- # read .entity_type, .value, .confidence, and .source_url.
709
- adapted: list[Any] = []
710
- for e in entities or []:
711
- if isinstance(e, dict):
712
- adapted.append(_DictEntityAdapter(e))
713
- else:
714
- adapted.append(e)
715
- rules = entities_to_sigma_rules(adapted)
716
- return "\n---\n".join(sigma_rule_to_yaml(r) for r in rules if r)
705
+ from export.sigma import render_sigma_rules
706
+ return render_sigma_rules(entities or [])
717
707
  except Exception as exc:
718
708
  logger.warning("Sigma generation for IOC package failed: %s", exc)
719
709
  return ""
720
710
 
721
711
 
722
- class _DictEntityAdapter:
723
- """Adapt a plain dict into an object with .entity_type / .value / etc.
724
-
725
- Used to feed dict-shaped entities into Sigma / STIX / MISP generators
726
- that expect object access. Keeps the IOC package module standalone
727
- without changing the existing Sigma / STIX / MISP module signatures.
728
- """
729
-
730
- __slots__ = ("_d",)
731
-
732
- def __init__(self, d: dict[str, Any]) -> None:
733
- self._d = d
734
-
735
- @property
736
- def entity_type(self) -> str:
737
- return _entity_type(self._d)
738
-
739
- @property
740
- def value(self) -> str:
741
- return _entity_value(self._d)
742
-
743
- @property
744
- def canonical_value(self) -> str:
745
- return entity_canonical_id(self._d)
746
-
747
- @property
748
- def confidence(self) -> float:
749
- return _entity_confidence(self._d)
750
-
751
- @property
752
- def source_url(self) -> str:
753
- return _entity_source_url(self._d)
754
-
755
-
756
712
  # ---------------------------------------------------------------------------
757
713
  # README + metadata builders
758
714
  # ---------------------------------------------------------------------------
@@ -207,7 +207,8 @@ def entities_to_sigma_rules(
207
207
  Falls back to base rule if LLM fails.
208
208
  """
209
209
  rules: list[dict] = []
210
- for entity in entities:
210
+ for raw_entity in entities:
211
+ entity = _adapt_entity(raw_entity)
211
212
  if entity.entity_type not in _SIGMA_ENTITY_TYPES:
212
213
  continue
213
214
  base = _build_base_rule(entity)
@@ -228,6 +229,23 @@ def sigma_rule_to_yaml(rule: dict) -> str:
228
229
  return ""
229
230
 
230
231
 
232
+ def render_sigma_rules(
233
+ entities: list[Any],
234
+ llm: Optional[Any] = None,
235
+ ) -> str:
236
+ """Render the shared Sigma artifact used by every export surface.
237
+
238
+ The CLI export and the IOC package both receive the same export payload,
239
+ whose entities are normally dictionaries. Keeping adaptation, rule
240
+ generation, and YAML assembly here prevents one surface from growing a
241
+ second DB-loading implementation with different failure semantics.
242
+ """
243
+ rules = entities_to_sigma_rules(list(entities or []), llm=llm)
244
+ return "\n---\n".join(
245
+ sigma_rule_to_yaml(rule) for rule in rules if rule
246
+ )
247
+
248
+
231
249
  def export_sigma_rules(
232
250
  investigation_id: Any,
233
251
  output_dir: str,
@@ -320,6 +338,45 @@ def _load_entities_for_investigation(investigation_id: Any) -> list[Any]:
320
338
  return []
321
339
 
322
340
 
341
+ class _DictEntityAdapter:
342
+ """Expose dictionary-shaped export entities through Sigma's object API."""
343
+
344
+ __slots__ = ("_data",)
345
+
346
+ def __init__(self, data: dict[str, Any]) -> None:
347
+ self._data = data
348
+
349
+ @property
350
+ def entity_type(self) -> str:
351
+ return str(self._data.get("entity_type") or "")
352
+
353
+ @property
354
+ def value(self) -> str:
355
+ return str(
356
+ self._data.get("canonical_value")
357
+ or self._data.get("value")
358
+ or ""
359
+ )
360
+
361
+ @property
362
+ def confidence(self) -> float:
363
+ try:
364
+ return float(self._data.get("confidence", 0.0) or 0.0)
365
+ except (TypeError, ValueError):
366
+ return 0.0
367
+
368
+ @property
369
+ def source_url(self) -> str:
370
+ return str(self._data.get("source_url") or "")
371
+
372
+
373
+ def _adapt_entity(entity: Any) -> Any:
374
+ """Accept both ORM/normalized entities and export dictionaries."""
375
+ if isinstance(entity, dict):
376
+ return _DictEntityAdapter(entity)
377
+ return entity
378
+
379
+
323
380
  def _coerce_uuid(value: Any):
324
381
  """Coerce value to uuid.UUID. Returns None on failure."""
325
382
  import uuid as _uuid
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "voidaccess"
7
- version = "2.0.1"
7
+ version = "2.0.2"
8
8
  description = "Dark web OSINT CLI — automated threat intelligence from query to report"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -154,7 +154,7 @@ exclude = [
154
154
  "sources" = ["data/onion_seeds.json"]
155
155
  "sources.data" = ["onion_seeds.json"]
156
156
 
157
- # v2.0.1 — ship the top-level reference data bundle inside the installed
157
+ # v2.0.2 — ship the top-level reference data bundle inside the installed
158
158
  # package. The runtime resolves each of these via
159
159
  # ``os.path.dirname(os.path.dirname(__file__))/data`` (from extractor/ and
160
160
  # monitor/), i.e. ``site-packages/data/<file>`` after a wheel install. The
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: voidaccess
3
- Version: 2.0.1
3
+ Version: 2.0.2
4
4
  Summary: Dark web OSINT CLI — automated threat intelligence from query to report
5
5
  Author: VoidAccess
6
6
  License-Expression: MIT
@@ -1,3 +1,3 @@
1
1
  """voidaccess CLI — dark-web OSINT command-line interface."""
2
2
 
3
- __version__ = "2.0.1"
3
+ __version__ = "2.0.2"
@@ -11,7 +11,6 @@ import csv
11
11
  import io
12
12
  import json
13
13
  import re as _re
14
- import tempfile
15
14
  import uuid
16
15
  from pathlib import Path
17
16
  from typing import Optional
@@ -83,7 +82,10 @@ def run(
83
82
  include_raw=include_raw,
84
83
  )
85
84
  out_path = output or _default_out_path(
86
- target, suffix, fmt=fmt, query=(data.get("investigation") or {}).get("query")
85
+ target,
86
+ suffix,
87
+ fmt=fmt,
88
+ query=_investigation_metadata(data, inv_id).get("query"),
87
89
  )
88
90
  out_path = Path(out_path).expanduser()
89
91
  if out_path.exists():
@@ -122,8 +124,23 @@ def _load_target(target: str) -> tuple[Optional[str], Optional[dict]]:
122
124
  return inv_id, data
123
125
  from voidaccess_cli.adapters import sqlite as sqlite_adapter
124
126
  sqlite_adapter.init_db()
125
- resolved = sqlite_adapter.resolve_investigation_id(target) or target
126
- data = sqlite_adapter.investigation_to_export_dict(resolved)
127
+ try:
128
+ resolved = sqlite_adapter.resolve_investigation_id(target) or target
129
+ data = sqlite_adapter.investigation_to_export_dict(resolved)
130
+ except Exception as exc:
131
+ # Do not let an ORM/SQLAlchemy read failure become an empty export.
132
+ # init_db() is the schema choke-point; this guard covers a schema
133
+ # mismatch that manifests while loading a table/column not included in
134
+ # the lightweight preflight contract. Rendering happens only after
135
+ # this function returns, so no artifact can be written on failure.
136
+ from sqlalchemy.exc import OperationalError
137
+
138
+ if isinstance(exc, OperationalError):
139
+ raise sqlite_adapter.DatabaseSchemaError(
140
+ "Export could not read the database; the schema may be stale. "
141
+ "Run `alembic upgrade head` and retry."
142
+ ) from exc
143
+ raise
127
144
  if not data or not data.get("investigation"):
128
145
  return None, None
129
146
  return resolved, data
@@ -193,17 +210,12 @@ def _render(
193
210
  return misp_event_to_json(event), ".json"
194
211
 
195
212
  if fmt == "sigma":
196
- from export import export_sigma_rules
197
- # The Sigma exporter writes one YAML file per rule and therefore needs
198
- # an output directory. The CLI itself promises one output artifact,
199
- # so collect those files in a temporary directory and combine them.
200
- with tempfile.TemporaryDirectory(prefix="voidaccess-sigma-") as temp_dir:
201
- rule_paths = export_sigma_rules(inv_uuid, temp_dir)
202
- rules_yaml = "\n---\n".join(
203
- Path(rule_path).read_text(encoding="utf-8")
204
- for rule_path in rule_paths
205
- )
206
- return rules_yaml, ".yml"
213
+ from export import render_sigma_rules
214
+ # The IOC package and direct CLI export must share the same generator.
215
+ # ``data`` was loaded through the CLI's init_db() choke-point above;
216
+ # loading the entities again through export_sigma_rules() used to
217
+ # create a second, error-swallowing DB path and yielded empty files.
218
+ return render_sigma_rules(data.get("entities") or []), ".yml"
207
219
 
208
220
  raise typer.BadParameter(f"Unknown format: {fmt}")
209
221
 
@@ -221,7 +233,7 @@ def _render_detection_rule(
221
233
  already embedded in the JSON payload so this still works when the user
222
234
  passes a ``.json`` file (the API path requires a DB investigation).
223
235
  """
224
- investigation = data.get("investigation") or {}
236
+ investigation = _investigation_metadata(data, inv_id)
225
237
  investigation_dict: dict = {
226
238
  "id": investigation.get("id") or inv_id or "",
227
239
  "run_id": investigation.get("run_id"),
@@ -278,7 +290,7 @@ def _render_package(
278
290
  import asyncio
279
291
  from export.ioc_package import build_package_filename, generate_ioc_package
280
292
 
281
- investigation = data.get("investigation") or {}
293
+ investigation = _investigation_metadata(data, inv_id)
282
294
  entities = data.get("entities") or []
283
295
 
284
296
  # Build the flat-shape dict the package generator expects.
@@ -309,6 +321,30 @@ def _render_package(
309
321
  return zip_bytes, suffix
310
322
 
311
323
 
324
+ def _investigation_metadata(data: dict, inv_id: Optional[str] = None) -> dict:
325
+ """Return metadata from either DB-shaped or flat CLI JSON payloads."""
326
+ nested = data.get("investigation")
327
+ nested = nested if isinstance(nested, dict) else {}
328
+ fields = (
329
+ "id",
330
+ "run_id",
331
+ "query",
332
+ "refined_query",
333
+ "model_used",
334
+ "summary",
335
+ "created_at",
336
+ "sources_used",
337
+ )
338
+ metadata = {field: data[field] for field in fields if field in data}
339
+ metadata.update(nested)
340
+ metadata["id"] = nested.get("id") or data.get("id") or inv_id or ""
341
+ metadata["query"] = nested.get("query") or data.get("query") or ""
342
+ metadata["sources_used"] = (
343
+ nested.get("sources_used") or data.get("sources_used") or {}
344
+ )
345
+ return metadata
346
+
347
+
312
348
  def _csv_from_data(data: dict) -> str:
313
349
  entities = data.get("entities", [])
314
350
  if not entities and isinstance(data.get("investigation"), dict):
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes