@slashgear/gdpr-cookie-scanner 3.5.1 → 3.7.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 (113) hide show
  1. package/CHANGELOG.md +106 -0
  2. package/CLAUDE.md +12 -1
  3. package/NEXT_STEPS.md +37 -3
  4. package/README.md +23 -0
  5. package/dist/analyzers/colour.d.ts +36 -0
  6. package/dist/analyzers/colour.d.ts.map +1 -0
  7. package/dist/analyzers/colour.js +75 -0
  8. package/dist/analyzers/colour.js.map +1 -0
  9. package/dist/analyzers/compliance.d.ts.map +1 -1
  10. package/dist/analyzers/compliance.js +24 -6
  11. package/dist/analyzers/compliance.js.map +1 -1
  12. package/dist/analyzers/tcf-decoder.d.ts +9 -0
  13. package/dist/analyzers/tcf-decoder.d.ts.map +1 -0
  14. package/dist/analyzers/tcf-decoder.js +123 -0
  15. package/dist/analyzers/tcf-decoder.js.map +1 -0
  16. package/dist/analyzers/wording.d.ts +1 -0
  17. package/dist/analyzers/wording.d.ts.map +1 -1
  18. package/dist/analyzers/wording.js +39 -0
  19. package/dist/analyzers/wording.js.map +1 -1
  20. package/dist/report/generator.d.ts +1 -2
  21. package/dist/report/generator.d.ts.map +1 -1
  22. package/dist/report/generator.js +80 -108
  23. package/dist/report/generator.js.map +1 -1
  24. package/dist/report/html.d.ts.map +1 -1
  25. package/dist/report/html.js +173 -4
  26. package/dist/report/html.js.map +1 -1
  27. package/dist/scanner/consent-modal.d.ts.map +1 -1
  28. package/dist/scanner/consent-modal.js +57 -39
  29. package/dist/scanner/consent-modal.js.map +1 -1
  30. package/dist/scanner/index.d.ts.map +1 -1
  31. package/dist/scanner/index.js +4 -0
  32. package/dist/scanner/index.js.map +1 -1
  33. package/dist/scanner/tcf.d.ts +9 -0
  34. package/dist/scanner/tcf.d.ts.map +1 -0
  35. package/dist/scanner/tcf.js +72 -0
  36. package/dist/scanner/tcf.js.map +1 -0
  37. package/dist/types.d.ts +26 -0
  38. package/dist/types.d.ts.map +1 -1
  39. package/docs/index.html +37 -49
  40. package/docs/reports/www.arte.tv/after-accept.png +0 -0
  41. package/docs/reports/www.arte.tv/after-reject.png +0 -0
  42. package/docs/reports/www.arte.tv/gdpr-report-arte.tv-2026-02-24.html +997 -0
  43. package/docs/reports/www.deezer.com/after-accept.png +0 -0
  44. package/docs/reports/www.deezer.com/after-reject.png +0 -0
  45. package/docs/reports/www.deezer.com/gdpr-report-deezer.com-2026-02-22.html +1667 -0
  46. package/docs/reports/www.impots.gouv.fr/after-accept.png +0 -0
  47. package/docs/reports/www.impots.gouv.fr/after-reject.png +0 -0
  48. package/docs/reports/www.impots.gouv.fr/gdpr-report-impots.gouv.fr-2026-02-22.html +751 -0
  49. package/docs/reports/www.leboncoin.fr/after-accept.png +0 -0
  50. package/docs/reports/www.leboncoin.fr/after-reject.png +0 -0
  51. package/docs/reports/www.leboncoin.fr/gdpr-report-leboncoin.fr-2026-02-22.html +764 -0
  52. package/docs/reports/www.netflix.com/after-accept.png +0 -0
  53. package/docs/reports/www.netflix.com/after-reject.png +0 -0
  54. package/docs/reports/www.netflix.com/gdpr-report-netflix.com-2026-02-23.html +1050 -0
  55. package/docs/reports/www.radiofrance.fr/after-accept.png +0 -0
  56. package/docs/reports/www.radiofrance.fr/after-reject.png +0 -0
  57. package/docs/reports/www.radiofrance.fr/gdpr-report-radiofrance.fr-2026-02-24.html +1145 -0
  58. package/package.json +1 -2
  59. package/src/analyzers/colour.ts +89 -0
  60. package/src/analyzers/compliance.ts +35 -10
  61. package/src/analyzers/tcf-decoder.ts +130 -0
  62. package/src/analyzers/wording.ts +44 -0
  63. package/src/report/generator.ts +92 -119
  64. package/src/report/html.ts +197 -4
  65. package/src/scanner/consent-modal.ts +64 -38
  66. package/src/scanner/index.ts +5 -0
  67. package/src/scanner/tcf.ts +80 -0
  68. package/src/types.ts +29 -0
  69. package/tests/analyzers/colour.test.ts +187 -0
  70. package/tests/analyzers/compliance.test.ts +102 -0
  71. package/tests/analyzers/tcf-decoder.test.ts +292 -0
  72. package/tests/analyzers/wording.test.ts +38 -0
  73. package/tests/scanner/button-classification.test.ts +32 -0
  74. package/docs/reports/github.com/after-accept.png +0 -0
  75. package/docs/reports/github.com/after-reject.png +0 -0
  76. package/docs/reports/github.com/gdpr-checklist-github.com-2026-02-22.md +0 -44
  77. package/docs/reports/github.com/gdpr-cookies-github.com-2026-02-22.md +0 -29
  78. package/docs/reports/github.com/gdpr-report-github.com-2026-02-22.md +0 -102
  79. package/docs/reports/github.com/gdpr-report-github.com-2026-02-22.pdf +0 -0
  80. package/docs/reports/gitlab.com/after-accept.png +0 -0
  81. package/docs/reports/gitlab.com/after-reject.png +0 -0
  82. package/docs/reports/gitlab.com/gdpr-checklist-gitlab.com-2026-02-22.md +0 -44
  83. package/docs/reports/gitlab.com/gdpr-cookies-gitlab.com-2026-02-22.md +0 -55
  84. package/docs/reports/gitlab.com/gdpr-report-gitlab.com-2026-02-22.md +0 -200
  85. package/docs/reports/gitlab.com/gdpr-report-gitlab.com-2026-02-22.pdf +0 -0
  86. package/docs/reports/gitlab.com/modal-initial.png +0 -0
  87. package/docs/reports/npmjs.com/after-accept.png +0 -0
  88. package/docs/reports/npmjs.com/after-reject.png +0 -0
  89. package/docs/reports/npmjs.com/gdpr-checklist-npmjs.com-2026-02-22.md +0 -44
  90. package/docs/reports/npmjs.com/gdpr-cookies-npmjs.com-2026-02-22.md +0 -25
  91. package/docs/reports/npmjs.com/gdpr-report-npmjs.com-2026-02-22.md +0 -88
  92. package/docs/reports/npmjs.com/gdpr-report-npmjs.com-2026-02-22.pdf +0 -0
  93. package/docs/reports/reddit.com/after-accept.png +0 -0
  94. package/docs/reports/reddit.com/after-reject.png +0 -0
  95. package/docs/reports/reddit.com/gdpr-checklist-reddit.com-2026-02-22.md +0 -44
  96. package/docs/reports/reddit.com/gdpr-cookies-reddit.com-2026-02-22.md +0 -33
  97. package/docs/reports/reddit.com/gdpr-report-reddit.com-2026-02-22.md +0 -148
  98. package/docs/reports/reddit.com/gdpr-report-reddit.com-2026-02-22.pdf +0 -0
  99. package/docs/reports/reddit.com/modal-initial.png +0 -0
  100. package/docs/reports/stackoverflow.com/after-accept.png +0 -0
  101. package/docs/reports/stackoverflow.com/after-reject.png +0 -0
  102. package/docs/reports/stackoverflow.com/gdpr-checklist-stackoverflow.com-2026-02-22.md +0 -44
  103. package/docs/reports/stackoverflow.com/gdpr-cookies-stackoverflow.com-2026-02-22.md +0 -67
  104. package/docs/reports/stackoverflow.com/gdpr-report-stackoverflow.com-2026-02-22.md +0 -206
  105. package/docs/reports/stackoverflow.com/gdpr-report-stackoverflow.com-2026-02-22.pdf +0 -0
  106. package/docs/reports/stackoverflow.com/modal-initial.png +0 -0
  107. package/docs/reports/www.afp.com/after-accept.png +0 -0
  108. package/docs/reports/www.afp.com/after-reject.png +0 -0
  109. package/docs/reports/www.afp.com/gdpr-checklist-afp.com-2026-02-22.md +0 -44
  110. package/docs/reports/www.afp.com/gdpr-cookies-afp.com-2026-02-22.md +0 -42
  111. package/docs/reports/www.afp.com/gdpr-report-afp.com-2026-02-22.md +0 -202
  112. package/docs/reports/www.afp.com/gdpr-report-afp.com-2026-02-22.pdf +0 -0
  113. package/docs/reports/www.afp.com/modal-initial.png +0 -0
