Harden scans and add LOC comparison endpoint (#1)
ci / test (push) Successful in 9s

Co-authored-by: luna <clawy@reversed.dev>
Co-committed-by: luna <clawy@reversed.dev>
This commit was merged in pull request #1.
This commit is contained in:
2026-07-21 19:33:08 +02:00
committed by Luna
parent ecc1578b92
commit 91c0ed7332
12 changed files with 276 additions and 29 deletions
+14 -2
View File
@@ -11,6 +11,7 @@ Tiny API that clones a Git repo and counts its non-empty lines of code.
- Generic project metadata files are ignored during counting
- Basic rate limiting
- Bounded concurrent scans so the host does not get hammered
- Host allowlist and scan/file size limits, with a capped temporary filesystem in Docker
- SSH key file support for private repos
- Docker Compose deployment
@@ -19,7 +20,9 @@ Tiny API that clones a Git repo and counts its non-empty lines of code.
- `GET /loc.txt?repo=<git-url>&ssh_key=<optional-key-file>&ref=<optional-ref>&api_key=<optional-api-key>`
- Returns the line count as plain text.
- `GET /loc?repo=<git-url>&ssh_key=<optional-key-file>&ref=<optional-ref>&api_key=<optional-api-key>`
- Returns JSON metadata, including a language breakdown by files and non-empty lines.
- Returns JSON metadata, including the resolved commit SHA and a language breakdown by files and non-empty lines.
- `GET /loc/diff?repo=<git-url>&base=<git-ref>&head=<git-ref>&ssh_key=<optional-key-file>`
- Returns both snapshots and their total/per-language LOC delta.
- `GET /health`
- Health plus queue/cache stats.
@@ -71,7 +74,12 @@ curl "http://localhost:3000/ssh/public-key?ssh_key=loc_via_git_ed25519"
- Only text files are counted.
- Empty lines are ignored.
- Generic project metadata files are skipped with a filename blacklist, for example `package.json`, lockfiles, `tsconfig.json`, and similar config/build files.
- Generic project metadata, generated/minified files, and common build/vendor directories are skipped.
- Scans are rejected when they exceed the configured file, per-file, or total scanned-byte limits.
## Repository access
`ALLOWED_GIT_HOSTS` is optional. Leave it unset or empty to allow every remote host, or use a comma-separated allowlist such as `gitea.reversed.dev,github.com`. Local paths, `file://` URLs, non-SSH/HTTPS protocols, and HTTPS URLs containing credentials are always rejected.
## Configuration
@@ -80,11 +88,15 @@ Copy `.env.example` to `.env` and adjust:
```env
PORT=3000
API_KEY=
ALLOWED_GIT_HOSTS=
CACHE_TTL_MINUTES=5
CACHE_SWEEP_INTERVAL_MINUTES=5
RATE_LIMIT_WINDOW_MINUTES=5
RATE_LIMIT_MAX=30
MAX_CONCURRENT_SCANS=4
MAX_FILES_PER_SCAN=20000
MAX_FILE_SIZE_MB=5
MAX_SCAN_SIZE_MB=100
CLONE_TIMEOUT_SECONDS=45
DEFAULT_SSH_KEY_NAME=loc_via_git_ed25519
GENERATE_SSH_KEY_IF_MISSING=false