@dreamdata_io/verify-tracking 0.1.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 (108) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +756 -0
  3. package/dist/ai/checker.js +222 -0
  4. package/dist/ai/checker.js.map +1 -0
  5. package/dist/ai/checklist.js +190 -0
  6. package/dist/ai/checklist.js.map +1 -0
  7. package/dist/ai/cli-presets.js +27 -0
  8. package/dist/ai/cli-presets.js.map +1 -0
  9. package/dist/ai/evidence-view.js +143 -0
  10. package/dist/ai/evidence-view.js.map +1 -0
  11. package/dist/ai/local-cli.js +58 -0
  12. package/dist/ai/local-cli.js.map +1 -0
  13. package/dist/ai/openai-compatible.js +78 -0
  14. package/dist/ai/openai-compatible.js.map +1 -0
  15. package/dist/ai/response-parser.js +105 -0
  16. package/dist/ai/response-parser.js.map +1 -0
  17. package/dist/ai/types.js +2 -0
  18. package/dist/ai/types.js.map +1 -0
  19. package/dist/analysis/consent-mode.js +225 -0
  20. package/dist/analysis/consent-mode.js.map +1 -0
  21. package/dist/analysis/deployment.js +2658 -0
  22. package/dist/analysis/deployment.js.map +1 -0
  23. package/dist/analysis/diagnosis/copy.en.js +303 -0
  24. package/dist/analysis/diagnosis/copy.en.js.map +1 -0
  25. package/dist/analysis/diagnosis/diagnose.js +172 -0
  26. package/dist/analysis/diagnosis/diagnose.js.map +1 -0
  27. package/dist/analysis/diagnosis/docs.js +118 -0
  28. package/dist/analysis/diagnosis/docs.js.map +1 -0
  29. package/dist/analysis/diagnosis/index.js +5 -0
  30. package/dist/analysis/diagnosis/index.js.map +1 -0
  31. package/dist/analysis/diagnosis/rules.js +656 -0
  32. package/dist/analysis/diagnosis/rules.js.map +1 -0
  33. package/dist/analysis/diagnosis/types.js +2 -0
  34. package/dist/analysis/diagnosis/types.js.map +1 -0
  35. package/dist/cli.js +344 -0
  36. package/dist/cli.js.map +1 -0
  37. package/dist/config/env.js +100 -0
  38. package/dist/config/env.js.map +1 -0
  39. package/dist/config/preflight.js +167 -0
  40. package/dist/config/preflight.js.map +1 -0
  41. package/dist/config/user-config.js +79 -0
  42. package/dist/config/user-config.js.map +1 -0
  43. package/dist/evidence/collect.js +527 -0
  44. package/dist/evidence/collect.js.map +1 -0
  45. package/dist/evidence/consent-accept.js +377 -0
  46. package/dist/evidence/consent-accept.js.map +1 -0
  47. package/dist/evidence/consent.js +340 -0
  48. package/dist/evidence/consent.js.map +1 -0
  49. package/dist/evidence/constants.js +615 -0
  50. package/dist/evidence/constants.js.map +1 -0
  51. package/dist/evidence/globals.js +132 -0
  52. package/dist/evidence/globals.js.map +1 -0
  53. package/dist/evidence/gtm-container.js +432 -0
  54. package/dist/evidence/gtm-container.js.map +1 -0
  55. package/dist/evidence/heuristic-banner.js +107 -0
  56. package/dist/evidence/heuristic-banner.js.map +1 -0
  57. package/dist/evidence/http-probe.js +139 -0
  58. package/dist/evidence/http-probe.js.map +1 -0
  59. package/dist/evidence/init-script.js +112 -0
  60. package/dist/evidence/init-script.js.map +1 -0
  61. package/dist/evidence/network.js +365 -0
  62. package/dist/evidence/network.js.map +1 -0
  63. package/dist/evidence/preference-center.js +368 -0
  64. package/dist/evidence/preference-center.js.map +1 -0
  65. package/dist/evidence/script.js +425 -0
  66. package/dist/evidence/script.js.map +1 -0
  67. package/dist/evidence/second-page.js +332 -0
  68. package/dist/evidence/second-page.js.map +1 -0
  69. package/dist/evidence/selector-probe.js +53 -0
  70. package/dist/evidence/selector-probe.js.map +1 -0
  71. package/dist/evidence/stealth.js +21 -0
  72. package/dist/evidence/stealth.js.map +1 -0
  73. package/dist/evidence/types.js +14 -0
  74. package/dist/evidence/types.js.map +1 -0
  75. package/dist/interactive/prompt.js +31 -0
  76. package/dist/interactive/prompt.js.map +1 -0
  77. package/dist/mcp/server.js +308 -0
  78. package/dist/mcp/server.js.map +1 -0
  79. package/dist/mcp/summary.js +41 -0
  80. package/dist/mcp/summary.js.map +1 -0
  81. package/dist/report/context.js +184 -0
  82. package/dist/report/context.js.map +1 -0
  83. package/dist/report/projection.js +125 -0
  84. package/dist/report/projection.js.map +1 -0
  85. package/dist/report/quote-check.js +90 -0
  86. package/dist/report/quote-check.js.map +1 -0
  87. package/dist/report/render.js +178 -0
  88. package/dist/report/render.js.map +1 -0
  89. package/dist/report/serializers.js +124 -0
  90. package/dist/report/serializers.js.map +1 -0
  91. package/dist/report/store.js +139 -0
  92. package/dist/report/store.js.map +1 -0
  93. package/dist/run/verify.js +77 -0
  94. package/dist/run/verify.js.map +1 -0
  95. package/dist/utils/duration.js +10 -0
  96. package/dist/utils/duration.js.map +1 -0
  97. package/dist/utils/errors.js +17 -0
  98. package/dist/utils/errors.js.map +1 -0
  99. package/dist/utils/logger.js +59 -0
  100. package/dist/utils/logger.js.map +1 -0
  101. package/dist/utils/runTimingsLog.js +27 -0
  102. package/dist/utils/runTimingsLog.js.map +1 -0
  103. package/dist/utils/slug.js +27 -0
  104. package/dist/utils/slug.js.map +1 -0
  105. package/dist/version.js +10 -0
  106. package/dist/version.js.map +1 -0
  107. package/package.json +57 -0
  108. package/scripts/install.sh +314 -0
