privalint 0.3.0 → 0.4.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 (61) hide show
  1. package/README.de.md +38 -0
  2. package/README.md +49 -11
  3. package/dist/assessment.d.ts +1 -1
  4. package/dist/assessment.js +45 -9
  5. package/dist/assessment.js.map +1 -1
  6. package/dist/capture.js +8 -1
  7. package/dist/capture.js.map +1 -1
  8. package/dist/cli.js +44 -11
  9. package/dist/cli.js.map +1 -1
  10. package/dist/config.d.ts +21 -0
  11. package/dist/config.js +113 -0
  12. package/dist/config.js.map +1 -0
  13. package/dist/consent.js +70 -8
  14. package/dist/consent.js.map +1 -1
  15. package/dist/coverage.d.ts +13 -0
  16. package/dist/coverage.js +86 -0
  17. package/dist/coverage.js.map +1 -0
  18. package/dist/data/third-parties.js +9 -0
  19. package/dist/data/third-parties.js.map +1 -1
  20. package/dist/diagnostics.d.ts +4 -3
  21. package/dist/diagnostics.js +22 -7
  22. package/dist/diagnostics.js.map +1 -1
  23. package/dist/index.d.ts +3 -0
  24. package/dist/index.js +3 -0
  25. package/dist/index.js.map +1 -1
  26. package/dist/network.d.ts +3 -2
  27. package/dist/network.js +6 -4
  28. package/dist/network.js.map +1 -1
  29. package/dist/policy.d.ts +6 -0
  30. package/dist/policy.js +37 -0
  31. package/dist/policy.js.map +1 -0
  32. package/dist/report-contract.d.ts +13 -0
  33. package/dist/report-contract.js +16 -0
  34. package/dist/report-contract.js.map +1 -0
  35. package/dist/reporters/capture.js +56 -4
  36. package/dist/reporters/capture.js.map +1 -1
  37. package/dist/reporters/markdown.js +6 -1
  38. package/dist/reporters/markdown.js.map +1 -1
  39. package/dist/reporters/messages.d.ts +1 -0
  40. package/dist/reporters/messages.js +6 -0
  41. package/dist/reporters/messages.js.map +1 -1
  42. package/dist/reporters/sarif.js +25 -11
  43. package/dist/reporters/sarif.js.map +1 -1
  44. package/dist/reporters/shared.js +3 -2
  45. package/dist/reporters/shared.js.map +1 -1
  46. package/dist/reporters/text.js +4 -0
  47. package/dist/reporters/text.js.map +1 -1
  48. package/dist/rules/reject-option.js +3 -1
  49. package/dist/rules/reject-option.js.map +1 -1
  50. package/dist/rules/third-party-embeds.js +2 -2
  51. package/dist/rules/third-party-embeds.js.map +1 -1
  52. package/dist/scan-options.d.ts +7 -1
  53. package/dist/scan-options.js.map +1 -1
  54. package/dist/scanner.js +95 -7
  55. package/dist/scanner.js.map +1 -1
  56. package/dist/types.d.ts +59 -2
  57. package/package.json +7 -1
  58. package/schemas/report-1.0.0.schema.json +813 -0
  59. package/schemas/report-1.1.0.schema.json +833 -0
  60. package/schemas/sarif-properties-1.0.0.schema.json +785 -0
  61. package/schemas/sarif-properties-1.1.0.schema.json +810 -0
