Protect FileDownloadController with reCAPTCHA v3 and rate limiting #40

Closed
claude wants to merge 0 commits from main into staging
Member

Closes #39

Changes

  • reCAPTCHA v3 token required on initial download requests (action: file_download)
  • Range/resume requests bypass captcha
  • download rate limit: 5 req / 1 min per IP
  • Policy wired in docker-compose.yml and .env.template

UI change required

Before triggering download: grecaptcha.execute(siteKey, {action: 'file_download'}) then append ?captchaToken=<token> to the URL.

Closes #39 ### Changes - reCAPTCHA v3 token required on initial download requests (action: `file_download`) - Range/resume requests bypass captcha - download rate limit: 5 req / 1 min per IP - Policy wired in docker-compose.yml and .env.template ### UI change required Before triggering download: `grecaptcha.execute(siteKey, {action: 'file_download'})` then append `?captchaToken=<token>` to the URL.
claude added 2 commits 2026-06-01 17:42:18 +00:00
- Require captchaToken query param on initial (non-range) download requests
- Range requests (HTTP resume) bypass captcha — they are continuations of an already-validated download
- Add download rate limit policy: 5 requests / 1 min per IP (configured in .env)
- Inject ICaptchaVerifier; action name is file_download

UI change required: execute grecaptcha.execute(siteKey, {action: 'file_download'})
before triggering the download and append ?captchaToken=<token> to the URL.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add download rate limit policy to template and docker-compose
Build and Push Docker Images Staging / build (push) Failing after 1m38s
1bcf95d8d4
5 requests / 1 min per IP. docker-compose.yml wired with ${VAR:-default}.
Staging and production .env files updated locally (gitignored).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
gelu approved these changes 2026-06-01 17:43:04 +00:00
Dismissed
gelu added 5 commits 2026-06-01 20:00:53 +00:00
Serilog.Sinks.Email v4 renamed all configuration parameters from their
v2 names. The old names were silently ignored, so no error alert emails
were ever sent.

Parameter renames applied across all 6 appsettings.json and docker-compose:
  fromEmail → from
  toEmail   → to
  mailServer → host
  networkCredential → credentials
  enableSsl: true → connectionSecurity: StartTls
  emailSubject → subject
  outputTemplate → body
  batchPostingLimit / period removed (v4 batching uses a separate overload)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
HTTP and Playwright fetch failures in HtmlJobSearcher are now logged at
Error so that Serilog's email sink triggers an alert when a job provider
is unreachable. Per-URL match failures remain at Warning (expected noise).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Serilog.Settings.Configuration cannot deserialize NetworkCredential or
MailKit's SecureSocketOptions from JSON, causing an InvalidOperationException
in the binder and preventing containers from starting.

Fix: remove Email from the WriteTo JSON array entirely and wire it in code
inside ConfigureJsonSerilog using a dedicated SerilogEmail:* config section.
The sink is skipped when From/To/Host are absent, so local dev is unaffected.

Also renames the docker-compose env vars from the verbose
Serilog__WriteTo__2__Args__* prefix to the clean SerilogEmail__* prefix.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
email-data references shared-data but the email-api Dockerfile never
copied it into the build context, causing MSB9008 during Docker build.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix email-api middleware order: API key check before swagger
Build and Push Docker Images Staging / build (push) Successful in 17m14s
91b2baa445
UseInternalApiKeyProtection was registered after UseSwaggerInDevelopment,
allowing unauthenticated access to /swagger. Swapped order to match
rag-api and cv-matcher-api.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
gelu approved these changes 2026-06-01 20:03:36 +00:00
claude closed this pull request 2026-06-01 20:09:53 +00:00
Some checks are pending
Build and Push Docker Images Staging / build (push) Successful in 17m14s

Pull request closed

Sign in to join this conversation.
No Reviewers
No Label
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: AI/myAi#40