privalint 0.1.1 → 0.2.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 (52) hide show
  1. package/README.de.md +89 -0
  2. package/README.md +29 -1
  3. package/dist/cli.js +8 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/i18n.d.ts +5 -0
  6. package/dist/i18n.js +3 -0
  7. package/dist/i18n.js.map +1 -0
  8. package/dist/index.d.ts +2 -0
  9. package/dist/index.js +2 -0
  10. package/dist/index.js.map +1 -1
  11. package/dist/legal.d.ts +10 -0
  12. package/dist/legal.js +99 -0
  13. package/dist/legal.js.map +1 -0
  14. package/dist/reporters/markdown.js +14 -12
  15. package/dist/reporters/markdown.js.map +1 -1
  16. package/dist/reporters/messages.d.ts +21 -0
  17. package/dist/reporters/messages.js +62 -0
  18. package/dist/reporters/messages.js.map +1 -0
  19. package/dist/reporters/sarif.js +7 -1
  20. package/dist/reporters/sarif.js.map +1 -1
  21. package/dist/reporters/shared.d.ts +1 -3
  22. package/dist/reporters/shared.js +0 -17
  23. package/dist/reporters/shared.js.map +1 -1
  24. package/dist/reporters/text.js +17 -13
  25. package/dist/reporters/text.js.map +1 -1
  26. package/dist/rules/google-fonts.js +26 -9
  27. package/dist/rules/google-fonts.js.map +1 -1
  28. package/dist/rules/impressum-link.js +21 -8
  29. package/dist/rules/impressum-link.js.map +1 -1
  30. package/dist/rules/links.d.ts +2 -0
  31. package/dist/rules/links.js +2 -0
  32. package/dist/rules/links.js.map +1 -1
  33. package/dist/rules/pre-consent-trackers.js +20 -7
  34. package/dist/rules/pre-consent-trackers.js.map +1 -1
  35. package/dist/rules/privacy-policy-link.js +12 -5
  36. package/dist/rules/privacy-policy-link.js.map +1 -1
  37. package/dist/rules/reject-option.js +27 -7
  38. package/dist/rules/reject-option.js.map +1 -1
  39. package/dist/rules/third-party-cdns.js +10 -3
  40. package/dist/rules/third-party-cdns.js.map +1 -1
  41. package/dist/rules/third-party-embeds.js +10 -3
  42. package/dist/rules/third-party-embeds.js.map +1 -1
  43. package/dist/rules/tracker-hits.d.ts +4 -2
  44. package/dist/rules/tracker-hits.js +14 -3
  45. package/dist/rules/tracker-hits.js.map +1 -1
  46. package/dist/rules/trackers-after-reject.js +24 -12
  47. package/dist/rules/trackers-after-reject.js.map +1 -1
  48. package/dist/scanner.d.ts +6 -0
  49. package/dist/scanner.js +10 -2
  50. package/dist/scanner.js.map +1 -1
  51. package/dist/types.d.ts +8 -0
  52. package/package.json +11 -6
