@ecomconsult/consentkit 0.5.3 → 0.5.5

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.
@@ -28,7 +28,7 @@ export function undecidedState() {
28
28
  */
29
29
  export function createStub() {
30
30
  const stub = {
31
- version: '0.5.3',
31
+ version: '0.5.5',
32
32
  config: {},
33
33
  init: function () { return undecidedState(); },
34
34
  allowed: function (cat) { return cat === 'necessary'; },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ecomconsult/consentkit",
3
- "version": "0.5.3",
3
+ "version": "0.5.5",
4
4
  "description": "GDPR cookie consent core with blocking engine, Shadow DOM UI and Google Consent Mode v2. Zero dependencies, no build step.",
5
5
  "repository": {
6
6
  "type": "git",
package/src/ck-core.js CHANGED
@@ -81,6 +81,13 @@
81
81
  // INFRA_DB: the rest of Cloudflare's edge is infrastructure, but this one
82
82
  // beacon is a measurement product (§8 names it by hand for that reason).
83
83
  'static.cloudflareinsights.com': 'analytics',
84
+ // Tilda's stats endpoint. The REST of tildaapi.one is platform plumbing and
85
+ // sits in INFRA_DB host by host; this one subdomain measures visitors, so it
86
+ // is classified here instead. There is deliberately NO bare `tildaapi.one`
87
+ // in either table: lookupHostMap returns the FIRST matching key, not the
88
+ // longest, so a bare entry could shadow this one depending on insertion
89
+ // order. Every Tilda API host is therefore named in full.
90
+ 'stat.tildaapi.one': 'analytics',
84
91
 
85
92
  // --- marketing -----------------------------------------------------
86
93
  'connect.facebook.net': 'marketing',
@@ -137,6 +144,22 @@
137
144
  // iuteCredit — a Moldovan consumer-credit calculator embedded on shop
138
145
  // product pages. A third party the owner chose, offering a feature.
139
146
  'iutecredit.md': 'functional',
147
+ // Google Maps — a map or a store locator the owner embedded. It is a
148
+ // FEATURE, not measurement: a visitor who declines functional loses the map
149
+ // and nothing else. The two API hosts are dedicated to Maps, so the whole
150
+ // host is the right scope; the www.google.com/maps halves cannot be, and
151
+ // are path-scoped in PATH_DB below.
152
+ //
153
+ // maps.gstatic.com is the deliberate exception to `gstatic.com` sitting in
154
+ // INFRA_DB: the parent serves fonts and ordinary images a page is broken
155
+ // without, but this subdomain serves the map tiles and marker sprites of an
156
+ // embed the owner chose. categoryForUrl runs BEFORE the strict allowlist, so
157
+ // naming it here classifies (and holds) it while fonts.gstatic.com stays
158
+ // waved through — which is the split the pair of tests in blocking.test.mjs
159
+ // pins down.
160
+ 'maps.googleapis.com': 'functional',
161
+ 'places.googleapis.com': 'functional',
162
+ 'maps.gstatic.com': 'functional',
140
163
 
141
164
  // --- necessary -----------------------------------------------------
142
165
  // recaptcha.net is Google's alternate reCAPTCHA domain, served for regions
@@ -183,6 +206,34 @@
183
206
  '/gtag/js': 'analytics', // googletagmanager.com/gtag/js?id=G-XXXX
184
207
  'www.google.com/recaptcha/': 'necessary',
185
208
  'www.gstatic.com/recaptcha/': 'necessary',
209
+ // Google Maps on www.google.<tld>. Like reCAPTCHA above, the host cannot be
210
+ // given a category as a whole, so the map is named by path. Functional: it
211
+ // is a map the owner put on the page, and allowed() holds it until the
212
+ // visitor accepts functional.
213
+ //
214
+ // The host half is kept IN the key rather than matching a bare '/maps/'.
215
+ // Every fragment here is tested against the WHOLE resolved URL, so a bare
216
+ // key would also classify a site's OWN page at /maps/… . For '/gtag/js'
217
+ // that is intended (a self-hosted gtag really is analytics); a first-party
218
+ // route called /maps/embed is just a route.
219
+ //
220
+ // Google serves the iframe embed from google.com/maps/embed regardless of
221
+ // the visitor's country, so google.com covers the embed case; the ccTLD
222
+ // hosts appear for /maps/ links, which the first key covers on www.google
223
+ // .com and which are ordinary navigation elsewhere.
224
+ 'www.google.com/maps/': 'functional',
225
+ 'google.com/maps/embed': 'functional', // also maps.google.com
226
+ // Google Ads pings that carry no cookie of their own but still report a
227
+ // visit to the ad platform — the remarketing/conversion beacons a gtag or
228
+ // Ads tag fires against www.google.<tld>. They reach doubleclick.net too,
229
+ // where HOST_DB already files them as marketing; these keys are what catches
230
+ // the www.google.com and www.google.lt (and every other ccTLD) form, which
231
+ // no host entry can cover without ruling on all of Google at once. Matching
232
+ // is a substring test against the WHOLE resolved URL, so a leading path
233
+ // fragment matches every host.
234
+ '/pagead/1p-user-list/': 'marketing',
235
+ '/pagead/1p-conversion/': 'marketing',
236
+ '/ads/ga-audiences': 'marketing',
186
237
  '/trackers/ga.js': 'analytics',
187
238
  '/trackers/pixel.js': 'marketing',
188
239
  '/trackers/chat.js': 'functional'
@@ -304,7 +355,21 @@
304
355
  // --- site builders and hosting platforms ---------------------------
305
356
  'tildacdn.com',
306
357
  'tildacdn.net',
358
+ 'tildacdn.one',
359
+ 'static.tildacdn.one', // redundant under the line above, named
360
+ // for symmetry with the tildacdn.com
361
+ // fixtures, which use the same subdomain
307
362
  'tilda.ws',
363
+ // Tilda's own platform APIs: block feeds, geo lookup, the members area and
364
+ // form delivery. A Tilda page is broken without them and none of them is a
365
+ // decision the site owner made — they are the builder serving its own site.
366
+ // Enumerated one by one rather than as a bare `tildaapi.one`, because
367
+ // stat.tildaapi.one IS measurement and sits in HOST_DB as analytics; a bare
368
+ // suffix here would be a claim about that host too.
369
+ 'feeds.tildaapi.one',
370
+ 'geo.tildaapi.one',
371
+ 'members.tildaapi.one',
372
+ 'forms.tildaapi.one',
308
373
  'static.wixstatic.com',
309
374
  'parastorage.com', // Wix static assets
310
375
  'cdn.shopify.com',
@@ -325,6 +390,8 @@
325
390
  'b-cdn.net', // bunny.net
326
391
  // --- fonts ----------------------------------------------------------
327
392
  'fonts.googleapis.com',
393
+ 'fonts.google.com', // the catalogue host; some embeds and
394
+ // builders link stylesheets through it
328
395
  // gstatic.com whole: Google's static-asset domain. Its subdomains serve
329
396
  // fonts (fonts.gstatic.com), the reCAPTCHA widget's own code
330
397
  // (www.gstatic.com/recaptcha/) and ordinary images — assets a page is
@@ -880,6 +947,15 @@
880
947
  // miss every page that sets it after the core loads.
881
948
  function isInfraHost(host) {
882
949
  if (!host) { return false; }
950
+ // A host the database gives a CATEGORY to is never infrastructure, even when
951
+ // it sits under an INFRA_DB suffix. Without this, maps.gstatic.com (named as
952
+ // `functional` in HOST_DB, under a bare `gstatic.com` here) would be held
953
+ // back by the engine until functional consent while the scanner — which
954
+ // reads _infra() to set thirdParty[].infra — filed it as infrastructure and
955
+ // kept it out of the report entirely. Blocking and reporting would then
956
+ // disagree about one host, which is exactly what §8 exists to prevent.
957
+ // Every other INFRA_DB entry is uncategorised, so this changes nothing else.
958
+ if (lookupHostMap(EXTRA_DB, host) || lookupHostMap(HOST_DB, host)) { return false; }
883
959
  for (var i = 0; i < INFRA_DB.length; i++) {
884
960
  if (hostMatches(host, INFRA_DB[i])) { return true; }
885
961
  }
@@ -1461,7 +1537,7 @@
1461
1537
  // Public API
1462
1538
  // ---------------------------------------------------------------------------
1463
1539
  var ConsentKit = {
1464
- version: '0.5.3',
1540
+ version: '0.5.5',
1465
1541
  config: config,
1466
1542
 
1467
1543
  init: function (userConfig) {
package/src/ck-locales.js CHANGED
@@ -553,30 +553,30 @@
553
553
  };
554
554
 
555
555
  L.ro = {
556
- bannerTitle: 'Folosim cookie-uri',
557
- bannerText: 'Cookie-urile necesare mențin site-ul în funcțiune. Restul analiză, marketing, funcții suplimentare pornește doar dacă permiteți. Vă puteți răzgândi oricând.',
556
+ bannerTitle: 'Cookie-uri pe acest site',
557
+ bannerText: 'Cookie-urile necesare mențin site-ul în funcțiune. Restul pornesc doar cu acordul dumneavoastră. Puteți schimba decizia oricând.',
558
558
  more: 'Aflați mai multe',
559
559
  acceptAll: 'Acceptă tot',
560
560
  rejectAll: 'Respinge tot',
561
561
  customize: 'Personalizează',
562
562
  bannerLabel: 'Consimțământ pentru cookie-uri',
563
563
  panelTitle: 'Setări cookie-uri',
564
- panelIntro: 'Alegeți ce cookie-uri permiteți. Nimic opțional nu este pornit până nu îl porniți dumneavoastră.',
564
+ panelIntro: 'Alegeți ce permiteți. Implicit este pornit doar strictul necesar.',
565
565
  save: 'Salvează alegerea',
566
566
  close: 'Închide',
567
567
  alwaysOn: 'mereu active',
568
- cookiesIn: 'Cookie-uri din acest grup',
568
+ cookiesIn: 'Ce cookie-uri',
569
569
  noCookies: 'Nu au fost declarate cookie-uri pentru acest grup.',
570
- colName: 'Nume',
571
- colVendor: 'Furnizor',
572
- colPurpose: 'Scop',
570
+ colName: 'Denumire',
571
+ colVendor: 'Cine le pune',
572
+ colPurpose: 'Pentru ce',
573
573
  colExpiry: 'Expiră',
574
574
  floating: 'Setări cookie-uri',
575
575
  cat: {
576
- necessary: { title: 'Necesare', desc: 'Sunt necesare pentru funcționarea site-ului: autentificare, securitate, reținerea consimțământului. Nu pot fi dezactivate.' },
577
- functional: { title: 'Funcționale', desc: 'Rețin preferințele dumneavoastră, precum limba sau chatul, ca să nu le setați din nou.' },
578
- analytics: { title: 'Analiză', desc: 'Ne arată ce pagini sunt folosite, ca reparăm ce derutează. Doar cifre, fără nume.' },
579
- marketing: { title: 'Marketing', desc: 'Ne permit arătăm reclame pe alte site-uri și să măsurăm dacă au fost de folos.' }
576
+ necessary: { title: 'Necesare', desc: 'Sunt necesare pentru funcționarea site-ului: autentificare, securitate, reținerea alegerii dumneavoastră. Nu pot fi dezactivate.' },
577
+ functional: { title: 'Funcționale', desc: 'Rețin alegerile dumneavoastră: limba, coșul, chatul.' },
578
+ analytics: { title: 'Analiză', desc: 'Ne ajută să înțelegem ce merge bine pe site și ce nu.' },
579
+ marketing: { title: 'Marketing', desc: 'Potrivesc reclamele cu interesele dumneavoastră pe alte site-uri.' }
580
580
  }
581
581
  };
582
582
 
package/src/ck-ui.js CHANGED
@@ -12,82 +12,82 @@
12
12
 
13
13
  var DICT = {
14
14
  en: {
15
- bannerTitle: 'We use cookies',
16
- bannerText: 'Necessary cookies keep the site working. Everything else analytics, marketing, extra features — runs only if you allow it. You can change your mind at any time.',
15
+ bannerTitle: 'Cookies on this site',
16
+ bannerText: 'Necessary cookies keep the site working. The rest are used only if you allow them. You can change your choice at any time.',
17
17
  more: 'Learn more',
18
18
  acceptAll: 'Accept all',
19
19
  rejectAll: 'Reject all',
20
20
  customize: 'Customize',
21
21
  bannerLabel: 'Cookie consent',
22
22
  panelTitle: 'Cookie settings',
23
- panelIntro: 'Choose which cookies you allow. Nothing optional is on until you turn it on.',
23
+ panelIntro: 'Choose what to allow. By default only the necessary ones are on.',
24
24
  save: 'Save choices',
25
25
  close: 'Close',
26
26
  alwaysOn: 'always on',
27
- cookiesIn: 'Cookies in this group',
27
+ cookiesIn: 'Which cookies',
28
28
  noCookies: 'No cookies declared for this group.',
29
29
  colName: 'Name',
30
- colVendor: 'Provider',
31
- colPurpose: 'Purpose',
30
+ colVendor: 'Who sets it',
31
+ colPurpose: 'What for',
32
32
  colExpiry: 'Expires',
33
33
  floating: 'Cookie settings',
34
34
  poweredBy: 'Powered by ConsentKit',
35
35
  cat: {
36
36
  necessary: {
37
37
  title: 'Necessary',
38
- desc: 'Needed for the site to work signing in, security, remembering your consent. They cannot be turned off.'
38
+ desc: 'Needed for the site to work: signing in, security, remembering your choice. They cannot be turned off.'
39
39
  },
40
40
  functional: {
41
41
  title: 'Functional',
42
- desc: 'Remember your preferences, such as language or chat, so you do not set them up again.'
42
+ desc: 'Remember your choices: language, basket, chat.'
43
43
  },
44
44
  analytics: {
45
45
  title: 'Analytics',
46
- desc: 'Help us see which pages people use, so we can fix what is confusing. Numbers only, no names.'
46
+ desc: 'Help us understand what works well on the site and what does not.'
47
47
  },
48
48
  marketing: {
49
49
  title: 'Marketing',
50
- desc: 'Let us show you ads on other sites and measure whether they were any use.'
50
+ desc: 'Match ads to your interests on other sites.'
51
51
  }
52
52
  }
53
53
  },
54
54
  ru: {
55
- bannerTitle: 'Мы используем cookie',
56
- bannerText: 'Необходимые cookie нужны, чтобы сайт работал. Всё остальное — аналитика, маркетинг, дополнительные удобства — включается только с вашего согласия. Решение можно изменить в любой момент.',
55
+ bannerTitle: 'Cookie на этом сайте',
56
+ bannerText: 'Необходимые cookie нужны, чтобы сайт работал. Остальные включаются только с вашего согласия. Решение можно изменить в любой момент.',
57
57
  more: 'Подробнее',
58
58
  acceptAll: 'Принять всё',
59
59
  rejectAll: 'Отклонить всё',
60
60
  customize: 'Настроить',
61
61
  bannerLabel: 'Согласие на cookie',
62
62
  panelTitle: 'Настройки cookie',
63
- panelIntro: 'Выберите, какие cookie вы разрешаете. Ничего необязательного не включено, пока вы сами это не сделаете.',
63
+ panelIntro: 'Выберите, что разрешить. По умолчанию включено только необходимое.',
64
64
  save: 'Сохранить выбор',
65
65
  close: 'Закрыть',
66
66
  alwaysOn: 'всегда активны',
67
- cookiesIn: 'Cookie в этой группе',
67
+ cookiesIn: 'Какие cookie',
68
68
  noCookies: 'Для этой группы cookie не заявлены.',
69
- colName: 'Имя',
70
- colVendor: 'Поставщик',
71
- colPurpose: 'Цель',
69
+ colName: 'Название',
70
+ colVendor: 'Кто ставит',
71
+ colPurpose: 'Зачем',
72
72
  colExpiry: 'Срок',
73
73
  floating: 'Настройки cookie',
74
74
  poweredBy: 'Работает на ConsentKit',
75
75
  cat: {
76
76
  necessary: {
77
77
  title: 'Необходимые',
78
- desc: 'Без них сайт не работает: вход, безопасность, память о вашем выборе. Отключить нельзя.'
78
+ desc: 'Нужны, чтобы сайт работал: вход, безопасность, память о вашем выборе. Отключить нельзя.'
79
79
  },
80
80
  functional: {
81
81
  title: 'Функциональные',
82
- desc: 'Запоминают ваши настройки например язык или чат, — чтобы вы не задавали их заново.'
82
+ desc: 'Запоминают ваш выбор: язык, корзину, чат.'
83
83
  },
84
84
  analytics: {
85
85
  title: 'Аналитика',
86
- desc: 'Показывают нам, какими страницами вы пользуетесь, чтобы мы исправили неудобное. Только цифры, без имён.'
86
+ desc: 'Помогают нам понять, что на сайте удобно, а что нет.'
87
87
  },
88
88
  marketing: {
89
89
  title: 'Маркетинг',
90
- desc: 'Позволяют показывать вам рекламу на других сайтах и понимать, была ли от неё польза.'
90
+ desc: 'Подбирают рекламу под ваши интересы на других сайтах.'
91
91
  }
92
92
  }
93
93
  }