@@ -0,0 +1,72 @@
1
+ import { decodeTcfConsentString } from "../analyzers/tcf-decoder.js";
2
+ /**
3
+ * Detect the IAB TCF (Transparency and Consent Framework) implementation on the page.
4
+ * Called at the end of Phase 1, after the initial page load and timeout.
5
+ * Purely informational — results do not affect the compliance score.
6
+ */
7
+ export async function detectTcf(page, cookies) {
8
+ // Step 1: Check for TCF v2 (__tcfapi) and v1 (__cmp) API
9
+ let apiPresent = false;
10
+ try {
11
+ apiPresent = await page.evaluate(() => {
12
+ const w = window;
13
+ return typeof w["__tcfapi"] === "function" || typeof w["__cmp"] === "function";
14
+ });
15
+ }
16
+ catch {
17
+ // Page context may have been destroyed
18
+ }
19
+ // Step 2: Check for __tcfapiLocator iframe
20
+ const locatorFramePresent = page.frames().some((f) => f.name() === "__tcfapiLocator");
21
+ // Step 3: Look for euconsent cookies already captured
22
+ const euconsentV2 = cookies.find((c) => c.name === "euconsent-v2");
23
+ const euconsentV1 = cookies.find((c) => c.name === "euconsent");
24
+ const consentCookie = euconsentV2 ?? euconsentV1;
25
+ const cookieName = consentCookie?.name ?? null;
26
+ // Step 4: Try to obtain the consent string via __tcfapi if the API is present
27
+ let tcString = consentCookie?.value ?? null;
28
+ if (apiPresent && !tcString) {
29
+ try {
30
+ const result = await page.evaluate(() => {
31
+ return new Promise((resolve) => {
32
+ const timeout = setTimeout(() => resolve(null), 3000);
33
+ try {
34
+ const w = window;
35
+ const tcfApi = w["__tcfapi"];
36
+ tcfApi("getTCData", 2, (tcData, success) => {
37
+ clearTimeout(timeout);
38
+ if (success && typeof tcData["tcString"] === "string") {
39
+ resolve(tcData["tcString"]);
40
+ }
41
+ else {
42
+ resolve(null);
43
+ }
44
+ });
45
+ }
46
+ catch {
47
+ clearTimeout(timeout);
48
+ resolve(null);
49
+ }
50
+ });
51
+ });
52
+ if (result)
53
+ tcString = result;
54
+ }
55
+ catch {
56
+ // page.evaluate() may throw if the page navigated
57
+ }
58
+ }
59
+ // Step 5: Decode the consent string
60
+ const consentString = tcString ? decodeTcfConsentString(tcString) : null;
61
+ const detected = apiPresent || locatorFramePresent || cookieName !== null;
62
+ return {
63
+ detected,
64
+ version: consentString?.version ?? (euconsentV2 ? 2 : euconsentV1 ? 1 : null),
65
+ apiPresent,
66
+ locatorFramePresent,
67
+ cookieName,
68
+ cmpId: consentString?.cmpId ?? null,
69
+ consentString,
70
+ };
71
+ }
72
+ //# sourceMappingURL=tcf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tcf.js","sourceRoot":"","sources":["../../src/scanner/tcf.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -98,6 +98,31 @@ export interface ScanOptions {
98
98
  /** Treat unrecognised cookies and unknown third-party requests as requiring consent. Default: false. */
