c15t 0.0.1-rc.3
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/.turbo/turbo-build.log +54 -0
- package/.turbo/turbo-fmt.log +6 -0
- package/.turbo/turbo-lint.log +288 -0
- package/.turbo/turbo-test.log +33 -0
- package/CHANGELOG.md +20 -0
- package/LICENSE.md +595 -0
- package/README.md +28 -0
- package/dist/index.cjs +118 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/libs/__tests__/tracking-blocker.test.cjs +269 -0
- package/dist/libs/__tests__/tracking-blocker.test.d.ts +2 -0
- package/dist/libs/__tests__/tracking-blocker.test.d.ts.map +1 -0
- package/dist/libs/__tests__/tracking-blocker.test.js +267 -0
- package/dist/libs/consent-utils.cjs +68 -0
- package/dist/libs/consent-utils.d.ts +49 -0
- package/dist/libs/consent-utils.d.ts.map +1 -0
- package/dist/libs/consent-utils.js +23 -0
- package/dist/libs/tracking-blocker.cjs +167 -0
- package/dist/libs/tracking-blocker.d.ts +33 -0
- package/dist/libs/tracking-blocker.d.ts.map +1 -0
- package/dist/libs/tracking-blocker.js +108 -0
- package/dist/libs/tracking-domains.cjs +188 -0
- package/dist/libs/tracking-domains.d.ts +7 -0
- package/dist/libs/tracking-domains.d.ts.map +1 -0
- package/dist/libs/tracking-domains.js +146 -0
- package/dist/store.cjs +248 -0
- package/dist/store.d.ts +58 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.initial-state.cjs +105 -0
- package/dist/store.initial-state.d.ts +43 -0
- package/dist/store.initial-state.d.ts.map +1 -0
- package/dist/store.initial-state.js +66 -0
- package/dist/store.js +219 -0
- package/dist/store.type.cjs +22 -0
- package/dist/store.type.d.ts +159 -0
- package/dist/store.type.d.ts.map +1 -0
- package/dist/store.type.js +0 -0
- package/dist/translations/en.cjs +96 -0
- package/dist/translations/en.d.ts +3 -0
- package/dist/translations/en.d.ts.map +1 -0
- package/dist/translations/en.js +54 -0
- package/dist/translations/index.cjs +51 -0
- package/dist/translations/index.d.ts +3 -0
- package/dist/translations/index.d.ts.map +1 -0
- package/dist/translations/index.js +9 -0
- package/dist/types/callbacks.cjs +22 -0
- package/dist/types/callbacks.d.ts +146 -0
- package/dist/types/callbacks.d.ts.map +1 -0
- package/dist/types/callbacks.js +0 -0
- package/dist/types/compliance.cjs +22 -0
- package/dist/types/compliance.d.ts +196 -0
- package/dist/types/compliance.d.ts.map +1 -0
- package/dist/types/compliance.js +0 -0
- package/dist/types/gdpr.cjs +86 -0
- package/dist/types/gdpr.d.ts +168 -0
- package/dist/types/gdpr.d.ts.map +1 -0
- package/dist/types/gdpr.js +44 -0
- package/dist/types/index.cjs +44 -0
- package/dist/types/index.d.ts +141 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +4 -0
- package/dist/types/translations.cjs +22 -0
- package/dist/types/translations.d.ts +52 -0
- package/dist/types/translations.d.ts.map +1 -0
- package/dist/types/translations.js +0 -0
- package/package.json +33 -0
- package/rslib.config.ts +28 -0
- package/src/index.ts +31 -0
- package/src/libs/__tests__/tracking-blocker.test.ts +271 -0
- package/src/libs/consent-utils.ts +70 -0
- package/src/libs/tracking-blocker.ts +202 -0
- package/src/libs/tracking-domains.ts +158 -0
- package/src/store.initial-state.ts +123 -0
- package/src/store.ts +450 -0
- package/src/store.type.ts +187 -0
- package/src/translations/en.ts +55 -0
- package/src/translations/index.ts +10 -0
- package/src/types/callbacks.ts +152 -0
- package/src/types/compliance.ts +205 -0
- package/src/types/gdpr.ts +217 -0
- package/src/types/index.ts +148 -0
- package/src/types/translations.ts +60 -0
- package/tsconfig.json +12 -0
- package/vitest.config.ts +15 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import * as __WEBPACK_EXTERNAL_MODULE_vitest__ from 'vitest';
|
|
2
|
+
import * as __WEBPACK_EXTERNAL_MODULE__tracking_blocker_js_d038b07a__ from '../tracking-blocker.js';
|
|
3
|
+
var __webpack_require__ = {};
|
|
4
|
+
(() => {
|
|
5
|
+
__webpack_require__.g = (function () {
|
|
6
|
+
if ('object' == typeof globalThis) return globalThis;
|
|
7
|
+
try {
|
|
8
|
+
return this || new Function('return this')();
|
|
9
|
+
} catch (e) {
|
|
10
|
+
if ('object' == typeof window) return window;
|
|
11
|
+
}
|
|
12
|
+
})();
|
|
13
|
+
})();
|
|
14
|
+
const BLOCKED_CONSENT = {
|
|
15
|
+
experience: false,
|
|
16
|
+
functionality: false,
|
|
17
|
+
marketing: false,
|
|
18
|
+
measurement: false,
|
|
19
|
+
necessary: true,
|
|
20
|
+
};
|
|
21
|
+
const ALLOWED_CONSENT = {
|
|
22
|
+
...BLOCKED_CONSENT,
|
|
23
|
+
measurement: true,
|
|
24
|
+
};
|
|
25
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.describe)('TrackingBlocker', () => {
|
|
26
|
+
const originalFetch = __webpack_require__.g.fetch;
|
|
27
|
+
const originalXHR = __webpack_require__.g.XMLHttpRequest;
|
|
28
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.beforeAll)(() => {
|
|
29
|
+
__webpack_require__.g.fetch = __WEBPACK_EXTERNAL_MODULE_vitest__.vi
|
|
30
|
+
.fn()
|
|
31
|
+
.mockImplementation(() => Promise.resolve(new Response()));
|
|
32
|
+
if (!__webpack_require__.g.XMLHttpRequest)
|
|
33
|
+
__webpack_require__.g.XMLHttpRequest = originalXHR;
|
|
34
|
+
});
|
|
35
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.afterAll)(() => {
|
|
36
|
+
__webpack_require__.g.fetch = originalFetch;
|
|
37
|
+
__webpack_require__.g.XMLHttpRequest = originalXHR;
|
|
38
|
+
});
|
|
39
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.beforeEach)(() => {
|
|
40
|
+
__WEBPACK_EXTERNAL_MODULE_vitest__.vi.clearAllMocks();
|
|
41
|
+
__WEBPACK_EXTERNAL_MODULE_vitest__.vi.restoreAllMocks();
|
|
42
|
+
__webpack_require__.g.fetch = __WEBPACK_EXTERNAL_MODULE_vitest__.vi
|
|
43
|
+
.fn()
|
|
44
|
+
.mockImplementation(() => Promise.resolve(new Response()));
|
|
45
|
+
window.fetch = __webpack_require__.g.fetch;
|
|
46
|
+
window.XMLHttpRequest = originalXHR;
|
|
47
|
+
__WEBPACK_EXTERNAL_MODULE_vitest__.vi.spyOn(document, 'dispatchEvent');
|
|
48
|
+
});
|
|
49
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.test)(
|
|
50
|
+
'blocks fetch requests to tracking domains when consent not granted',
|
|
51
|
+
async () => {
|
|
52
|
+
(0,
|
|
53
|
+
__WEBPACK_EXTERNAL_MODULE__tracking_blocker_js_d038b07a__.createTrackingBlocker)(
|
|
54
|
+
{},
|
|
55
|
+
BLOCKED_CONSENT
|
|
56
|
+
);
|
|
57
|
+
await (0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
|
|
58
|
+
fetch('https://www.google-analytics.com/analytics.js')
|
|
59
|
+
).rejects.toThrow(
|
|
60
|
+
'Request to https://www.google-analytics.com/analytics.js blocked due to missing consent'
|
|
61
|
+
);
|
|
62
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
|
|
63
|
+
document.dispatchEvent
|
|
64
|
+
).toHaveBeenCalledWith(
|
|
65
|
+
__WEBPACK_EXTERNAL_MODULE_vitest__.expect.objectContaining({
|
|
66
|
+
type: 'ConsentBlockedRequest',
|
|
67
|
+
detail: {
|
|
68
|
+
url: 'https://www.google-analytics.com/analytics.js',
|
|
69
|
+
},
|
|
70
|
+
})
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.test)(
|
|
75
|
+
'blocks XMLHttpRequest to tracking domains when consent not granted',
|
|
76
|
+
() => {
|
|
77
|
+
(0,
|
|
78
|
+
__WEBPACK_EXTERNAL_MODULE__tracking_blocker_js_d038b07a__.createTrackingBlocker)(
|
|
79
|
+
{},
|
|
80
|
+
BLOCKED_CONSENT
|
|
81
|
+
);
|
|
82
|
+
const xhr = new XMLHttpRequest();
|
|
83
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(() => {
|
|
84
|
+
xhr.open('GET', 'https://www.google-analytics.com/analytics.js');
|
|
85
|
+
}).toThrow(
|
|
86
|
+
'Request to https://www.google-analytics.com/analytics.js blocked due to missing consent'
|
|
87
|
+
);
|
|
88
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
|
|
89
|
+
document.dispatchEvent
|
|
90
|
+
).toHaveBeenCalledWith(
|
|
91
|
+
__WEBPACK_EXTERNAL_MODULE_vitest__.expect.objectContaining({
|
|
92
|
+
type: 'ConsentBlockedRequest',
|
|
93
|
+
detail: {
|
|
94
|
+
url: 'https://www.google-analytics.com/analytics.js',
|
|
95
|
+
},
|
|
96
|
+
})
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
);
|
|
100
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.test)(
|
|
101
|
+
'allows fetch requests to tracking domains after consent granted',
|
|
102
|
+
async () => {
|
|
103
|
+
window.fetch = __webpack_require__.g.fetch;
|
|
104
|
+
const trackingBlocker = (0,
|
|
105
|
+
__WEBPACK_EXTERNAL_MODULE__tracking_blocker_js_d038b07a__.createTrackingBlocker)(
|
|
106
|
+
{},
|
|
107
|
+
ALLOWED_CONSENT
|
|
108
|
+
);
|
|
109
|
+
const fetchSpy = __WEBPACK_EXTERNAL_MODULE_vitest__.vi.spyOn(
|
|
110
|
+
window,
|
|
111
|
+
'fetch'
|
|
112
|
+
);
|
|
113
|
+
await fetch('https://www.google-analytics.com/analytics.js');
|
|
114
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
|
|
115
|
+
fetchSpy
|
|
116
|
+
).toHaveBeenCalledWith('https://www.google-analytics.com/analytics.js');
|
|
117
|
+
trackingBlocker.destroy();
|
|
118
|
+
}
|
|
119
|
+
);
|
|
120
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.test)(
|
|
121
|
+
'allows XMLHttpRequest to tracking domains after consent granted',
|
|
122
|
+
() => {
|
|
123
|
+
(0,
|
|
124
|
+
__WEBPACK_EXTERNAL_MODULE__tracking_blocker_js_d038b07a__.createTrackingBlocker)(
|
|
125
|
+
{},
|
|
126
|
+
ALLOWED_CONSENT
|
|
127
|
+
);
|
|
128
|
+
const xhr = new XMLHttpRequest();
|
|
129
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(() => {
|
|
130
|
+
xhr.open('GET', 'https://www.google-analytics.com/analytics.js');
|
|
131
|
+
}).not.toThrow();
|
|
132
|
+
}
|
|
133
|
+
);
|
|
134
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.test)(
|
|
135
|
+
'allows requests to non-tracking domains regardless of consent',
|
|
136
|
+
async () => {
|
|
137
|
+
(0,
|
|
138
|
+
__WEBPACK_EXTERNAL_MODULE__tracking_blocker_js_d038b07a__.createTrackingBlocker)(
|
|
139
|
+
{},
|
|
140
|
+
BLOCKED_CONSENT
|
|
141
|
+
);
|
|
142
|
+
const fetchSpy = __WEBPACK_EXTERNAL_MODULE_vitest__.vi.spyOn(
|
|
143
|
+
window,
|
|
144
|
+
'fetch'
|
|
145
|
+
);
|
|
146
|
+
await fetch('https://api.example.com/data');
|
|
147
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
|
|
148
|
+
fetchSpy
|
|
149
|
+
).toHaveBeenCalledWith('https://api.example.com/data');
|
|
150
|
+
const xhr = new XMLHttpRequest();
|
|
151
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(() => {
|
|
152
|
+
xhr.open('GET', 'https://api.example.com/data');
|
|
153
|
+
}).not.toThrow();
|
|
154
|
+
}
|
|
155
|
+
);
|
|
156
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.test)(
|
|
157
|
+
'handles custom domain consent map',
|
|
158
|
+
async () => {
|
|
159
|
+
const trackingBlocker = (0,
|
|
160
|
+
__WEBPACK_EXTERNAL_MODULE__tracking_blocker_js_d038b07a__.createTrackingBlocker)(
|
|
161
|
+
{
|
|
162
|
+
overrideDomainConsentMap: true,
|
|
163
|
+
domainConsentMap: {
|
|
164
|
+
'custom-analytics.example.com': 'measurement',
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
BLOCKED_CONSENT
|
|
168
|
+
);
|
|
169
|
+
await (0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
|
|
170
|
+
fetch('https://custom-analytics.example.com/track')
|
|
171
|
+
).rejects.toThrow(
|
|
172
|
+
'Request to https://custom-analytics.example.com/track blocked due to missing consent'
|
|
173
|
+
);
|
|
174
|
+
trackingBlocker.updateConsents({
|
|
175
|
+
experience: false,
|
|
176
|
+
functionality: false,
|
|
177
|
+
marketing: false,
|
|
178
|
+
measurement: true,
|
|
179
|
+
necessary: true,
|
|
180
|
+
});
|
|
181
|
+
const fetchSpy = __WEBPACK_EXTERNAL_MODULE_vitest__.vi.spyOn(
|
|
182
|
+
window,
|
|
183
|
+
'fetch'
|
|
184
|
+
);
|
|
185
|
+
await fetch('https://custom-analytics.example.com/track');
|
|
186
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
|
|
187
|
+
fetchSpy
|
|
188
|
+
).toHaveBeenCalledWith('https://custom-analytics.example.com/track');
|
|
189
|
+
}
|
|
190
|
+
);
|
|
191
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.test)(
|
|
192
|
+
'handles subdomains correctly',
|
|
193
|
+
async () => {
|
|
194
|
+
(0,
|
|
195
|
+
__WEBPACK_EXTERNAL_MODULE__tracking_blocker_js_d038b07a__.createTrackingBlocker)(
|
|
196
|
+
{},
|
|
197
|
+
BLOCKED_CONSENT
|
|
198
|
+
);
|
|
199
|
+
await (0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
|
|
200
|
+
fetch('https://subdomain.google-analytics.com/track')
|
|
201
|
+
).rejects.toThrow(
|
|
202
|
+
'Request to https://subdomain.google-analytics.com/track blocked due to missing consent'
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
);
|
|
206
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.test)(
|
|
207
|
+
'can be disabled via config',
|
|
208
|
+
async () => {
|
|
209
|
+
(0,
|
|
210
|
+
__WEBPACK_EXTERNAL_MODULE__tracking_blocker_js_d038b07a__.createTrackingBlocker)(
|
|
211
|
+
{
|
|
212
|
+
disableAutomaticBlocking: true,
|
|
213
|
+
},
|
|
214
|
+
BLOCKED_CONSENT
|
|
215
|
+
);
|
|
216
|
+
await fetch('https://www.google-analytics.com/analytics.js');
|
|
217
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
|
|
218
|
+
fetch
|
|
219
|
+
).toHaveBeenCalledWith('https://www.google-analytics.com/analytics.js');
|
|
220
|
+
}
|
|
221
|
+
);
|
|
222
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.test)(
|
|
223
|
+
'cleanup restores original fetch and XMLHttpRequest functionality',
|
|
224
|
+
async () => {
|
|
225
|
+
const trackingBlocker = (0,
|
|
226
|
+
__WEBPACK_EXTERNAL_MODULE__tracking_blocker_js_d038b07a__.createTrackingBlocker)(
|
|
227
|
+
{},
|
|
228
|
+
BLOCKED_CONSENT
|
|
229
|
+
);
|
|
230
|
+
await (0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
|
|
231
|
+
fetch('https://www.google-analytics.com/analytics.js')
|
|
232
|
+
).rejects.toThrow();
|
|
233
|
+
trackingBlocker.destroy();
|
|
234
|
+
await fetch('https://www.google-analytics.com/analytics.js');
|
|
235
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
|
|
236
|
+
fetch
|
|
237
|
+
).toHaveBeenCalledWith('https://www.google-analytics.com/analytics.js');
|
|
238
|
+
const xhr = new XMLHttpRequest();
|
|
239
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(() => {
|
|
240
|
+
xhr.open('GET', 'https://www.google-analytics.com/analytics.js');
|
|
241
|
+
}).not.toThrow();
|
|
242
|
+
}
|
|
243
|
+
);
|
|
244
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.test)(
|
|
245
|
+
'handles multiple concurrent requests correctly',
|
|
246
|
+
async () => {
|
|
247
|
+
(0,
|
|
248
|
+
__WEBPACK_EXTERNAL_MODULE__tracking_blocker_js_d038b07a__.createTrackingBlocker)(
|
|
249
|
+
{},
|
|
250
|
+
BLOCKED_CONSENT
|
|
251
|
+
);
|
|
252
|
+
const requests = Promise.all([
|
|
253
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
|
|
254
|
+
fetch('https://www.google-analytics.com/analytics.js')
|
|
255
|
+
).rejects.toThrow(),
|
|
256
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
|
|
257
|
+
fetch('https://www.google-analytics.com/collect')
|
|
258
|
+
).rejects.toThrow(),
|
|
259
|
+
fetch('https://api.example.com/data'),
|
|
260
|
+
]);
|
|
261
|
+
await requests;
|
|
262
|
+
(0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
|
|
263
|
+
document.dispatchEvent
|
|
264
|
+
).toHaveBeenCalledTimes(6);
|
|
265
|
+
}
|
|
266
|
+
);
|
|
267
|
+
});
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(() => {
|
|
4
|
+
__webpack_require__.d = function (exports1, definition) {
|
|
5
|
+
for (var key in definition)
|
|
6
|
+
if (
|
|
7
|
+
__webpack_require__.o(definition, key) &&
|
|
8
|
+
!__webpack_require__.o(exports1, key)
|
|
9
|
+
)
|
|
10
|
+
Object.defineProperty(exports1, key, {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
get: definition[key],
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
})();
|
|
16
|
+
(() => {
|
|
17
|
+
__webpack_require__.o = function (obj, prop) {
|
|
18
|
+
return Object.prototype.hasOwnProperty.call(obj, prop);
|
|
19
|
+
};
|
|
20
|
+
})();
|
|
21
|
+
(() => {
|
|
22
|
+
__webpack_require__.r = function (exports1) {
|
|
23
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag)
|
|
24
|
+
Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
25
|
+
value: 'Module',
|
|
26
|
+
});
|
|
27
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
28
|
+
value: true,
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
})();
|
|
32
|
+
var __webpack_exports__ = {};
|
|
33
|
+
__webpack_require__.r(__webpack_exports__);
|
|
34
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
35
|
+
getEffectiveConsents: () => getEffectiveConsents,
|
|
36
|
+
hasConsentFor: () => hasConsentFor,
|
|
37
|
+
hasConsented: () => hasConsented,
|
|
38
|
+
isConsentEnabled: () => isConsentEnabled,
|
|
39
|
+
});
|
|
40
|
+
function getEffectiveConsents(consents, honorDoNotTrack) {
|
|
41
|
+
if (
|
|
42
|
+
honorDoNotTrack &&
|
|
43
|
+
'undefined' != typeof window &&
|
|
44
|
+
'1' === window.navigator.doNotTrack
|
|
45
|
+
)
|
|
46
|
+
return Object.keys(consents).reduce((acc, key) => {
|
|
47
|
+
if (key in consents) acc[key] = 'necessary' === key;
|
|
48
|
+
return acc;
|
|
49
|
+
}, {});
|
|
50
|
+
return consents;
|
|
51
|
+
}
|
|
52
|
+
function hasConsentFor(consentType, consents, honorDoNotTrack) {
|
|
53
|
+
const effectiveConsents = getEffectiveConsents(consents, honorDoNotTrack);
|
|
54
|
+
return effectiveConsents[consentType] || false;
|
|
55
|
+
}
|
|
56
|
+
function hasConsented(consentInfo) {
|
|
57
|
+
return null !== consentInfo;
|
|
58
|
+
}
|
|
59
|
+
function isConsentEnabled(consentType, consents) {
|
|
60
|
+
return consents[consentType] || false;
|
|
61
|
+
}
|
|
62
|
+
var __webpack_export_target__ = exports;
|
|
63
|
+
for (var __webpack_i__ in __webpack_exports__)
|
|
64
|
+
__webpack_export_target__[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
65
|
+
if (__webpack_exports__.__esModule)
|
|
66
|
+
Object.defineProperty(__webpack_export_target__, '__esModule', {
|
|
67
|
+
value: true,
|
|
68
|
+
});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { AllConsentNames, ConsentState } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Determines the effective consents based on the user's Do Not Track setting.
|
|
4
|
+
*
|
|
5
|
+
* @param consents - The current state of user consents.
|
|
6
|
+
* @param honorDoNotTrack - Whether to respect the user's Do Not Track setting.
|
|
7
|
+
* @returns The effective consents after considering Do Not Track.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getEffectiveConsents(
|
|
10
|
+
consents: ConsentState,
|
|
11
|
+
honorDoNotTrack: boolean
|
|
12
|
+
): ConsentState;
|
|
13
|
+
/**
|
|
14
|
+
* Checks if the user has given consent for a specific type.
|
|
15
|
+
*
|
|
16
|
+
* @param consentType - The type of consent to check.
|
|
17
|
+
* @param consents - The current state of user consents.
|
|
18
|
+
* @param honorDoNotTrack - Whether to respect the user's Do Not Track setting.
|
|
19
|
+
* @returns True if consent is given, false otherwise.
|
|
20
|
+
*/
|
|
21
|
+
export declare function hasConsentFor(
|
|
22
|
+
consentType: AllConsentNames,
|
|
23
|
+
consents: ConsentState,
|
|
24
|
+
honorDoNotTrack: boolean
|
|
25
|
+
): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Determines if the user has consented based on consent information.
|
|
28
|
+
*
|
|
29
|
+
* @param consentInfo - The consent information.
|
|
30
|
+
* @returns True if the user has consented, false otherwise.
|
|
31
|
+
*/
|
|
32
|
+
export declare function hasConsented(
|
|
33
|
+
consentInfo: {
|
|
34
|
+
time: number;
|
|
35
|
+
type: 'all' | 'custom' | 'necessary';
|
|
36
|
+
} | null
|
|
37
|
+
): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Checks if a specific consent type is enabled.
|
|
40
|
+
*
|
|
41
|
+
* @param consentType - The type of consent to check.
|
|
42
|
+
* @param consents - The current state of user consents.
|
|
43
|
+
* @returns True if the consent type is enabled, false otherwise.
|
|
44
|
+
*/
|
|
45
|
+
export declare function isConsentEnabled(
|
|
46
|
+
consentType: AllConsentNames,
|
|
47
|
+
consents: ConsentState
|
|
48
|
+
): boolean;
|
|
49
|
+
//# sourceMappingURL=consent-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consent-utils.d.ts","sourceRoot":"","sources":["../../src/libs/consent-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE9D;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CACnC,QAAQ,EAAE,YAAY,EACtB,eAAe,EAAE,OAAO,GACtB,YAAY,CAcd;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC5B,WAAW,EAAE,eAAe,EAC5B,QAAQ,EAAE,YAAY,EACtB,eAAe,EAAE,OAAO,GACtB,OAAO,CAGT;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC3B,WAAW,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,WAAW,CAAA;CAAE,GAAG,IAAI,GACxE,OAAO,CAET;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC/B,WAAW,EAAE,eAAe,EAC5B,QAAQ,EAAE,YAAY,GACpB,OAAO,CAET"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
function getEffectiveConsents(consents, honorDoNotTrack) {
|
|
2
|
+
if (
|
|
3
|
+
honorDoNotTrack &&
|
|
4
|
+
'undefined' != typeof window &&
|
|
5
|
+
'1' === window.navigator.doNotTrack
|
|
6
|
+
)
|
|
7
|
+
return Object.keys(consents).reduce((acc, key) => {
|
|
8
|
+
if (key in consents) acc[key] = 'necessary' === key;
|
|
9
|
+
return acc;
|
|
10
|
+
}, {});
|
|
11
|
+
return consents;
|
|
12
|
+
}
|
|
13
|
+
function hasConsentFor(consentType, consents, honorDoNotTrack) {
|
|
14
|
+
const effectiveConsents = getEffectiveConsents(consents, honorDoNotTrack);
|
|
15
|
+
return effectiveConsents[consentType] || false;
|
|
16
|
+
}
|
|
17
|
+
function hasConsented(consentInfo) {
|
|
18
|
+
return null !== consentInfo;
|
|
19
|
+
}
|
|
20
|
+
function isConsentEnabled(consentType, consents) {
|
|
21
|
+
return consents[consentType] || false;
|
|
22
|
+
}
|
|
23
|
+
export { getEffectiveConsents, hasConsentFor, hasConsented, isConsentEnabled };
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(() => {
|
|
4
|
+
__webpack_require__.n = function (module) {
|
|
5
|
+
var getter =
|
|
6
|
+
module && module.__esModule
|
|
7
|
+
? function () {
|
|
8
|
+
return module['default'];
|
|
9
|
+
}
|
|
10
|
+
: function () {
|
|
11
|
+
return module;
|
|
12
|
+
};
|
|
13
|
+
__webpack_require__.d(getter, {
|
|
14
|
+
a: getter,
|
|
15
|
+
});
|
|
16
|
+
return getter;
|
|
17
|
+
};
|
|
18
|
+
})();
|
|
19
|
+
(() => {
|
|
20
|
+
__webpack_require__.d = function (exports1, definition) {
|
|
21
|
+
for (var key in definition)
|
|
22
|
+
if (
|
|
23
|
+
__webpack_require__.o(definition, key) &&
|
|
24
|
+
!__webpack_require__.o(exports1, key)
|
|
25
|
+
)
|
|
26
|
+
Object.defineProperty(exports1, key, {
|
|
27
|
+
enumerable: true,
|
|
28
|
+
get: definition[key],
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
})();
|
|
32
|
+
(() => {
|
|
33
|
+
__webpack_require__.o = function (obj, prop) {
|
|
34
|
+
return Object.prototype.hasOwnProperty.call(obj, prop);
|
|
35
|
+
};
|
|
36
|
+
})();
|
|
37
|
+
(() => {
|
|
38
|
+
__webpack_require__.r = function (exports1) {
|
|
39
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag)
|
|
40
|
+
Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
41
|
+
value: 'Module',
|
|
42
|
+
});
|
|
43
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
44
|
+
value: true,
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
})();
|
|
48
|
+
var __webpack_exports__ = {};
|
|
49
|
+
__webpack_require__.r(__webpack_exports__);
|
|
50
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
51
|
+
createTrackingBlocker: () => createTrackingBlocker,
|
|
52
|
+
});
|
|
53
|
+
const external_tracking_domains_cjs_namespaceObject = require('./tracking-domains.cjs');
|
|
54
|
+
var external_tracking_domains_cjs_default = /*#__PURE__*/ __webpack_require__.n(
|
|
55
|
+
external_tracking_domains_cjs_namespaceObject
|
|
56
|
+
);
|
|
57
|
+
function createDefaultConsentState() {
|
|
58
|
+
return {
|
|
59
|
+
experience: false,
|
|
60
|
+
functionality: false,
|
|
61
|
+
marketing: false,
|
|
62
|
+
measurement: false,
|
|
63
|
+
necessary: true,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function createTrackingBlocker(config = {}, initialConsents) {
|
|
67
|
+
const blockerConfig = {
|
|
68
|
+
disableAutomaticBlocking: false,
|
|
69
|
+
...config,
|
|
70
|
+
domainConsentMap: config.overrideDomainConsentMap
|
|
71
|
+
? config.domainConsentMap
|
|
72
|
+
: {
|
|
73
|
+
...external_tracking_domains_cjs_default(),
|
|
74
|
+
...config.domainConsentMap,
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
let consents = initialConsents || createDefaultConsentState();
|
|
78
|
+
const originalFetch = window.fetch;
|
|
79
|
+
const originalXHR = window.XMLHttpRequest;
|
|
80
|
+
function normalizeDomain(domain) {
|
|
81
|
+
return domain
|
|
82
|
+
.toLowerCase()
|
|
83
|
+
.replace(/^www\./, '')
|
|
84
|
+
.replace(/:\d+$/, '')
|
|
85
|
+
.trim();
|
|
86
|
+
}
|
|
87
|
+
function findMatchingDomain(domain, domainMap) {
|
|
88
|
+
const normalizedDomain = normalizeDomain(domain);
|
|
89
|
+
const directMatch = domainMap[normalizedDomain];
|
|
90
|
+
if (directMatch) return directMatch;
|
|
91
|
+
for (const [mapDomain, consent] of Object.entries(domainMap)) {
|
|
92
|
+
const normalizedMapDomain = normalizeDomain(mapDomain);
|
|
93
|
+
if (
|
|
94
|
+
normalizedDomain.endsWith(`.${normalizedMapDomain}`) ||
|
|
95
|
+
normalizedDomain === normalizedMapDomain
|
|
96
|
+
)
|
|
97
|
+
return consent;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
function isRequestAllowed(url) {
|
|
101
|
+
try {
|
|
102
|
+
const domain = new URL(url).hostname;
|
|
103
|
+
const requiredConsent = findMatchingDomain(
|
|
104
|
+
domain,
|
|
105
|
+
blockerConfig.domainConsentMap || {}
|
|
106
|
+
);
|
|
107
|
+
if (!requiredConsent) return true;
|
|
108
|
+
const isAllowed = true === consents[requiredConsent];
|
|
109
|
+
return isAllowed;
|
|
110
|
+
} catch (error) {
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function dispatchConsentBlockedEvent(url) {
|
|
115
|
+
document.dispatchEvent(
|
|
116
|
+
new CustomEvent('ConsentBlockedRequest', {
|
|
117
|
+
detail: {
|
|
118
|
+
url,
|
|
119
|
+
},
|
|
120
|
+
})
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
function interceptNetworkRequests() {
|
|
124
|
+
if (window.fetch === originalFetch)
|
|
125
|
+
window.fetch = async (input, init) => {
|
|
126
|
+
const url = input instanceof Request ? input.url : input.toString();
|
|
127
|
+
if (!isRequestAllowed(url)) {
|
|
128
|
+
dispatchConsentBlockedEvent(url);
|
|
129
|
+
return Promise.reject(
|
|
130
|
+
new Error(`Request to ${url} blocked due to missing consent`)
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
return await originalFetch.call(window, input, init);
|
|
134
|
+
};
|
|
135
|
+
if (window.XMLHttpRequest === originalXHR)
|
|
136
|
+
window.XMLHttpRequest = class extends originalXHR {
|
|
137
|
+
open(method, url, async = true, username, password) {
|
|
138
|
+
if (!isRequestAllowed(url.toString())) {
|
|
139
|
+
dispatchConsentBlockedEvent(url.toString());
|
|
140
|
+
throw new Error(`Request to ${url} blocked due to missing consent`);
|
|
141
|
+
}
|
|
142
|
+
super.open(method, url, async, username, password);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
function restoreOriginalRequests() {
|
|
147
|
+
if (window.fetch !== originalFetch) window.fetch = originalFetch;
|
|
148
|
+
if (window.XMLHttpRequest !== originalXHR)
|
|
149
|
+
window.XMLHttpRequest = originalXHR;
|
|
150
|
+
}
|
|
151
|
+
if (!blockerConfig.disableAutomaticBlocking) interceptNetworkRequests();
|
|
152
|
+
return {
|
|
153
|
+
updateConsents: (newConsents) => {
|
|
154
|
+
consents = newConsents;
|
|
155
|
+
},
|
|
156
|
+
destroy: () => {
|
|
157
|
+
restoreOriginalRequests();
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
var __webpack_export_target__ = exports;
|
|
162
|
+
for (var __webpack_i__ in __webpack_exports__)
|
|
163
|
+
__webpack_export_target__[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
164
|
+
if (__webpack_exports__.__esModule)
|
|
165
|
+
Object.defineProperty(__webpack_export_target__, '__esModule', {
|
|
166
|
+
value: true,
|
|
167
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* Implements automatic blocking of tracking scripts and network requests until user consent is granted.
|
|
4
|
+
*
|
|
5
|
+
* IMPORTANT: This module overrides global `fetch` and `XMLHttpRequest` APIs to enforce consent requirements.
|
|
6
|
+
* While this approach is necessary for proper consent management, it may conflict with other libraries that
|
|
7
|
+
* also modify these APIs. This implementation takes precedence to ensure compliance.
|
|
8
|
+
*/
|
|
9
|
+
import type { AllConsentNames, ConsentState } from '../types';
|
|
10
|
+
/**
|
|
11
|
+
* Configuration options for the tracking blocker
|
|
12
|
+
*/
|
|
13
|
+
export interface TrackingBlockerConfig {
|
|
14
|
+
/** Whether to disable automatic blocking (defaults to false) */
|
|
15
|
+
disableAutomaticBlocking?: boolean;
|
|
16
|
+
/** Override the default domain consent map */
|
|
17
|
+
overrideDomainConsentMap?: boolean;
|
|
18
|
+
/** Map of domains to their required consent types */
|
|
19
|
+
domainConsentMap?: Record<string, AllConsentNames>;
|
|
20
|
+
}
|
|
21
|
+
interface TrackingBlocker {
|
|
22
|
+
updateConsents: (newConsents: ConsentState) => void;
|
|
23
|
+
destroy: () => void;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Creates a tracking blocker instance that handles blocking of tracking scripts and network requests
|
|
27
|
+
*/
|
|
28
|
+
export declare function createTrackingBlocker(
|
|
29
|
+
config?: TrackingBlockerConfig,
|
|
30
|
+
initialConsents?: ConsentState
|
|
31
|
+
): TrackingBlocker;
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=tracking-blocker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracking-blocker.d.ts","sourceRoot":"","sources":["../../src/libs/tracking-blocker.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAG9D;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACrC,gEAAgE;IAChE,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAEnC,8CAA8C;IAC9C,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAEnC,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CACnD;AAeD,UAAU,eAAe;IACxB,cAAc,EAAE,CAAC,WAAW,EAAE,YAAY,KAAK,IAAI,CAAC;IACpD,OAAO,EAAE,MAAM,IAAI,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACpC,MAAM,GAAE,qBAA0B,EAClC,eAAe,CAAC,EAAE,YAAY,GAC5B,eAAe,CAuJjB"}
|