flowsint-app/package.json was stuck at 1.0.0 and root pyproject.toml
at 1.2.8, both behind the actual v1.2.11 tag. standard-version reads
flowsint-app/package.json as its source of truth, so the next release
would have tagged v1.0.1 — a semver regression breaking the Docker
image tags in images.yml.
TXT imports of file hashes were detected as Username, because File.detect
always returned False and Username.detect matches any 3-80 char
alphanumeric string. Hashes therefore couldn't be used as File entities
to pivot from (VirusTotal, MalwareBazaar, sandboxes), per #45.
- File.detect now recognizes 32/40/64-char hex strings (MD5/SHA1/SHA256),
and File.from_string stores the value in the matching hash_* field
(normalized to lowercase) while keeping it as the filename/label.
- Username.detect now explicitly rejects hash-shaped strings, so hash
detection is correct regardless of type-registration order (File is
already registered before Username, but this removes the implicit
dependency).
Tests cover detection of each hash type (case/whitespace), rejection of
non-hashes, from_string field population, the Username regression, and
end-to-end detect_type() resolution to File.
Closes#45
Any code path reaching the Neo4jConnection singleton requires NEO4J_*
env vars at construction — tests only passed thanks to developers'
local .env files. Driver creation is lazy, nothing connects.
Verified by running all four suites with every .env removed:
458 passed.
Previous fix covered one occurrence; 17 other tests built
Neo4jGraphRepository(neo4j_connection=None), hitting the singleton
fallback that requires NEO4J_* env vars. Single helper, no env
dependency left.
Neo4jGraphRepository(neo4j_connection=None) falls back to the
Neo4jConnection singleton, which requires NEO4J_* env vars — the test
only passed locally thanks to .env. Pass a mock instead; the test
nulls _connection right after anyway.
flowsint_core imports yaml (template_generator_service, yaml_loader)
but never declared it — present locally only as a leftover in the
shared venv. CI's clean resolve exposed the missing declaration.
pip-audit reported 27 vulnerabilities across 12 packages, including
cryptography PYSEC-2026-36 (CVSS 9.8) used by the vault, a starlette
Host-header path bypass, and python-multipart arbitrary file write.
- cryptography 45.0.7 -> 46.0.7 (pin was capped at <46)
- fastapi 0.115 -> 0.136, pulling starlette 0.46 -> 1.2
- python-multipart 0.0.20 -> 0.0.32
- pyjwt, urllib3, aiohttp, lxml, idna, mako and transitive bumps
- dev tools: pytest 8 -> 9 (requires pytest-httpx >=0.36), black 25 -> 26
All four module test suites pass (458 tests). pip-audit now reports
no known vulnerabilities.
parse_json unconditionally replaced every single quote with a double
quote (`.replace("'", '"')`) before calling json.loads. This corrupted
any valid JSON string value containing an apostrophe, e.g. a person's
surname "Sarah O'Brien" became "Sarah O"Brien", causing the parse to
fail with "Invalid JSON" and the whole import to be rejected.
Parse strict JSON first so well-formed payloads (including apostrophes
in string values) import correctly, and only fall back to the lenient
single-quote replacement for Python-dict-style payloads that are not
valid JSON on their own.
Adds regression tests covering an apostrophe-bearing JSON value and the
retained single-quoted fallback.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The Scan model exposes details (JSON) and error (Text) columns, but the
enricher/flow tasks assigned to scan.results — a non-mapped attribute.
SQLAlchemy accepted the assignment silently, so commit() never persisted
it and the data was lost. Success paths now write scan.details; failure
paths write scan.error. ScanCreate.results renamed to details to match.
Scan repository tests pass.
- Add ADMIN role to Role enum (OWNER > ADMIN > EDITOR > VIEWER)
- Update permission matrix: ADMIN can read/create/update/manage
- Fix get_with_relations bug filtering by owner_id (blocked non-owner collaborators)
- Add collaborator management methods to InvestigationRepository and InvestigationService
- Return user profile data in auth response
Add POST /api/types/detect endpoint that detects the type of a text input
by iterating registered types and calling their detect() classmethod.
Returns detected type with fields and primary field pre-filled.
Falls back to Phrase when no type matches.