package/README.de.md ADDED
@@ -0,0 +1,89 @@
1
+ # privalint
2
+
3
+ **English:** [README.md](README.md)
4
+
5
+ privalint prüft Websites auf die Datenschutzfehler, für die es Abmahnungen gibt: Tracker, die vor
6
+ der Einwilligung laden oder nach „Ablehnen“ weiterlaufen, Google Fonts vom Google-Server,
7
+ eingebundene Inhalte wie YouTube oder Google Maps und ein fehlendes Impressum.
8
+
9
+ privalint öffnet die Seite in einem echten Chromium-Browser ohne Cookies, wie beim ersten Besuch.
10
+ Es zeichnet auf, was geladen wird, bevor jemand das Cookie-Banner bedient, klickt dann auf
11
+ „Ablehnen“ und prüft, was trotzdem noch lädt. Es läuft im Terminal oder als GitHub Action bei
12
+ jedem Pull Request.
13
+
14
+ ```bash
15
+ npx privalint https://ihre-seite.de --lang de
16
+ ```
17
+
18
+ > [!IMPORTANT]
19
+ > privalint führt automatisierte Prüfungen durch. Ein sauberes Ergebnis bedeutet, dass keines der
20
+ > geprüften Probleme gefunden wurde. Es macht eine Website nicht DSGVO-konform und ist keine
21
+ > Rechtsberatung.
22
+
23
+ ## Deutschland, Österreich, Schweiz
24
+
25
+ Mit `--region` wählen Sie, nach welchem Recht privalint die Befunde einordnet. Jeder Befund nennt
26
+ die Rechtsgrundlage des gewählten Landes.
27
+
28
+ | Region | Cookies und Tracking | Impressum | Besonderheit |
29
+ | --------------- | ----------------------------------------- | ----------------------------------------------- | ----------------------------------------------------- |
30
+ | `de` (Standard) | Opt-in, § 25 TDDDG | § 5 DDG | – |
31
+ | `at` | Opt-in, § 165 Abs. 3 TKG 2021 | § 5 ECG, § 25 MedienG | – |
32
+ | `ch` | Opt-out, Art. 45c FMG | Art. 3 Abs. 1 lit. s UWG (bei Online-Angeboten) | Tracker, Einbindungen und Impressum eine Stufe milder |
33
+ | `eu` | Opt-in, Art. 5 Abs. 3 ePrivacy-Richtlinie | Art. 5 E-Commerce-Richtlinie | – |
34
+
35
+ Tracker, die nach einem ausdrücklichen „Ablehnen“ weiterlaufen, bleiben überall ein Fehler, auch in
36
+ der Schweiz (Art. 30 Abs. 2 lit. b DSG). Richtet sich eine Schweizer Website auch an Besucher aus
37
+ der EU, prüfen Sie sie zusätzlich mit `--region eu`.
38
+
39
+ ```bash
40
+ npx privalint https://ihre-seite.at --region at --lang de --max-pages 20
41
+ ```
42
+
43
+ ## Was geprüft wird
44
+
45
+ | Regel | Was sie findet |
46
+ | ----------------------- | ------------------------------------------------------------------------------------------------------- |
47
+ | `pre-consent-trackers` | Analyse-, Werbe- und Session-Replay-Tools, die vor der Einwilligung Anfragen senden oder Cookies setzen |
48
+ | `trackers-after-reject` | Tracker, die nach Klick auf „Ablehnen“ und Neuladen weiterlaufen |
49
+ | `reject-option` | Cookie-Banner mit „Zustimmen“, aber ohne „Ablehnen“ auf der ersten Ebene; Pur-Abo-Modelle als Hinweis |
50
+ | `google-fonts` | Schriften von `fonts.googleapis.com` / `fonts.gstatic.com` |
51
+ | `third-party-embeds` | YouTube, Vimeo, Google Maps, reCAPTCHA, Gravatar und Social-Media-Einbindungen vor der Einwilligung |
52
+ | `third-party-cdns` | Skripte und Styles von jsDelivr, unpkg, cdnjs und anderen öffentlichen CDNs (Hinweis) |
53
+ | `impressum-link` | Seiten ohne Link zum Impressum |
54
+ | `privacy-policy-link` | Seiten ohne Link zur Datenschutzerklärung |
55
+
56
+ Details, Hintergründe und Lösungen stehen auf Englisch in [`docs/rules`](docs/rules).
57
+
58
+ ## GitHub Action
59
+
60
+ ```yaml
61
+ - uses: jexcellence/privalint@v0
62
+ with:
63
+ url: https://ihre-seite.de
64
+ max-pages: 20
65
+ lang: de
66
+ region: de
67
+ ```
68
+
69
+ Der Bericht erscheint auf Deutsch in der Zusammenfassung des Workflow-Laufs. Alle Eingaben und
70
+ die Anbindung an GitHub Code Scanning beschreibt die [englische README](README.md#github-action).
71
+
72
+ ## Grenzen
73
+
74
+ - Manche Seiten zeigen ihr Cookie-Banner Headless-Browsern nicht. Dann meldet privalint „kein
75
+ Banner gefunden“. Lokal hilft `--headed --channel msedge` (oder `chrome`).
76
+ - Viele Consent-Tools entscheiden anhand der IP-Adresse, ob sie ein Banner zeigen. GitHub-Runner
77
+ haben US-Adressen und sehen deshalb unter Umständen etwas anderes als Besucher aus der EU.
78
+ - Serverseitiges Tracking ist im Browser nicht sichtbar.
79
+
80
+ ## Mitmachen
81
+
82
+ Fehlalarme, fehlende Tracker, Consent-Tools und neue Regeln sind sehr willkommen. Gerade
83
+ Anbieter aus dem deutschsprachigen Raum fehlen noch. Der Einstieg steht in
84
+ [CONTRIBUTING.md](CONTRIBUTING.md), passende Aufgaben tragen das Label
85
+ [`good first issue`](https://github.com/jexcellence/privalint/labels/good%20first%20issue).
86
+
87
+ ## Lizenz
88
+
89
+ [MIT](LICENSE)
package/README.md CHANGED
@@ -4,6 +4,8 @@
4
4
  [![npm](https://img.shields.io/npm/v/privalint)](https://www.npmjs.com/package/privalint)
5
5
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
6
6
 
7
+ **Deutsch:** [README.de.md](README.de.md)
8
+
7
9
  Lint your website for the GDPR mistakes that get people warning letters: trackers that fire before
8
10
  consent or keep running after "reject", Google Fonts loaded from Google, embeds and a missing
9
11
  Impressum.
@@ -84,6 +86,8 @@ preview URL from your hosting provider's deployment event or action output as `u
84
86
  | `max-pages` | `1` | How many pages of the same site to crawl. |
85
87
  | `fail-on` | `error` | `error`, `warning` or `never`. |
86
88
  | `disable` | | Comma-separated rule ids to skip. |
89
+ | `lang` | `en` | Language of the report: `en` or `de`. |
90
+ | `region` | `de` | Whose law to cite: `de`, `at`, `ch`, `eu`. |
87
91
  | `sarif-file` | `privalint.sarif` | Where to write SARIF. Empty to skip. |
88
92
  | `job-summary` | `true` | Add the Markdown report to the job summary. |
89
93
 
@@ -113,6 +117,8 @@ privalint <url> [options]
113
117
  --settle <ms> Wait this long after load for late tags (default 2000)
114
118
  --timeout <ms> Navigation timeout per page (default 30000)
115
119
  --locale <locale> Browser locale (default de-DE)
120
+ --lang <lang> Language of the report: en | de (default en)
121
+ --region <region> Whose law to cite: de | at | ch | eu (default de)
116
122
  --skip-consent Don't click "reject" on the consent banner
117
123
  --headed Open a visible browser window instead of running headless
118
124
  --channel <name> Use an installed browser: chrome or msedge
@@ -127,12 +133,34 @@ The first run needs a browser. If Playwright hasn't installed one yet:
127
133
  npx playwright install chromium
128
134
  ```
129
135
 
136
+ ## Countries and languages
137
+
138
+ The same finding can be a clear violation in one country and a hint in another. `--region` picks
139
+ whose law privalint cites and how strictly it judges:
140
+
141
+ | Region | Cookies and tracking | Imprint | Changes |
142
+ | -------------- | ------------------------------------ | ------------------------------------- | -------------------------------------------------------------------------------- |
143
+ | `de` (default) | Opt-in, § 25 TDDDG | § 5 DDG | none |
144
+ | `at` | Opt-in, § 165 Abs. 3 TKG 2021 | § 5 ECG, § 25 MedienG | none |
145
+ | `ch` | Opt-out, Art. 45c FMG | Art. 3 Abs. 1 lit. s UWG (e-commerce) | `pre-consent-trackers`, `third-party-embeds` and `impressum-link` drop one level |
146
+ | `eu` | Opt-in, Art. 5(3) ePrivacy Directive | Art. 5 Directive 2000/31/EC | none |
147
+
148
+ Every finding lists its legal basis for the chosen country. Trackers that run after an explicit
149
+ "reject" stay an error everywhere, Switzerland included (Art. 30 Abs. 2 lit. b DSG). If a Swiss
150
+ site also targets visitors in the EU, scan it with `--region eu` as well.
151
+
152
+ `--lang de` writes findings, fixes and the report in German:
153
+
154
+ ```bash
155
+ npx privalint https://ihre-seite.ch --region ch --lang de
156
+ ```
157
+
130
158
  ## Use it from code
131
159
 
132
160
  ```ts
133
161
  import { scan } from 'privalint';
134
162
 
135
- const result = await scan('https://your-site.de', { maxPages: 10 });
163
+ const result = await scan('https://your-site.de', { maxPages: 10, region: 'at', lang: 'de' });
136
164
  for (const finding of result.findings) {
137
165
  console.log(finding.severity, finding.ruleId, finding.pageUrl);
138
166
  }
package/dist/cli.js CHANGED
@@ -2,6 +2,8 @@
2
2
  import { writeFile } from 'node:fs/promises';
3
3
  import { extname } from 'node:path';
4
4
  import { parseArgs } from 'node:util';
5
+ import { LANGS } from './i18n.js';
6
+ import { REGIONS } from './legal.js';
5
7
  import { VERSION } from './meta.js';
6
8
  import { FORMATS, format, formatText } from './reporters/index.js';
7
9
  import { defaultRules } from './rules/index.js';
@@ -29,6 +31,8 @@ Options
29
31
  --settle <ms> Wait this long after load for late tags (default 2000)
30
32
  --timeout <ms> Navigation timeout per page (default 30000)
31
33
  --locale <locale> Browser locale (default de-DE)
34
+ --lang <lang> Language of the report: en | de (default en)
35
+ --region <region> Whose law to cite: de | at | ch | eu (default de)
32
36
  --skip-consent Don't click "reject" on the consent banner
33
37
  --headed Open a visible browser window instead of running headless
34
38
  --channel <name> Use an installed browser: chrome or msedge
@@ -59,6 +63,8 @@ async function main(argv) {
59
63
  settle: { type: 'string' },
60
64
  timeout: { type: 'string' },
61
65
  locale: { type: 'string' },
66
+ lang: { type: 'string', default: 'en' },
67
+ region: { type: 'string', default: 'de' },
62
68
  'skip-consent': { type: 'boolean' },
63
69
  headed: { type: 'boolean' },
64
70
  channel: { type: 'string' },
@@ -91,6 +97,8 @@ async function main(argv) {
91
97
  settleMs: wholeNumber(values.settle, '--settle', 0),
92
98
  timeoutMs: wholeNumber(values.timeout, '--timeout', 1),
93
99
  locale: values.locale,
100
+ lang: oneOf(values.lang, LANGS, '--lang'),
101
+ region: oneOf(values.region, REGIONS, '--region'),
94
102
  consentCheck: values['skip-consent'] !== true,
95
103
  headed: values.headed === true,
96
104
  channel: values.channel === undefined ? undefined : oneOf(values.channel, CHANNELS, '--channel'),
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/i18n.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ export declare const LANGS: readonly ['en', 'de'];
2
+ export type Lang = (typeof LANGS)[number];
3
+ /** One string per language. Adding a language makes every missing translation a type error. */
4
+ export type Text = Record<Lang, string>;
5
+ export declare const say: (lang: Lang, text: Text) => string;
package/dist/i18n.js ADDED
@@ -0,0 +1,3 @@
1
+ export const LANGS = ['en', 'de'];
2
+ export const say = (lang, text) => text[lang];
3
+ //# sourceMappingURL=i18n.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"i18n.js","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,IAAI,EAAE,IAAI,CAAU,CAAC;AAM3C,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,IAAU,EAAE,IAAU,EAAU,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  export { type Tracker, type TrackerCategory, trackers } from './data/trackers.js';
2
+ export { LANGS, type Lang, type Text } from './i18n.js';
3
+ export { legalReferences, REGIONS, type Region } from './legal.js';
2
4
  export { defaultRules, googleFonts, impressumLink, preConsentTrackers, privacyPolicyLink, rejectOption, thirdPartyCdns, thirdPartyEmbeds, trackersAfterReject, } from './rules/index.js';
3
5
  export { type ScanOptions, scan } from './scanner.js';
4
6
  export type * from './types.js';
package/dist/index.js CHANGED
@@ -1,4 +1,6 @@
1
1
  export { trackers } from './data/trackers.js';
2
+ export { LANGS } from './i18n.js';
3
+ export { legalReferences, REGIONS } from './legal.js';
2
4
  export { defaultRules, googleFonts, impressumLink, preConsentTrackers, privacyPolicyLink, rejectOption, thirdPartyCdns, thirdPartyEmbeds, trackersAfterReject, } from './rules/index.js';
3
5
  export { scan } from './scanner.js';
4
6
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsC,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAClF,OAAO,EACL,YAAY,EACZ,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAoB,IAAI,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsC,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAClF,OAAO,EAAE,KAAK,EAAwB,MAAM,WAAW,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,OAAO,EAAe,MAAM,YAAY,CAAC;AACnE,OAAO,EACL,YAAY,EACZ,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAoB,IAAI,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { Finding } from './types.js';
2
+ export declare const REGIONS: readonly ['de', 'at', 'ch', 'eu'];
3
+ export type Region = (typeof REGIONS)[number];
4
+ export declare const legalReferences: (ruleId: string, region: Region) => string[] | undefined;
5
+ /**
6
+ * Attaches the legal basis of the chosen country to each finding and adjusts
7
+ * its severity where that country's law is softer or stricter. Findings of
8
+ * custom rules without an entry above are left as they are.
9
+ */
10
+ export declare function applyRegion(findings: readonly Finding[], region: Region): Finding[];
package/dist/legal.js ADDED
@@ -0,0 +1,99 @@
1
+ export const REGIONS = ['de', 'at', 'ch', 'eu'];
2
+ /**
3
+ * Legal basis per rule and country, cited the way lawyers in that country
4
+ * would cite it. `eu` is for sites outside Germany, Austria and Switzerland
5
+ * and refers to the EU instruments directly.
6
+ */
7
+ const LEGAL = {
8
+ 'pre-consent-trackers': {
9
+ de: ['§ 25 Abs. 1 TDDDG', 'Art. 6 Abs. 1 lit. a DSGVO', 'EuGH C-673/17 (Planet49)'],
10
+ at: ['§ 165 Abs. 3 TKG 2021', 'Art. 6 Abs. 1 lit. a DSGVO', 'EuGH C-673/17 (Planet49)'],
11
+ ch: ['Art. 45c FMG', 'Art. 6 DSG'],
12
+ eu: ['Art. 5(3) ePrivacy Directive', 'Art. 6(1)(a) GDPR', 'CJEU C-673/17 (Planet49)'],
13
+ },
14
+ 'trackers-after-reject': {
15
+ de: ['§ 25 Abs. 1 TDDDG', 'Art. 7 Abs. 3 DSGVO'],
16
+ at: ['§ 165 Abs. 3 TKG 2021', 'Art. 7 Abs. 3 DSGVO'],
17
+ ch: ['Art. 45c FMG', 'Art. 30 Abs. 2 lit. b DSG'],
18
+ eu: ['Art. 5(3) ePrivacy Directive', 'Art. 7(3) GDPR'],
19
+ },
20
+ 'reject-option': {
21
+ de: [
22
+ '§ 25 Abs. 1 TDDDG',
23
+ 'Art. 4 Nr. 11 DSGVO',
24
+ 'EDSA Cookie-Banner-Taskforce, 17.01.2023',
25
+ 'DSK-Beschluss, 22.03.2023 (Pur-Abo-Modelle)',
26
+ ],
27
+ at: [
28
+ '§ 165 Abs. 3 TKG 2021',
29
+ 'Art. 4 Nr. 11 DSGVO',
30
+ 'EDSA Cookie-Banner-Taskforce, 17.01.2023',
31
+ ],
32
+ ch: ['Art. 45c FMG', 'EDÖB, Leitfaden zu Cookies (2025)'],
33
+ eu: ['Art. 4(11) GDPR', 'Art. 7(3) GDPR', 'EDPB Cookie Banner Taskforce report, 17.01.2023'],
34
+ },
35
+ 'google-fonts': {
36
+ de: ['Art. 6 Abs. 1 DSGVO', 'LG München I, 20.01.2022, Az. 3 O 17493/20'],
37
+ at: ['Art. 6 Abs. 1 DSGVO'],
38
+ ch: ['Art. 6 DSG'],
39
+ eu: ['Art. 6(1) GDPR'],
40
+ },
41
+ 'third-party-embeds': {
42
+ de: ['Art. 6 Abs. 1 DSGVO', '§ 25 Abs. 1 TDDDG'],
43
+ at: ['Art. 6 Abs. 1 DSGVO', '§ 165 Abs. 3 TKG 2021'],
44
+ ch: ['Art. 6 DSG', 'Art. 45c FMG'],
45
+ eu: ['Art. 6(1) GDPR', 'Art. 5(3) ePrivacy Directive'],
46
+ },
47
+ 'third-party-cdns': {
48
+ de: ['Art. 6 Abs. 1 DSGVO'],
49
+ at: ['Art. 6 Abs. 1 DSGVO'],
50
+ ch: ['Art. 6 DSG'],
51
+ eu: ['Art. 6(1) GDPR'],
52
+ },
53
+ 'impressum-link': {
54
+ de: ['§ 5 DDG', 'BGH, 20.07.2006, Az. I ZR 228/03'],
55
+ at: ['§ 5 ECG', '§ 25 MedienG'],
56
+ ch: ['Art. 3 Abs. 1 lit. s UWG'],
57
+ eu: ['Art. 5 Directive 2000/31/EC (e-commerce)'],
58
+ },
59
+ 'privacy-policy-link': {
60
+ de: ['Art. 12 DSGVO', 'Art. 13 DSGVO'],
61
+ at: ['Art. 12 DSGVO', 'Art. 13 DSGVO'],
62
+ ch: ['Art. 19 DSG'],
63
+ eu: ['Art. 12 GDPR', 'Art. 13 GDPR'],
64
+ },
65
+ };
66
+ export const legalReferences = (ruleId, region) => LEGAL[ruleId]?.[region];
67
+ /**
68
+ * Attaches the legal basis of the chosen country to each finding and adjusts
69
+ * its severity where that country's law is softer or stricter. Findings of
70
+ * custom rules without an entry above are left as they are.
71
+ */
72
+ export function applyRegion(findings, region) {
73
+ return findings.map((finding) => {
74
+ const references = legalReferences(finding.ruleId, region);
75
+ return {
76
+ ...finding,
77
+ severity: severityFor(finding, region),
78
+ ...(references === undefined ? {} : { references }),
79
+ };
80
+ });
81
+ }
82
+ /**
83
+ * Switzerland uses an opt-out model for cookies and tracking (Art. 45c FMG) and
84
+ * requires an imprint only for offers in electronic commerce, so those findings
85
+ * drop one level there. Ignoring an explicit refusal stays as serious as anywhere.
86
+ */
87
+ const SOFTER_IN_SWITZERLAND = new Set([
88
+ 'pre-consent-trackers',
89
+ 'third-party-embeds',
90
+ 'impressum-link',
91
+ ]);
92
+ function severityFor(finding, region) {
93
+ if (region === 'ch' && SOFTER_IN_SWITZERLAND.has(finding.ruleId)) {
94
+ return lower(finding.severity);
95
+ }
96
+ return finding.severity;
97
+ }
98
+ const lower = (severity) => (severity === 'error' ? 'warning' : 'info');
99
+ //# sourceMappingURL=legal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legal.js","sourceRoot":"","sources":["../src/legal.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
- import { countBySeverity, describeConsent, groupByPage, plural } from './shared.js';
1
+ import { messagesFor } from './messages.js';
2
+ import { countBySeverity, groupByPage } from './shared.js';
2
3
  const ICONS = { error: '🔴', warning: '🟡', info: '🔵' };
3
4
  /**
4
5
  * Compact report for GitHub job summaries and PR comments.
@@ -8,38 +9,39 @@ const ICONS = { error: '🔴', warning: '🟡', info: '🔵' };
8
9
  * rendered inside code spans.
9
10
  */
10
11
  export function formatMarkdown(result) {
12
+ const m = messagesFor(result.lang);
11
13
  const counts = countBySeverity(result.findings);
12
14
  const lines = [
13
15
  `### privalint: ${code(result.siteUrl)}`,
14
16
  '',
15
- `${plural(counts.error, 'error')} · ${plural(counts.warning, 'warning')} · ${plural(result.pages.length, 'page')} scanned`,
17
+ `${m.errors(counts.error)} · ${m.warnings(counts.warning)} · ${m.scanned(m.pages(result.pages.length))}`,
16
18
  ];
17
- const consent = describeConsent(result.consent);
18
- if (consent !== undefined) {
19
- lines.push('', escapeText(consent));
19
+ if (result.consent !== undefined) {
20
+ lines.push('', escapeText(m.consent(result.consent)));
20
21
  }
21
22
  for (const [pageUrl, findings] of groupByPage(result.findings)) {
22
- lines.push('', `#### ${code(pageUrl)}`, '', '| | Rule | Finding |', '|---|---|---|');
23
+ lines.push('', `#### ${code(pageUrl)}`, '', `| | ${m.rule} | ${m.finding} |`, '|---|---|---|');
23
24
  for (const finding of findings) {
24
25
  lines.push(`| ${ICONS[finding.severity]} | \`${finding.ruleId}\` | ${escapeText(finding.message)} |`);
25
26
  }
26
27
  }
27
28
  const failed = result.pages.filter((page) => page.error !== undefined);
28
29
  if (failed.length > 0) {
29
- lines.push('', `${plural(failed.length, 'page')} could not be scanned:`, '');
30
+ lines.push('', m.couldNotScan(failed.length), '');
30
31
  for (const page of failed) {
31
32
  lines.push(`- ${code(page.url)}: ${escapeText(page.error ?? '')}`);
32
33
  }
33
34
  }
34
- const fixes = new Map(result.findings.filter((f) => f.fix !== undefined).map((f) => [f.ruleId, f.fix ?? '']));
35
+ const fixes = new Map(result.findings.filter((f) => f.fix !== undefined).map((f) => [f.ruleId, f]));
35
36
  if (fixes.size > 0) {
36
- lines.push('', '<details><summary>How to fix</summary>', '');
37
- for (const [ruleId, fix] of fixes) {
38
- lines.push(`- **${ruleId}**: ${escapeText(fix)}`);
37
+ lines.push('', `<details><summary>${m.howToFix}</summary>`, '');
38
+ for (const [ruleId, { fix, references }] of fixes) {
39
+ const legal = references?.length ? ` (${m.legalBasis} ${references.join('; ')})` : '';
40
+ lines.push(`- **${ruleId}**: ${escapeText(`${fix ?? ''}${legal}`)}`);
39
41
  }
40
42
  lines.push('', '</details>');
41
43
  }
42
- lines.push('', '<sub>Automated checks only. A clean result is not proof of GDPR compliance.</sub>');
44
+ lines.push('', `<sub>${m.disclaimer}</sub>`);
43
45
  return `${lines.join('\n')}\n`;
44
46
  }
45
47
  const code = (text) => `\`${text.replaceAll('`', '%60').replaceAll('\n', ' ')}\``;
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/reporters/markdown.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/reporters/markdown.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { Lang } from '../i18n.js';
2
+ import type { ConsentSummary } from '../types.js';
3
+ /** Fixed wording of the text and Markdown reports. */
4
+ export interface ReportMessages {
5
+ errors(count: number): string;
6
+ warnings(count: number): string;
7
+ pages(count: number): string;
8
+ duration(ms: number): string;
9
+ noProblems(pages: string, duration: string): string;
10
+ on: string;
11
+ scanned(pages: string): string;
12
+ couldNotScan(count: number): string;
13
+ fix: string;
14
+ legalBasis: string;
15
+ rule: string;
16
+ finding: string;
17
+ howToFix: string;
18
+ disclaimer: string;
19
+ consent(consent: ConsentSummary): string;
20
+ }
21
+ export declare const messagesFor: (lang: Lang) => ReportMessages;
@@ -0,0 +1,62 @@
1
+ const count = (n, one, many) => `${n} ${n === 1 ? one : many}`;
2
+ const en = {
3
+ errors: (n) => count(n, 'error', 'errors'),
4
+ warnings: (n) => count(n, 'warning', 'warnings'),
5
+ pages: (n) => count(n, 'page', 'pages'),
6
+ duration: (ms) => `${(ms / 1000).toFixed(1)}s`,
7
+ noProblems: (pages, duration) => `No problems found on ${pages} (${duration}).`,
8
+ on: 'on',
9
+ scanned: (pages) => `${pages} scanned`,
10
+ couldNotScan: (n) => `Could not scan ${count(n, 'page', 'pages')}:`,
11
+ fix: 'fix:',
12
+ legalBasis: 'legal basis:',
13
+ rule: 'Rule',
14
+ finding: 'Finding',
15
+ howToFix: 'How to fix',
16
+ disclaimer: 'Automated checks only. A clean result is not proof of GDPR compliance.',
17
+ consent(consent) {
18
+ if (!consent.bannerFound) {
19
+ return 'Consent banner: none found';
20
+ }
21
+ const vendor = consent.cmp === undefined ? '' : ` (${consent.cmp})`;
22
+ if (consent.error !== undefined) {
23
+ return `Consent banner${vendor}: found, but rejecting failed: ${consent.error}`;
24
+ }
25
+ if (consent.rejected) {
26
+ return `Consent banner${vendor}: clicked "${consent.rejectLabel}" and reloaded`;
27
+ }
28
+ return `Consent banner${vendor}: found, no reject button`;
29
+ },
30
+ };
31
+ const de = {
32
+ errors: (n) => count(n, 'Fehler', 'Fehler'),
33
+ warnings: (n) => count(n, 'Warnung', 'Warnungen'),
34
+ pages: (n) => count(n, 'Seite', 'Seiten'),
35
+ duration: (ms) => `${(ms / 1000).toFixed(1).replace('.', ',')} s`,
36
+ noProblems: (pages, duration) => `Keine Probleme auf ${pages} gefunden (${duration}).`,
37
+ on: 'auf',
38
+ scanned: (pages) => `${pages} geprüft`,
39
+ couldNotScan: (n) => `${count(n, 'Seite', 'Seiten')} ${n === 1 ? 'konnte' : 'konnten'} nicht geprüft werden:`,
40
+ fix: 'Lösung:',
41
+ legalBasis: 'Rechtsgrundlage:',
42
+ rule: 'Regel',
43
+ finding: 'Befund',
44
+ howToFix: 'So beheben Sie es',
45
+ disclaimer: 'Nur automatisierte Prüfungen. Ein sauberes Ergebnis ist kein Nachweis der DSGVO-Konformität.',
46
+ consent(consent) {
47
+ if (!consent.bannerFound) {
48
+ return 'Cookie-Banner: keines gefunden';
49
+ }
50
+ const vendor = consent.cmp === undefined ? '' : ` (${consent.cmp})`;
51
+ if (consent.error !== undefined) {
52
+ return `Cookie-Banner${vendor}: gefunden, aber Ablehnen ist fehlgeschlagen: ${consent.error}`;
53
+ }
54
+ if (consent.rejected) {
55
+ return `Cookie-Banner${vendor}: „${consent.rejectLabel}“ geklickt und neu geladen`;
56
+ }
57
+ return `Cookie-Banner${vendor}: gefunden, kein Ablehnen-Button`;
58
+ },
59
+ };
60
+ const MESSAGES = { en, de };
61
+ export const messagesFor = (lang) => MESSAGES[lang];
62
+ //# sourceMappingURL=messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/reporters/messages.ts"],"names":[],"mappings":"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"}
@@ -50,7 +50,13 @@ function toResult(finding) {
50
50
  ruleId: finding.ruleId,
51
51
  level: LEVELS[finding.severity],
52
52
  message: {
53
- text: [finding.message, `Page: ${finding.pageUrl}`, evidence, finding.fix]
53
+ text: [
54
+ finding.message,
55
+ `Page: ${finding.pageUrl}`,
56
+ evidence,
57
+ finding.fix,
58
+ finding.references?.join('; '),
59
+ ]
54
60
  .filter(Boolean)
55
61
  .join('\n\n'),
56
62
  },
@@ -1 +1 @@
1
- {"version":3,"file":"sarif.js","sourceRoot":"","sources":["../../src/reporters/sarif.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sarif.js","sourceRoot":"","sources":["../../src/reporters/sarif.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,3 @@
1
- import type { ConsentSummary, Finding, Severity } from '../types.js';
1
+ import type { Finding, Severity } from '../types.js';
2
2
  export declare function groupByPage(findings: readonly Finding[]): Map<string, Finding[]>;
3
3
  export declare function countBySeverity(findings: readonly Finding[]): Record<Severity, number>;
4
- export declare function describeConsent(consent: ConsentSummary | undefined): string | undefined;
5
- export declare const plural: (count: number, word: string) => string;
@@ -14,21 +14,4 @@ export function countBySeverity(findings) {
14
14
  }
15
15
  return counts;
16
16
  }
17
- export function describeConsent(consent) {
18
- if (consent === undefined) {
19
- return undefined;
20
- }
21
- if (!consent.bannerFound) {
22
- return 'Consent banner: none found';
23
- }
24
- const vendor = consent.cmp === undefined ? '' : ` (${consent.cmp})`;
25
- if (consent.error !== undefined) {
26
- return `Consent banner${vendor}: found, but rejecting failed: ${consent.error}`;
27
- }
28
- if (consent.rejected) {
29
- return `Consent banner${vendor}: clicked "${consent.rejectLabel}" and reloaded`;
30
- }
31
- return `Consent banner${vendor}: found, no reject button`;
32
- }
33
- export const plural = (count, word) => `${count} ${word}${count === 1 ? '' : 's'}`;
34
17
  //# sourceMappingURL=shared.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/reporters/shared.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,WAAW,CAAC,QAA4B;IACtD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC3C,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAC9C,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACnB,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,QAA4B;IAC1D,MAAM,MAAM,GAA6B,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAC3E,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;IAC7B,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAmC;IACjE,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QACzB,OAAO,4BAA4B,CAAC;IACtC,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,GAAG,GAAG,CAAC;IACpE,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAChC,OAAO,iBAAiB,MAAM,kCAAkC,OAAO,CAAC,KAAK,EAAE,CAAC;IAClF,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,OAAO,iBAAiB,MAAM,cAAc,OAAO,CAAC,WAAW,gBAAgB,CAAC;IAClF,CAAC;IACD,OAAO,iBAAiB,MAAM,2BAA2B,CAAC;AAC5D,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,KAAa,EAAE,IAAY,EAAE,EAAE,CAAC,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC"}
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/reporters/shared.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,WAAW,CAAC,QAA4B;IACtD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC3C,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAC9C,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACnB,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,QAA4B;IAC1D,MAAM,MAAM,GAA6B,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAC3E,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;IAC7B,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}