@secureport/core 2.1.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/index.d.ts +9 -3
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +4 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/issue.d.ts +1 -1
  6. package/dist/issue.d.ts.map +1 -1
  7. package/dist/reconcile.d.ts +46 -1
  8. package/dist/reconcile.d.ts.map +1 -1
  9. package/dist/reconcile.js +34 -1
  10. package/dist/reconcile.js.map +1 -1
  11. package/dist/report/anchors.d.ts +39 -0
  12. package/dist/report/anchors.d.ts.map +1 -0
  13. package/dist/report/anchors.js +73 -0
  14. package/dist/report/anchors.js.map +1 -0
  15. package/dist/report/csv.d.ts +41 -0
  16. package/dist/report/csv.d.ts.map +1 -0
  17. package/dist/report/csv.js +152 -0
  18. package/dist/report/csv.js.map +1 -0
  19. package/dist/report/html.d.ts.map +1 -1
  20. package/dist/report/html.js +126 -22
  21. package/dist/report/html.js.map +1 -1
  22. package/dist/report/json.d.ts +15 -0
  23. package/dist/report/json.d.ts.map +1 -1
  24. package/dist/report/json.js +1 -0
  25. package/dist/report/json.js.map +1 -1
  26. package/dist/report/markdown.d.ts +24 -2
  27. package/dist/report/markdown.d.ts.map +1 -1
  28. package/dist/report/markdown.js +133 -31
  29. package/dist/report/markdown.js.map +1 -1
  30. package/dist/report/model.d.ts +288 -2
  31. package/dist/report/model.d.ts.map +1 -1
  32. package/dist/report/model.js +153 -21
  33. package/dist/report/model.js.map +1 -1
  34. package/dist/report/sarif.d.ts +60 -0
  35. package/dist/report/sarif.d.ts.map +1 -0
  36. package/dist/report/sarif.js +125 -0
  37. package/dist/report/sarif.js.map +1 -0
  38. package/dist/report/stream.d.ts +108 -0
  39. package/dist/report/stream.d.ts.map +1 -0
  40. package/dist/report/stream.js +534 -0
  41. package/dist/report/stream.js.map +1 -0
  42. package/package.json +4 -2
  43. package/src/index.ts +11 -2
  44. package/src/issue.ts +1 -0
  45. package/src/reconcile.ts +86 -2
  46. package/src/report/anchors.ts +96 -0
  47. package/src/report/csv.ts +180 -0
  48. package/src/report/html.ts +146 -26
  49. package/src/report/json.ts +17 -0
  50. package/src/report/markdown.ts +146 -30
  51. package/src/report/model.ts +433 -21
  52. package/src/report/sarif.ts +166 -0
  53. package/src/report/stream.ts +702 -0
@@ -1,5 +1,6 @@
1
+ import { anchorHtmlHeadings } from './anchors.js';
1
2
  import { SEVERITY_ORDER } from '../severity.js';
2
- import { buildReportModel, } from './model.js';
3
+ import { buildReportModel, VERDICT_LABELS, } from './model.js';
3
4
  import { formatDate } from './markdown.js';
4
5
  /** Escapes text for HTML. Every value from a snapshot goes through this. */
