@blotoutio/edgetag-sdk-js 0.25.0 → 0.26.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/index.cjs +233 -254
- package/index.d.ts +8 -7
- package/index.esm.js +233 -254
- package/internal.d.ts +5 -5
- package/package.json +1 -1
package/index.cjs
CHANGED
|
@@ -12,147 +12,6 @@ var api = /*#__PURE__*/Object.freeze({
|
|
|
12
12
|
get user () { return user; }
|
|
13
13
|
});
|
|
14
14
|
|
|
15
|
-
const getMessage = (error) => {
|
|
16
|
-
if (error instanceof Error) {
|
|
17
|
-
return error.message;
|
|
18
|
-
}
|
|
19
|
-
if (typeof error === 'string') {
|
|
20
|
-
return error;
|
|
21
|
-
}
|
|
22
|
-
try {
|
|
23
|
-
return JSON.stringify(error);
|
|
24
|
-
}
|
|
25
|
-
catch {
|
|
26
|
-
return error;
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
const log = (data) => {
|
|
30
|
-
console.log('[EdgeTag]', getMessage(data));
|
|
31
|
-
};
|
|
32
|
-
const error = (data) => {
|
|
33
|
-
console.error('[EdgeTag]', getMessage(data));
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
let endpointUrl = '';
|
|
37
|
-
const generateUrl = (path) => {
|
|
38
|
-
const endpoint = getUrl();
|
|
39
|
-
if (!endpoint) {
|
|
40
|
-
log('URL is not valid');
|
|
41
|
-
return '';
|
|
42
|
-
}
|
|
43
|
-
return `${endpoint}${path}`;
|
|
44
|
-
};
|
|
45
|
-
const getUrl = () => {
|
|
46
|
-
return endpointUrl;
|
|
47
|
-
};
|
|
48
|
-
const setUrl = (url) => {
|
|
49
|
-
if (url == null) {
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
endpointUrl = url;
|
|
53
|
-
};
|
|
54
|
-
const getTagURL = () => {
|
|
55
|
-
return generateUrl('/tag');
|
|
56
|
-
};
|
|
57
|
-
const getInitURL = () => {
|
|
58
|
-
return generateUrl('/init');
|
|
59
|
-
};
|
|
60
|
-
const getConsentURL = () => {
|
|
61
|
-
return generateUrl('/consent');
|
|
62
|
-
};
|
|
63
|
-
const getUserURL = () => {
|
|
64
|
-
return generateUrl('/user');
|
|
65
|
-
};
|
|
66
|
-
const getDataURL = () => {
|
|
67
|
-
return generateUrl(`/data`);
|
|
68
|
-
};
|
|
69
|
-
const getGetDataURL = (keys) => {
|
|
70
|
-
return generateUrl(`/data?keys=${encodeURIComponent(keys.join(','))}`);
|
|
71
|
-
};
|
|
72
|
-
const getKeysURL = () => {
|
|
73
|
-
return generateUrl(`/keys`);
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
let allowedProvider = [];
|
|
77
|
-
let initialized = false;
|
|
78
|
-
let consentDisabled = false;
|
|
79
|
-
const providersPackages = {};
|
|
80
|
-
const setPreferences = (preferences) => {
|
|
81
|
-
var _a;
|
|
82
|
-
if (!preferences) {
|
|
83
|
-
return false;
|
|
84
|
-
}
|
|
85
|
-
if (!preferences.edgeURL) {
|
|
86
|
-
error('Please provide URL for EdgeTag');
|
|
87
|
-
return false;
|
|
88
|
-
}
|
|
89
|
-
consentDisabled = !!preferences.disableConsentCheck;
|
|
90
|
-
(_a = preferences.providers) === null || _a === void 0 ? void 0 : _a.forEach((provider) => {
|
|
91
|
-
if (!provider.name) {
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
providersPackages[provider.name] = provider;
|
|
95
|
-
});
|
|
96
|
-
try {
|
|
97
|
-
if (window && Array.isArray(window.edgetagProviders)) {
|
|
98
|
-
window.edgetagProviders.forEach((provider) => {
|
|
99
|
-
if (!provider.name) {
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
providersPackages[provider.name] = provider;
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
catch {
|
|
107
|
-
// do nothing
|
|
108
|
-
}
|
|
109
|
-
setUrl(preferences.edgeURL);
|
|
110
|
-
return true;
|
|
111
|
-
};
|
|
112
|
-
const isConsentDisabled = () => consentDisabled;
|
|
113
|
-
const getProvidersPackage = () => providersPackages;
|
|
114
|
-
const isInitialized = () => initialized;
|
|
115
|
-
const setInitialized = () => {
|
|
116
|
-
initialized = true;
|
|
117
|
-
};
|
|
118
|
-
const getAllowedProviders = () => allowedProvider;
|
|
119
|
-
const setAllowedProviders = (providers) => {
|
|
120
|
-
allowedProvider = providers;
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
const checkConsent = (providers) => {
|
|
124
|
-
if (isConsentDisabled()) {
|
|
125
|
-
return true;
|
|
126
|
-
}
|
|
127
|
-
const consent = getConsent();
|
|
128
|
-
if (!consent) {
|
|
129
|
-
return false;
|
|
130
|
-
}
|
|
131
|
-
const consentLength = Object.keys(consent).length;
|
|
132
|
-
if (!consentLength || (consentLength === 1 && consent['all'] === false)) {
|
|
133
|
-
return false;
|
|
134
|
-
}
|
|
135
|
-
const providersLength = Object.keys(providers || {}).length;
|
|
136
|
-
if (!providers ||
|
|
137
|
-
providersLength === 0 ||
|
|
138
|
-
(providersLength === 1 && providers['all'])) {
|
|
139
|
-
return (Object.values(consent).find((isAllowed) => isAllowed) || false);
|
|
140
|
-
}
|
|
141
|
-
for (const [key, value] of Object.entries(providers)) {
|
|
142
|
-
if (value === false || consent[key] === false) {
|
|
143
|
-
continue;
|
|
144
|
-
}
|
|
145
|
-
// we have consent
|
|
146
|
-
if (consent[key] ||
|
|
147
|
-
(consent['all'] === true && consent[key] === undefined)) {
|
|
148
|
-
// we have provider
|
|
149
|
-
if (value || (providers['all'] && providers[key] === undefined)) {
|
|
150
|
-
return true;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
return false;
|
|
155
|
-
};
|
|
156
15
|
const getUserAgent = () => {
|
|
157
16
|
try {
|
|
158
17
|
const nav = navigator;
|
|
@@ -210,81 +69,33 @@ const getPageTitle = () => {
|
|
|
210
69
|
return '';
|
|
211
70
|
}
|
|
212
71
|
};
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
const
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
return true;
|
|
223
|
-
}
|
|
224
|
-
const allProviders = getAllowedProviders();
|
|
225
|
-
const allProvidersLength = Object.keys(allProviders || {}).length;
|
|
226
|
-
if (allProvidersLength === 0) {
|
|
227
|
-
return true;
|
|
228
|
-
}
|
|
229
|
-
for (const provider of allProviders) {
|
|
230
|
-
if (isProviderIncluded(providers, providers[provider])) {
|
|
231
|
-
return true;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
return false;
|
|
235
|
-
};
|
|
236
|
-
const allowProviders = (providers) => {
|
|
237
|
-
if (!providers || Object.keys(providers).length === 0 || providers['all']) {
|
|
238
|
-
return true;
|
|
72
|
+
|
|
73
|
+
const tagStorage = 'edgeTag';
|
|
74
|
+
const consentKey = 'consent';
|
|
75
|
+
const keyPrefix = `_worker`;
|
|
76
|
+
const cookieKey = 'tag_user_id';
|
|
77
|
+
|
|
78
|
+
const getMessage = (error) => {
|
|
79
|
+
if (error instanceof Error) {
|
|
80
|
+
return error.message;
|
|
239
81
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
let found = false;
|
|
243
|
-
Object.entries(providers).forEach(([key, value]) => {
|
|
244
|
-
if (!value) {
|
|
245
|
-
return;
|
|
246
|
-
}
|
|
247
|
-
if (allowedProvider.includes(key)) {
|
|
248
|
-
found = true;
|
|
249
|
-
}
|
|
250
|
-
});
|
|
251
|
-
return found;
|
|
82
|
+
if (typeof error === 'string') {
|
|
83
|
+
return error;
|
|
252
84
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
const allowProvider = (providerId) => {
|
|
256
|
-
if (!providerId) {
|
|
257
|
-
return true;
|
|
85
|
+
try {
|
|
86
|
+
return JSON.stringify(error);
|
|
258
87
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
return allowedProvider.includes(providerId);
|
|
88
|
+
catch {
|
|
89
|
+
return error;
|
|
262
90
|
}
|
|
263
|
-
return true;
|
|
264
91
|
};
|
|
265
|
-
const
|
|
266
|
-
|
|
267
|
-
return false;
|
|
268
|
-
}
|
|
269
|
-
if (!checkConsent(providers)) {
|
|
270
|
-
return false;
|
|
271
|
-
}
|
|
272
|
-
if (providers && Object.keys(providers).length) {
|
|
273
|
-
if (!isProviderIncluded(providers, providers[providerId])) {
|
|
274
|
-
return false;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
return true;
|
|
92
|
+
const log = (data) => {
|
|
93
|
+
console.log('[EdgeTag]', getMessage(data));
|
|
278
94
|
};
|
|
279
|
-
const
|
|
280
|
-
|
|
95
|
+
const error = (data) => {
|
|
96
|
+
console.error('[EdgeTag]', getMessage(data));
|
|
281
97
|
};
|
|
282
98
|
|
|
283
|
-
const tagStorage = 'edgeTag';
|
|
284
|
-
const consentKey = 'consent';
|
|
285
|
-
const keyPrefix = `_worker`;
|
|
286
|
-
const cookieKey = 'tag_user_id';
|
|
287
|
-
|
|
288
99
|
const initKey = `${keyPrefix}Store`;
|
|
289
100
|
const saveDataPerKey = (persistType, provider, value, key) => {
|
|
290
101
|
const storage = getData$1(persistType);
|
|
@@ -512,7 +323,7 @@ const getStandardPayload = (payload) => {
|
|
|
512
323
|
referrer: getReferrer(),
|
|
513
324
|
search: getSearch(),
|
|
514
325
|
locale: getLocale(),
|
|
515
|
-
sdkVersion: "0.
|
|
326
|
+
sdkVersion: "0.26.0" ,
|
|
516
327
|
...(payload || {}),
|
|
517
328
|
};
|
|
518
329
|
let storage = {};
|
|
@@ -555,6 +366,46 @@ async function getRequest(url, options) {
|
|
|
555
366
|
return await ajax('GET', url);
|
|
556
367
|
}
|
|
557
368
|
|
|
369
|
+
let endpointUrl = '';
|
|
370
|
+
const generateUrl = (path) => {
|
|
371
|
+
const endpoint = getUrl();
|
|
372
|
+
if (!endpoint) {
|
|
373
|
+
log('URL is not valid');
|
|
374
|
+
return '';
|
|
375
|
+
}
|
|
376
|
+
return `${endpoint}${path}`;
|
|
377
|
+
};
|
|
378
|
+
const getUrl = () => {
|
|
379
|
+
return endpointUrl;
|
|
380
|
+
};
|
|
381
|
+
const setUrl = (url) => {
|
|
382
|
+
if (url == null) {
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
endpointUrl = url;
|
|
386
|
+
};
|
|
387
|
+
const getTagURL = () => {
|
|
388
|
+
return generateUrl('/tag');
|
|
389
|
+
};
|
|
390
|
+
const getInitURL = () => {
|
|
391
|
+
return generateUrl('/init');
|
|
392
|
+
};
|
|
393
|
+
const getConsentURL = () => {
|
|
394
|
+
return generateUrl('/consent');
|
|
395
|
+
};
|
|
396
|
+
const getUserURL = () => {
|
|
397
|
+
return generateUrl('/user');
|
|
398
|
+
};
|
|
399
|
+
const getDataURL = () => {
|
|
400
|
+
return generateUrl(`/data`);
|
|
401
|
+
};
|
|
402
|
+
const getGetDataURL = (keys) => {
|
|
403
|
+
return generateUrl(`/data?keys=${encodeURIComponent(keys.join(','))}`);
|
|
404
|
+
};
|
|
405
|
+
const getKeysURL = () => {
|
|
406
|
+
return generateUrl(`/keys`);
|
|
407
|
+
};
|
|
408
|
+
|
|
558
409
|
let memoryConsent;
|
|
559
410
|
const saveConsent = (consent) => {
|
|
560
411
|
setConsent(consent);
|
|
@@ -580,6 +431,53 @@ const getConsent = () => {
|
|
|
580
431
|
return memoryConsent;
|
|
581
432
|
};
|
|
582
433
|
|
|
434
|
+
const allowedProvider = new Set();
|
|
435
|
+
let initialized = false;
|
|
436
|
+
const providersPackages = {};
|
|
437
|
+
const setPreferences = (preferences) => {
|
|
438
|
+
var _a;
|
|
439
|
+
if (!preferences) {
|
|
440
|
+
return false;
|
|
441
|
+
}
|
|
442
|
+
if (!preferences.edgeURL) {
|
|
443
|
+
error('Please provide URL for EdgeTag');
|
|
444
|
+
return false;
|
|
445
|
+
}
|
|
446
|
+
!!preferences.disableConsentCheck;
|
|
447
|
+
(_a = preferences.providers) === null || _a === void 0 ? void 0 : _a.forEach((provider) => {
|
|
448
|
+
if (!provider.name) {
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
providersPackages[provider.name] = provider;
|
|
452
|
+
});
|
|
453
|
+
try {
|
|
454
|
+
if (window && Array.isArray(window.edgetagProviders)) {
|
|
455
|
+
window.edgetagProviders.forEach((provider) => {
|
|
456
|
+
if (!provider.name) {
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
providersPackages[provider.name] = provider;
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
catch {
|
|
464
|
+
// do nothing
|
|
465
|
+
}
|
|
466
|
+
setUrl(preferences.edgeURL);
|
|
467
|
+
return true;
|
|
468
|
+
};
|
|
469
|
+
const getProvidersPackage = () => providersPackages;
|
|
470
|
+
const isInitialized = () => initialized;
|
|
471
|
+
const setInitialized = () => {
|
|
472
|
+
initialized = true;
|
|
473
|
+
};
|
|
474
|
+
const getAllowedProviders = () => allowedProvider;
|
|
475
|
+
const setAllowedProviders = (providers) => {
|
|
476
|
+
for (const provider of providers) {
|
|
477
|
+
allowedProvider.add(provider);
|
|
478
|
+
}
|
|
479
|
+
};
|
|
480
|
+
|
|
583
481
|
const manifestVariables = {};
|
|
584
482
|
const addProviderVariable = (name, variables, tagName) => {
|
|
585
483
|
manifestVariables[name] = {
|
|
@@ -613,11 +511,60 @@ const processStubs = () => {
|
|
|
613
511
|
}
|
|
614
512
|
};
|
|
615
513
|
|
|
616
|
-
const
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
514
|
+
const isBool = (v) => typeof v == 'boolean';
|
|
515
|
+
const isRecord = (v) => !!v && typeof v == 'object';
|
|
516
|
+
/**
|
|
517
|
+
* This function validates user consent for a given provider and tag name.
|
|
518
|
+
* It should be used in conjunction with `UserConsent`, not `ProvidersConfig`.
|
|
519
|
+
*/
|
|
520
|
+
const hasUserConsent = (consent, provider, tagName) => {
|
|
521
|
+
if (!isRecord(consent)) {
|
|
522
|
+
return false;
|
|
523
|
+
}
|
|
524
|
+
let allowed = isBool(consent.all) ? consent.all : false;
|
|
525
|
+
if (provider in consent) {
|
|
526
|
+
const providerSpecific = consent[provider];
|
|
527
|
+
if (isBool(providerSpecific)) {
|
|
528
|
+
allowed = providerSpecific;
|
|
529
|
+
}
|
|
530
|
+
else if (isRecord(providerSpecific)) {
|
|
531
|
+
if ('all' in providerSpecific && isBool(providerSpecific.all)) {
|
|
532
|
+
allowed = providerSpecific.all;
|
|
533
|
+
}
|
|
534
|
+
if (tagName in providerSpecific && isBool(providerSpecific[tagName])) {
|
|
535
|
+
allowed = providerSpecific[tagName];
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
return allowed;
|
|
540
|
+
};
|
|
541
|
+
/**
|
|
542
|
+
* This function validates provider allowance for a given provider and tag name.
|
|
543
|
+
* It should not be used to validate `UserConsent`.
|
|
544
|
+
*/
|
|
545
|
+
const isProviderInstanceAllowed = (providersConfig, provider, tagName) => {
|
|
546
|
+
if (!isRecord(providersConfig)) {
|
|
547
|
+
return true;
|
|
620
548
|
}
|
|
549
|
+
let allowed = isBool(providersConfig.all) ? providersConfig.all : true;
|
|
550
|
+
if (provider in providersConfig) {
|
|
551
|
+
const providerSpecific = providersConfig[provider];
|
|
552
|
+
if (isBool(providerSpecific)) {
|
|
553
|
+
allowed = providerSpecific;
|
|
554
|
+
}
|
|
555
|
+
else if (isRecord(providerSpecific)) {
|
|
556
|
+
if ('all' in providerSpecific && isBool(providerSpecific.all)) {
|
|
557
|
+
allowed = providerSpecific.all;
|
|
558
|
+
}
|
|
559
|
+
if (tagName in providerSpecific && isBool(providerSpecific[tagName])) {
|
|
560
|
+
allowed = providerSpecific[tagName];
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
return allowed;
|
|
565
|
+
};
|
|
566
|
+
|
|
567
|
+
const sendTag = ({ eventName, eventId, data, providerData, providers, options, }) => {
|
|
621
568
|
const payload = {
|
|
622
569
|
eventName,
|
|
623
570
|
eventId,
|
|
@@ -638,14 +585,6 @@ const handleTag = (eventName, data = {}, providers, options) => {
|
|
|
638
585
|
});
|
|
639
586
|
return;
|
|
640
587
|
}
|
|
641
|
-
if (!allowProviders(providers)) {
|
|
642
|
-
log('Provider is not allowed.');
|
|
643
|
-
return;
|
|
644
|
-
}
|
|
645
|
-
if (!allowTag(providers)) {
|
|
646
|
-
log('Consent is missing.');
|
|
647
|
-
return;
|
|
648
|
-
}
|
|
649
588
|
let eventId = data['eventId'];
|
|
650
589
|
if (!eventId) {
|
|
651
590
|
eventId = generateEventId(eventName);
|
|
@@ -653,18 +592,32 @@ const handleTag = (eventName, data = {}, providers, options) => {
|
|
|
653
592
|
const providerPackages = getProvidersPackage();
|
|
654
593
|
const userId = handleGetUserId();
|
|
655
594
|
const providerData = {};
|
|
595
|
+
const consent = getConsent();
|
|
596
|
+
const allowedProviders = getAllowedProviders();
|
|
597
|
+
let anyProviderCalled = false;
|
|
656
598
|
if (providerPackages) {
|
|
657
|
-
Object.values(providerPackages)
|
|
658
|
-
if (!pkg ||
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
599
|
+
for (const pkg of Object.values(providerPackages)) {
|
|
600
|
+
if (!pkg || !pkg.name || !pkg.tag) {
|
|
601
|
+
continue;
|
|
602
|
+
}
|
|
603
|
+
if (!allowedProviders.has(pkg.name)) {
|
|
604
|
+
log(`Provider ${pkg.name} is not in allow list`);
|
|
605
|
+
continue;
|
|
664
606
|
}
|
|
665
607
|
const variables = getProviderVariables(pkg.name);
|
|
666
608
|
const result = {};
|
|
667
|
-
|
|
609
|
+
const providerVariables = Object.entries(variables);
|
|
610
|
+
const executionContext = new Map();
|
|
611
|
+
for (const [tagName, variableSet] of providerVariables) {
|
|
612
|
+
if (!isProviderInstanceAllowed(providers, pkg.name, tagName)) {
|
|
613
|
+
log(`Provider instance is not allowed (${pkg.name}: ${tagName})`);
|
|
614
|
+
continue;
|
|
615
|
+
}
|
|
616
|
+
if (!hasUserConsent(consent, pkg.name, tagName)) {
|
|
617
|
+
log(`Consent is missing (${pkg.name}: ${tagName})`);
|
|
618
|
+
continue;
|
|
619
|
+
}
|
|
620
|
+
anyProviderCalled = true;
|
|
668
621
|
result[tagName] = pkg.tag({
|
|
669
622
|
userId,
|
|
670
623
|
eventName,
|
|
@@ -672,10 +625,14 @@ const handleTag = (eventName, data = {}, providers, options) => {
|
|
|
672
625
|
data: JSON.parse(JSON.stringify(data)),
|
|
673
626
|
sendTag,
|
|
674
627
|
manifestVariables: variableSet,
|
|
628
|
+
executionContext,
|
|
675
629
|
});
|
|
676
630
|
}
|
|
677
631
|
providerData[pkg.name] = result;
|
|
678
|
-
}
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
if (!anyProviderCalled) {
|
|
635
|
+
return;
|
|
679
636
|
}
|
|
680
637
|
sendTag({
|
|
681
638
|
eventName,
|
|
@@ -695,23 +652,34 @@ const handleData = (data, providers, options) => {
|
|
|
695
652
|
saveKV(data);
|
|
696
653
|
const providerPackages = getProvidersPackage();
|
|
697
654
|
const userId = handleGetUserId();
|
|
655
|
+
const consent = getConsent();
|
|
656
|
+
const allowedProviders = getAllowedProviders();
|
|
698
657
|
if (providerPackages) {
|
|
699
|
-
Object.values(providerPackages)
|
|
700
|
-
if (!pkg ||
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
658
|
+
for (const pkg of Object.values(providerPackages)) {
|
|
659
|
+
if (!pkg || !pkg.user || !pkg.name) {
|
|
660
|
+
continue;
|
|
661
|
+
}
|
|
662
|
+
if (!allowedProviders.has(pkg.name)) {
|
|
663
|
+
log(`Provider ${pkg.name} is not in allow list`);
|
|
664
|
+
continue;
|
|
705
665
|
}
|
|
706
666
|
const variables = getProviderVariables(pkg.name);
|
|
707
|
-
for (const variableSet of Object.
|
|
667
|
+
for (const [tagName, variableSet] of Object.entries(variables)) {
|
|
668
|
+
if (!isProviderInstanceAllowed(providers, pkg.name, tagName)) {
|
|
669
|
+
log(`Data not allowed for ${pkg.name} (${tagName})`);
|
|
670
|
+
continue;
|
|
671
|
+
}
|
|
672
|
+
if (!hasUserConsent(consent, pkg.name, tagName)) {
|
|
673
|
+
log(`Consent is missing for ${pkg.name} (${tagName})`);
|
|
674
|
+
continue;
|
|
675
|
+
}
|
|
708
676
|
pkg.user({
|
|
709
677
|
userId,
|
|
710
678
|
data,
|
|
711
679
|
manifestVariables: variableSet,
|
|
712
680
|
});
|
|
713
681
|
}
|
|
714
|
-
}
|
|
682
|
+
}
|
|
715
683
|
}
|
|
716
684
|
postRequest(getDataURL(), { data, providers }, options).catch(error);
|
|
717
685
|
};
|
|
@@ -828,16 +796,15 @@ const handleManifest = (manifest) => {
|
|
|
828
796
|
}
|
|
829
797
|
if (providerPackages) {
|
|
830
798
|
const pkg = providerPackages[provider.package];
|
|
831
|
-
if (pkg && pkg.name && pkg.init
|
|
832
|
-
|
|
799
|
+
if (pkg && pkg.name && pkg.init) {
|
|
800
|
+
pkg.init({
|
|
833
801
|
userId,
|
|
834
802
|
manifest: provider,
|
|
835
803
|
sendTag,
|
|
836
804
|
sendEdgeData: handleData,
|
|
837
805
|
getEdgeData: handleGetData,
|
|
838
806
|
keyName: `${keyPrefix}Store`,
|
|
839
|
-
};
|
|
840
|
-
pkg.init(initData);
|
|
807
|
+
});
|
|
841
808
|
}
|
|
842
809
|
}
|
|
843
810
|
});
|
|
@@ -888,25 +855,37 @@ const handleUser = (key, value, providers, options) => {
|
|
|
888
855
|
saveKV({
|
|
889
856
|
[key]: value,
|
|
890
857
|
});
|
|
858
|
+
const consent = getConsent();
|
|
859
|
+
const allowedProviders = getAllowedProviders();
|
|
891
860
|
const providerPackages = getProvidersPackage();
|
|
892
861
|
const userId = handleGetUserId();
|
|
893
862
|
if (providerPackages) {
|
|
894
|
-
Object.values(providerPackages)
|
|
895
|
-
if (!pkg ||
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
863
|
+
for (const pkg of Object.values(providerPackages)) {
|
|
864
|
+
if (!pkg || !pkg.name || !pkg.user) {
|
|
865
|
+
continue;
|
|
866
|
+
}
|
|
867
|
+
if (!allowedProviders.has(pkg.name)) {
|
|
868
|
+
log(`Provider ${pkg.name} is not in allow list`);
|
|
869
|
+
continue;
|
|
900
870
|
}
|
|
901
871
|
const variables = getProviderVariables(pkg.name);
|
|
902
|
-
for (const variableSet of Object.
|
|
872
|
+
for (const [tagName, variableSet] of Object.entries(variables)) {
|
|
873
|
+
if (!isProviderInstanceAllowed(providers, pkg.name, tagName)) {
|
|
874
|
+
// should we be logging this?
|
|
875
|
+
log(`User not allowed for ${pkg.name} (${tagName})`);
|
|
876
|
+
continue;
|
|
877
|
+
}
|
|
878
|
+
if (!hasUserConsent(consent, pkg.name, tagName)) {
|
|
879
|
+
log(`User doesn't have consent for ${pkg.name} (${tagName})`);
|
|
880
|
+
continue;
|
|
881
|
+
}
|
|
903
882
|
pkg.user({
|
|
904
883
|
userId,
|
|
905
884
|
data: { [key]: value },
|
|
906
885
|
manifestVariables: variableSet,
|
|
907
886
|
});
|
|
908
887
|
}
|
|
909
|
-
}
|
|
888
|
+
}
|
|
910
889
|
}
|
|
911
890
|
postRequest(getUserURL(), {
|
|
912
891
|
key,
|
|
@@ -929,14 +908,14 @@ const init = (preferences) => {
|
|
|
929
908
|
const tag = (name, data, providers, options) => {
|
|
930
909
|
handleTag(name, data, providers, options);
|
|
931
910
|
};
|
|
932
|
-
const consent = (
|
|
933
|
-
handleConsent(
|
|
911
|
+
const consent = (value, options) => {
|
|
912
|
+
handleConsent(value, options);
|
|
934
913
|
};
|
|
935
914
|
const user = (key, value, providers, options) => {
|
|
936
915
|
handleUser(key, value, providers, options);
|
|
937
916
|
};
|
|
938
|
-
const data = (
|
|
939
|
-
handleData(
|
|
917
|
+
const data = (value, providers, options) => {
|
|
918
|
+
handleData(value, providers, options);
|
|
940
919
|
};
|
|
941
920
|
const getData = (keys, callback) => {
|
|
942
921
|
handleGetData(keys, callback);
|
package/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// TODO this all located in '@blotoutio/shared/utility-sdk'
|
|
2
2
|
|
|
3
|
-
import { Library } from '@blotoutio/cdn/types'
|
|
3
|
+
import { Library, ProvidersConfig } from '@blotoutio/cdn/types'
|
|
4
4
|
|
|
5
5
|
type PersistType = 'local' | 'session' | 'edge'
|
|
6
6
|
|
|
@@ -15,7 +15,7 @@ export type SendTag = {
|
|
|
15
15
|
eventId: string
|
|
16
16
|
data: Data
|
|
17
17
|
providerData?: Partial<Record<Library, Record<string, Data>>>
|
|
18
|
-
providers?:
|
|
18
|
+
providers?: Possibly<ProvidersConfig>
|
|
19
19
|
options?: EventOptions
|
|
20
20
|
}
|
|
21
21
|
|
|
@@ -27,7 +27,7 @@ type ManifestRule = {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
type Manifest = {
|
|
30
|
-
package:
|
|
30
|
+
package: Library
|
|
31
31
|
tagName: string
|
|
32
32
|
variables?: Record<string, string>
|
|
33
33
|
rules: Record<string, ManifestRule[]>
|
|
@@ -46,10 +46,11 @@ type TagParams = {
|
|
|
46
46
|
data: Data
|
|
47
47
|
manifestVariables: Record<string, string>
|
|
48
48
|
sendTag: (params: SendTag) => void
|
|
49
|
+
executionContext: Map<string, unknown>
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
type ProviderInit = {
|
|
52
|
-
name?:
|
|
53
|
+
name?: Library
|
|
53
54
|
init?: (params: InitParams) => void
|
|
54
55
|
tag?: (params: TagParams) => unknown
|
|
55
56
|
}
|
|
@@ -84,7 +85,7 @@ export declare const init: (preferences: InitPreferences) => void
|
|
|
84
85
|
export declare const tag: (
|
|
85
86
|
name: string,
|
|
86
87
|
data?: Data,
|
|
87
|
-
providers?:
|
|
88
|
+
providers?: ProvidersConfig,
|
|
88
89
|
options?: EventOptions
|
|
89
90
|
) => void
|
|
90
91
|
|
|
@@ -93,13 +94,13 @@ export declare const consent: (consent: Data) => void
|
|
|
93
94
|
export declare const user: (
|
|
94
95
|
key: UserKey,
|
|
95
96
|
value: string,
|
|
96
|
-
providers?:
|
|
97
|
+
providers?: ProvidersConfig,
|
|
97
98
|
options?: EventOptions
|
|
98
99
|
) => void
|
|
99
100
|
|
|
100
101
|
export declare const data: (
|
|
101
102
|
data: Record<string, string>,
|
|
102
|
-
providers?:
|
|
103
|
+
providers?: ProvidersConfig,
|
|
103
104
|
options?: EventOptions
|
|
104
105
|
) => void
|
|
105
106
|
|
package/index.esm.js
CHANGED
|
@@ -10,147 +10,6 @@ var api = /*#__PURE__*/Object.freeze({
|
|
|
10
10
|
get user () { return user; }
|
|
11
11
|
});
|
|
12
12
|
|
|
13
|
-
const getMessage = (error) => {
|
|
14
|
-
if (error instanceof Error) {
|
|
15
|
-
return error.message;
|
|
16
|
-
}
|
|
17
|
-
if (typeof error === 'string') {
|
|
18
|
-
return error;
|
|
19
|
-
}
|
|
20
|
-
try {
|
|
21
|
-
return JSON.stringify(error);
|
|
22
|
-
}
|
|
23
|
-
catch {
|
|
24
|
-
return error;
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
const log = (data) => {
|
|
28
|
-
console.log('[EdgeTag]', getMessage(data));
|
|
29
|
-
};
|
|
30
|
-
const error = (data) => {
|
|
31
|
-
console.error('[EdgeTag]', getMessage(data));
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
let endpointUrl = '';
|
|
35
|
-
const generateUrl = (path) => {
|
|
36
|
-
const endpoint = getUrl();
|
|
37
|
-
if (!endpoint) {
|
|
38
|
-
log('URL is not valid');
|
|
39
|
-
return '';
|
|
40
|
-
}
|
|
41
|
-
return `${endpoint}${path}`;
|
|
42
|
-
};
|
|
43
|
-
const getUrl = () => {
|
|
44
|
-
return endpointUrl;
|
|
45
|
-
};
|
|
46
|
-
const setUrl = (url) => {
|
|
47
|
-
if (url == null) {
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
endpointUrl = url;
|
|
51
|
-
};
|
|
52
|
-
const getTagURL = () => {
|
|
53
|
-
return generateUrl('/tag');
|
|
54
|
-
};
|
|
55
|
-
const getInitURL = () => {
|
|
56
|
-
return generateUrl('/init');
|
|
57
|
-
};
|
|
58
|
-
const getConsentURL = () => {
|
|
59
|
-
return generateUrl('/consent');
|
|
60
|
-
};
|
|
61
|
-
const getUserURL = () => {
|
|
62
|
-
return generateUrl('/user');
|
|
63
|
-
};
|
|
64
|
-
const getDataURL = () => {
|
|
65
|
-
return generateUrl(`/data`);
|
|
66
|
-
};
|
|
67
|
-
const getGetDataURL = (keys) => {
|
|
68
|
-
return generateUrl(`/data?keys=${encodeURIComponent(keys.join(','))}`);
|
|
69
|
-
};
|
|
70
|
-
const getKeysURL = () => {
|
|
71
|
-
return generateUrl(`/keys`);
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
let allowedProvider = [];
|
|
75
|
-
let initialized = false;
|
|
76
|
-
let consentDisabled = false;
|
|
77
|
-
const providersPackages = {};
|
|
78
|
-
const setPreferences = (preferences) => {
|
|
79
|
-
var _a;
|
|
80
|
-
if (!preferences) {
|
|
81
|
-
return false;
|
|
82
|
-
}
|
|
83
|
-
if (!preferences.edgeURL) {
|
|
84
|
-
error('Please provide URL for EdgeTag');
|
|
85
|
-
return false;
|
|
86
|
-
}
|
|
87
|
-
consentDisabled = !!preferences.disableConsentCheck;
|
|
88
|
-
(_a = preferences.providers) === null || _a === void 0 ? void 0 : _a.forEach((provider) => {
|
|
89
|
-
if (!provider.name) {
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
providersPackages[provider.name] = provider;
|
|
93
|
-
});
|
|
94
|
-
try {
|
|
95
|
-
if (window && Array.isArray(window.edgetagProviders)) {
|
|
96
|
-
window.edgetagProviders.forEach((provider) => {
|
|
97
|
-
if (!provider.name) {
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
providersPackages[provider.name] = provider;
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
catch {
|
|
105
|
-
// do nothing
|
|
106
|
-
}
|
|
107
|
-
setUrl(preferences.edgeURL);
|
|
108
|
-
return true;
|
|
109
|
-
};
|
|
110
|
-
const isConsentDisabled = () => consentDisabled;
|
|
111
|
-
const getProvidersPackage = () => providersPackages;
|
|
112
|
-
const isInitialized = () => initialized;
|
|
113
|
-
const setInitialized = () => {
|
|
114
|
-
initialized = true;
|
|
115
|
-
};
|
|
116
|
-
const getAllowedProviders = () => allowedProvider;
|
|
117
|
-
const setAllowedProviders = (providers) => {
|
|
118
|
-
allowedProvider = providers;
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
const checkConsent = (providers) => {
|
|
122
|
-
if (isConsentDisabled()) {
|
|
123
|
-
return true;
|
|
124
|
-
}
|
|
125
|
-
const consent = getConsent();
|
|
126
|
-
if (!consent) {
|
|
127
|
-
return false;
|
|
128
|
-
}
|
|
129
|
-
const consentLength = Object.keys(consent).length;
|
|
130
|
-
if (!consentLength || (consentLength === 1 && consent['all'] === false)) {
|
|
131
|
-
return false;
|
|
132
|
-
}
|
|
133
|
-
const providersLength = Object.keys(providers || {}).length;
|
|
134
|
-
if (!providers ||
|
|
135
|
-
providersLength === 0 ||
|
|
136
|
-
(providersLength === 1 && providers['all'])) {
|
|
137
|
-
return (Object.values(consent).find((isAllowed) => isAllowed) || false);
|
|
138
|
-
}
|
|
139
|
-
for (const [key, value] of Object.entries(providers)) {
|
|
140
|
-
if (value === false || consent[key] === false) {
|
|
141
|
-
continue;
|
|
142
|
-
}
|
|
143
|
-
// we have consent
|
|
144
|
-
if (consent[key] ||
|
|
145
|
-
(consent['all'] === true && consent[key] === undefined)) {
|
|
146
|
-
// we have provider
|
|
147
|
-
if (value || (providers['all'] && providers[key] === undefined)) {
|
|
148
|
-
return true;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
return false;
|
|
153
|
-
};
|
|
154
13
|
const getUserAgent = () => {
|
|
155
14
|
try {
|
|
156
15
|
const nav = navigator;
|
|
@@ -208,81 +67,33 @@ const getPageTitle = () => {
|
|
|
208
67
|
return '';
|
|
209
68
|
}
|
|
210
69
|
};
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
return true;
|
|
221
|
-
}
|
|
222
|
-
const allProviders = getAllowedProviders();
|
|
223
|
-
const allProvidersLength = Object.keys(allProviders || {}).length;
|
|
224
|
-
if (allProvidersLength === 0) {
|
|
225
|
-
return true;
|
|
226
|
-
}
|
|
227
|
-
for (const provider of allProviders) {
|
|
228
|
-
if (isProviderIncluded(providers, providers[provider])) {
|
|
229
|
-
return true;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
return false;
|
|
233
|
-
};
|
|
234
|
-
const allowProviders = (providers) => {
|
|
235
|
-
if (!providers || Object.keys(providers).length === 0 || providers['all']) {
|
|
236
|
-
return true;
|
|
70
|
+
|
|
71
|
+
const tagStorage = 'edgeTag';
|
|
72
|
+
const consentKey = 'consent';
|
|
73
|
+
const keyPrefix = `_worker`;
|
|
74
|
+
const cookieKey = 'tag_user_id';
|
|
75
|
+
|
|
76
|
+
const getMessage = (error) => {
|
|
77
|
+
if (error instanceof Error) {
|
|
78
|
+
return error.message;
|
|
237
79
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
let found = false;
|
|
241
|
-
Object.entries(providers).forEach(([key, value]) => {
|
|
242
|
-
if (!value) {
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
if (allowedProvider.includes(key)) {
|
|
246
|
-
found = true;
|
|
247
|
-
}
|
|
248
|
-
});
|
|
249
|
-
return found;
|
|
80
|
+
if (typeof error === 'string') {
|
|
81
|
+
return error;
|
|
250
82
|
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
const allowProvider = (providerId) => {
|
|
254
|
-
if (!providerId) {
|
|
255
|
-
return true;
|
|
83
|
+
try {
|
|
84
|
+
return JSON.stringify(error);
|
|
256
85
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
return allowedProvider.includes(providerId);
|
|
86
|
+
catch {
|
|
87
|
+
return error;
|
|
260
88
|
}
|
|
261
|
-
return true;
|
|
262
89
|
};
|
|
263
|
-
const
|
|
264
|
-
|
|
265
|
-
return false;
|
|
266
|
-
}
|
|
267
|
-
if (!checkConsent(providers)) {
|
|
268
|
-
return false;
|
|
269
|
-
}
|
|
270
|
-
if (providers && Object.keys(providers).length) {
|
|
271
|
-
if (!isProviderIncluded(providers, providers[providerId])) {
|
|
272
|
-
return false;
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
return true;
|
|
90
|
+
const log = (data) => {
|
|
91
|
+
console.log('[EdgeTag]', getMessage(data));
|
|
276
92
|
};
|
|
277
|
-
const
|
|
278
|
-
|
|
93
|
+
const error = (data) => {
|
|
94
|
+
console.error('[EdgeTag]', getMessage(data));
|
|
279
95
|
};
|
|
280
96
|
|
|
281
|
-
const tagStorage = 'edgeTag';
|
|
282
|
-
const consentKey = 'consent';
|
|
283
|
-
const keyPrefix = `_worker`;
|
|
284
|
-
const cookieKey = 'tag_user_id';
|
|
285
|
-
|
|
286
97
|
const initKey = `${keyPrefix}Store`;
|
|
287
98
|
const saveDataPerKey = (persistType, provider, value, key) => {
|
|
288
99
|
const storage = getData$1(persistType);
|
|
@@ -510,7 +321,7 @@ const getStandardPayload = (payload) => {
|
|
|
510
321
|
referrer: getReferrer(),
|
|
511
322
|
search: getSearch(),
|
|
512
323
|
locale: getLocale(),
|
|
513
|
-
sdkVersion: "0.
|
|
324
|
+
sdkVersion: "0.26.0" ,
|
|
514
325
|
...(payload || {}),
|
|
515
326
|
};
|
|
516
327
|
let storage = {};
|
|
@@ -553,6 +364,46 @@ async function getRequest(url, options) {
|
|
|
553
364
|
return await ajax('GET', url);
|
|
554
365
|
}
|
|
555
366
|
|
|
367
|
+
let endpointUrl = '';
|
|
368
|
+
const generateUrl = (path) => {
|
|
369
|
+
const endpoint = getUrl();
|
|
370
|
+
if (!endpoint) {
|
|
371
|
+
log('URL is not valid');
|
|
372
|
+
return '';
|
|
373
|
+
}
|
|
374
|
+
return `${endpoint}${path}`;
|
|
375
|
+
};
|
|
376
|
+
const getUrl = () => {
|
|
377
|
+
return endpointUrl;
|
|
378
|
+
};
|
|
379
|
+
const setUrl = (url) => {
|
|
380
|
+
if (url == null) {
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
endpointUrl = url;
|
|
384
|
+
};
|
|
385
|
+
const getTagURL = () => {
|
|
386
|
+
return generateUrl('/tag');
|
|
387
|
+
};
|
|
388
|
+
const getInitURL = () => {
|
|
389
|
+
return generateUrl('/init');
|
|
390
|
+
};
|
|
391
|
+
const getConsentURL = () => {
|
|
392
|
+
return generateUrl('/consent');
|
|
393
|
+
};
|
|
394
|
+
const getUserURL = () => {
|
|
395
|
+
return generateUrl('/user');
|
|
396
|
+
};
|
|
397
|
+
const getDataURL = () => {
|
|
398
|
+
return generateUrl(`/data`);
|
|
399
|
+
};
|
|
400
|
+
const getGetDataURL = (keys) => {
|
|
401
|
+
return generateUrl(`/data?keys=${encodeURIComponent(keys.join(','))}`);
|
|
402
|
+
};
|
|
403
|
+
const getKeysURL = () => {
|
|
404
|
+
return generateUrl(`/keys`);
|
|
405
|
+
};
|
|
406
|
+
|
|
556
407
|
let memoryConsent;
|
|
557
408
|
const saveConsent = (consent) => {
|
|
558
409
|
setConsent(consent);
|
|
@@ -578,6 +429,53 @@ const getConsent = () => {
|
|
|
578
429
|
return memoryConsent;
|
|
579
430
|
};
|
|
580
431
|
|
|
432
|
+
const allowedProvider = new Set();
|
|
433
|
+
let initialized = false;
|
|
434
|
+
const providersPackages = {};
|
|
435
|
+
const setPreferences = (preferences) => {
|
|
436
|
+
var _a;
|
|
437
|
+
if (!preferences) {
|
|
438
|
+
return false;
|
|
439
|
+
}
|
|
440
|
+
if (!preferences.edgeURL) {
|
|
441
|
+
error('Please provide URL for EdgeTag');
|
|
442
|
+
return false;
|
|
443
|
+
}
|
|
444
|
+
!!preferences.disableConsentCheck;
|
|
445
|
+
(_a = preferences.providers) === null || _a === void 0 ? void 0 : _a.forEach((provider) => {
|
|
446
|
+
if (!provider.name) {
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
providersPackages[provider.name] = provider;
|
|
450
|
+
});
|
|
451
|
+
try {
|
|
452
|
+
if (window && Array.isArray(window.edgetagProviders)) {
|
|
453
|
+
window.edgetagProviders.forEach((provider) => {
|
|
454
|
+
if (!provider.name) {
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
providersPackages[provider.name] = provider;
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
catch {
|
|
462
|
+
// do nothing
|
|
463
|
+
}
|
|
464
|
+
setUrl(preferences.edgeURL);
|
|
465
|
+
return true;
|
|
466
|
+
};
|
|
467
|
+
const getProvidersPackage = () => providersPackages;
|
|
468
|
+
const isInitialized = () => initialized;
|
|
469
|
+
const setInitialized = () => {
|
|
470
|
+
initialized = true;
|
|
471
|
+
};
|
|
472
|
+
const getAllowedProviders = () => allowedProvider;
|
|
473
|
+
const setAllowedProviders = (providers) => {
|
|
474
|
+
for (const provider of providers) {
|
|
475
|
+
allowedProvider.add(provider);
|
|
476
|
+
}
|
|
477
|
+
};
|
|
478
|
+
|
|
581
479
|
const manifestVariables = {};
|
|
582
480
|
const addProviderVariable = (name, variables, tagName) => {
|
|
583
481
|
manifestVariables[name] = {
|
|
@@ -611,11 +509,60 @@ const processStubs = () => {
|
|
|
611
509
|
}
|
|
612
510
|
};
|
|
613
511
|
|
|
614
|
-
const
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
512
|
+
const isBool = (v) => typeof v == 'boolean';
|
|
513
|
+
const isRecord = (v) => !!v && typeof v == 'object';
|
|
514
|
+
/**
|
|
515
|
+
* This function validates user consent for a given provider and tag name.
|
|
516
|
+
* It should be used in conjunction with `UserConsent`, not `ProvidersConfig`.
|
|
517
|
+
*/
|
|
518
|
+
const hasUserConsent = (consent, provider, tagName) => {
|
|
519
|
+
if (!isRecord(consent)) {
|
|
520
|
+
return false;
|
|
521
|
+
}
|
|
522
|
+
let allowed = isBool(consent.all) ? consent.all : false;
|
|
523
|
+
if (provider in consent) {
|
|
524
|
+
const providerSpecific = consent[provider];
|
|
525
|
+
if (isBool(providerSpecific)) {
|
|
526
|
+
allowed = providerSpecific;
|
|
527
|
+
}
|
|
528
|
+
else if (isRecord(providerSpecific)) {
|
|
529
|
+
if ('all' in providerSpecific && isBool(providerSpecific.all)) {
|
|
530
|
+
allowed = providerSpecific.all;
|
|
531
|
+
}
|
|
532
|
+
if (tagName in providerSpecific && isBool(providerSpecific[tagName])) {
|
|
533
|
+
allowed = providerSpecific[tagName];
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
return allowed;
|
|
538
|
+
};
|
|
539
|
+
/**
|
|
540
|
+
* This function validates provider allowance for a given provider and tag name.
|
|
541
|
+
* It should not be used to validate `UserConsent`.
|
|
542
|
+
*/
|
|
543
|
+
const isProviderInstanceAllowed = (providersConfig, provider, tagName) => {
|
|
544
|
+
if (!isRecord(providersConfig)) {
|
|
545
|
+
return true;
|
|
618
546
|
}
|
|
547
|
+
let allowed = isBool(providersConfig.all) ? providersConfig.all : true;
|
|
548
|
+
if (provider in providersConfig) {
|
|
549
|
+
const providerSpecific = providersConfig[provider];
|
|
550
|
+
if (isBool(providerSpecific)) {
|
|
551
|
+
allowed = providerSpecific;
|
|
552
|
+
}
|
|
553
|
+
else if (isRecord(providerSpecific)) {
|
|
554
|
+
if ('all' in providerSpecific && isBool(providerSpecific.all)) {
|
|
555
|
+
allowed = providerSpecific.all;
|
|
556
|
+
}
|
|
557
|
+
if (tagName in providerSpecific && isBool(providerSpecific[tagName])) {
|
|
558
|
+
allowed = providerSpecific[tagName];
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
return allowed;
|
|
563
|
+
};
|
|
564
|
+
|
|
565
|
+
const sendTag = ({ eventName, eventId, data, providerData, providers, options, }) => {
|
|
619
566
|
const payload = {
|
|
620
567
|
eventName,
|
|
621
568
|
eventId,
|
|
@@ -636,14 +583,6 @@ const handleTag = (eventName, data = {}, providers, options) => {
|
|
|
636
583
|
});
|
|
637
584
|
return;
|
|
638
585
|
}
|
|
639
|
-
if (!allowProviders(providers)) {
|
|
640
|
-
log('Provider is not allowed.');
|
|
641
|
-
return;
|
|
642
|
-
}
|
|
643
|
-
if (!allowTag(providers)) {
|
|
644
|
-
log('Consent is missing.');
|
|
645
|
-
return;
|
|
646
|
-
}
|
|
647
586
|
let eventId = data['eventId'];
|
|
648
587
|
if (!eventId) {
|
|
649
588
|
eventId = generateEventId(eventName);
|
|
@@ -651,18 +590,32 @@ const handleTag = (eventName, data = {}, providers, options) => {
|
|
|
651
590
|
const providerPackages = getProvidersPackage();
|
|
652
591
|
const userId = handleGetUserId();
|
|
653
592
|
const providerData = {};
|
|
593
|
+
const consent = getConsent();
|
|
594
|
+
const allowedProviders = getAllowedProviders();
|
|
595
|
+
let anyProviderCalled = false;
|
|
654
596
|
if (providerPackages) {
|
|
655
|
-
Object.values(providerPackages)
|
|
656
|
-
if (!pkg ||
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
597
|
+
for (const pkg of Object.values(providerPackages)) {
|
|
598
|
+
if (!pkg || !pkg.name || !pkg.tag) {
|
|
599
|
+
continue;
|
|
600
|
+
}
|
|
601
|
+
if (!allowedProviders.has(pkg.name)) {
|
|
602
|
+
log(`Provider ${pkg.name} is not in allow list`);
|
|
603
|
+
continue;
|
|
662
604
|
}
|
|
663
605
|
const variables = getProviderVariables(pkg.name);
|
|
664
606
|
const result = {};
|
|
665
|
-
|
|
607
|
+
const providerVariables = Object.entries(variables);
|
|
608
|
+
const executionContext = new Map();
|
|
609
|
+
for (const [tagName, variableSet] of providerVariables) {
|
|
610
|
+
if (!isProviderInstanceAllowed(providers, pkg.name, tagName)) {
|
|
611
|
+
log(`Provider instance is not allowed (${pkg.name}: ${tagName})`);
|
|
612
|
+
continue;
|
|
613
|
+
}
|
|
614
|
+
if (!hasUserConsent(consent, pkg.name, tagName)) {
|
|
615
|
+
log(`Consent is missing (${pkg.name}: ${tagName})`);
|
|
616
|
+
continue;
|
|
617
|
+
}
|
|
618
|
+
anyProviderCalled = true;
|
|
666
619
|
result[tagName] = pkg.tag({
|
|
667
620
|
userId,
|
|
668
621
|
eventName,
|
|
@@ -670,10 +623,14 @@ const handleTag = (eventName, data = {}, providers, options) => {
|
|
|
670
623
|
data: JSON.parse(JSON.stringify(data)),
|
|
671
624
|
sendTag,
|
|
672
625
|
manifestVariables: variableSet,
|
|
626
|
+
executionContext,
|
|
673
627
|
});
|
|
674
628
|
}
|
|
675
629
|
providerData[pkg.name] = result;
|
|
676
|
-
}
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
if (!anyProviderCalled) {
|
|
633
|
+
return;
|
|
677
634
|
}
|
|
678
635
|
sendTag({
|
|
679
636
|
eventName,
|
|
@@ -693,23 +650,34 @@ const handleData = (data, providers, options) => {
|
|
|
693
650
|
saveKV(data);
|
|
694
651
|
const providerPackages = getProvidersPackage();
|
|
695
652
|
const userId = handleGetUserId();
|
|
653
|
+
const consent = getConsent();
|
|
654
|
+
const allowedProviders = getAllowedProviders();
|
|
696
655
|
if (providerPackages) {
|
|
697
|
-
Object.values(providerPackages)
|
|
698
|
-
if (!pkg ||
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
656
|
+
for (const pkg of Object.values(providerPackages)) {
|
|
657
|
+
if (!pkg || !pkg.user || !pkg.name) {
|
|
658
|
+
continue;
|
|
659
|
+
}
|
|
660
|
+
if (!allowedProviders.has(pkg.name)) {
|
|
661
|
+
log(`Provider ${pkg.name} is not in allow list`);
|
|
662
|
+
continue;
|
|
703
663
|
}
|
|
704
664
|
const variables = getProviderVariables(pkg.name);
|
|
705
|
-
for (const variableSet of Object.
|
|
665
|
+
for (const [tagName, variableSet] of Object.entries(variables)) {
|
|
666
|
+
if (!isProviderInstanceAllowed(providers, pkg.name, tagName)) {
|
|
667
|
+
log(`Data not allowed for ${pkg.name} (${tagName})`);
|
|
668
|
+
continue;
|
|
669
|
+
}
|
|
670
|
+
if (!hasUserConsent(consent, pkg.name, tagName)) {
|
|
671
|
+
log(`Consent is missing for ${pkg.name} (${tagName})`);
|
|
672
|
+
continue;
|
|
673
|
+
}
|
|
706
674
|
pkg.user({
|
|
707
675
|
userId,
|
|
708
676
|
data,
|
|
709
677
|
manifestVariables: variableSet,
|
|
710
678
|
});
|
|
711
679
|
}
|
|
712
|
-
}
|
|
680
|
+
}
|
|
713
681
|
}
|
|
714
682
|
postRequest(getDataURL(), { data, providers }, options).catch(error);
|
|
715
683
|
};
|
|
@@ -826,16 +794,15 @@ const handleManifest = (manifest) => {
|
|
|
826
794
|
}
|
|
827
795
|
if (providerPackages) {
|
|
828
796
|
const pkg = providerPackages[provider.package];
|
|
829
|
-
if (pkg && pkg.name && pkg.init
|
|
830
|
-
|
|
797
|
+
if (pkg && pkg.name && pkg.init) {
|
|
798
|
+
pkg.init({
|
|
831
799
|
userId,
|
|
832
800
|
manifest: provider,
|
|
833
801
|
sendTag,
|
|
834
802
|
sendEdgeData: handleData,
|
|
835
803
|
getEdgeData: handleGetData,
|
|
836
804
|
keyName: `${keyPrefix}Store`,
|
|
837
|
-
};
|
|
838
|
-
pkg.init(initData);
|
|
805
|
+
});
|
|
839
806
|
}
|
|
840
807
|
}
|
|
841
808
|
});
|
|
@@ -886,25 +853,37 @@ const handleUser = (key, value, providers, options) => {
|
|
|
886
853
|
saveKV({
|
|
887
854
|
[key]: value,
|
|
888
855
|
});
|
|
856
|
+
const consent = getConsent();
|
|
857
|
+
const allowedProviders = getAllowedProviders();
|
|
889
858
|
const providerPackages = getProvidersPackage();
|
|
890
859
|
const userId = handleGetUserId();
|
|
891
860
|
if (providerPackages) {
|
|
892
|
-
Object.values(providerPackages)
|
|
893
|
-
if (!pkg ||
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
861
|
+
for (const pkg of Object.values(providerPackages)) {
|
|
862
|
+
if (!pkg || !pkg.name || !pkg.user) {
|
|
863
|
+
continue;
|
|
864
|
+
}
|
|
865
|
+
if (!allowedProviders.has(pkg.name)) {
|
|
866
|
+
log(`Provider ${pkg.name} is not in allow list`);
|
|
867
|
+
continue;
|
|
898
868
|
}
|
|
899
869
|
const variables = getProviderVariables(pkg.name);
|
|
900
|
-
for (const variableSet of Object.
|
|
870
|
+
for (const [tagName, variableSet] of Object.entries(variables)) {
|
|
871
|
+
if (!isProviderInstanceAllowed(providers, pkg.name, tagName)) {
|
|
872
|
+
// should we be logging this?
|
|
873
|
+
log(`User not allowed for ${pkg.name} (${tagName})`);
|
|
874
|
+
continue;
|
|
875
|
+
}
|
|
876
|
+
if (!hasUserConsent(consent, pkg.name, tagName)) {
|
|
877
|
+
log(`User doesn't have consent for ${pkg.name} (${tagName})`);
|
|
878
|
+
continue;
|
|
879
|
+
}
|
|
901
880
|
pkg.user({
|
|
902
881
|
userId,
|
|
903
882
|
data: { [key]: value },
|
|
904
883
|
manifestVariables: variableSet,
|
|
905
884
|
});
|
|
906
885
|
}
|
|
907
|
-
}
|
|
886
|
+
}
|
|
908
887
|
}
|
|
909
888
|
postRequest(getUserURL(), {
|
|
910
889
|
key,
|
|
@@ -927,14 +906,14 @@ const init = (preferences) => {
|
|
|
927
906
|
const tag = (name, data, providers, options) => {
|
|
928
907
|
handleTag(name, data, providers, options);
|
|
929
908
|
};
|
|
930
|
-
const consent = (
|
|
931
|
-
handleConsent(
|
|
909
|
+
const consent = (value, options) => {
|
|
910
|
+
handleConsent(value, options);
|
|
932
911
|
};
|
|
933
912
|
const user = (key, value, providers, options) => {
|
|
934
913
|
handleUser(key, value, providers, options);
|
|
935
914
|
};
|
|
936
|
-
const data = (
|
|
937
|
-
handleData(
|
|
915
|
+
const data = (value, providers, options) => {
|
|
916
|
+
handleData(value, providers, options);
|
|
938
917
|
};
|
|
939
918
|
const getData = (keys, callback) => {
|
|
940
919
|
handleGetData(keys, callback);
|
package/internal.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Library } from '@blotoutio/cdn/types'
|
|
1
|
+
import { Library, ProvidersConfig, UserConsent } from '@blotoutio/cdn/types'
|
|
2
2
|
import { UserKey, Data } from './index'
|
|
3
3
|
|
|
4
4
|
type Navigator = {
|
|
@@ -11,22 +11,22 @@ type TagPayload = {
|
|
|
11
11
|
timestamp: number
|
|
12
12
|
providerData?: Partial<Record<Library, Record<string, Data>>>
|
|
13
13
|
data?: Data
|
|
14
|
-
providers?:
|
|
14
|
+
providers?: ProvidersConfig | null | undefined
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
type ConsentPayload = {
|
|
18
|
-
consentString:
|
|
18
|
+
consentString: UserConsent
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
type UserPayload = {
|
|
22
22
|
key: UserKey
|
|
23
23
|
value: string
|
|
24
|
-
providers?:
|
|
24
|
+
providers?: ProvidersConfig | null | undefined
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
type DataPayload = {
|
|
28
28
|
data: Record<string, string>
|
|
29
|
-
providers?:
|
|
29
|
+
providers?: ProvidersConfig | null | undefined
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
type PostPayload = {
|