Skip to content

fix(resume): Scope resume download to the caller's troop - #1249

Open
jeromehardaway wants to merge 3 commits into
masterfrom
fix/resume-download-ownership
Open

fix(resume): Scope resume download to the caller's troop#1249
jeromehardaway wants to merge 3 commits into
masterfrom
fix/resume-download-ownership

Conversation

@jeromehardaway

Copy link
Copy Markdown
Contributor

Problem

GET /api/j0di3/jobs/resume/download/[sessionId] authenticated the caller but proxied to J0dI3 with only the app-level X-API-Key — it never scoped the request to the caller's troop. J0dI3 had no way to know who was asking, so any authenticated user could download another user's resume by guessing/enumerating a sessionId.

Fix

Forward the caller's troop context — troop_id (query param) and X-Troop-Token (header) — exactly as every other resume endpoint (upload, upload-and-score) and the shared j0di3-proxy already do. J0dI3, which owns the session→troop mapping, then enforces that the session belongs to the requesting troop. Callers with no linked troop are rejected (400) before any download.

Boundary note

The app keeps no local session→troop record, so the definitive 403 for a cross-user sessionId is enforced by J0dI3 given the troop scoping this PR adds. Worth confirming J0dI3 rejects a mismatched troop_id/session — if it doesn't, that's a J0dI3-side follow-up.

Verification

New tests (__tests__/pages/api/j0di3/resume-download.test.ts, 3 passing): the request is troop-scoped (troop_id + X-Troop-Token forwarded); a caller with no troop is 400'd before any J0dI3 call; a J0dI3 403 is propagated to the client. npm run typecheck — pass.

Closes #1198

The download proxied to J0dI3 with only the app API key, so any authenticated user could

download another user's resume by guessing a sessionId. It now forwards the caller's troop_id

and X-Troop-Token (like the other resume endpoints) so J0dI3 enforces session ownership, and

rejects callers with no linked troop before any download.
@vercel

vercel Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
vets-who-code-app Ready Ready Preview, Comment Jul 28, 2026 12:15am

Request Review

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR closes a security gap in the J0dI3 resume download proxy by scoping the upstream download request to the authenticated caller’s troop context, preventing cross-user resume downloads via guessed/enumerated sessionIds.

Changes:

  • Forward troop_id (query param) and X-Troop-Token (header) to J0dI3 for /jobs/resume/download/:sessionId.
  • Return 400 early when the caller lacks required troop context, and propagate upstream authorization statuses (e.g., 403) instead of masking them.
  • Add Vitest coverage to ensure troop scoping is forwarded, missing-troop callers are rejected pre-upstream, and J0dI3 403 is propagated.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/pages/api/j0di3/jobs/resume/download/[sessionId].ts Adds troop scoping (troop_id + X-Troop-Token) to the resume download request and preserves upstream auth status codes.
__tests__/pages/api/j0di3/resume-download.test.ts Adds tests validating troop scoping, early 400 behavior, and upstream 403 propagation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/pages/api/j0di3/jobs/resume/download/[sessionId].ts
Comment thread __tests__/pages/api/j0di3/resume-download.test.ts Outdated
jeromehardaway and others added 2 commits July 27, 2026 20:12
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

accounts: Fix resume download session ownership check

2 participants