Commit Graph
443 Commits
Author SHA1 Message Date
tdurieux 3667e8e3cd fix: preserve anonymous sessions during GitHub sign-in 2026-09-10 16:15:39 +02:00
Thomas Durieux 4e52f42009 Merge pull request #814 from tdurieux/feat/github-app-dual-auth
Add read-only GitHub App access alongside OAuth
2026-09-10 06:27:36 -07:00
tdurieux 19f819949e perf: avoid anonymization timeouts for absent literal terms 2026-09-10 14:49:01 +02:00
Thomas Durieux a60ad6a921 feat: add read-only GitHub App access alongside OAuth 2026-09-09 22:08:12 +02:00
tdurieux 74bd6bb779 fix: restore scripts and video playback on project pages 2026-09-08 18:01:32 +02:00
tdurieux 8ad0ec65f0 chore: upgrade Express to 5.2.1 2026-09-08 16:22:23 +02:00
Thomas Durieux a05f42ad9f Merge pull request #801 from tdurieux/t3code/archive-legacy-spaced-ids
fix: archive legacy repository IDs containing spaces
2026-09-08 02:46:38 -10:00
tdurieux c7eed1a6b4 perf: parallelize credential migration owner analysis 2026-09-08 14:28:46 +02:00
tdurieux 0c808a8675 fix: recover conflicting credentials by verifying the recorded owner 2026-09-08 14:21:16 +02:00
tdurieux 90f14b19b7 fix: archive legacy repository IDs containing spaces 2026-09-08 14:08:48 +02:00
Thomas Durieux 530e388e46 fix: archive ownerless repositories without assigning ownership (#800) 2026-09-08 14:03:09 +02:00
Thomas Durieux 8de4a536cc fix: recover legacy repository owners through GitHub (#799) 2026-09-08 13:39:39 +02:00
Thomas Durieux 3fb376dd53 fix: encrypt stored GitHub credentials (#797) 2026-09-08 13:04:28 +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
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
Thomas Durieux 7aa9557905 perf: cut MongoDB scans in repository workflows (#780)
* Add repository name index

* Optimize repository file counts

* Optimize MongoDB query workloads
2026-08-20 12:29:26 +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 Opus 4.8 5ef10dee9e fix: dashboard menu clickability + expiration date UX (#753)
* fix: dashboard menu clickability + expiration date UX

Dashboard actions menu:
- Inactive (expired/removed) rows dimmed via their cells instead of the
  row, so `opacity` no longer creates a stacking context that trapped the
  actions dropdown beneath later rows and made its items unclickable.
- Add an "Extend 6 months" menu item for expired repos/PRs/gists.

Expiration form (anonymize):
- Fix the "After , the content will be removed." blank date: guard the
  helper text and add min/max validation feedback so an invalid pick no
  longer nulls the model into a broken sentence.
- Add a `min` (today) so past dates can no longer be selected, and
  compute min/max from local date parts (not UTC) to avoid a timezone
  off-by-one in the native picker.
- Default expiration is now 6 months (single source of truth, removing a
  latent double-offset bug); max stays at 1 year.
- Block submitting a missing/out-of-range expiration date.

Backend:
- New POST /:id/extend endpoint for repos, PRs and gists that pushes the
  expiration +6 months and re-anonymizes so expired items come back
  online, mirroring the refresh flow. Shared extendExpirationDate helper.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: add frontend translation for invalid_status error code

The new /extend endpoints throw an "invalid_status" AnonymousError, which
the error-code coverage test requires to have a locale entry.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 14:10:38 +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