99
99
  strict?: boolean;
100
100
  }
101
+ export interface TcfConsentString {
102
+ raw: string;
103
+ version: 1 | 2;
104
+ created: Date;
105
+ lastUpdated: Date;
106
+ cmpId: number;
107
+ cmpVersion: number;
108
+ consentLanguage: string;
109
+ vendorListVersion: number;
110
+ tcfPolicyVersion?: number;
111
+ isServiceSpecific?: boolean;
112
+ specialFeatureOptins: number[];
113
+ purposesConsent: number[];
114
+ purposesLegitimateInterest: number[];
115
+ publisherCC?: string;
116
+ }
117
+ export interface TcfInfo {
118
+ detected: boolean;
119
+ version: 1 | 2 | null;
120
+ apiPresent: boolean;
121
+ locatorFramePresent: boolean;
122
+ cookieName: string | null;
123
+ cmpId: number | null;
124
+ consentString: TcfConsentString | null;
125
+ }
101
126
  export interface ScanResult {
102
127
  url: string;
103
128
  scanDate: string;
@@ -113,5 +138,6 @@ export interface ScanResult {
113
138
  compliance: ComplianceScore;
114
139
  screenshotPaths: string[];
115
140
  errors: string[];
141
+ tcf: TcfInfo;
116
142
  }
117
143
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/docs/index.html CHANGED
@@ -6,7 +6,7 @@
6
6
  <title>gdpr-cookie-scanner — GDPR compliance auditor for cookie consent</title>
7
7
  <meta
8
8
  name="description"
9
- content="Open-source CLI that audits websites for GDPR/RGPD cookie consent compliance using Playwright. Detects dark patterns, scores 4 compliance dimensions, and generates Markdown reports."
9
+ content="Open-source CLI that audits websites for GDPR/RGPD cookie consent compliance using Playwright. Detects dark patterns, scores 4 compliance dimensions, and generates detailed HTML reports."
10
10
  />
11
11
  <link rel="stylesheet" href="style.css" />
12
12
  </head>
@@ -37,7 +37,7 @@
37
37
  </h1>
38
38
  <p class="hero-tagline">
39
39
  Open-source CLI that scans any website for GDPR compliance — detects dark patterns, scores
40
- 4 regulatory dimensions, and generates ready-to-share Markdown reports.
40
+ 4 regulatory dimensions, and generates ready-to-share HTML reports.
41
41
  </p>
42
42
 
43
43
  <div class="install-block">
@@ -97,10 +97,10 @@
97
97
  </div>
98
98
  <div class="feature-card">
99
99
  <div class="feature-icon">📄</div>
100
- <h3>3 Markdown reports</h3>
100
+ <h3>Detailed HTML report</h3>
101
101
  <p>
102
- Compliance report, per-rule checklist with legal references, and a deduplicated cookie
103
- inventoryall rendered in GitHub.
102
+ Full compliance report with score breakdown, dark pattern evidence, cookie inventory,
103
+ and IAB TCF analysis ready to share or attach to an audit.
104
104
  </p>
105
105
  </div>
106
106
  <div class="feature-card">
@@ -120,124 +120,112 @@
120
120
  <div class="container">
121
121
  <h2 class="section-title">Live GDPR reports</h2>
122
122
  <p class="section-subtitle">
123
- Real scans run on 22 Feb 2026. Click to read the full Markdown report.
123
+ Real scans run on Feb 2026. Click to open the full interactive HTML report.
124
124
  </p>
125
125
  <div class="reports-grid">
126
- <!-- reddit.com34/100 F -->
126
+ <!-- radiofrance.fr87/100 B -->
127
127
  <div class="report-card">
128
128
  <div class="report-header">
129
- <div class="grade-badge grade-F">F</div>
129
+ <div class="grade-badge grade-B">B</div>
130
130
  <div class="report-meta">
131
- <h3>reddit.com</h3>
132
- <span class="score">34 / 100</span>
131
+ <h3>radiofrance.fr</h3>
132
+ <span class="score">87 / 100</span>
133
133
  </div>
134
134
  </div>
135
- <p class="report-date">Scanned 22 Feb 2026</p>
135
+ <p class="report-date">Scanned 24 Feb 2026</p>
136
136
  <a
137
137
  class="btn btn-outline"
138
- href="https://github.com/Slashgear/gdpr-cookie-scanner/blob/main/docs/reports/reddit.com/gdpr-report-reddit.com-2026-02-22.md"
139
- target="_blank"
140
- rel="noopener"
138
+ href="reports/www.radiofrance.fr/gdpr-report-radiofrance.fr-2026-02-24.html"
141
139
  >
142
140
  View report →
143
141
  </a>
144
142
  </div>
145
143
 
146
- <!-- github.com — 15/100 F -->
144
+ <!-- deezer.com — 80/100 B -->
147
145
  <div class="report-card">
148
146
  <div class="report-header">
149
- <div class="grade-badge grade-F">F</div>
147
+ <div class="grade-badge grade-B">B</div>
150
148
  <div class="report-meta">
151
- <h3>github.com</h3>
152
- <span class="score">15 / 100</span>
149
+ <h3>deezer.com</h3>
150
+ <span class="score">80 / 100</span>
153
151
  </div>
154
152
  </div>
155
153
  <p class="report-date">Scanned 22 Feb 2026</p>
156
154
  <a
157
155
  class="btn btn-outline"
158
- href="https://github.com/Slashgear/gdpr-cookie-scanner/blob/main/docs/reports/github.com/gdpr-report-github.com-2026-02-22.md"
159
- target="_blank"
160
- rel="noopener"
156
+ href="reports/www.deezer.com/gdpr-report-deezer.com-2026-02-22.html"
161
157
  >
162
158
  View report →
163
159
  </a>
164
160
  </div>
165
161
 
166
- <!-- gitlab.com — 50/100 D -->
162
+ <!-- netflix.com — 71/100 C -->
167
163
  <div class="report-card">
168
164
  <div class="report-header">
169
- <div class="grade-badge grade-D">D</div>
165
+ <div class="grade-badge grade-C">C</div>
170
166
  <div class="report-meta">
171
- <h3>gitlab.com</h3>
172
- <span class="score">50 / 100</span>
167
+ <h3>netflix.com</h3>
168
+ <span class="score">71 / 100</span>
173
169
  </div>
174
170
  </div>
175
- <p class="report-date">Scanned 22 Feb 2026</p>
171
+ <p class="report-date">Scanned 23 Feb 2026</p>
176
172
  <a
177
173
  class="btn btn-outline"
178
- href="https://github.com/Slashgear/gdpr-cookie-scanner/blob/main/docs/reports/gitlab.com/gdpr-report-gitlab.com-2026-02-22.md"
179
- target="_blank"
180
- rel="noopener"
174
+ href="reports/www.netflix.com/gdpr-report-netflix.com-2026-02-23.html"
181
175
  >
182
176
  View report →
183
177
  </a>
184
178
  </div>
185
179
 
186
- <!-- stackoverflow.com66/100 C -->
180
+ <!-- arte.tv53/100 D -->
187
181
  <div class="report-card">
188
182
  <div class="report-header">
189
- <div class="grade-badge grade-C">C</div>
183
+ <div class="grade-badge grade-D">D</div>
190
184
  <div class="report-meta">
191
- <h3>stackoverflow.com</h3>
192
- <span class="score">66 / 100</span>
185
+ <h3>arte.tv</h3>
186
+ <span class="score">53 / 100</span>
193
187
  </div>
194
188
  </div>
195
- <p class="report-date">Scanned 22 Feb 2026</p>
189
+ <p class="report-date">Scanned 24 Feb 2026</p>
196
190
  <a
197
191
  class="btn btn-outline"
198
- href="https://github.com/Slashgear/gdpr-cookie-scanner/blob/main/docs/reports/stackoverflow.com/gdpr-report-stackoverflow.com-2026-02-22.md"
199
- target="_blank"
200
- rel="noopener"
192
+ href="reports/www.arte.tv/gdpr-report-arte.tv-2026-02-24.html"
201
193
  >
202
194
  View report →
203
195
  </a>
204
196
  </div>
205
197
 
206
- <!-- npmjs.com — 25/100 F -->
198
+ <!-- leboncoin.fr — 25/100 F -->
207
199
  <div class="report-card">
208
200
  <div class="report-header">
209
201
  <div class="grade-badge grade-F">F</div>
210
202
  <div class="report-meta">
211
- <h3>npmjs.com</h3>
203
+ <h3>leboncoin.fr</h3>
212
204
  <span class="score">25 / 100</span>
213
205
  </div>
214
206
  </div>
215
207
  <p class="report-date">Scanned 22 Feb 2026</p>
216
208
  <a
217
209
  class="btn btn-outline"
218
- href="https://github.com/Slashgear/gdpr-cookie-scanner/blob/main/docs/reports/npmjs.com/gdpr-report-npmjs.com-2026-02-22.md"
219
- target="_blank"
220
- rel="noopener"
210
+ href="reports/www.leboncoin.fr/gdpr-report-leboncoin.fr-2026-02-22.html"
221
211
  >
222
212
  View report →
223
213
  </a>
224
214
  </div>
225
215
 
226
- <!-- afp.com47/100 D -->
216
+ <!-- impots.gouv.fr25/100 F -->
227
217
  <div class="report-card">
228
218
  <div class="report-header">
229
- <div class="grade-badge grade-D">D</div>
219
+ <div class="grade-badge grade-F">F</div>
230
220
  <div class="report-meta">
231
- <h3>afp.com</h3>
232
- <span class="score">47 / 100</span>
221
+ <h3>impots.gouv.fr</h3>
222
+ <span class="score">25 / 100</span>
233
223
  </div>
234
224
  </div>
235
225
  <p class="report-date">Scanned 22 Feb 2026</p>
236
226
  <a
237
227
  class="btn btn-outline"
238
- href="https://github.com/Slashgear/gdpr-cookie-scanner/blob/main/docs/reports/www.afp.com/gdpr-report-afp.com-2026-02-22.md"
239
- target="_blank"
240
- rel="noopener"
228
+ href="reports/www.impots.gouv.fr/gdpr-report-impots.gouv.fr-2026-02-22.html"
241
229
  >
242
230
  View report →
243
231
  </a>