@blakfy/cookie 2.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.
- package/ARCHITECTURE.md +186 -0
- package/CHANGELOG.md +107 -0
- package/COMPLIANCE.md +191 -0
- package/LICENSE +21 -0
- package/MIGRATION.md +156 -0
- package/README.md +480 -0
- package/TCF-CERTIFICATION.md +106 -0
- package/dist/cookie-defaults.js +76 -0
- package/dist/cookie-defaults.js.LEGAL.txt +0 -0
- package/dist/cookie-defaults.min.js +10 -0
- package/dist/cookie-defaults.min.js.LEGAL.txt +0 -0
- package/dist/cookie.js +3998 -0
- package/dist/cookie.js.LEGAL.txt +0 -0
- package/dist/cookie.js.map +7 -0
- package/dist/cookie.min.js +10 -0
- package/dist/cookie.min.js.LEGAL.txt +0 -0
- package/package.json +60 -0
package/ARCHITECTURE.md
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# Blakfy Cookie — v2.0 Architecture
|
|
2
|
+
|
|
3
|
+
> Tek script ile yüklenen, sıfır bağımlılık, çok motorlu uyumluluk sağlayan widget tabanlı cookie consent sistemi. Vanilla + Next.js destekli, jsDelivr CDN üzerinden otomatik güncellenir.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Tasarım İlkeleri
|
|
8
|
+
|
|
9
|
+
| İlke | Karar | Neden |
|
|
10
|
+
|---|---|---|
|
|
11
|
+
| **Dağıtım** | jsDelivr `@2` major-pin | Kullanıcılar `@2`'ye bağlanır; biz `git tag v2.x.x` push edince anında yayılır. `@latest` yasak. |
|
|
12
|
+
| **Sıfır bağımlılık** | Vanilla JS, IIFE, ES5 syntax (cookie.js); ESM build (cookie-next) | Eski tarayıcılar, çoklu stack |
|
|
13
|
+
| **Geriye uyumluluk** | v1 API kontratı v2'de korunur | Mevcut `@1` entegrasyonları kırılmaz, yeni metotlar additive |
|
|
14
|
+
| **Boyut bütçesi** | Core ≤ 24 KB minified+gzip (gerçek: ~23 KB) | Site performansı; rakipler 50-150 KB |
|
|
15
|
+
| **Re-consent disiplini** | Sadece `data-blakfy-version` (policyVersion) re-consent tetikler | `cookie.js` bump'ı kullanıcıyı etkilemez |
|
|
16
|
+
| **Branding** | "Powered by Blakfy Studio" badge — kapatılamaz, anti-tampering korumalı | Marka koruması |
|
|
17
|
+
| **Compliance kapsamı** | Google CMv2 + Microsoft UET + Yandex Metrica + IAB TCF v2.2 + CCPA + GPC + DNT | Üç büyük arama motoru + AB + ABD yasal uyumluluk |
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Klasör Yapısı
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
blakfy-cookie/
|
|
25
|
+
├── src/ # v2 kaynak ağacı
|
|
26
|
+
│ ├── core/ # consent state, cookie I/O, audit, events
|
|
27
|
+
│ ├── compliance/ # motor + yasal uyumluluk modülleri
|
|
28
|
+
│ │ ├── google-cmv2.js
|
|
29
|
+
│ │ ├── microsoft-uet.js
|
|
30
|
+
│ │ ├── yandex-metrica.js
|
|
31
|
+
│ │ ├── tcf-v2.js
|
|
32
|
+
│ │ ├── ccpa.js
|
|
33
|
+
│ │ ├── gpc.js
|
|
34
|
+
│ │ └── dnt.js
|
|
35
|
+
│ ├── i18n/ # 23 dil, BCP47 detect
|
|
36
|
+
│ ├── ui/ # banner, modal, status-bar, badge, focus-trap
|
|
37
|
+
│ ├── gating/ # script + iframe unblocker, observer, cleaner
|
|
38
|
+
│ ├── presets/ # 18 hazır araç entegrasyonu
|
|
39
|
+
│ ├── geo/ # jurisdiction tespiti (GDPR/CCPA/LGPD)
|
|
40
|
+
│ ├── api.js # window.BlakfyCookie public API
|
|
41
|
+
│ └── index.js # entry
|
|
42
|
+
├── packages/
|
|
43
|
+
│ └── cookie-next/ # Next.js wrapper (npm: @blakfy/cookie-next)
|
|
44
|
+
├── dist/ # CDN servis edilen build çıktısı
|
|
45
|
+
├── examples/ # vanilla + nextjs + wordpress
|
|
46
|
+
├── tests/ # Vitest (jsdom)
|
|
47
|
+
├── scripts/ # esbuild build script'i
|
|
48
|
+
├── .github/workflows/ # test.yml + release.yml
|
|
49
|
+
├── legacy/ # v1.x kaynak (geri dönüş güvenliği)
|
|
50
|
+
├── ARCHITECTURE.md # bu dosya
|
|
51
|
+
├── COMPLIANCE.md # uyumluluk detayları
|
|
52
|
+
├── TCF-CERTIFICATION.md # IAB Europe başvuru süreci
|
|
53
|
+
├── CHANGELOG.md
|
|
54
|
+
├── MIGRATION.md # v1 → v2 (genelde sıfır iş)
|
|
55
|
+
└── README.md # AI-friendly kurulum kılavuzu
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Veri Akışı
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
┌─────────────────────────────────────────────────────┐
|
|
64
|
+
│ 1. Bootstrap (cookie-defaults.min.js, <head> ilk) │
|
|
65
|
+
│ - GCM v2 default 'denied' │
|
|
66
|
+
│ - UET default 'denied' │
|
|
67
|
+
│ - Yandex cookies engelli │
|
|
68
|
+
│ - GPC/DNT header okundu, opt-out flag set │
|
|
69
|
+
└─────────────────────┬───────────────────────────────┘
|
|
70
|
+
↓
|
|
71
|
+
┌─────────────────────────────────────────────────────┐
|
|
72
|
+
│ 2. Widget (cookie.min.js, <body> sonu) │
|
|
73
|
+
│ ───────────────────────────────────────── │
|
|
74
|
+
│ a) src/geo/jurisdiction tespit (GDPR/CCPA/...) │
|
|
75
|
+
│ b) src/core/consent-store cookie oku │
|
|
76
|
+
│ c) Yoksa → src/ui/banner render │
|
|
77
|
+
│ (sağ alt köşede badge dahil) │
|
|
78
|
+
│ d) src/gating/observer DOM tara │
|
|
79
|
+
│ e) Aktif preset'leri kaydet │
|
|
80
|
+
└─────────────────────┬───────────────────────────────┘
|
|
81
|
+
↓
|
|
82
|
+
┌─────────────────────────────────────────────────────┐
|
|
83
|
+
│ 3. Kullanıcı kararı │
|
|
84
|
+
│ - acceptAll / rejectAll / save preferences │
|
|
85
|
+
│ ↓ │
|
|
86
|
+
│ src/core/consent-store cookie yaz │
|
|
87
|
+
│ src/compliance/* her motora sinyal gönder │
|
|
88
|
+
│ src/gating/script-unblocker tag'leri aktive et │
|
|
89
|
+
│ src/core/audit endpoint POST │
|
|
90
|
+
│ window.BlakfyCookie.onChange listener'ları emit │
|
|
91
|
+
└─────────────────────────────────────────────────────┘
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Public API Yüzeyi
|
|
97
|
+
|
|
98
|
+
### v1 Uyumluluğu (kırılmaz)
|
|
99
|
+
|
|
100
|
+
```js
|
|
101
|
+
window.BlakfyCookie.open() / acceptAll() / rejectAll()
|
|
102
|
+
window.BlakfyCookie.getConsent("analytics")
|
|
103
|
+
window.BlakfyCookie.getState() / onChange(fn) / setLocale("ar")
|
|
104
|
+
window.BlakfyCookie.version
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### v2 Yeni API
|
|
108
|
+
|
|
109
|
+
```js
|
|
110
|
+
// Tag-gating
|
|
111
|
+
BlakfyCookie.onConsent("marketing", granted => {})
|
|
112
|
+
BlakfyCookie.registerCleanup({ category, cookies, storage })
|
|
113
|
+
BlakfyCookie.unblock("marketing")
|
|
114
|
+
BlakfyCookie.scan()
|
|
115
|
+
BlakfyCookie.usePreset("google-analytics")
|
|
116
|
+
|
|
117
|
+
// IAB TCF v2.2
|
|
118
|
+
window.__tcfapi("getTCData", 2, callback)
|
|
119
|
+
BlakfyCookie.tcf.getTCString()
|
|
120
|
+
|
|
121
|
+
// CCPA / CPRA
|
|
122
|
+
BlakfyCookie.ccpa.optOut() / isOptedOut()
|
|
123
|
+
|
|
124
|
+
// Jurisdiction
|
|
125
|
+
BlakfyCookie.getJurisdiction() // "GDPR" | "CCPA" | "LGPD" | "default"
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Re-consent Politikası
|
|
131
|
+
|
|
132
|
+
Tek tetikleyici: `data-blakfy-version` (politika versiyonu) değişimi.
|
|
133
|
+
|
|
134
|
+
```js
|
|
135
|
+
// Cookie okuma
|
|
136
|
+
if (s.version !== config.policyVersion) return null; // re-consent
|
|
137
|
+
// blakfy version (kütüphane sürümü) artık karşılaştırılmıyor — v1 bug fix
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Yani sen `cookie.js`'i `v2.0.0 → v2.0.1` güncellersen kullanıcılar etkilenmez. Sadece sen `data-blakfy-version="1.0" → "2.0"` yaparsan re-consent tetiklenir.
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Branding (Anti-Tampering)
|
|
145
|
+
|
|
146
|
+
3 katmanlı koruma:
|
|
147
|
+
|
|
148
|
+
1. **CSS:** `.blakfy-badge { display: flex !important; opacity: 1 !important; pointer-events: auto !important; }`
|
|
149
|
+
2. **DOM:** `MutationObserver` widget kökünü izler. Badge silinirse 50ms sonra geri ekler. `data-*` attribute manipulation görmezden gelinir.
|
|
150
|
+
3. **Kod:** Badge HTML build sırasında sabitlenir, config'den okumaz.
|
|
151
|
+
|
|
152
|
+
Test: `tests/badge-anti-tamper.test.js` — silme, CSS injection, attribute tampering senaryoları.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Boyut Bütçesi
|
|
157
|
+
|
|
158
|
+
| Katman | Hedef (gzip) |
|
|
159
|
+
|---|---|
|
|
160
|
+
| Core (consent + UI + i18n + badge) | ≤ 14 KB |
|
|
161
|
+
| Compliance toplamı (lazy) | ≤ 6 KB |
|
|
162
|
+
| 18 Preset (lazy) | ≤ 4 KB |
|
|
163
|
+
| **TOPLAM (her şey aktif)** | **≤ 22 KB** |
|
|
164
|
+
|
|
165
|
+
`scripts/build.js` her release'de boyut kontrolü yapar; bütçeyi aşan PR'lar CI'da fail olur.
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## Geliştirme Akışı
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
npm install # workspace + cookie-next deps
|
|
173
|
+
npm run dev # esbuild watch
|
|
174
|
+
npm test # Vitest jsdom
|
|
175
|
+
npm run build # dist/cookie.min.js + cookie-defaults.min.js
|
|
176
|
+
npm run build:next # tsup → packages/cookie-next/dist
|
|
177
|
+
npm run size # bundle size guard
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Release:
|
|
181
|
+
```bash
|
|
182
|
+
git tag v2.0.0
|
|
183
|
+
git push --tags
|
|
184
|
+
# GitHub Actions → tests + build + npm publish + GitHub Release
|
|
185
|
+
# jsDelivr @2 anında güncellenir
|
|
186
|
+
```
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes follow [Keep a Changelog](https://keepachangelog.com/) and SemVer.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## [2.1.0] — 2026-04-30
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- **3-tab preferences modal** — Kategoriler / Hizmetler / Hakkında
|
|
11
|
+
- Hizmetler sekmesi: GDPR Madde 13/14 + KVKK Madde 10 uyumlu servis ifşası (veri işleyici, adres, amaçlar, teknolojiler, toplanan veriler, hukuki dayanak, saklama süresi, aktarım ülkeleri, gizlilik politikası linkleri)
|
|
12
|
+
- Accordion kartlar: accordion expand/collapse per service
|
|
13
|
+
- Hakkında sekmesi: CMP kimliği, platform açıklaması, sürüm
|
|
14
|
+
- **18 preset için `SERVICE_METADATA`** (`src/data/service-metadata.js`) — ga4, gtm, facebook, clarity, hotjar, youtube, vimeo, linkedin, yandex, bing, tiktok, pinterest, tawkto, intercom, hubspot, mailchimp, maps, recaptcha
|
|
15
|
+
- **3 renk teması** — `light` (beyaz), `gray` (açık gri), `dark` (siyah); `auto` → `prefers-color-scheme`
|
|
16
|
+
- 23 dile `tabs`, `service`, `svcAbout` çeviri anahtarları eklendi
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
- Banner emoji kaldırıldı (kurumsal uyumluluk)
|
|
20
|
+
- Banner butonları `flex:1 flex-wrap:nowrap` ile eşit genişlikte, yatay düzen
|
|
21
|
+
- Widget kart genişliği `min(96vw,1100px)` (önceki: 780px)
|
|
22
|
+
- Widget kart `border-radius: 8px` (önceki: 16px)
|
|
23
|
+
- Buton `min-height: 36px` (önceki: 44px)
|
|
24
|
+
- Service list `max-height: 420px` (önceki: 340px)
|
|
25
|
+
- Bundle size budget `32 KB` (önceki: 24 KB) — service-metadata DB nedeniyle
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
- CDN URL `@v2` → jsDelivr semver tag desteği
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## [2.0.0] — Unreleased
|
|
33
|
+
|
|
34
|
+
### Architecture
|
|
35
|
+
- **Modular source tree** under `src/` — split monolithic `cookie.js` into `core/`, `compliance/`, `i18n/`, `ui/`, `gating/`, `presets/`, `geo/`.
|
|
36
|
+
- **Build pipeline** with esbuild — produces `dist/cookie.min.js`, `dist/cookie-defaults.min.js`, and tsup-built `cookie-next` package.
|
|
37
|
+
- **Bundle size budget** — core ≤ 22 KB minified+gzip, enforced in CI.
|
|
38
|
+
|
|
39
|
+
### Compliance (NEW)
|
|
40
|
+
- Microsoft UET Consent Mode (Bing Ads, Clarity)
|
|
41
|
+
- Yandex Metrica consent + Webvisor as separate `recording` category
|
|
42
|
+
- IAB TCF v2.2 — `__tcfapi` global, TC string encoding, vendor list (preview mode until CMP ID assigned)
|
|
43
|
+
- CCPA / CPRA — opt-out mode, USP string, "Do Not Sell" footer link, GPC respect
|
|
44
|
+
- GPC (Global Privacy Control) — `navigator.globalPrivacyControl` auto-deny
|
|
45
|
+
- DNT (Do Not Track) — opt-in respect mode
|
|
46
|
+
- Jurisdiction detection (`GDPR` / `CCPA` / `LGPD` / `default`)
|
|
47
|
+
|
|
48
|
+
### Tag-Gating (NEW)
|
|
49
|
+
- `<script type="text/plain" data-blakfy-category="...">` automatic activation
|
|
50
|
+
- `<iframe data-blakfy-src="..." data-blakfy-category="...">` placeholder UI
|
|
51
|
+
- MutationObserver for SPA / dynamically added tags
|
|
52
|
+
- Cookie & localStorage cleanup on consent withdrawal
|
|
53
|
+
|
|
54
|
+
### Presets (NEW — 18 tools)
|
|
55
|
+
- Google: Analytics 4, Tag Manager, Maps, reCAPTCHA
|
|
56
|
+
- Meta: Facebook Pixel
|
|
57
|
+
- Video: YouTube, Vimeo
|
|
58
|
+
- Analytics: Hotjar, Microsoft Clarity, LinkedIn Insight, Yandex Metrica
|
|
59
|
+
- Ads: Bing Ads (UET), TikTok Pixel, Pinterest Tag
|
|
60
|
+
- Chat/CRM: Tawk.to, Intercom, HubSpot, Mailchimp
|
|
61
|
+
|
|
62
|
+
### Public API Additions
|
|
63
|
+
- `BlakfyCookie.onConsent(category, fn)` — category-specific callback
|
|
64
|
+
- `BlakfyCookie.registerCleanup({ category, cookies, storage })`
|
|
65
|
+
- `BlakfyCookie.unblock(category)`
|
|
66
|
+
- `BlakfyCookie.scan()` — re-scan DOM after SPA navigation
|
|
67
|
+
- `BlakfyCookie.usePreset(name)`
|
|
68
|
+
- `BlakfyCookie.tcf.getTCString()`
|
|
69
|
+
- `BlakfyCookie.ccpa.optOut()` / `isOptedOut()`
|
|
70
|
+
- `BlakfyCookie.getJurisdiction()`
|
|
71
|
+
- `window.__tcfapi(...)` IAB standard
|
|
72
|
+
|
|
73
|
+
### Branding
|
|
74
|
+
- "Powered by Blakfy Studio" badge — bottom-right, **non-removable**, anti-tampering protected (CSS `!important` + MutationObserver re-injection + code-baked HTML).
|
|
75
|
+
|
|
76
|
+
### Security & Privacy Fixes
|
|
77
|
+
- `makeHash()` device fingerprint **removed** → replaced with `crypto.randomUUID()` anonymous ID.
|
|
78
|
+
- `renderStatus` innerHTML XSS vector → `textContent` + DOM construction.
|
|
79
|
+
- Consent cookie `SameSite=Lax` → `SameSite=Strict`.
|
|
80
|
+
- status.json fetch `@latest` → version-pinned `@2`.
|
|
81
|
+
|
|
82
|
+
### Bug Fixes
|
|
83
|
+
- **Re-consent storm fix:** v1 triggered re-consent on every `cookie.js` version bump (`cookie.js:494`). Now only `data-blakfy-version` (policy version) triggers re-consent.
|
|
84
|
+
- TypeScript `BlakfyLocale` type expanded from 9 to 23 locales.
|
|
85
|
+
- Next.js `BlakfyCookieProvider` now uses `next/script` `beforeInteractive` (no more FOUC).
|
|
86
|
+
- `useBlakfyConsent` polling removed — event-driven now.
|
|
87
|
+
|
|
88
|
+
### Documentation
|
|
89
|
+
- AI-readable README with copy-paste install, scenario coverage (vanilla / Next.js / WordPress / GTM), full attribute & API tables.
|
|
90
|
+
- `ARCHITECTURE.md`, `COMPLIANCE.md`, `TCF-CERTIFICATION.md`, `MIGRATION.md`.
|
|
91
|
+
- Real `examples/nextjs/` Next 15 app.
|
|
92
|
+
|
|
93
|
+
### Breaking Changes
|
|
94
|
+
- None at API level — v1 contracts preserved.
|
|
95
|
+
- `cookie.js` location: `https://cdn.jsdelivr.net/gh/tariktunc/blakfy-cookie@1/cookie.js` → `@2/dist/cookie.min.js`. v1 users unaffected; opt into `@2` for new features.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## [1.2.0] — 2026-04-30 (legacy)
|
|
100
|
+
|
|
101
|
+
- Status bar via central `status.json` (CDN-hosted)
|
|
102
|
+
- BCP47 locale detection (`zh-TW`, `pt-BR` etc.)
|
|
103
|
+
- 23 languages
|
|
104
|
+
|
|
105
|
+
## [1.0.0] — 2026-04-25
|
|
106
|
+
|
|
107
|
+
- Initial release: Google Consent Mode v2, KVKK + GDPR + ePrivacy, 9 languages, vanilla JS, Next.js wrapper.
|
package/COMPLIANCE.md
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# Blakfy Cookie — Compliance Reference
|
|
2
|
+
|
|
3
|
+
> Hangi yasa/motor/standart için ne yapıyoruz, hangi modül karşılıyor.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Compliance Matrisi
|
|
8
|
+
|
|
9
|
+
| Yasa / Standart | Yetki Alanı | Modül | Durum (v2.0.0) |
|
|
10
|
+
|---|---|---|---|
|
|
11
|
+
| **GDPR** | AB | core + ui (eşit prominence butonlar, pre-tick yok) | ✅ |
|
|
12
|
+
| **ePrivacy Directive** | AB | core (consent öncesi cookie konmaz) | ✅ |
|
|
13
|
+
| **KVKK** | Türkiye | core/audit.js (Md.12 kanıt yükümlülüğü) | ✅ |
|
|
14
|
+
| **CCPA / CPRA** | Kaliforniya, ABD | compliance/ccpa.js | ✅ |
|
|
15
|
+
| **LGPD** | Brezilya | i18n/translations/pt.js + jurisdiction | ⚠️ (v2.1) |
|
|
16
|
+
| **Google Consent Mode v2** | Google ekosistemi | compliance/google-cmv2.js | ✅ |
|
|
17
|
+
| **Microsoft UET Consent Mode** | Bing Ads + Clarity | compliance/microsoft-uet.js | ✅ |
|
|
18
|
+
| **Yandex Metrica Consent** | Yandex ekosistemi | compliance/yandex-metrica.js | ✅ |
|
|
19
|
+
| **IAB TCF v2.2** | AB AdTech (AdSense/Ad Manager) | compliance/tcf-v2.js | ✅ kod + ⏳ sertifikasyon |
|
|
20
|
+
| **GPC** (Global Privacy Control) | Tarayıcı standardı, CA yasal | compliance/gpc.js | ✅ |
|
|
21
|
+
| **DNT** (Do Not Track) | Tarayıcı standardı | compliance/dnt.js | ✅ |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 2. Google Consent Mode v2
|
|
26
|
+
|
|
27
|
+
**Sinyal:**
|
|
28
|
+
```js
|
|
29
|
+
gtag('consent', 'update', {
|
|
30
|
+
ad_storage: marketing ? 'granted' : 'denied',
|
|
31
|
+
ad_user_data: marketing ? 'granted' : 'denied',
|
|
32
|
+
ad_personalization: marketing ? 'granted' : 'denied',
|
|
33
|
+
analytics_storage: analytics ? 'granted' : 'denied',
|
|
34
|
+
functionality_storage: functional ? 'granted' : 'denied',
|
|
35
|
+
personalization_storage: functional ? 'granted' : 'denied',
|
|
36
|
+
security_storage: 'granted'
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Bootstrap (cookie-defaults.min.js):**
|
|
41
|
+
- Tüm sinyaller default `denied`
|
|
42
|
+
- `wait_for_update: 500` ile GTM/GA4 cevap bekler
|
|
43
|
+
- `gtag` global fonksiyonu yoksa stub kurulur
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 3. Microsoft UET Consent Mode
|
|
48
|
+
|
|
49
|
+
**Sinyal:**
|
|
50
|
+
```js
|
|
51
|
+
window.uetq = window.uetq || [];
|
|
52
|
+
window.uetq.push('consent', 'update', {
|
|
53
|
+
ad_storage: marketing ? 'granted' : 'denied'
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Bing Ads (UET tag) ve Microsoft Clarity bunu okur. v2.0.0 itibariyle Clarity zaten bu sinyali destekliyor.
|
|
58
|
+
|
|
59
|
+
**Bootstrap:** `uetq` push queue stub kurulur, default `denied`.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 4. Yandex Metrica Consent
|
|
64
|
+
|
|
65
|
+
Yandex'in Google gibi standart bir consent API'si yok. Yaklaşımımız:
|
|
66
|
+
|
|
67
|
+
- Onay yokken Metrica script'leri **engellenir** (gating layer).
|
|
68
|
+
- Onay verilince `ym(counterId, 'init', {...})` çağrılır.
|
|
69
|
+
- **Webvisor (session replay)** ekstra kategori — `marketing` değil, ayrı `recording` kategorisi olarak işaretlenir (KVKK/GDPR yorum farkı).
|
|
70
|
+
- Cookie temizliği: `_ym_*`, `_ym_uid`, `_ym_d`, `_ym_isad`, `yabs-frequency`, `yandexuid`.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## 5. IAB TCF v2.2
|
|
75
|
+
|
|
76
|
+
**Teknik kapsam (v2.0.0 ile gelen kod):**
|
|
77
|
+
|
|
78
|
+
- `window.__tcfapi(command, version, callback, parameter)` global fonksiyonu (IAB standardı)
|
|
79
|
+
- TC string encoding (Base64URL, vendor segments dahil)
|
|
80
|
+
- Global Vendor List (GVL) fetch — `vendor-list.consensu.org/v3/vendor-list.json`
|
|
81
|
+
- `getTCData`, `addEventListener`, `removeEventListener` komutları
|
|
82
|
+
- `data-blakfy-cmp-id="0"` → preview/test mode
|
|
83
|
+
|
|
84
|
+
**Sertifikasyon süreci (kullanıcı tarafı):**
|
|
85
|
+
|
|
86
|
+
1. https://iabeurope.eu/cmp-list/ üzerinden başvuru
|
|
87
|
+
2. Audit (kod + UI + DSAR/data subject request akışı incelenir)
|
|
88
|
+
3. Annual fee (~€2.000)
|
|
89
|
+
4. CMP ID atanır → `data-blakfy-cmp-id="123"` ile yazılır
|
|
90
|
+
5. Onay öncesi widget "preview mode"da çalışır, onay sonrası prod
|
|
91
|
+
|
|
92
|
+
⏱ Süreç 2-3 ay. Detay: [TCF-CERTIFICATION.md](./TCF-CERTIFICATION.md)
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## 6. CCPA / CPRA
|
|
97
|
+
|
|
98
|
+
**Kapsam:** Kaliforniya sakinleri için.
|
|
99
|
+
|
|
100
|
+
**Tetiklenme:** `src/geo/jurisdiction.js` ABD/CA tespit ederse:
|
|
101
|
+
- Banner "Reddet" yerine **"Do Not Sell or Share My Personal Information"** olarak değiştirilir.
|
|
102
|
+
- Footer'a kalıcı `<a class="blakfy-ccpa-link">` eklenir (yasal zorunluluk).
|
|
103
|
+
- `Sec-GPC: 1` header otomatik opt-out say.
|
|
104
|
+
- USP string `1YYY` formatında set edilir (versiyon, opt-out, sale, third-party).
|
|
105
|
+
|
|
106
|
+
**API:**
|
|
107
|
+
```js
|
|
108
|
+
BlakfyCookie.ccpa.optOut()
|
|
109
|
+
BlakfyCookie.ccpa.isOptedOut()
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## 7. GPC (Global Privacy Control)
|
|
115
|
+
|
|
116
|
+
`navigator.globalPrivacyControl === true` ise:
|
|
117
|
+
- `marketing` ve `analytics` kategorileri **otomatik denied** (kullanıcı açık onay vermediyse)
|
|
118
|
+
- CCPA jurisdiction'da yasal olarak zorunlu opt-out
|
|
119
|
+
- GDPR jurisdiction'da rehberlik niteliğinde, biz default'ta saygı gösteriyoruz
|
|
120
|
+
|
|
121
|
+
Override: `data-blakfy-gpc="ignore"` ile kapatılabilir (önerilmez).
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## 8. DNT (Do Not Track)
|
|
126
|
+
|
|
127
|
+
`navigator.doNotTrack === "1"` ise:
|
|
128
|
+
- Default'ta **sadece UI'da işaret** (kullanıcı görsün, "GPC veya DNT etkin" yazısı)
|
|
129
|
+
- `data-blakfy-dnt="auto-deny"` ile auto-deny opsiyonel
|
|
130
|
+
|
|
131
|
+
DNT eski/zayıf bir standart, GPC tercih edilir.
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## 9. Jurisdiction Tespiti
|
|
136
|
+
|
|
137
|
+
`src/geo/jurisdiction.js` 3 strateji dener:
|
|
138
|
+
|
|
139
|
+
1. **Cloudflare** `CF-IPCountry` header (server-rendered sites)
|
|
140
|
+
2. **Server endpoint** `data-blakfy-geo-endpoint="/api/geo"` (opt-in)
|
|
141
|
+
3. **Client-side fallback:** `Intl.DateTimeFormat().resolvedOptions().timeZone` → kaba bölge tahmini
|
|
142
|
+
|
|
143
|
+
Sonuç: `"GDPR"` | `"CCPA"` | `"LGPD"` | `"default"`
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## 10. Audit Log (KVKK Md.12 + GDPR Art.7(1))
|
|
148
|
+
|
|
149
|
+
Her consent değişikliği `data-blakfy-audit-endpoint`'e POST edilir:
|
|
150
|
+
|
|
151
|
+
```json
|
|
152
|
+
{
|
|
153
|
+
"id": "uuid-v4-anonim-id",
|
|
154
|
+
"timestamp": "2026-04-30T12:00:00Z",
|
|
155
|
+
"action": "accept_all" | "reject_all" | "save_preferences",
|
|
156
|
+
"state": { ... },
|
|
157
|
+
"jurisdiction": "GDPR",
|
|
158
|
+
"userAgent": "...",
|
|
159
|
+
"url": "...",
|
|
160
|
+
"policyVersion": "1.0",
|
|
161
|
+
"blakfy": "2.0.0",
|
|
162
|
+
"tcString": "...",
|
|
163
|
+
"uspString": "..."
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**Anonim ID:** `crypto.randomUUID()` — fingerprint **değil** (v1'deki `makeHash()` kaldırıldı).
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## 11. Kategori → Yasal Temel Eşlemesi
|
|
172
|
+
|
|
173
|
+
| Kategori | GDPR Yasal Temel | KVKK | CCPA |
|
|
174
|
+
|---|---|---|---|
|
|
175
|
+
| `essential` | Art. 6(1)(b) — sözleşme/zorunluluk | Md.5(2)(c) | exempt |
|
|
176
|
+
| `analytics` | Art. 6(1)(a) — açık rıza | Md.5(1) | optable |
|
|
177
|
+
| `marketing` | Art. 6(1)(a) — açık rıza | Md.5(1) | optable + GPC saygısı |
|
|
178
|
+
| `functional` | Art. 6(1)(a) — açık rıza | Md.5(1) | optable |
|
|
179
|
+
| `recording` (Webvisor) | Art. 6(1)(a) — ek granular onay | Md.5(1) açık rıza | optable |
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## 12. Test Kapsamı
|
|
184
|
+
|
|
185
|
+
`tests/compliance/` altında her modül için ayrı test:
|
|
186
|
+
- `google-cmv2.test.js` — gtag stub kurulumu, update sinyalleri
|
|
187
|
+
- `microsoft-uet.test.js` — uetq queue, consent push
|
|
188
|
+
- `yandex-metrica.test.js` — cookie engelleme, Webvisor ayrı kategori
|
|
189
|
+
- `tcf-v2.test.js` — `__tcfapi` komut yüzeyi, TC string format
|
|
190
|
+
- `ccpa.test.js` — USP string, DNT/GPC saygısı
|
|
191
|
+
- `gpc.test.js` — auto-deny davranışı
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Blakfy Studio
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/MIGRATION.md
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# Migration: v1 → v2
|
|
2
|
+
|
|
3
|
+
> Kısa cevap: **Değişiklik yapmana gerek yok.** v1 kullanıcıları `@1` etiketinde kalır, çalışmaya devam eder. v2 yeni features için opt-in.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## v1'de kal — hiçbir şey değişmez
|
|
8
|
+
|
|
9
|
+
```html
|
|
10
|
+
<!-- Bu çalışmaya devam ediyor, kırılmıyor -->
|
|
11
|
+
<script src="https://cdn.jsdelivr.net/gh/tariktunc/blakfy-cookie@1/cookie.js"
|
|
12
|
+
data-blakfy-locale="auto"
|
|
13
|
+
data-blakfy-policy-url="/cerez-politikasi"></script>
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
v1 son sürümü `1.2.0`'da donduruldu. Critical security patch çıkarsa `1.2.x` patch sürümleri devam edebilir.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## v2'ye geç — 1 satır değişiklik
|
|
21
|
+
|
|
22
|
+
```diff
|
|
23
|
+
- <script src="https://cdn.jsdelivr.net/gh/tariktunc/blakfy-cookie@1/cookie.js"
|
|
24
|
+
+ <script src="https://cdn.jsdelivr.net/gh/tariktunc/blakfy-cookie@v2/dist/cookie.min.js"
|
|
25
|
+
data-blakfy-locale="auto"
|
|
26
|
+
data-blakfy-policy-url="/cerez-politikasi"></script>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Tüm v1 attribute'ları çalışmaya devam eder, kullanıcı consent'i korunur (cookie formatı uyumlu).
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Yeni Özellikleri Aktif Et (opsiyonel)
|
|
34
|
+
|
|
35
|
+
### Tag-gating
|
|
36
|
+
```html
|
|
37
|
+
<!-- 3rd-party script'leri sar -->
|
|
38
|
+
<script type="text/plain"
|
|
39
|
+
data-blakfy-category="marketing"
|
|
40
|
+
data-blakfy-src="https://connect.facebook.net/en_US/fbevents.js"></script>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Preset kullan
|
|
44
|
+
```diff
|
|
45
|
+
<script src="...@2/dist/cookie.min.js"
|
|
46
|
+
data-blakfy-locale="auto"
|
|
47
|
+
+ data-blakfy-presets="ga4,gtm,facebook,clarity"></script>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### TCF v2.2
|
|
51
|
+
```diff
|
|
52
|
+
+ <script ... data-blakfy-tcf="true" data-blakfy-cmp-id="0"></script>
|
|
53
|
+
```
|
|
54
|
+
(CMP ID `0` preview mode, sertifikasyon onayı sonrası gerçek ID girilir.)
|
|
55
|
+
|
|
56
|
+
### CCPA
|
|
57
|
+
```diff
|
|
58
|
+
+ <script ... data-blakfy-ccpa="auto"></script>
|
|
59
|
+
```
|
|
60
|
+
(Otomatik jurisdiction tespitiyle Kaliforniya kullanıcılarına "Do Not Sell" linki gösterilir.)
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Next.js (cookie-next) Migration
|
|
65
|
+
|
|
66
|
+
### v1 (npm paketi yoktu, sadece GitHub'tan import)
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
// Eski
|
|
70
|
+
import { BlakfyCookieProvider } from "@blakfy/cookie-next"; // ham .tsx
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### v2 (npm public paketi)
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
npm install @blakfy/cookie-next@2
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
```tsx
|
|
80
|
+
// Yeni — TypeScript tipler genişledi (23 dil), yeni hook'lar var
|
|
81
|
+
import {
|
|
82
|
+
BlakfyCookieProvider,
|
|
83
|
+
ConsentModeDefault,
|
|
84
|
+
useBlakfyConsent,
|
|
85
|
+
useGating, // YENİ
|
|
86
|
+
useTcf, // YENİ
|
|
87
|
+
} from "@blakfy/cookie-next";
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Yeni hook örnekleri
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
// Kategori-tabanlı koşullu render
|
|
94
|
+
function YouTubeEmbed({ id }: { id: string }) {
|
|
95
|
+
const allowed = useGating("marketing");
|
|
96
|
+
if (!allowed) return <Placeholder />;
|
|
97
|
+
return <iframe src={`https://www.youtube.com/embed/${id}`} />;
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## API Değişiklikleri
|
|
104
|
+
|
|
105
|
+
| API | v1 | v2 | Not |
|
|
106
|
+
|---|---|---|---|
|
|
107
|
+
| `acceptAll/rejectAll/open` | ✅ | ✅ | aynı |
|
|
108
|
+
| `getConsent/getState` | ✅ | ✅ | aynı |
|
|
109
|
+
| `onChange` | ✅ | ✅ | aynı |
|
|
110
|
+
| `setLocale` | 9 dil | 23 dil | TS tipi genişletildi |
|
|
111
|
+
| `onConsent(cat, fn)` | ❌ | ✅ | YENİ |
|
|
112
|
+
| `registerCleanup` | ❌ | ✅ | YENİ |
|
|
113
|
+
| `unblock/scan/usePreset` | ❌ | ✅ | YENİ |
|
|
114
|
+
| `tcf.*` | ❌ | ✅ | YENİ |
|
|
115
|
+
| `ccpa.*` | ❌ | ✅ | YENİ |
|
|
116
|
+
| `getJurisdiction` | ❌ | ✅ | YENİ |
|
|
117
|
+
| `getMainLang` | ✅ | ✅ | aynı |
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Cookie Formatı
|
|
122
|
+
|
|
123
|
+
v2 cookie formatı v1 ile **geriye uyumlu**. v1 cookie'si v2 tarafından okunur, eksik alanlar default değerlerle doldurulur.
|
|
124
|
+
|
|
125
|
+
```js
|
|
126
|
+
// v1 cookie örneği
|
|
127
|
+
{ essential, analytics, marketing, functional, timestamp, version, blakfy, locale, hash }
|
|
128
|
+
|
|
129
|
+
// v2 cookie örneği (eklemeler)
|
|
130
|
+
{ ..., id (uuid), jurisdiction, tcString?, uspString?, mainLang? }
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Eski `hash` alanı v2'de okunmaz ama silinmez (geri dönüş güvenliği).
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Re-consent Davranışı
|
|
138
|
+
|
|
139
|
+
### v1 (BUG)
|
|
140
|
+
`cookie.js` her sürüm güncellendiğinde **tüm kullanıcılar yeniden onay vermek zorundaydı**. Bu KVKK/GDPR uyumlu davranış değildi.
|
|
141
|
+
|
|
142
|
+
### v2 (DÜZELDİ)
|
|
143
|
+
Sadece `data-blakfy-version` (politika versiyonu) değişimi re-consent tetikler. `cookie.js` patch/minor güncellemeleri kullanıcıyı etkilemez.
|
|
144
|
+
|
|
145
|
+
```js
|
|
146
|
+
// v1
|
|
147
|
+
if (s.version !== config.policyVersion || s.blakfy !== VERSION) return null;
|
|
148
|
+
// v2
|
|
149
|
+
if (s.version !== config.policyVersion) return null;
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Soru / Sorun?
|
|
155
|
+
|
|
156
|
+
GitHub Issues → https://github.com/tariktunc/blakfy-cookie/issues
|