UNPKG

html2canvas-pro

Version:

Screenshots with JavaScript. Next generation!

296 lines 15.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const assert_1 = require("assert"); const validator_1 = require("../validator"); describe('Validator', () => { describe('URL validation', () => { const validator = (0, validator_1.createDefaultValidator)(); it('should accept valid HTTP URLs', () => { const result = validator.validateUrl('http://example.com/test.jpg', 'image'); (0, assert_1.strictEqual)(result.valid, true); }); it('should accept valid HTTPS URLs', () => { const result = validator.validateUrl('https://example.com/test.jpg', 'image'); (0, assert_1.strictEqual)(result.valid, true); }); it('should accept data URLs by default', () => { const result = validator.validateUrl('data:image/png;base64,iVBORw0KGgo=', 'image'); (0, assert_1.strictEqual)(result.valid, true); }); it('should accept blob URLs', () => { const result = validator.validateUrl('blob:http://example.com/uuid', 'image'); (0, assert_1.strictEqual)(result.valid, true); }); it('should reject invalid protocols', () => { const result = validator.validateUrl('ftp://example.com/test.jpg', 'image'); (0, assert_1.strictEqual)(result.valid, false); (0, assert_1.strictEqual)(result.error?.includes('Protocol'), true); }); it('should reject file:// URLs', () => { const result = validator.validateUrl('file:///etc/passwd', 'image'); (0, assert_1.strictEqual)(result.valid, false); }); it('should reject javascript: URLs', () => { const result = validator.validateUrl('javascript:alert(1)', 'general'); (0, assert_1.strictEqual)(result.valid, false); }); it('should reject empty URLs', () => { const result = validator.validateUrl('', 'image'); (0, assert_1.strictEqual)(result.valid, false); }); it('should reject non-string URLs', () => { const result = validator.validateUrl(null, 'image'); (0, assert_1.strictEqual)(result.valid, false); }); it('should reject malformed URLs', () => { const result = validator.validateUrl('not a url', 'image'); (0, assert_1.strictEqual)(result.valid, false); (0, assert_1.strictEqual)(result.error?.includes('Invalid URL'), true); }); }); describe('Proxy URL validation (SSRF prevention)', () => { it('should reject localhost for proxy URLs', () => { const validator = (0, validator_1.createDefaultValidator)(); const result = validator.validateUrl('http://localhost:8080/proxy', 'proxy'); (0, assert_1.strictEqual)(result.valid, false); (0, assert_1.strictEqual)(result.error?.includes('Localhost'), true); }); it('should reject 127.0.0.1 for proxy URLs', () => { const validator = (0, validator_1.createDefaultValidator)(); const result = validator.validateUrl('http://127.0.0.1/proxy', 'proxy'); (0, assert_1.strictEqual)(result.valid, false); }); it('should reject ::1 for proxy URLs', () => { const validator = (0, validator_1.createDefaultValidator)(); const result = validator.validateUrl('http://[::1]/proxy', 'proxy'); (0, assert_1.strictEqual)(result.valid, false); }); it('should reject private IP ranges (10.x.x.x)', () => { const validator = (0, validator_1.createDefaultValidator)(); const result = validator.validateUrl('http://10.0.0.1/proxy', 'proxy'); (0, assert_1.strictEqual)(result.valid, false); (0, assert_1.strictEqual)(result.error?.includes('Private IP'), true); }); it('should reject private IP ranges (172.16-31.x.x)', () => { const validator = (0, validator_1.createDefaultValidator)(); const results = [ validator.validateUrl('http://172.16.0.1/proxy', 'proxy'), validator.validateUrl('http://172.20.0.1/proxy', 'proxy'), validator.validateUrl('http://172.31.255.254/proxy', 'proxy') ]; results.forEach((result) => (0, assert_1.strictEqual)(result.valid, false)); }); it('should reject private IP ranges (192.168.x.x)', () => { const validator = (0, validator_1.createDefaultValidator)(); const result = validator.validateUrl('http://192.168.1.1/proxy', 'proxy'); (0, assert_1.strictEqual)(result.valid, false); }); it('should reject link-local addresses', () => { const validator = (0, validator_1.createDefaultValidator)(); const result = validator.validateUrl('http://169.254.1.1/proxy', 'proxy'); (0, assert_1.strictEqual)(result.valid, false); }); it('should accept public IPs for proxy URLs', () => { const validator = (0, validator_1.createDefaultValidator)(); const result = validator.validateUrl('https://8.8.8.8/proxy', 'proxy'); (0, assert_1.strictEqual)(result.valid, true); }); it('should enforce proxy domain whitelist', () => { const validator = (0, validator_1.createStrictValidator)(['example.com', 'trusted.org']); const allowed = validator.validateUrl('https://example.com/proxy', 'proxy'); (0, assert_1.strictEqual)(allowed.valid, true); const notAllowed = validator.validateUrl('https://evil.com/proxy', 'proxy'); (0, assert_1.strictEqual)(notAllowed.valid, false); (0, assert_1.strictEqual)(notAllowed.error?.includes('not in the allowed list'), true); }); it('should allow subdomains of whitelisted domains', () => { const validator = (0, validator_1.createStrictValidator)(['example.com']); const result = validator.validateUrl('https://api.example.com/proxy', 'proxy'); (0, assert_1.strictEqual)(result.valid, true); }); }); describe('CSP nonce validation', () => { const validator = (0, validator_1.createDefaultValidator)(); it('should accept valid nonce', () => { const result = validator.validateCspNonce('ABC123def456GHI789jkl'); (0, assert_1.strictEqual)(result.valid, true); }); it('should reject empty nonce', () => { const result = validator.validateCspNonce(''); (0, assert_1.strictEqual)(result.valid, false); }); it('should reject non-string nonce', () => { const result = validator.validateCspNonce(123); (0, assert_1.strictEqual)(result.valid, false); }); it('should reject too short nonce', () => { const result = validator.validateCspNonce('short'); (0, assert_1.strictEqual)(result.valid, false); (0, assert_1.strictEqual)(result.error?.includes('too short'), true); }); it('should reject nonce with invalid characters', () => { const result = validator.validateCspNonce('ABC<script>alert(1)</script>'); (0, assert_1.strictEqual)(result.valid, false); (0, assert_1.strictEqual)(result.error?.includes('invalid characters'), true); }); it('should accept base64-like nonces', () => { const result = validator.validateCspNonce('AbCdEfGhIjKlMnOpQrStUvWxYz0123456789+/='); (0, assert_1.strictEqual)(result.valid, true); }); }); describe('Image timeout validation', () => { const validator = (0, validator_1.createDefaultValidator)(); it('should accept valid timeout', () => { const result = validator.validateImageTimeout(15000); (0, assert_1.strictEqual)(result.valid, true); }); it('should reject negative timeout', () => { const result = validator.validateImageTimeout(-1000); (0, assert_1.strictEqual)(result.valid, false); }); it('should reject non-number timeout', () => { const result = validator.validateImageTimeout('15000'); (0, assert_1.strictEqual)(result.valid, false); }); it('should reject NaN timeout', () => { const result = validator.validateImageTimeout(NaN); (0, assert_1.strictEqual)(result.valid, false); }); it('should enforce maximum timeout', () => { const strictValidator = (0, validator_1.createStrictValidator)([]); const result = strictValidator.validateImageTimeout(120000); // 2 minutes (0, assert_1.strictEqual)(result.valid, false); (0, assert_1.strictEqual)(result.error?.includes('exceeds maximum'), true); }); it('should accept timeout within limit', () => { const strictValidator = (0, validator_1.createStrictValidator)([]); const result = strictValidator.validateImageTimeout(30000); // 30 seconds (0, assert_1.strictEqual)(result.valid, true); }); }); describe('Dimensions validation', () => { const validator = (0, validator_1.createDefaultValidator)(); it('should accept valid dimensions', () => { const result = validator.validateDimensions(800, 600); (0, assert_1.strictEqual)(result.valid, true); }); it('should reject zero dimensions', () => { const result = validator.validateDimensions(0, 600); (0, assert_1.strictEqual)(result.valid, false); }); it('should reject negative dimensions', () => { const result = validator.validateDimensions(800, -100); (0, assert_1.strictEqual)(result.valid, false); }); it('should reject NaN dimensions', () => { const result = validator.validateDimensions(NaN, 600); (0, assert_1.strictEqual)(result.valid, false); }); it('should reject non-number dimensions', () => { const result = validator.validateDimensions('800', 600); (0, assert_1.strictEqual)(result.valid, false); }); it('should reject dimensions exceeding maximum', () => { const result = validator.validateDimensions(40000, 600); (0, assert_1.strictEqual)(result.valid, false); (0, assert_1.strictEqual)(result.error?.includes('exceed maximum'), true); }); it('should accept dimensions at the limit', () => { const result = validator.validateDimensions(32767, 32767); (0, assert_1.strictEqual)(result.valid, true); }); }); describe('Scale validation', () => { const validator = (0, validator_1.createDefaultValidator)(); it('should accept valid scale', () => { const result = validator.validateScale(2); (0, assert_1.strictEqual)(result.valid, true); }); it('should accept fractional scale', () => { const result = validator.validateScale(0.5); (0, assert_1.strictEqual)(result.valid, true); }); it('should reject zero scale', () => { const result = validator.validateScale(0); (0, assert_1.strictEqual)(result.valid, false); }); it('should reject negative scale', () => { const result = validator.validateScale(-2); (0, assert_1.strictEqual)(result.valid, false); }); it('should reject too large scale', () => { const result = validator.validateScale(20); (0, assert_1.strictEqual)(result.valid, false); (0, assert_1.strictEqual)(result.error?.includes('too large'), true); }); it('should reject NaN scale', () => { const result = validator.validateScale(NaN); (0, assert_1.strictEqual)(result.valid, false); }); }); describe('Element validation', () => { const validator = (0, validator_1.createDefaultValidator)(); it('should reject null element', () => { const result = validator.validateElement(null); (0, assert_1.strictEqual)(result.valid, false); }); it('should reject undefined element', () => { const result = validator.validateElement(undefined); (0, assert_1.strictEqual)(result.valid, false); }); it('should reject non-object element', () => { const result = validator.validateElement('not an element'); (0, assert_1.strictEqual)(result.valid, false); }); // Note: Full HTMLElement testing requires DOM environment (jsdom/browser) }); describe('Options validation', () => { const validator = (0, validator_1.createDefaultValidator)(); it('should accept valid options', () => { const options = { scale: 2, width: 800, height: 600, imageTimeout: 15000 }; const result = validator.validateOptions(options); (0, assert_1.strictEqual)(result.valid, true); }); it('should collect multiple errors', () => { const options = { scale: -1, width: -800, imageTimeout: -5000 }; const result = validator.validateOptions(options); (0, assert_1.strictEqual)(result.valid, false); // Should contain multiple error messages (0, assert_1.strictEqual)(result.error?.includes('Scale'), true); (0, assert_1.strictEqual)(result.error?.includes('Dimensions'), true); (0, assert_1.strictEqual)(result.error?.includes('timeout'), true); }); it('should allow missing optional fields', () => { const options = {}; const result = validator.validateOptions(options); (0, assert_1.strictEqual)(result.valid, true); }); }); describe('Strict validator', () => { const strictValidator = (0, validator_1.createStrictValidator)(['trusted.com']); it('should reject data URLs in strict mode', () => { // Note: This would need implementation in createStrictValidator // Currently it doesn't disable data URLs }); it('should enforce shorter timeout in strict mode', () => { const result = strictValidator.validateImageTimeout(120000); (0, assert_1.strictEqual)(result.valid, false); }); it('should enforce proxy whitelist in strict mode', () => { const allowed = strictValidator.validateUrl('https://trusted.com/proxy', 'proxy'); (0, assert_1.strictEqual)(allowed.valid, true); const denied = strictValidator.validateUrl('https://untrusted.com/proxy', 'proxy'); (0, assert_1.strictEqual)(denied.valid, false); }); }); }); //# sourceMappingURL=validator.js.map