admin: view order PDFs from MinIO (signed forms, prepared filings, evidence)
Adds a Documents section to the compliance-order detail drawer so you can review the actual filing PDFs before approving an order: GET /api/v1/admin/compliance-orders/:id/documents list viewable objects GET /api/v1/admin/compliance-orders/:id/document?key=&token= stream one Key discovery pulls from esign_records (unsigned + signed docs per order), intake_data.filing_status (pdf_minio_path, attested_pdf, evidence/*), and the order's engagement_letter / rmd_packet columns. Rather than hand out presigned URLs (MinIO's public host is IP-allowlisted to a few office IPs, so links break elsewhere), the API streams the object through itself from internal minio:9000, gated by the admin JWT. The stream endpoint accepts the token via ?token= (new middleware requireAdminQueryOrHeader) so a PDF opens in a new tab, and refuses any key that isn't one of the order's own documents.
This commit is contained in:
parent
d65f5ea279
commit
bce5db4a09
3 changed files with 192 additions and 1 deletions
|
|
@ -39,3 +39,26 @@ export function requireAdmin(req: Request, res: Response, next: NextFunction): v
|
|||
res.status(401).json({ error: "Invalid or expired token." });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify admin JWT from EITHER the Authorization header OR a `?token=` query
|
||||
* param. Needed for endpoints opened directly by the browser (e.g. a PDF in a
|
||||
* new tab / <iframe>), where custom request headers cannot be set. The token is
|
||||
* the same short-lived admin JWT; only use this for read-only document streams.
|
||||
*/
|
||||
export function requireAdminQueryOrHeader(req: Request, res: Response, next: NextFunction): void {
|
||||
const header = req.headers.authorization;
|
||||
const headerTok = header && header.startsWith("Bearer ") ? header.slice(7) : null;
|
||||
const queryTok = typeof req.query.token === "string" ? req.query.token : null;
|
||||
const token = headerTok || queryTok;
|
||||
if (!token) {
|
||||
res.status(401).json({ error: "Authentication required." });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
req.admin = jwt.verify(token, JWT_SECRET) as AdminPayload;
|
||||
next();
|
||||
} catch {
|
||||
res.status(401).json({ error: "Invalid or expired token." });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue