| 07-audit-trail-and-download |
01 |
api |
| jwt |
| jose |
| pdf |
| download |
| security |
| next.js |
|
| phase |
provides |
| 06-signing-flow |
token.ts with createDownloadToken/verifyDownloadToken pattern and SIGNING_JWT_SECRET |
|
| phase |
provides |
| 04-pdf-ingest |
uploads/ directory and path traversal guard pattern |
|
|
| createAgentDownloadToken (purpose:'agent-download', 5-min TTL) in src/lib/signing/token.ts |
| verifyAgentDownloadToken in src/lib/signing/token.ts |
| GET /api/documents/[id]/download?adt=[token] — agent-authenticated signed PDF streaming |
|
| 07-02 (audit trail plan will likely link download events to this route) |
| document detail page (will need createAgentDownloadToken server-side to generate adt links) |
|
| added |
patterns |
|
|
| Agent download token — purpose:'agent-download', 5-min TTL, no DB record (mirrors client download pattern) |
| Route-level document ID cross-check — token documentId must match route [id] param (403 on mismatch) |
| Path traversal guard |
| absPath.startsWith(UPLOADS_DIR) before every readFile from uploads/ |
|
| new Uint8Array(fileBuffer) for Response BodyInit compatibility in Next.js 16 TypeScript strict mode |
|
|
| created |
modified |
| teressa-copeland-homes/src/app/api/documents/[id]/download/route.ts |
|
| teressa-copeland-homes/src/lib/signing/token.ts |
|
|
| Agent download token uses same SIGNING_JWT_SECRET as other tokens, purpose:'agent-download' claim distinguishes it |
| 5-min TTL for agent-download (shorter than 15-min client download) — agent generates token on demand per LEGAL-03 |
| No Auth.js session check in download route — short-lived JWT is the credential (same as client download pattern) |
| Token documentId vs route [id] cross-check added as defense-in-depth against token reuse across documents |
|
| Agent download token pattern: createAgentDownloadToken server-side → adt query param → GET /api/documents/[id]/download |
| Path traversal guard: always check absPath.startsWith(UPLOADS_DIR) before readFile, no exceptions |
|
|
2min |
2026-03-21 |