Commit Graph
69 Commits
Author SHA1 Message Date
tdurieux 5c6e5b6519 fix: anonymize PR comment authors and bodies in previews 2026-09-06 10:47:26 +02:00
tdurieux 66e4be0a0c fix: reload PR and Gist views when resource IDs change 2026-09-06 10:47:20 +02:00
tdurieux a6e17e18d9 fix: clear failed searches without racing subsequent requests 2026-09-06 10:47:09 +02:00
tdurieux a27f9f34d6 fix: reload explorer state when repository identity changes 2026-09-06 10:47:03 +02:00
tdurieux b6c0d3a8ed fix: ignore stale file responses after viewer navigation 2026-09-06 10:46:57 +02:00
tdurieux b2dfda1838 fix: sanitize Org previews before trusting rendered HTML 2026-09-06 10:46:44 +02:00
tdurieux cf58aa330b fix: handle prototype property names in repository trees 2026-09-06 10:46:38 +02:00
tdurieux d793d2c7c6 fix: bind file tree names without compiling repository content 2026-09-06 10:46:32 +02:00
tdurieux b070d7e281 fix: evaluate document creation timestamps per instance 2026-09-06 09:19:33 +02:00
tdurieux f312105ec3 fix: fetch private pull request diffs through authenticated API 2026-09-06 09:19:28 +02:00
tdurieux 4aecc1d92f fix: fetch complete content for truncated Gist files 2026-09-06 09:19:23 +02:00
tdurieux b1cb9093bb fix: close streaming responses after upstream errors 2026-09-06 09:19:18 +02:00
tdurieux 38a09188ad fix: expire conference repositories before completing expiration 2026-09-06 09:18:42 +02:00
tdurieux 6777537d44 fix: restrict S3 deletion to exact keys and descendants 2026-09-06 09:18:37 +02:00
tdurieux 5e84bfaa5b fix: surface partial S3 object deletion failures 2026-09-06 09:18:32 +02:00
tdurieux 4643e9f838 fix: preserve and anonymize truncated folder warnings 2026-09-06 09:18:28 +02:00
tdurieux 8d2921b406 fix: respect backpressure when resolving Git LFS pointers 2026-09-06 09:18:24 +02:00
tdurieux 9c18526d52 fix: decode and validate webview file paths 2026-09-06 09:17:56 +02:00
tdurieux 67eb83674c fix: sandbox repository webview documents 2026-09-06 09:17:52 +02:00
tdurieux 3e275311f1 fix: derive file ETags from current source content 2026-09-06 09:17:47 +02:00
tdurieux c14a548cb9 fix: enforce content policies using original file types 2026-09-06 09:17:42 +02:00
tdurieux 7210db2b61 fix: catch authentication failures in async route handlers 2026-09-06 09:17:37 +02:00
tdurieux 11eb160d2b fix: prevent stale downloads from reviving removed repositories 2026-09-06 09:17:33 +02:00
tdurieux 2af66cd1b6 fix: authorize coauthors by stable GitHub identity 2026-09-06 09:17:01 +02:00
tdurieux 8ec656c201 fix: authorize access before returning cached GitHub metadata 2026-09-06 09:16:57 +02:00
tdurieux a401bb21d6 fix: reject OAuth linking across different GitHub identities 2026-09-06 09:16:53 +02:00
tdurieux 50d606d0c1 fix: bound regex execution during anonymization 2026-09-06 09:16:48 +02:00
tdurieux b3f86513dd fix: prevent anonymization leaks across stream boundaries 2026-09-06 09:16:44 +02:00
tdurieux 900516f225 fix: omit source content length for rewritten file responses 2026-09-06 09:16:23 +02:00
tdurieux 12c07641e0 fix: persist and recover repository removals for banned owners 2026-09-06 09:16:20 +02:00
tdurieux f5f44c2511 fix: preserve removal intent when Redis enqueue fails 2026-09-06 09:16:17 +02:00
tdurieux 12b0bb52c0 fix: ignore stale removal jobs after repository restoration 2026-09-06 09:16:13 +02:00
Archit Rastogi 420fa9e450 fix: clip overflowing conference link in dashboard table (#790)
The Conference cell is a grid item with the default min-width:auto,
so a long unbroken URL forces the grid track wider than its
minmax(140px, 1fr) size and bleeds visually into the Status column.
Clip it with overflow:hidden/ellipsis and expose the full value via
a title attribute.
2026-08-26 21:47:23 +02:00
Thomas Durieux adb0dcaec2 fix: reactivate removed repositories after edits (#784) 2026-08-20 14:33:09 +02:00
Thomas Durieux 7b585fdefd Fix BullMQ removal processor arguments (#783) 2026-08-20 14:23:21 +02:00
Thomas Durieux 35c3b1804b Fix repository cleanup after removal and expiration (#782) 2026-08-20 12:52:19 +02:00
Thomas Durieux 46e956a779 fix: reactivate repositories with future expiration (#781) 2026-08-20 12:29:52 +02:00
tdurieux f0fdd9250b fix: improve pdf rendering and html 2026-08-06 14:35:21 -07:00
Thomas Durieux debd83c079 feat: add optional MongoDB replica deployment (#765) 2026-07-30 02:28:19 +02:00
Thomas Durieux f040557ae8 fix: preserve state across backend updates (#756) 2026-07-22 04:29:58 +02:00
Thomas Durieux beef8387ae fix: close account authorization gaps (#755) 2026-07-22 04:29:04 +02:00
Thomas Durieux aab6ccf7fc fix: harden anonymization privacy paths (#754) 2026-07-22 04:28:01 +02:00
Thomas DurieuxandClaude Fable 5 6a820408a1 fix: rate-limit visitors by real IP regardless of Cloudflare proxy hops (#750)
Since the night of 2026-07-16 production keyed the rate limiter on
Cloudflare edge IPs instead of visitor IPs: every visitor routed through
the same edge shared one 175-req/15min bucket, causing widespread 429s
(confirmed by probing: sequential requests alternated 200/429 across
fresh and exhausted buckets).

Root cause: 'trust proxy' used a fixed hop count (TRUST_PROXY=1), which
silently breaks whenever the proxy chain gains or loses an
X-Forwarded-For entry (e.g. a Cloudflare-side change).

- TRUST_PROXY now accepts a comma-separated subnet list; the new default
  'loopback,uniquelocal,cloudflare' expands Cloudflare's published IP
  ranges so Express skips trusted proxies no matter how many entries
  they add. Plain numbers keep the legacy hop-count behavior.
- If resolution still stops at a Cloudflare address (visitor missing
  from X-Forwarded-For entirely), the limiter key falls back to
  cf-connecting-ip — safe because request.ip can only be a Cloudflare
  address when the whole chain to it is trusted.
- CIDR matching uses Node's built-in net.BlockList (no new dependency).

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 06:44:21 +02:00
tdurieux 1c1993f972 fix: try to fix gist 2026-07-02 14:53:26 +03:00
Thomas Durieux 839582c657 Fix .bat anonymization, truncated-tree misses, submodule warning, account deletion (#742)
* fix: anonymize Windows batch scripts (#735)

mime-types maps .bat to application/x-msdownload, the same MIME type as
.exe/.dll, so batch scripts were classified as binary and streamed
through without any anonymization. Special-case .bat/.cmd as text before
the MIME lookup, keeping .exe/.dll binary.

* fix: recover files missing from truncated tree listings (#738)

GitHub truncates tree listings of very large repositories. Folders whose
listing was truncated are recorded in truncatedFolders, but files that
fell outside the listing never reached the database, so requesting them
returned 404 file_not_found even though they exist on GitHub — and a
force refresh could not help.

When a file lookup misses and its directory is under a truncated folder,
fetch the file metadata directly from GitHub's contents API (object
media type, so it works past the 1MB inline limit), cache it in the
database, and serve it normally.

* feat: warn when a repository uses git submodules (#737)

GitHub archives and tree listings never include submodule contents, so
submodules end up as empty folders in the anonymized repository, which
surprises users. Detect a root .gitmodules file and show a warning
banner in the explorer explaining that submodule contents are not
included.

* feat: allow users to delete their account (#741)

Add DELETE /api/user: removes all anonymized repositories, gists, and
pull requests owned by the user, best-effort revokes the GitHub OAuth
grant, and scrubs personal data (username, emails, tokens, GitHub id,
photo) from the user record. The record itself is kept with a
placeholder username so removed repoIds stay reserved and owner
references remain resolvable.

The settings page gains an Account section with a confirmed delete
button.

* fix: add missing error translations for token_expired and job_is_active

The error-code coverage test failed because both backend codes had no
frontend translation.
2026-07-02 13:35:48 +02:00
tdurieux 03e18fd572 repo change + daily stat improvements 2026-05-11 12:10:17 +03:00
tdurieux 7a163f2d35 Fix streamer crash and misclassified transient GitHub errors
Add missing error handler on the anonymizer transform stream in the
streamer route — without it, an upstream error tears down the pipe and
the anonymizer emits an unhandled error that crashes the process
(surfacing as ECONNRESET to the main server).

Classify transient network errors (ReadError, ECONNRESET, ETIMEDOUT)
as upstream_error/502 instead of file_not_found/404 so they are
distinguishable in logs and don't cache-poison downstream.

Update handleError tests to match the existing sanitization behavior
that returns internal_error for non-AnonymousError instances.
2026-05-07 07:44:15 +03:00
tdurieux bd8656206a fix persistance bugs 2026-05-06 20:00:59 +03:00
tdurieux 804bbffb7a Improve error handling 2026-05-06 17:03:19 +03:00
tdurieux b2461088e8 fix test 2026-05-06 16:55:50 +03:00