5
6
  function esc(value) {
@@ -53,6 +54,30 @@ td code, code { font: .88em ui-monospace, SFMono-Regular, Menlo, monospace; word
53
54
  .breached { color: var(--critical); font-weight: 600; }
54
55
  .issue { break-inside: avoid; page-break-inside: avoid; margin-bottom: 1.5rem; }
55
56
  .none { color: var(--muted); font-style: italic; }
57
+ .evidence { color: var(--muted); font-size: .92em; margin: 0 0 1rem; }
58
+ /* Fixed rather than absolute: Chromium repeats a fixed element on every page
59
+ of a PDF, which is the only way one element can mark a whole document. */
60
+ .toc { margin: 2rem 0; }
61
+ .toc h2 { margin-top: 0; }
62
+ .toc ul { list-style: none; padding: 0; margin: 0; }
63
+ .toc li { margin: .2rem 0; }
64
+ .toc-3 { padding-left: 1.25rem; font-size: .94em; }
65
+ .toc a { color: inherit; text-decoration: none; border-bottom: 1px solid var(--rule); }
66
+ .cover {
67
+ min-height: 88vh; display: flex; flex-direction: column; justify-content: center;
68
+ break-after: page; page-break-after: always;
69
+ }
70
+ .cover img { max-height: 5rem; max-width: 18rem; margin-bottom: 2.5rem; }
71
+ .cover h1 { font-size: 2.6rem; margin: 0 0 .5rem; }
72
+ .cover .for { font-size: 1.15rem; margin: 0 0 3rem; }
73
+ .cover .details { color: var(--muted); font-size: .92em; }
74
+ .cover .details div { margin: .15rem 0; }
75
+ .watermark {
76
+ position: fixed; inset: 0; z-index: -1; pointer-events: none;
77
+ display: flex; align-items: center; justify-content: center;
78
+ font: 700 5.5rem/1 ui-serif, Georgia, serif; letter-spacing: .08em;
79
+ color: rgba(20, 24, 31, .07); transform: rotate(-28deg); text-transform: uppercase;
80
+ }
56
81
  footer { margin-top: 3rem; padding-top: .75rem; border-top: 1px solid var(--rule); color: var(--muted); font-size: .85em; }
57
82
 
58
83
  @media print {
@@ -82,8 +107,46 @@ function changeSummary(model) {
82
107
  ? ` <span class="breached">${model.breached} past ${model.breached === 1 ? 'its' : 'their'} remediation deadline.</span>`
83
108
  : ''}</p>`;
84
109
  }
110
+ /**
111
+ * One supporting finding, in a sentence.
112
+ *
113
+ * Every field here is something that was *found*. Nothing identifies what
114
+ * found it — the engine name has leaked into rendered output twice.
115
+ */
116
+ function evidenceLine(finding) {
117
+ const where = finding.parameter === undefined
118
+ ? `<code>${esc(finding.location)}</code>`
119
+ : `<code>${esc(finding.location)}</code> (<code>${esc(finding.parameter)}</code>)`;
120
+ const detail = [`${finding.detectedSeverity}, seen ${formatDate(finding.createdAt)}`];
121
+ if (finding.cve !== undefined)
122
+ detail.push(esc(finding.cve));
123
+ if (finding.cvssScore !== undefined) {
124
+ detail.push(finding.cvssVector === undefined
125
+ ? `CVSS ${String(finding.cvssScore)}`
126
+ : `CVSS ${String(finding.cvssScore)} <code>${esc(finding.cvssVector)}</code>`);
127
+ }
128
+ if (finding.confidence !== undefined) {
129
+ detail.push(`confidence ${String(Math.round(finding.confidence * 100))}%`);
130
+ }
131
+ const captures = finding.evidenceUri ?? [];
132
+ if (captures.length > 0) {
133
+ detail.push(`${String(captures.length)} capture${captures.length === 1 ? '' : 's'} stored`);
134
+ }
135
+ return `${where} — ${detail.join('; ')}`;
136
+ }
137
+ /** The count, the detail, or nothing — never the engine. */
138
+ function evidenceBlock(entry, verbosity) {
139
+ if (entry.findings.length === 0 || verbosity === 'none')
140
+ return '';
141
+ if (verbosity === 'summary') {
142
+ return `<p class="lede">Evidence: ${entry.findings.length} finding${entry.findings.length === 1 ? '' : 's'} recorded.</p>`;
143
+ }
144
+ return `<p class="lede">Evidence</p><ul class="evidence">${entry.findings
145
+ .map((f) => `<li>${evidenceLine(f)}</li>`)
146
+ .join('')}</ul>`;
147
+ }
85
148
  /** One issue in full. */
86
- function issueDetail(entry) {
149
+ function issueDetail(entry, verbosity) {
87
150
  const { issue } = entry;
88
151
  const first = entry.findings[0];
89
152
  const references = [...new Set(entry.findings.flatMap((f) => f.references ?? []))];
@@ -103,22 +166,12 @@ ${issue.cwe === undefined ? '' : `<tr><td>Weakness</td><td>${esc(issue.cwe)}</td
103
166
  </tbody></table>
104
167
  ${first?.description === undefined ? '' : `<p>${esc(first.description)}</p>`}
105
168
  ${first?.recommendation === undefined ? '' : `<p><strong>Recommendation.</strong> ${esc(first.recommendation)}</p>`}
106
- ${entry.findings.length === 0
107
- ? ''
108
- : `<p class="lede">Evidence: ${entry.findings.length} finding${entry.findings.length === 1 ? '' : 's'} recorded.</p>`}
169
+ ${evidenceBlock(entry, verbosity)}
109
170
  ${references.length === 0
110
171
  ? ''
111
172
  : `<ul class="refs">${references.map((r) => `<li><a href="${esc(r)}">${esc(r)}</a></li>`).join('')}</ul>`}
112
173
  </div>`;
113
174
  }
114
- /** How a verdict is printed. The dashes are an implementation detail. */
115
- const VERDICT_LABELS = Object.freeze({
116
- fixed: 'fixed',
117
- still_present: 'still present',
118
- returned: 'returned',
119
- not_retested: 'not retested',
120
- new: 'new since',
121
- });
122
175
  /** The Retest body: the difference between two runs, and nothing else. */
123
176
  function retestBody(model) {
124
177
  // `buildReportModel` refuses to build a retest without one.
@@ -200,7 +253,7 @@ function attestationBody(model) {
200
253
  const found = snapshot.issues.length + snapshot.suppressed.length;
201
254
  const rows = SEVERITY_ORDER.map((sev) => `<tr><td class="${sevClass(sev)}">${sev}</td><td>${model.outstanding[sev]}</td></tr>`).join('');
202
255
  return `<h2>Statement</h2>
203
- <p>${esc(model.preparedBy ?? 'Secureport')} carried out security testing of <strong>${esc(snapshot.target.name)}</strong> (${esc(snapshot.target.url)}) on ${formatDate(snapshot.run.createdAt)}.</p>
256
+ <p>${esc(model.attestor)} carried out security testing of <strong>${esc(snapshot.target.name)}</strong> (${esc(snapshot.target.url)}) on ${formatDate(snapshot.run.createdAt)}.</p>
204
257
  <p>${esc(model.basis.statement)}</p>
205
258
  <p>The testing identified ${found} issue${found === 1 ? '' : 's'} in total, of which ${model.outstandingTotal} ${model.outstandingTotal === 1 ? 'remains' : 'remain'} outstanding at the date of this letter:</p>
206
259
  <table><thead><tr><th>Severity</th><th>Outstanding</th></tr></thead><tbody>${rows}</tbody></table>
@@ -263,14 +316,20 @@ ${changeSummary(model)}`;
263
316
  findings = attestationBody(model);
264
317
  }
265
318
  else if (model.sections.length === 0) {
266
- findings = '<h2>Findings</h2><p class="none">No issues were found.</p>';
319
+ // "No issues were found" is false when a floor is what emptied the
320
+ // section, and it is the most dangerous sentence in the document to get
321
+ // wrong — a reader would take it as a clean result.
322
+ findings =
323
+ model.omitted === undefined
324
+ ? '<h2>Findings</h2><p class="none">No issues were found.</p>'
325
+ : '<h2>Findings</h2><p class="none">No issues at or above the reporting threshold were found.</p>';
267
326
  }
268
327
  else if (model.kind === 'pen') {
269
328
  findings =
270
329
  '<h2>Findings</h2>' +
271
330
  model.sections
272
331
  .map((section) => `<h3 class="${sevClass(section.severity)}">${section.severity} (${section.issues.length})</h3>` +
273
- section.issues.map(issueDetail).join(''))
332
+ section.issues.map((e) => issueDetail(e, model.evidenceVerbosity)).join(''))
274
333
  .join('');
275
334
  }
276
335
  else {
@@ -284,6 +343,14 @@ ${changeSummary(model)}`;
284
343
  .join('');
285
344
  findings = `<h2>Findings</h2><table><thead><tr><th>Issue</th><th>Severity</th><th>Location</th><th>Change</th><th>Days open</th><th>Remediation</th></tr></thead><tbody>${rows}</tbody></table>`;
286
345
  }
346
+ // Beside the section it is about, rather than left to the limitations list,
347
+ // which only the Attestation Letter renders (B109). The Executive Summary
348
+ // and the Attestation have no findings section to attach it to, and both
349
+ // already print counts rather than issues, so neither is misled by its
350
+ // absence.
351
+ if (model.omitted !== undefined && model.kind !== 'exec' && model.kind !== 'attest') {
352
+ findings += `<p class="lede">${esc(model.omitted.statement)}</p>`;
353
+ }
287
354
  const resolved = model.kind === 'exec' ||
288
355
  model.kind === 'attest' ||
289
356
  model.kind === 'retest' ||
@@ -301,23 +368,60 @@ ${changeSummary(model)}`;
301
368
  <table><thead><tr><th>Issue</th><th>Severity when suppressed</th><th>Reason</th><th>By</th><th>Expires</th><th>Justification</th></tr></thead><tbody>${snapshot.suppressed
302
369
  .map((s) => `<tr><td>${esc(s.issue.title)}</td><td class="${sevClass(s.severityAtIgnore)}">${s.severityAtIgnore}</td><td>${s.reason.replace('_', ' ')}</td><td>${esc(s.ignoredBy)}</td><td>${s.expiresAt === undefined ? 'never' : formatDate(s.expiresAt)}</td><td>${esc(s.comment)}</td></tr>`)
303
370
  .join('')}</tbody></table>`;
371
+ // Appended rather than interpolated into STYLES, so the base stylesheet is
372
+ // one constant that every report shares and the brand is visibly an
373
+ // override. `primaryColour` is refused unless it is a hex triplet
374
+ // (`buildReportModel`), which is what makes this safe to put in a <style>
375
+ // element at all — `esc` protects text nodes, not CSS.
376
+ const accent = model.branding?.primaryColour;
377
+ const brandStyles = accent === undefined
378
+ ? ''
379
+ : `\n:root { --accent: ${accent}; }\nh1 { color: var(--accent); }\nh2 { border-bottom-color: var(--accent); }`;
380
+ const brand = model.branding;
381
+ const cover = !model.coverPage
382
+ ? ''
383
+ : `<section class="cover">
384
+ ${brand?.logo === undefined ? '' : `<img src="${esc(brand.logo)}" alt="${esc(model.attestor)}">`}
385
+ <h1>${esc(model.title)}</h1>
386
+ <p class="for"><strong>${esc(target.name)}</strong> — ${esc(target.url)}</p>
387
+ <div class="details">
388
+ <div>${esc(model.attestor)}</div>
389
+ ${(brand?.companyDetails ?? []).map((line) => `<div>${esc(line)}</div>`).join('\n')}
390
+ <div>${formatDate(model.generatedAt)}</div>
391
+ ${model.preparedFor === undefined ? '' : `<div>Prepared for ${esc(model.preparedFor)}</div>`}
392
+ </div>
393
+ </section>`;
394
+ const watermark = model.branding?.watermark === undefined
395
+ ? ''
396
+ : `<div class="watermark" aria-hidden="true">${esc(model.branding.watermark)}</div>`;
397
+ // One scan produces both, so an entry cannot point at an anchor that does
398
+ // not exist. Always run, even when no list is printed: the anchors are what
399
+ // Chromium turns into a PDF outline.
400
+ const body = anchorHtmlHeadings([preamble, findings, resolved, suppressed].join('\n'));
401
+ const contents = !model.tableOfContents
402
+ ? ''
403
+ : `<nav class="toc"><h2>Contents</h2><ul>${body.toc
404
+ .map((entry) => `<li class="toc-${String(entry.level)}"><a href="#${entry.id}">${entry.text}</a></li>`)
405
+ .join('')}</ul></nav>`;
304
406
  return `<!doctype html>
305
407
  <html lang="en">
306
408
  <head>
307
409
  <meta charset="utf-8">
308
410
  <meta name="viewport" content="width=device-width, initial-scale=1">
309
411
  <title>${esc(model.title)} — ${esc(target.name)}</title>
310
- <style>${STYLES}</style>
412
+ <style>${STYLES}${brandStyles}</style>
311
413
  </head>
312
414
  <body>
415
+ ${watermark}
416
+ ${cover}
313
417
  <h1>${esc(model.title)}</h1>
314
418
  <p class="lede"><strong>${esc(target.name)}</strong> — ${esc(target.url)}</p>
315
419
  <table class="meta"><tbody>${meta}</tbody></table>
316
- ${preamble}
317
- ${findings}
318
- ${resolved}
319
- ${suppressed}
320
- <footer>Generated by Secureport from run ${esc(snapshot.run.runId)}. Issue state as of ${formatDate(snapshot.run.createdAt)}.</footer>
420
+ ${contents}
421
+ ${body.html}
422
+ <footer>${model.branding?.whiteLabel === true
423
+ ? `Run ${esc(snapshot.run.runId)}`
424
+ : `Generated by Secureport from run ${esc(snapshot.run.runId)}`}. Issue state as of ${formatDate(snapshot.run.createdAt)}.</footer>
321
425
  </body>
322
426
  </html>`;
323
427
  }
@@ -1 +1 @@
1
- {"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/report/html.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/report/html.ts"],"names":[],"mappings":"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"}
@@ -22,6 +22,21 @@ export interface JsonReport {
22
22
  readonly preparedBy?: string;
23
23
  /** Who it is for, if stated. */
24
24
  readonly preparedFor?: string;
25
+ /**
26
+ * The party that carried out the testing.
27
+ *
28
+ * **Content rather than presentation, which is why this is the one branding-
29
+ * derived value the JSON carries** (7.4b). A logo and an accent colour
30
+ * describe how a document looks and mean nothing to a consumer building a
31
+ * dashboard; who attested is the substance of an Attestation Letter, and a
32
+ * machine-readable report that omitted it would be missing the claim the
33
+ * document exists to make.
34
+ *
35
+ * Resolved the same way the prose resolves it: `preparedBy`, else the
36
+ * branding's `companyName`, else `Secureport`. Always present, because every
37
+ * report is produced by somebody.
38
+ */
39
+ readonly attestor: string;
25
40
  /**
26
41
  * How the findings were produced.
27
42
  *
@@ -1 +1 @@
1
- {"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/report/json.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;AAEpB;;;;;;;;GAQG;AACH,MAAM,WAAW,UAAU;IACzB,kEAAkE;IAClE,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC;IAE1B,4BAA4B;IAC5B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAE1B,4BAA4B;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,sCAAsC;IACtC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B,kCAAkC;IAClC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAE7B,gCAAgC;IAChC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAE9B;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,EAAE;QACd,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;QAC5B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;QAC3B,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;QACjC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;QACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;KAC5B,CAAC;IAEF;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAExC;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE;QAChB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;QAC/B,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;QACzD,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAChC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;KAC5D,CAAC;IAEF,8DAA8D;IAC9D,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAEpF,sCAAsC;IACtC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAE/B,8CAA8C;IAC9C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,2CAA2C;IAC3C,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;CAC7B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,CAqC7E"}
1
+ {"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/report/json.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;AAEpB;;;;;;;;GAQG;AACH,MAAM,WAAW,UAAU;IACzB,kEAAkE;IAClE,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC;IAE1B,4BAA4B;IAC5B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAE1B,4BAA4B;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,sCAAsC;IACtC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B,kCAAkC;IAClC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAE7B,gCAAgC;IAChC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAE9B;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,EAAE;QACd,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;QAC5B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;QAC3B,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;QACjC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;QACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;KAC5B,CAAC;IAEF;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAExC;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE;QAChB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;QAC/B,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;QACzD,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAChC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;KAC5D,CAAC;IAEF,8DAA8D;IAC9D,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAEpF,sCAAsC;IACtC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAE/B,8CAA8C;IAC9C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,2CAA2C;IAC3C,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;CAC7B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,CAsC7E"}
@@ -19,6 +19,7 @@ export function renderJson(snapshot, options) {
19
19
  generatedAt: model.generatedAt.toISOString(),
20
20
  ...(model.preparedBy === undefined ? {} : { preparedBy: model.preparedBy }),
21
21
  ...(model.preparedFor === undefined ? {} : { preparedFor: model.preparedFor }),
22
+ attestor: model.attestor,
22
23
  basis: {
23
24
  automated: model.basis.automated,
24
25
  uploaded: model.basis.uploaded,
@@ -1 +1 @@
1
- {"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/report/json.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gBAAgB,GAIjB,MAAM,YAAY,CAAC;AA+EpB;;;;;;;;;;GAUG;AACH,MAAM,UAAU,UAAU,CAAC,QAAkB,EAAE,OAAsB;IACnE,MAAM,KAAK,GAAG,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAElD,MAAM,MAAM,GAAe;QACzB,aAAa,EAAE,CAAC;QAChB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,WAAW,EAAE,KAAK,CAAC,WAAW,CAAC,WAAW,EAAE;QAC5C,GAAG,CAAC,KAAK,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC;QAC3E,GAAG,CAAC,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC;QAC9E,KAAK,EAAE;YACL,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS;YAChC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,QAAQ;YAC9B,cAAc,EAAE,KAAK,CAAC,KAAK,CAAC,cAAc;YAC1C,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO;YAC5B,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS;SACjC;QACD,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS;YAC5B,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC;gBACE,MAAM,EAAE;oBACN,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK;oBAC1C,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM;oBAC3B,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO;oBAC7B,QAAQ,EAAE,MAAM,CAAC,WAAW,CAC1B,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAC/D;iBACF;aACF,CAAC;QACN,WAAW,EAAE,EAAE,GAAG,KAAK,CAAC,WAAW,EAAE,KAAK,EAAE,KAAK,CAAC,gBAAgB,EAAE;QACpE,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,QAAQ;KACT,CAAC;IAEF,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACzC,CAAC"}
1
+ {"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/report/json.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gBAAgB,GAIjB,MAAM,YAAY,CAAC;AA+FpB;;;;;;;;;;GAUG;AACH,MAAM,UAAU,UAAU,CAAC,QAAkB,EAAE,OAAsB;IACnE,MAAM,KAAK,GAAG,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAElD,MAAM,MAAM,GAAe;QACzB,aAAa,EAAE,CAAC;QAChB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,WAAW,EAAE,KAAK,CAAC,WAAW,CAAC,WAAW,EAAE;QAC5C,GAAG,CAAC,KAAK,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC;QAC3E,GAAG,CAAC,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC;QAC9E,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,KAAK,EAAE;YACL,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS;YAChC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,QAAQ;YAC9B,cAAc,EAAE,KAAK,CAAC,KAAK,CAAC,cAAc;YAC1C,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO;YAC5B,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS;SACjC;QACD,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS;YAC5B,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC;gBACE,MAAM,EAAE;oBACN,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK;oBAC1C,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM;oBAC3B,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO;oBAC7B,QAAQ,EAAE,MAAM,CAAC,WAAW,CAC1B,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAC/D;iBACF;aACF,CAAC;QACN,WAAW,EAAE,EAAE,GAAG,KAAK,CAAC,WAAW,EAAE,KAAK,EAAE,KAAK,CAAC,gBAAgB,EAAE;QACpE,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,QAAQ;KACT,CAAC;IAEF,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACzC,CAAC"}
@@ -1,7 +1,29 @@
1
- import type { Snapshot } from '../snapshot.js';
2
- import { type ReportOptions } from './model.js';
1
+ import type { Snapshot, SnapshotIssue } from '../snapshot.js';
2
+ import { type EvidenceVerbosity, type ReportOptions } from './model.js';
3
3
  /** A date, printed the same way everywhere, without a locale to disagree about. */
4
4
  export declare function formatDate(date: Date): string;
5
+ /**
6
+ * Escapes the characters that would break out of a Markdown table cell.
7
+ *
8
+ * Exported: the streaming renderer formats a row the moment it sees it, and
9
+ * needs the exact same escaping — a second copy is a copy free to miss the
10
+ * next character somebody discovers breaks a table.
11
+ */
12
+ export declare function cell(value: string): string;
13
+ /**
14
+ * One issue, in full. The Penetration Test presentation.
15
+ *
16
+ * Exported: it is already a pure per-issue function needing nothing but the
17
+ * one entry, which is exactly what the streaming renderer can offer it a row
18
+ * at a time — the same reason `verdictFor` is exported from `model.ts`.
19
+ */
20
+ export declare function issueDetail(entry: SnapshotIssue, verbosity: EvidenceVerbosity): string[];
21
+ /**
22
+ * One issue, as a table row. The Vulnerability Assessment presentation.
23
+ *
24
+ * Exported for the same reason {@link issueDetail} is.
25
+ */
26
+ export declare function issueRow(entry: SnapshotIssue): string;
5
27
  /**
6
28
  * Renders a snapshot as Markdown.
7
29
  *
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/report/markdown.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAiB,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAGL,KAAK,aAAa,EAEnB,MAAM,YAAY,CAAC;AAEpB,mFAAmF;AACnF,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAE7C;AA0TD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,CA0FjF"}
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/report/markdown.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAEL,KAAK,iBAAiB,EAGtB,KAAK,aAAa,EAEnB,MAAM,YAAY,CAAC;AAEpB,mFAAmF;AACnF,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAE7C;AAED;;;;;;GAMG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE1C;AAmCD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,iBAAiB,GAAG,MAAM,EAAE,CAqDxF;AAkCD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAKrD;AAmPD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,CA2HjF"}
@@ -1,11 +1,18 @@
1
+ import { markdownHeadings } from './anchors.js';
1
2
  import { SEVERITY_ORDER } from '../severity.js';
2
- import { buildReportModel, } from './model.js';
3
+ import { buildReportModel, VERDICT_LABELS, } from './model.js';
3
4
  /** A date, printed the same way everywhere, without a locale to disagree about. */
4
5
  export function formatDate(date) {
5
6
  return date.toISOString().slice(0, 10);
6
7
  }
7
- /** Escapes the characters that would break out of a Markdown table cell. */
8
- function cell(value) {
8
+ /**
9
+ * Escapes the characters that would break out of a Markdown table cell.
10
+ *
11
+ * Exported: the streaming renderer formats a row the moment it sees it, and
12
+ * needs the exact same escaping — a second copy is a copy free to miss the
13
+ * next character somebody discovers breaks a table.
14
+ */
15
+ export function cell(value) {
9
16
  return value.replace(/\|/gu, '\\|').replace(/\n/gu, ' ');
10
17
  }
11
18
  /** The change summary every report opens with, per `00-DOMAIN.md` §7. */
@@ -39,8 +46,14 @@ function changeSummary(model) {
39
46
  : ''),
40
47
  ];
41
48
  }