@@ -0,0 +1,813 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/JExcellence/privalint/raw/refs/heads/main/schemas/report-1.0.0.schema.json",
4
+ "title": "PrivaLint scan report 1.0.0",
5
+ "description": "Structural contract; not a guarantee of complete observation, URL safety or legal compliance. Counter equations and page-ID references require semantic checks.",
6
+ "type": "object",
7
+ "properties": {
8
+ "schemaVersion": {
9
+ "const": "1.0.0"
10
+ },
11
+ "scannerVersion": {
12
+ "type": "string",
13
+ "minLength": 1
14
+ },
15
+ "options": {
16
+ "$ref": "#/$defs/options"
17
+ },
18
+ "siteUrl": {
19
+ "type": "string"
20
+ },
21
+ "lang": {
22
+ "type": "string",
23
+ "enum": [
24
+ "en",
25
+ "de"
26
+ ]
27
+ },
28
+ "region": {
29
+ "type": "string",
30
+ "enum": [
31
+ "de",
32
+ "at",
33
+ "ch",
34
+ "eu"
35
+ ]
36
+ },
37
+ "scannedAt": {
38
+ "type": "string",
39
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"
40
+ },
41
+ "durationMs": {
42
+ "type": "number",
43
+ "minimum": 0
44
+ },
45
+ "pages": {
46
+ "type": "array",
47
+ "items": {
48
+ "$ref": "#/$defs/page"
49
+ }
50
+ },
51
+ "consent": {
52
+ "$ref": "#/$defs/consent"
53
+ },
54
+ "findings": {
55
+ "type": "array",
56
+ "items": {
57
+ "$ref": "#/$defs/finding"
58
+ }
59
+ },
60
+ "rules": {
61
+ "type": "array",
62
+ "items": {
63
+ "$ref": "#/$defs/rule"
64
+ }
65
+ },
66
+ "coverage": {
67
+ "type": "string",
68
+ "enum": [
69
+ "complete",
70
+ "partial"
71
+ ]
72
+ }
73
+ },
74
+ "required": [
75
+ "schemaVersion",
76
+ "scannerVersion",
77
+ "options",
78
+ "siteUrl",
79
+ "lang",
80
+ "region",
81
+ "scannedAt",
82
+ "durationMs",
83
+ "pages",
84
+ "findings",
85
+ "rules",
86
+ "coverage"
87
+ ],
88
+ "$defs": {
89
+ "diagnostic": {
90
+ "type": "object",
91
+ "properties": {
92
+ "kind": {
93
+ "type": "string",
94
+ "enum": [
95
+ "security-blocked",
96
+ "unsupported-method",
97
+ "unsupported-protocol",
98
+ "dns",
99
+ "tls",
100
+ "connection",
101
+ "timeout",
102
+ "resource-limit",
103
+ "http-error",
104
+ "browser-failure",
105
+ "skipped",
106
+ "aborted"
107
+ ]
108
+ },
109
+ "phase": {
110
+ "type": "string",
111
+ "enum": [
112
+ "before-consent",
113
+ "after-reject"
114
+ ]
115
+ },
116
+ "url": {
117
+ "type": "string",
118
+ "pattern": "^(https?://[^/?#@\\s]+/\\[redacted\\]|\\[redacted\\])$"
119
+ },
120
+ "status": {
121
+ "type": "integer",
122
+ "minimum": 100,
123
+ "maximum": 599
124
+ },
125
+ "limit": {
126
+ "type": "string",
127
+ "enum": [
128
+ "requests",
129
+ "response-bytes",
130
+ "total-bytes",
131
+ "redirects"
132
+ ]
133
+ },
134
+ "skippedReason": {
135
+ "type": "string",
136
+ "enum": [
137
+ "beacon",
138
+ "unsupported-method",
139
+ "unsupported-protocol",
140
+ "policy"
141
+ ]
142
+ }
143
+ },
144
+ "required": [
145
+ "kind",
146
+ "phase",
147
+ "url"
148
+ ]
149
+ },
150
+ "diagnostics": {
151
+ "type": "object",
152
+ "properties": {
153
+ "requests": {
154
+ "type": "integer",
155
+ "minimum": 0
156
+ },
157
+ "omittedRequests": {
158
+ "type": "integer",
159
+ "minimum": 0
160
+ },
161
+ "responses": {
162
+ "type": "integer",
163
+ "minimum": 0
164
+ },
165
+ "finished": {
166
+ "type": "integer",
167
+ "minimum": 0
168
+ },
169
+ "failed": {
170
+ "type": "integer",
171
+ "minimum": 0
172
+ },
173
+ "blocked": {
174
+ "type": "integer",
175
+ "minimum": 0
176
+ },
177
+ "skippedRequests": {
178
+ "type": "integer",
179
+ "minimum": 0
180
+ },
181
+ "failedRequests": {
182
+ "type": "integer",
183
+ "minimum": 0
184
+ },
185
+ "securityBlockedRequests": {
186
+ "type": "integer",
187
+ "minimum": 0
188
+ },
189
+ "httpErrors": {
190
+ "type": "integer",
191
+ "minimum": 0
192
+ },
193
+ "bytes": {
194
+ "type": "integer",
195
+ "minimum": 0
196
+ },
197
+ "issueCount": {
198
+ "type": "integer",
199
+ "minimum": 0
200
+ },
201
+ "dropped": {
202
+ "type": "integer",
203
+ "minimum": 0
204
+ },
205
+ "issues": {
206
+ "type": "array",
207
+ "items": {
208
+ "$ref": "#/$defs/diagnostic"
209
+ }
210
+ }
211
+ },
212
+ "required": [
213
+ "requests",
214
+ "omittedRequests",
215
+ "responses",
216
+ "finished",
217
+ "failed",
218
+ "blocked",
219
+ "skippedRequests",
220
+ "failedRequests",
221
+ "securityBlockedRequests",
222
+ "httpErrors",
223
+ "bytes",
224
+ "issueCount",
225
+ "dropped",
226
+ "issues"
227
+ ]
228
+ },
229
+ "capture": {
230
+ "type": "object",
231
+ "properties": {
232
+ "complete": {
233
+ "type": "boolean"
234
+ },
235
+ "beforeConsentComplete": {
236
+ "type": "boolean"
237
+ },
238
+ "document": {
239
+ "type": "boolean"
240
+ },
241
+ "diagnostics": {
242
+ "$ref": "#/$defs/diagnostics"
243
+ }
244
+ },
245
+ "required": [
246
+ "complete",
247
+ "beforeConsentComplete",
248
+ "document",
249
+ "diagnostics"
250
+ ],
251
+ "allOf": [
252
+ {
253
+ "if": {
254
+ "properties": {
255
+ "complete": {
256
+ "const": true
257
+ }
258
+ },
259
+ "required": [
260
+ "complete"
261
+ ]
262
+ },
263
+ "then": {
264
+ "properties": {
265
+ "document": {
266
+ "const": true
267
+ },
268
+ "beforeConsentComplete": {
269
+ "const": true
270
+ },
271
+ "diagnostics": {
272
+ "type": "object",
273
+ "properties": {
274
+ "omittedRequests": {
275
+ "const": 0
276
+ },
277
+ "failed": {
278
+ "const": 0
279
+ },
280
+ "blocked": {
281
+ "const": 0
282
+ },
283
+ "skippedRequests": {
284
+ "const": 0
285
+ },
286
+ "failedRequests": {
287
+ "const": 0
288
+ },
289
+ "securityBlockedRequests": {
290
+ "const": 0
291
+ },
292
+ "httpErrors": {
293
+ "const": 0
294
+ },
295
+ "issueCount": {
296
+ "const": 0
297
+ },
298
+ "dropped": {
299
+ "const": 0
300
+ }
301
+ }
302
+ }
303
+ }
304
+ }
305
+ }
306
+ ]
307
+ },
308
+ "evaluation": {
309
+ "type": "object",
310
+ "properties": {
311
+ "ruleId": {
312
+ "type": "string"
313
+ },
314
+ "status": {
315
+ "type": "string",
316
+ "enum": [
317
+ "executed",
318
+ "skipped",
319
+ "not-evaluable"
320
+ ]
321
+ },
322
+ "reason": {
323
+ "type": "string",
324
+ "enum": [
325
+ "disabled",
326
+ "consent-disabled",
327
+ "not-start-page",
328
+ "missing-observation"
329
+ ]
330
+ },
331
+ "partial": {
332
+ "type": "boolean"
333
+ },
334
+ "outcome": {
335
+ "type": "string",
336
+ "enum": [
337
+ "checked-no-finding",
338
+ "finding-detected",
339
+ "not-evaluable"
340
+ ]
341
+ },
342
+ "explanation": {
343
+ "type": "string",
344
+ "enum": [
345
+ "disabled",
346
+ "not-start-page",
347
+ "consent-disabled",
348
+ "missing-reject-observation",
349
+ "missing-consent-observation",
350
+ "incomplete-document",
351
+ "positive-evidence",
352
+ "incomplete-observation",
353
+ "required-observations-available",
354
+ "no-supported-banner",
355
+ "no-supported-reject-control",
356
+ "unsupported-banner-markup",
357
+ "browser-interaction-failed",
358
+ "reject-clicked-and-reloaded"
359
+ ]
360
+ },
361
+ "findingCount": {
362
+ "type": "integer",
363
+ "minimum": 0
364
+ }
365
+ },
366
+ "required": [
367
+ "ruleId",
368
+ "status",
369
+ "partial",
370
+ "outcome",
371
+ "explanation",
372
+ "findingCount"
373
+ ],
374
+ "allOf": [
375
+ {
376
+ "if": {
377
+ "properties": {
378
+ "outcome": {
379
+ "const": "checked-no-finding"
380
+ }
381
+ },
382
+ "required": [
383
+ "outcome"
384
+ ]
385
+ },
386
+ "then": {
387
+ "properties": {
388
+ "findingCount": {
389
+ "const": 0
390
+ },
391
+ "partial": {
392
+ "const": false
393
+ },
394
+ "status": {
395
+ "const": "executed"
396
+ }
397
+ }
398
+ }
399
+ },
400
+ {
401
+ "if": {
402
+ "properties": {
403
+ "outcome": {
404
+ "const": "finding-detected"
405
+ }
406
+ },
407
+ "required": [
408
+ "outcome"
409
+ ]
410
+ },
411
+ "then": {
412
+ "properties": {
413
+ "findingCount": {
414
+ "type": "integer",
415
+ "minimum": 1
416
+ },
417
+ "status": {
418
+ "const": "executed"
419
+ }
420
+ }
421
+ }
422
+ }
423
+ ]
424
+ },
425
+ "page": {
426
+ "type": "object",
427
+ "properties": {
428
+ "url": {
429
+ "type": "string"
430
+ },
431
+ "finalUrl": {
432
+ "type": "string"
433
+ },
434
+ "status": {
435
+ "anyOf": [
436
+ {
437
+ "type": "integer",
438
+ "minimum": 100,
439
+ "maximum": 599
440
+ },
441
+ {
442
+ "type": "null"
443
+ }
444
+ ]
445
+ },
446
+ "requestCount": {
447
+ "type": "integer",
448
+ "minimum": 0
449
+ },
450
+ "cookieCount": {
451
+ "type": "integer",
452
+ "minimum": 0
453
+ },
454
+ "error": {
455
+ "type": "string"
456
+ },
457
+ "capture": {
458
+ "$ref": "#/$defs/capture"
459
+ },
460
+ "ruleEvaluations": {
461
+ "type": "array",
462
+ "items": {
463
+ "$ref": "#/$defs/evaluation"
464
+ }
465
+ }
466
+ },
467
+ "required": [
468
+ "url",
469
+ "finalUrl",
470
+ "status",
471
+ "requestCount",
472
+ "cookieCount",
473
+ "capture",
474
+ "ruleEvaluations"
475
+ ]
476
+ },
477
+ "finding": {
478
+ "type": "object",
479
+ "properties": {
480
+ "ruleId": {
481
+ "type": "string"
482
+ },
483
+ "severity": {
484
+ "type": "string",
485
+ "enum": [
486
+ "error",
487
+ "warning",
488
+ "info"
489
+ ]
490
+ },
491
+ "message": {
492
+ "type": "string"
493
+ },
494
+ "pageUrl": {
495
+ "type": "string"
496
+ },
497
+ "evidence": {
498
+ "type": "array",
499
+ "items": {
500
+ "type": "string"
501
+ }
502
+ },
503
+ "fix": {
504
+ "type": "string"
505
+ },
506
+ "subject": {
507
+ "type": "string"
508
+ },
509
+ "references": {
510
+ "type": "array",
511
+ "items": {
512
+ "type": "string"
513
+ }
514
+ },
515
+ "policy": {
516
+ "type": "object",
517
+ "properties": {
518
+ "allowed": {
519
+ "type": "boolean"
520
+ },
521
+ "originalSeverity": {
522
+ "type": "string",
523
+ "enum": [
524
+ "error",
525
+ "warning",
526
+ "info"
527
+ ]
528
+ }
529
+ },
530
+ "required": [
531
+ "allowed",
532
+ "originalSeverity"
533
+ ]
534
+ }
535
+ },
536
+ "required": [
537
+ "ruleId",
538
+ "severity",
539
+ "message",
540
+ "pageUrl",
541
+ "evidence"
542
+ ]
543
+ },
544
+ "consent": {
545
+ "type": "object",
546
+ "properties": {
547
+ "bannerFound": {
548
+ "type": "boolean"
549
+ },
550
+ "rejected": {
551
+ "type": "boolean"
552
+ },
553
+ "state": {
554
+ "type": "string",
555
+ "enum": [
556
+ "not-detected",
557
+ "reject-unavailable",
558
+ "interaction-failed",
559
+ "reject-tested"
560
+ ]
561
+ },
562
+ "outcome": {
563
+ "type": "string",
564
+ "enum": [
565
+ "no-banner-detected",
566
+ "unsupported-banner",
567
+ "interaction-failed",
568
+ "reject-succeeded"
569
+ ]
570
+ },
571
+ "reason": {
572
+ "type": "string",
573
+ "enum": [
574
+ "no-supported-banner",
575
+ "no-supported-reject-control",
576
+ "unsupported-banner-markup",
577
+ "browser-interaction-failed",
578
+ "reject-clicked-and-reloaded"
579
+ ]
580
+ },
581
+ "cmp": {
582
+ "type": "string"
583
+ },
584
+ "acceptLabel": {
585
+ "type": "string"
586
+ },
587
+ "rejectLabel": {
588
+ "type": "string"
589
+ },
590
+ "payOrOk": {
591
+ "type": "boolean"
592
+ },
593
+ "afterRejectComplete": {
594
+ "type": "boolean"
595
+ },
596
+ "error": {
597
+ "type": "string"
598
+ }
599
+ },
600
+ "required": [
601
+ "bannerFound",
602
+ "rejected",
603
+ "state",
604
+ "outcome",
605
+ "reason"
606
+ ]
607
+ },
608
+ "rule": {
609
+ "type": "object",
610
+ "properties": {
611
+ "id": {
612
+ "type": "string"
613
+ },
614
+ "title": {
615
+ "type": "string"
616
+ },
617
+ "description": {
618
+ "type": "string"
619
+ },
620
+ "references": {
621
+ "type": "array",
622
+ "items": {
623
+ "type": "string"
624
+ }
625
+ },
626
+ "requires": {
627
+ "type": "array",
628
+ "items": {
629
+ "type": "string",
630
+ "enum": [
631
+ "document",
632
+ "network",
633
+ "consent",
634
+ "after-reject"
635
+ ]
636
+ }
637
+ }
638
+ },
639
+ "required": [
640
+ "id",
641
+ "title",
642
+ "description",
643
+ "references"
644
+ ]
645
+ },
646
+ "networkLimits": {
647
+ "type": "object",
648
+ "properties": {
649
+ "concurrency": {
650
+ "type": "integer",
651
+ "minimum": 1
652
+ },
653
+ "maxRequests": {
654
+ "type": "integer",
655
+ "minimum": 1
656
+ },
657
+ "maxResponseBytes": {
658
+ "type": "integer",
659
+ "minimum": 1
660
+ },
661
+ "maxTotalBytes": {
662
+ "type": "integer",
663
+ "minimum": 1
664
+ },
665
+ "maxRedirects": {
666
+ "type": "integer",
667
+ "minimum": 0
668
+ },
669
+ "requestTimeoutMs": {
670
+ "type": "integer",
671
+ "minimum": 1
672
+ }
673
+ },
674
+ "required": [
675
+ "concurrency",
676
+ "maxRequests",
677
+ "maxResponseBytes",
678
+ "maxTotalBytes",
679
+ "maxRedirects",
680
+ "requestTimeoutMs"
681
+ ]
682
+ },
683
+ "options": {
684
+ "type": "object",
685
+ "properties": {
686
+ "maxPages": {
687
+ "type": "integer",
688
+ "minimum": 1
689
+ },
690
+ "settleMs": {
691
+ "type": "integer",
692
+ "minimum": 0
693
+ },
694
+ "timeoutMs": {
695
+ "type": "integer",
696
+ "minimum": 1
697
+ },
698
+ "locale": {
699
+ "type": "string"
700
+ },
701
+ "lang": {
702
+ "type": "string",
703
+ "enum": [
704
+ "en",
705
+ "de"
706
+ ]
707
+ },
708
+ "region": {
709
+ "type": "string",
710
+ "enum": [
711
+ "de",
712
+ "at",
713
+ "ch",
714
+ "eu"
715
+ ]
716
+ },
717
+ "consentCheck": {
718
+ "type": "boolean"
719
+ },
720
+ "headed": {
721
+ "type": "boolean"
722
+ },
723
+ "channel": {
724
+ "type": "string"
725
+ },
726
+ "captureTimeoutMs": {
727
+ "anyOf": [
728
+ {
729
+ "type": "integer",
730
+ "minimum": 1
731
+ },
732
+ {
733
+ "type": "null"
734
+ }
735
+ ]
736
+ },
737
+ "maxDiagnostics": {
738
+ "type": "integer",
739
+ "minimum": 0
740
+ },
741
+ "failureMode": {
742
+ "type": "string",
743
+ "enum": [
744
+ "throw",
745
+ "report"
746
+ ]
747
+ },
748
+ "captureMode": {
749
+ "type": "string",
750
+ "enum": [
751
+ "native",
752
+ "adapter",
753
+ "offline-fixture"
754
+ ]
755
+ },
756
+ "networkLimits": {
757
+ "anyOf": [
758
+ {
759
+ "$ref": "#/$defs/networkLimits"
760
+ },
761
+ {
762
+ "type": "null"
763
+ }
764
+ ]
765
+ },
766
+ "selectedRules": {
767
+ "type": "array",
768
+ "items": {
769
+ "type": "string"
770
+ },
771
+ "uniqueItems": true
772
+ },
773
+ "ruleSettings": {
774
+ "type": "object",
775
+ "additionalProperties": {
776
+ "type": "string",
777
+ "enum": [
778
+ "error",
779
+ "warning",
780
+ "info",
781
+ "off"
782
+ ]
783
+ }
784
+ },
785
+ "allowedVendors": {
786
+ "type": "array",
787
+ "items": {
788
+ "type": "string"
789
+ }
790
+ }
791
+ },
792
+ "required": [
793
+ "maxPages",
794
+ "settleMs",
795
+ "timeoutMs",
796
+ "locale",
797
+ "lang",
798
+ "region",
799
+ "consentCheck",
800
+ "headed",
801
+ "channel",
802
+ "captureTimeoutMs",
803
+ "maxDiagnostics",
804
+ "failureMode",
805
+ "captureMode",
806
+ "networkLimits",
807
+ "selectedRules",
808
+ "ruleSettings",
809
+ "allowedVendors"
810
+ ]
811
+ }
812
+ }
813
+ }