@@ -0,0 +1,340 @@
1
+ import { BANNER_CONTEXT_KEYWORDS, BANNER_REVEAL_SCROLL_PX, BANNER_REVEAL_SETTLE_MS, CMP_VENDORS, DOM_ONLY_CMP_VENDORS, GENERIC_ACCEPT_PHRASES, GENERIC_REJECT_PHRASES, PREFERENCE_CENTER_COUNTERPART_PHRASES, } from "./constants.js";
2
+ import { runHeuristicBanner } from "./heuristic-banner.js";
3
+ import { CONSENT_SIGNAL_NAMES, CONSENT_V2_ONLY_SIGNALS, } from "./types.js";
4
+ /**
5
+ * Turns one recorded dataLayer consent push into typed fields.
6
+ *
7
+ * Parsed here rather than in the page for the same reason
8
+ * classifyAnalyticsStorage is: what a report says about a customer's install
9
+ * has to be decided somewhere a unit test can reach.
10
+ *
11
+ * Three fields matter beyond the value itself, and none of them was readable
12
+ * before without reaching into `raw` — which both compaction layers drop:
13
+ *
14
+ * - `verb` (raw[1]). A `default` is the site's configuration; an `update` is
15
+ * the visitor's decision. Logic that reads a push log without separating
16
+ * them treats a permissive default meant for some other visitor as consent.
17
+ * - `region` (raw[2].region). A region-scoped declaration overrides an
18
+ * earlier global one for the visitors it covers. It is the reason a push
19
+ * log can read "granted" on a page Google resolved to "denied".
20
+ * - `signals`. Which of the seven the call actually named — a v2-aware CMP
21
+ * call carries the two ad signals v2 added, a v1 one does not.
22
+ */
23
+ export function parseConsentPush(raw, timestamp) {
24
+ const push = { raw, verb: null, region: null, waitForUpdate: null, timestamp };
25
+ if (!Array.isArray(raw) || raw[0] !== "consent") {
26
+ // The {event:"consent"} object form init-script.ts also records. Nothing
27
+ // more can be said about it than that it happened.
28
+ push.verb = "other";
29
+ return push;
30
+ }
31
+ const verb = raw[1];
32
+ push.verb = verb === "default" || verb === "update" || verb === "declare" ? verb : "other";
33
+ const payload = raw[2];
34
+ if (payload === undefined || payload === null || typeof payload !== "object")
35
+ return push;
36
+ const signals = {};
37
+ for (const name of CONSENT_SIGNAL_NAMES) {
38
+ const value = payload[name];
39
+ if (value === "granted" || value === "denied")
40
+ signals[name] = value;
41
+ }
42
+ if (Object.keys(signals).length > 0)
43
+ push.signals = signals;
44
+ if (signals.analytics_storage !== undefined)
45
+ push.analyticsStorage = signals.analytics_storage;
46
+ // A `region` present but empty is not a scope; only a list of regions is.
47
+ const region = payload["region"];
48
+ if (Array.isArray(region) && region.length > 0) {
49
+ push.region = region.filter((entry) => typeof entry === "string");
50
+ }
51
+ const wait = payload["wait_for_update"];
52
+ if (typeof wait === "number" && Number.isFinite(wait))
53
+ push.waitForUpdate = wait;
54
+ return push;
55
+ }
56
+ /**
57
+ * Turns one google_tag_data.ics analytics_storage entry into a state and a
58
+ * provenance.
59
+ *
60
+ * The provenance rests on which KEYS the entry carries, not on its
61
+ * `implicit` flag. gtag.js sets `implicit: true` on every entry it ever
62
+ * touches — verified against live gtag.js for "nothing declared", an
63
+ * unregioned default, a region-scoped default that matches, and an explicit
64
+ * update: all of them read `implicit: true`. It therefore cannot tell a real
65
+ * declared default from gtag.js's own fallback, and trusting it labelled
66
+ * every properly-configured default as "implicit-default".
67
+ *
68
+ * What gtag.js does do is only write `default` when a declared default
69
+ * actually applies to this visitor. A region-scoped default whose region
70
+ * list doesn't cover them leaves the entry as bare `{implicit: true}` —
71
+ * indistinguishable from a site that declared nothing, and correctly so:
72
+ * neither is a Consent Mode decision for this visitor.
73
+ *
74
+ * `declare` is ignored: gtag('consent','declare',…) is a no-op in current
75
+ * gtag.js (it leaves the entry untouched and suppresses no data collection).
76
+ */
77
+ export function classifyAnalyticsStorage(entry) {
78
+ if (entry === null)
79
+ return { state: null, source: null };
80
+ // An explicit consent *update* always wins over a *default*; which one we
81
+ // read is recorded, because a declared default is a configuration choice,
82
+ // not a user decision.
83
+ const hasUpdate = entry.update !== undefined && entry.update !== null;
84
+ const hasDefault = entry.default !== undefined && entry.default !== null;
85
+ const raw = hasUpdate ? entry.update : entry.default;
86
+ const state = raw === true || raw === "granted" ? "granted" : raw === false || raw === "denied" ? "denied" : "unset";
87
+ const source = hasUpdate ? "update" : hasDefault ? "default" : "implicit-default";
88
+ return { state, source };
89
+ }
90
+ /**
91
+ * Resolves every signal ics.entries carries, through the one rule above.
92
+ *
93
+ * The point of reading all seven rather than analytics_storage alone is the
94
+ * v1/v2 question: v2 is defined by ad_user_data and ad_personalization
95
+ * existing, and "exists" is only half of it — a signal whose source is
96
+ * implicit-default has nothing declared for it, which is a half-configured v2
97
+ * rather than a working one. One rule covers all seven, so there is still
98
+ * only one definition of what a state and a provenance are.
99
+ */
100
+ export function classifyConsentEntries(entries) {
101
+ const resolved = {};
102
+ for (const name of CONSENT_SIGNAL_NAMES) {
103
+ const entry = entries[name];
104
+ if (entry === undefined || entry === null)
105
+ continue;
106
+ const { state, source } = classifyAnalyticsStorage(entry);
107
+ // classifyAnalyticsStorage only returns nulls for a null entry, which the
108
+ // guard above already excluded.
109
+ if (state === null || source === null)
110
+ continue;
111
+ resolved[name] = { state, source, region: entry.region };
112
+ }
113
+ return resolved;
114
+ }
115
+ /**
116
+ * Whether the page is running Consent Mode v2 or v1, from the keys
117
+ * ics.entries carries.
118
+ *
119
+ * Deliberately NOT a judgement about whether Consent Mode is configured:
120
+ * gtag/GTM creates every key it knows about as soon as a container loads, so
121
+ * a page that never calls gtag('consent', …) still reports seven keys. Only
122
+ * ics.active answers that, and the two are asked separately.
123
+ */
124
+ export function consentModeVersionFromKeys(entryKeys) {
125
+ return CONSENT_V2_ONLY_SIGNALS.every((name) => entryKeys.includes(name)) ? "v2" : "v1";
126
+ }
127
+ const EMPTY = {
128
+ cmpDetected: false,
129
+ cmpVendor: null,
130
+ cmpVendorConfirmed: false,
131
+ cmpHasResponse: null,
132
+ googleTagDataExists: false,
133
+ ics: null,
134
+ rawEntries: {},
135
+ rawConsentPushes: [],
136
+ // readConsentState is itself what nudgeVisitorInteraction calls to
137
+ // decide whether a nudge worked, so it cannot know the answer. The phase
138
+ // stamps the real value onto the snapshot it keeps.
139
+ bannerReveal: "not-needed",
140
+ };
141
+ /**
142
+ * Does what a visitor does in their first seconds on a page: moves the mouse,
143
+ * and scrolls.
144
+ *
145
+ * Not a nicety. Two of the ten accounts in the corpus render or load NOTHING
146
+ * tracking-related until the page sees an interaction, and neither is
147
+ * detectable by waiting:
148
+ *
149
+ * - factorial.es builds its consent banner from the first `mousemove` or
150
+ * `scroll` (`I && (I = false, S())`), with no timer anywhere. A passive run
151
+ * waited fifteen seconds and saw no banner, then reported "no consent
152
+ * platform was detected" about a site that has one.
153
+ * - catonetworks.com fires its GTM tags on scroll. With no scroll not one
154
+ * Dreamdata script is ever injected, and the run said the visitor "agreed to
155
+ * identified tracking and did not get it" about a site that tracks
156
+ * correctly. A mouse move alone does NOT reach it; only the scroll does.
157
+ *
158
+ * So both steps always run, and they run for every phase before any consent
159
+ * or script evidence is read. The earlier version stopped as soon as a CMP was
160
+ * detected, which is exactly why catonetworks was missed: Cookiebot answered
161
+ * on load, the nudge was skipped as unnecessary, and the tags it would have
162
+ * triggered never loaded.
163
+ *
164
+ * A run that never interacts is not measuring a cautious visitor — it is
165
+ * measuring one who loads a page and then freezes, which is nobody. The scroll
166
+ * can start lazy-loading and scroll-depth tracking, and that is the correct
167
+ * trade: those are things a real visit also does. The position is restored so
168
+ * nothing read afterwards depends on where the page was left.
169
+ */
170
+ export async function nudgeVisitorInteraction(page,
171
+ /**
172
+ * Optional. When given, it is sampled around each step so the caller can
173
+ * report WHICH interaction revealed a banner. Omit it on a page where there
174
+ * is no banner question — the second-page walk — and the interaction still
175
+ * happens, which is the part every caller needs.
176
+ */
177
+ isDetected) {
178
+ const detectedBefore = isDetected ? await isDetected() : true;
179
+ const viewport = page.viewportSize() ?? { width: 1280, height: 800 };
180
+ await page.mouse.move(viewport.width / 2, viewport.height / 2).catch(() => { });
181
+ await page.waitForTimeout(BANNER_REVEAL_SETTLE_MS);
182
+ const detectedAfterMove = detectedBefore || (isDetected !== undefined && (await isDetected()));
183
+ await page.mouse.wheel(0, BANNER_REVEAL_SCROLL_PX).catch(() => { });
184
+ await page.waitForTimeout(BANNER_REVEAL_SETTLE_MS);
185
+ await page.evaluate(() => window.scrollTo(0, 0)).catch(() => { });
186
+ if (detectedBefore)
187
+ return "not-needed";
188
+ if (detectedAfterMove)
189
+ return "mousemove";
190
+ return isDetected !== undefined && (await isDetected()) ? "scroll" : "unrevealed";
191
+ }
192
+ export async function readConsentState(page) {
193
+ const result = await page
194
+ .evaluate(({ vendors, domVendors, signalNames }) => {
195
+ const w = window;
196
+ const googleTagDataExists = Boolean(w.google_tag_data);
197
+ // Read raw and classify in node (classifyAnalyticsStorage,
198
+ // classifyConsentEntries, judgeConsentModeV2), so the rules that decide
199
+ // a fail/pass are unit-testable rather than buried in a page closure.
200
+ // `?? null` keeps a real `false` intact while collapsing "key absent"
201
+ // to something that survives serialization.
202
+ //
203
+ // Every ics read is wrapped: these are undocumented gtag.js internals,
204
+ // and one renamed property must cost this phase its consent evidence at
205
+ // most, never the whole collection.
206
+ let ics = null;
207
+ const rawEntries = {};
208
+ try {
209
+ if (googleTagDataExists) {
210
+ const raw = w.google_tag_data?.ics;
211
+ const entries = raw?.entries ?? {};
212
+ const asBool = (value) => (typeof value === "boolean" ? value : null);
213
+ ics = {
214
+ present: Boolean(raw),
215
+ active: asBool(raw?.active),
216
+ usedDefault: asBool(raw?.usedDefault),
217
+ usedUpdate: asBool(raw?.usedUpdate),
218
+ wasSetLate: asBool(raw?.wasSetLate),
219
+ waitPeriodTimedOut: asBool(raw?.waitPeriodTimedOut),
220
+ entryKeys: Object.keys(entries).sort(),
221
+ };
222
+ for (const name of signalNames) {
223
+ const entry = entries[name];
224
+ if (!entry)
225
+ continue;
226
+ const region = Array.isArray(entry.region)
227
+ ? entry.region.filter((value) => typeof value === "string")
228
+ : null;
229
+ rawEntries[name] = {
230
+ update: entry.update ?? null,
231
+ default: entry.default ?? null,
232
+ region: region !== null && region.length > 0 ? region : null,
233
+ };
234
+ }
235
+ }
236
+ }
237
+ catch {
238
+ ics = null;
239
+ }
240
+ const bag = w;
241
+ const globalVendor = vendors.find((v) => Boolean(bag[v.globalKey]));
242
+ // Only consulted when no vendor global matched: a rendered banner is
243
+ // real evidence of a gate, an always-present tracker global is not.
244
+ const domVendor = globalVendor
245
+ ? undefined
246
+ : domVendors.find((v) => document.getElementById(v.bannerElementId) !== null);
247
+ const vendor = globalVendor ?? domVendor;
248
+ let cmpHasResponse = null;
249
+ if (typeof w.Cookiebot?.hasResponse === "boolean") {
250
+ cmpHasResponse = w.Cookiebot.hasResponse;
251
+ }
252
+ else if (typeof w.OneTrust?.IsAlertBoxClosed === "function") {
253
+ try {
254
+ cmpHasResponse = Boolean(w.OneTrust.IsAlertBoxClosed());
255
+ }
256
+ catch {
257
+ cmpHasResponse = null;
258
+ }
259
+ }
260
+ else if (typeof w.getCkyConsent === "function") {
261
+ // CookieYes writes cookieyes-consent on load, before the visitor has
262
+ // answered anything, so the cookie's presence proves nothing; the
263
+ // flag inside it is the only thing that says an answer was given.
264
+ // This matters most for banners answered through the preference
265
+ // centre, where it is the reload check's only evidence.
266
+ try {
267
+ cmpHasResponse = Boolean(w.getCkyConsent()?.isUserActionCompleted);
268
+ }
269
+ catch {
270
+ cmpHasResponse = null;
271
+ }
272
+ }
273
+ else if (domVendor) {
274
+ cmpHasResponse = document.cookie.includes(`${domVendor.responseCookiePrefix}=`);
275
+ }
276
+ else if (vendor?.id === "complianz") {
277
+ // Complianz stores its decision in a cookie rather than exposing a
278
+ // readable flag on window.complianz; the banner's own visibility
279
+ // class is the fallback when the cookie hasn't been set yet.
280
+ cmpHasResponse = document.cookie.includes("cmplz_banner-status=");
281
+ }
282
+ return {
283
+ bannerReveal: "not-needed",
284
+ // google_tag_data alone means GTM is present, not that a CMP is —
285
+ // so a real vendor global is required to claim a CMP.
286
+ cmpDetected: vendor !== undefined,
287
+ cmpVendor: vendor?.id ?? null,
288
+ cmpVendorConfirmed: vendor !== undefined,
289
+ cmpHasResponse,
290
+ googleTagDataExists,
291
+ ics,
292
+ rawEntries,
293
+ rawConsentPushes: w.__ddEvidence?.consentPushes ?? [],
294
+ };
295
+ }, {
296
+ vendors: CMP_VENDORS.map((v) => ({ id: v.id, globalKey: v.globalKey })),
297
+ domVendors: DOM_ONLY_CMP_VENDORS.map((v) => ({
298
+ id: v.id,
299
+ bannerElementId: v.bannerElementId,
300
+ responseCookiePrefix: v.responseCookiePrefix,
301
+ })),
302
+ signalNames: CONSENT_SIGNAL_NAMES,
303
+ })
304
+ .catch(() => EMPTY);
305
+ // No named vendor and no known DOM banner matched — try the generic
306
+ // text-matched fallback before concluding there is no gate at all. A
307
+ // bespoke, hand-rolled banner exposes none of the above but still has an
308
+ // "Accept all"/"Necessary only"-style pair a visitor would actually see.
309
+ let heuristicOverride = null;
310
+ if (!result.cmpDetected) {
311
+ const heuristic = await page
312
+ .evaluate(runHeuristicBanner, {
313
+ mode: "detect",
314
+ acceptPhrases: GENERIC_ACCEPT_PHRASES,
315
+ rejectPhrases: GENERIC_REJECT_PHRASES,
316
+ preferenceCounterpartPhrases: PREFERENCE_CENTER_COUNTERPART_PHRASES,
317
+ contextKeywords: BANNER_CONTEXT_KEYWORDS,
318
+ })
319
+ .catch(() => null);
320
+ if (heuristic?.detected) {
321
+ heuristicOverride = { cmpDetected: true, cmpVendor: "unknown-custom", cmpVendorConfirmed: false };
322
+ }
323
+ }
324
+ const { rawConsentPushes, rawEntries, ...snapshot } = result;
325
+ const signals = classifyConsentEntries(rawEntries);
326
+ const { state, source } = classifyAnalyticsStorage(rawEntries["analytics_storage"] ?? null);
327
+ return {
328
+ ...snapshot,
329
+ analyticsStorageState: state,
330
+ analyticsStorageSource: source,
331
+ signals,
332
+ // A CMP being present does not imply this: many CMPs never call
333
+ // gtag('consent', …) at all, and a declared default can be scoped to a
334
+ // region this visitor isn't in, which leaves no applicable value behind.
335
+ consentModeConfigured: source === "update" || source === "default",
336
+ ...heuristicOverride,
337
+ dataLayerConsentPushes: rawConsentPushes.map((push) => parseConsentPush(push.raw, push.timestamp)),
338
+ };
339
+ }
340
+ //# sourceMappingURL=consent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consent.js","sourceRoot":"","sources":["../../src/evidence/consent.ts"],"names":[],"mappings":"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"}