42
- /** One issue, in full. The Penetration Test presentation. */
43
- function issueDetail(entry) {
49
+ /**
50
+ * One issue, in full. The Penetration Test presentation.
51
+ *
52
+ * Exported: it is already a pure per-issue function needing nothing but the
53
+ * one entry, which is exactly what the streaming renderer can offer it a row
54
+ * at a time — the same reason `verdictFor` is exported from `model.ts`.
55
+ */
56
+ export function issueDetail(entry, verbosity) {
44
57
  const { issue } = entry;
45
58
  const lines = [
46
59
  `#### ${issue.title}`,
@@ -66,32 +79,65 @@ function issueDetail(entry) {
66
79
  if (first?.recommendation !== undefined) {
67
80
  lines.push('**Recommendation.** ' + first.recommendation, '');
68
81
  }
69
- if (entry.findings.length > 0) {
70
- // The count, not the engine. Which scanner produced a finding is an
71
- // implementation detail of the assessment, and naming the stack in a
72
- // customer-facing document gives away more than it explains.
82
+ // The count or the detail, never the engine. Which scanner produced a
83
+ // finding is an implementation detail of the assessment, and naming the
84
+ // stack in a customer-facing document gives away more than it explains —
85
+ // it has leaked into rendered output twice, so no branch below reads
86
+ // `sourceEngine` or `sourceRuleId`.
87
+ if (entry.findings.length > 0 && verbosity === 'summary') {
73
88
  lines.push(`_Evidence: ${entry.findings.length} finding${entry.findings.length === 1 ? '' : 's'} recorded._`, '');
74
- const references = [...new Set(entry.findings.flatMap((f) => f.references ?? []))];
75
- if (references.length > 0) {
76
- lines.push(...references.map((r) => `- ${r}`), '');
77
- }
89
+ }
90
+ else if (entry.findings.length > 0 && verbosity === 'full') {
91
+ lines.push('**Evidence**', '');
92
+ for (const finding of entry.findings)
93
+ lines.push(`- ${evidenceLine(finding)}`);
94
+ lines.push('');
95
+ }
96
+ // Outside the verbosity branch: an advisory is external reading, not
97
+ // evidence, so `none` still lists it.
98
+ const references = [...new Set(entry.findings.flatMap((f) => f.references ?? []))];
99
+ if (references.length > 0) {
100
+ lines.push(...references.map((r) => `- ${r}`), '');
78
101
  }
79
102
  return lines;
80
103
  }
81
- /** One issue, as a table row. The Vulnerability Assessment presentation. */
82
- function issueRow(entry) {
104
+ /**
105
+ * One supporting finding, in a sentence.
106
+ *
107
+ * Every field here is something that was *found*. Nothing identifies what
108
+ * found it.
109
+ */
110
+ function evidenceLine(finding) {
111
+ const where = finding.parameter === undefined
112
+ ? `\`${cell(finding.location)}\``
113
+ : `\`${cell(finding.location)}\` (\`${cell(finding.parameter)}\`)`;
114
+ const detail = [`${finding.detectedSeverity}, seen ${formatDate(finding.createdAt)}`];
115
+ if (finding.cve !== undefined)
116
+ detail.push(cell(finding.cve));
117
+ if (finding.cvssScore !== undefined) {
118
+ detail.push(finding.cvssVector === undefined
119
+ ? `CVSS ${finding.cvssScore}`
120
+ : `CVSS ${finding.cvssScore} \`${cell(finding.cvssVector)}\``);
121
+ }
122
+ if (finding.confidence !== undefined) {
123
+ detail.push(`confidence ${Math.round(finding.confidence * 100)}%`);
124
+ }
125
+ const captures = finding.evidenceUri ?? [];
126
+ if (captures.length > 0) {
127
+ detail.push(`${captures.length} capture${captures.length === 1 ? '' : 's'} stored`);
128
+ }
129
+ return `${where} — ${detail.join('; ')}`;
130
+ }
131
+ /**
132
+ * One issue, as a table row. The Vulnerability Assessment presentation.
133
+ *
134
+ * Exported for the same reason {@link issueDetail} is.
135
+ */
136
+ export function issueRow(entry) {
83
137
  const { issue } = entry;
84
138
  const location = issue.parameter === undefined ? issue.location : `${issue.location} (${issue.parameter})`;
85
139
  return `| ${cell(issue.title)} | ${issue.effectiveSeverity} | \`${cell(location)}\` | ${entry.change.replace('_', ' ')} | ${entry.daysOpen} | ${entry.slaStatus.replace('_', ' ')} |`;
86
140
  }
87
- /** How a verdict is printed. The dashes are an implementation detail. */
88
- const VERDICT_LABELS = Object.freeze({
89
- fixed: 'fixed',
90
- still_present: 'still present',
91
- returned: 'returned',
92
- not_retested: 'not retested',
93
- new: 'new since',
94
- });
95
141
  /** The Retest body: the difference between two runs, and nothing else. */
96
142
  function retestBody(model) {
97
143
  // `buildReportModel` refuses to build a retest without one.
@@ -195,7 +241,7 @@ function attestationBody(model) {
195
241
  return [
196
242
  '## Statement',
197
243
  '',
198
- `${model.preparedBy ?? 'Secureport'} carried out security testing of **${snapshot.target.name}**`,
244
+ `${model.attestor} carried out security testing of **${snapshot.target.name}**`,
199
245
  `(${snapshot.target.url}) on ${formatDate(snapshot.run.createdAt)}.`,
200
246
  '',
201
247
  model.basis.statement,
@@ -219,6 +265,35 @@ function attestationBody(model) {
219
265
  '',
220
266
  ];
221
267
  }
268
+ /**
269
+ * The contents list, inserted above the first section.
270
+ *
271
+ * Computed from the finished document rather than from a list kept alongside
272
+ * it, for the reason `anchors.ts` explains: a contents list assembled
273
+ * separately from the headings it points at is one that can point at nothing,
274
+ * and the failure is silent.
275
+ *
276
+ * Markdown headings carry no explicit id, so the links rely on the anchor
277
+ * every common Markdown renderer derives from the heading text. `slug` matches
278
+ * that convention, which is the only way this can work at all.
279
+ */
280
+ function withContents(lines, model) {
281
+ if (!model.tableOfContents)
282
+ return lines.join('\n');
283
+ // Before inserting, so the contents list does not list itself.
284
+ const toc = markdownHeadings(lines);
285
+ if (toc.length === 0)
286
+ return lines.join('\n');
287
+ const block = [
288
+ '## Contents',
289
+ '',
290
+ ...toc.map((entry) => `${entry.level === 3 ? ' ' : ''}- [${entry.text}](#${entry.id})`),
291
+ '',
292
+ ];
293
+ const firstSection = lines.findIndex((line) => /^##\s/u.test(line));
294
+ const at = firstSection < 0 ? lines.length : firstSection;
295
+ return [...lines.slice(0, at), ...block, ...lines.slice(at)].join('\n');
296
+ }
222
297
  /**
223
298
  * Renders a snapshot as Markdown.
224
299
  *
@@ -241,9 +316,24 @@ export function renderMarkdown(snapshot, options) {
241
316
  const model = buildReportModel(snapshot, options);
242
317
  const { target } = snapshot;
243
318
  const lines = [
319
+ // Markdown has no pages and no rotation, so the stamp the HTML puts across
320
+ // every page becomes a line at the top. Same statement, in the only form
321
+ // this format has for it.
322
+ ...(model.branding?.watermark === undefined ? [] : [`**${model.branding.watermark}**`, '']),
244
323
  `# ${model.title}`,
245
324
  '',
246
325
  `**${target.name}** — ${target.url}`,
326
+ // Markdown has no pages, so the cover is a block under the title rather
327
+ // than a page of its own. The same facts, in the only form this format
328
+ // has for them.
329
+ ...(model.coverPage
330
+ ? [
331
+ '',
332
+ model.attestor,
333
+ ...(model.branding?.companyDetails ?? []),
334
+ ...(model.preparedFor === undefined ? [] : [`Prepared for ${model.preparedFor}`]),
335
+ ].map((line, i) => (i === 0 ? line : `_${line}_`))
336
+ : []),
247
337
  '',
248
338
  `| | |`,
249
339
  `| --- | --- |`,
@@ -261,7 +351,7 @@ export function renderMarkdown(snapshot, options) {
261
351
  // reader stops trusting.
262
352
  if (model.kind === 'attest') {
263
353
  lines.push(...attestationBody(model), ...suppressedAppendix(snapshot), '');
264
- return lines.join('\n');
354
+ return withContents(lines, model);
265
355
  }
266
356
  lines.push('## Basis of testing', '', model.basis.statement, '');
267
357
  lines.push('## Scope', '', `This report covers only what the run exercised: ${snapshot.run.coverage.paths
@@ -270,21 +360,27 @@ export function renderMarkdown(snapshot, options) {
270
360
  lines.push(...changeSummary(model), '');
271
361
  if (model.kind === 'exec') {
272
362
  lines.push(...executiveBody(model), ...suppressedAppendix(snapshot), '');
273
- return lines.join('\n');
363
+ return withContents(lines, model);
274
364
  }
275
365
  if (model.kind === 'retest') {
276
366
  lines.push(...retestBody(model), ...suppressedAppendix(snapshot), '');
277
- return lines.join('\n');
367
+ return withContents(lines, model);
278
368
  }
279
369
  if (model.sections.length === 0) {
280
- lines.push('## Findings', '', '_No issues were found._', '');
370
+ // "No issues were found" is false when a floor is what emptied the
371
+ // section, and it is the most dangerous sentence in the document to get
372
+ // wrong — a reader would take it as a clean result.
373
+ lines.push('## Findings', '', model.omitted === undefined
374
+ ? '_No issues were found._'
375
+ : '_No issues at or above the reporting threshold were found._', '');
281
376
  }
282
377
  else if (model.kind === 'pen') {
283
378
  lines.push('## Findings', '');
284
379
  for (const section of model.sections) {
285
380
  lines.push(`### ${section.severity} (${section.issues.length})`, '');
286
- for (const entry of section.issues)
287
- lines.push(...issueDetail(entry));
381
+ for (const entry of section.issues) {
382
+ lines.push(...issueDetail(entry, model.evidenceVerbosity));
383
+ }
288
384
  }
289
385
  }
290
386
  else {
@@ -295,10 +391,16 @@ export function renderMarkdown(snapshot, options) {
295
391
  }
296
392
  lines.push('');
297
393
  }
394
+ // Printed here, beside the section it is about, rather than left to the
395
+ // limitations list — which only the Attestation Letter renders (B109). A
396
+ // floor that removed issues from this section and said so nowhere the reader
397
+ // will look is the quiet form of the over-claim §7 exists to stop.
398
+ if (model.omitted !== undefined)
399
+ lines.push(`_${model.omitted.statement}_`, '');
298
400
  if (model.resolved.length > 0) {
299
401
  lines.push('## Resolved since the last run', '', `${model.resolved.length} issue${model.resolved.length === 1 ? '' : 's'} no longer detected by a run that covered ${model.resolved.length === 1 ? 'it' : 'them'}.`, '', '| Issue | Severity | Location | Open for |', '| --- | --- | --- | --- |', ...model.resolved.map((entry) => `| ${cell(entry.issue.title)} | ${entry.issue.effectiveSeverity} | \`${cell(entry.issue.location)}\` | ${entry.daysOpen} days |`), '');
300
402
  }
301
403
  lines.push(...suppressedAppendix(snapshot), '');
302
- return lines.join('\n');
404
+ return withContents(lines, model);
303
405
  }
304
406
  //# sourceMappingURL=markdown.js.map