const assert = require('node:assert/strict'); const fs = require('node:fs'); const path = require('node:path'); const test = require('node:test'); const root = path.join(__dirname, '..'); test('admin HTML escape helper also escapes single quotes for attribute contexts', () => { const source = fs.readFileSync(path.join(root, 'public', 'js', 'admin.js'), 'utf8'); assert.match(source, /function adminEscapeHtml\(str\)[\s\S]+replace\(\/\'\/g, '''\)/); }); test('billing E/M suggestion fields are escaped before innerHTML insertion', () => { const source = fs.readFileSync(path.join(root, 'public', 'js', 'app.js'), 'utf8'); assert.match(source, /Level ' \+ escHtml\(data\.emLevel\.level\)/); assert.match(source, /MDM: ' \+ escHtml\(data\.emLevel\.complexity\)/); assert.match(source, /escHtml\(data\.emLevel\.diagnosisCount\)/); assert.match(source, /escHtml\(data\.emLevel\.rosCount\)/); assert.match(source, /escHtml\(data\.emLevel\.peCount\)/); }); test('the announcement banner formats without becoming an injection point', () => { const fs = require('node:fs'); const path = require('node:path'); const app = fs.readFileSync(path.join(__dirname, '..', 'public/js/app.js'), 'utf8'); const fn = app.slice(app.indexOf('function renderAnnouncement(el, raw)'), app.indexOf('function loadAnnouncement()')); // Inline only: this text sits on every page, so it must not be able to // introduce headings, images or block layout that shifts the app around. assert.match(fn, /window\.marked\.parseInline\(markdown, \{ gfm: true \}\)/); assert.match(fn, /ALLOWED_TAGS: \['strong', 'em', 'b', 'i', 'u', 's', 'code', 'a', 'br'\]/); assert.doesNotMatch(fn, /'img'|'script'|'iframe'|'h1'|'h2'/); assert.match(fn, /FORBID_ATTR: \['style', 'onerror', 'onload', 'onclick', 'onmouseover'\]/); assert.match(fn, /ALLOW_DATA_ATTR: false/); // Sanitising is not optional: without either library, or on any failure, the // text is shown literally rather than as markup. assert.match(fn, /if \(!window\.marked \|\| typeof window\.marked\.parseInline !== 'function' \|\|\s*\n\s*!window\.DOMPurify \|\| typeof window\.DOMPurify\.sanitize !== 'function'\) \{\s*\n\s*el\.textContent = markdown;/); assert.match(fn, /catch \(e\) \{\s*\n\s*el\.textContent = markdown;/); // innerHTML is only ever reached through sanitize(). const assignments = fn.match(/\.innerHTML\s*=/g) || []; assert.equal(assignments.length, 1, 'one innerHTML assignment'); assert.match(fn, /el\.innerHTML = window\.DOMPurify\.sanitize\(/); });