Add input validation for waitUntil and size limits for headerTemplate/footerTemplate
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Has been cancelled
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Has been cancelled
- Add waitUntil validation with allowed values: load, domcontentloaded, networkidle0, networkidle2 - Add size limit validation for headerTemplate and footerTemplate (100KB max) - Follow TDD approach: 15 new failing tests, then implementation - All 462 tests passing (was 447)
This commit is contained in:
parent
646a94dd6a
commit
7d44524ae0
2 changed files with 146 additions and 3 deletions
|
|
@ -2,6 +2,8 @@ const VALID_FORMATS = ["Letter", "Legal", "Tabloid", "Ledger", "A0", "A1", "A2",
|
|||
const FORMAT_MAP = new Map(VALID_FORMATS.map(f => [f.toLowerCase(), f]));
|
||||
const PAGE_RANGES_RE = /^\d+(-\d*)?(\s*,\s*\d+(-\d*)?)*$/;
|
||||
const MARGIN_KEYS = new Set(["top", "right", "bottom", "left"]);
|
||||
const VALID_WAIT_UNTIL = ["load", "domcontentloaded", "networkidle0", "networkidle2"];
|
||||
const MAX_TEMPLATE_SIZE = 102400; // 100KB in characters
|
||||
|
||||
type PdfInput = Record<string, any>;
|
||||
type ValidResult = { valid: true; sanitized: Record<string, any> };
|
||||
|
|
@ -79,9 +81,37 @@ export function validatePdfOptions(opts: PdfInput): ValidResult | InvalidResult
|
|||
sanitized.pageRanges = opts.pageRanges;
|
||||
}
|
||||
|
||||
// Pass through non-validated fields
|
||||
for (const key of ["headerTemplate", "footerTemplate"]) {
|
||||
if (opts[key] !== undefined) sanitized[key] = opts[key];
|
||||
// waitUntil
|
||||
if (opts.waitUntil !== undefined) {
|
||||
if (typeof opts.waitUntil !== "string") {
|
||||
return { valid: false, error: "waitUntil must be a string" };
|
||||
}
|
||||
if (!VALID_WAIT_UNTIL.includes(opts.waitUntil)) {
|
||||
return { valid: false, error: `waitUntil must be one of: ${VALID_WAIT_UNTIL.join(", ")}` };
|
||||
}
|
||||
sanitized.waitUntil = opts.waitUntil;
|
||||
}
|
||||
|
||||
// headerTemplate
|
||||
if (opts.headerTemplate !== undefined) {
|
||||
if (typeof opts.headerTemplate !== "string") {
|
||||
return { valid: false, error: "headerTemplate must be a string" };
|
||||
}
|
||||
if (opts.headerTemplate.length > MAX_TEMPLATE_SIZE) {
|
||||
return { valid: false, error: "headerTemplate must not exceed 100KB" };
|
||||
}
|
||||
sanitized.headerTemplate = opts.headerTemplate;
|
||||
}
|
||||
|
||||
// footerTemplate
|
||||
if (opts.footerTemplate !== undefined) {
|
||||
if (typeof opts.footerTemplate !== "string") {
|
||||
return { valid: false, error: "footerTemplate must be a string" };
|
||||
}
|
||||
if (opts.footerTemplate.length > MAX_TEMPLATE_SIZE) {
|
||||
return { valid: false, error: "footerTemplate must not exceed 100KB" };
|
||||
}
|
||||
sanitized.footerTemplate = opts.footerTemplate;
|
||||
}
|
||||
|
||||
return { valid: true, sanitized };
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue