@blotoutio/edgetag-sdk-js 0.26.1 → 0.26.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/index.cjs +166 -151
- package/index.esm.js +166 -151
- package/package.json +1 -1
package/index.cjs
CHANGED
|
@@ -89,7 +89,18 @@ const getMessage = (error) => {
|
|
|
89
89
|
return error;
|
|
90
90
|
}
|
|
91
91
|
};
|
|
92
|
+
const allowLog = () => {
|
|
93
|
+
try {
|
|
94
|
+
return localStorage.getItem('edgeTagDebug') === '1';
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
};
|
|
92
100
|
const log = (data) => {
|
|
101
|
+
if (!allowLog()) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
93
104
|
console.log('[EdgeTag]', getMessage(data));
|
|
94
105
|
};
|
|
95
106
|
const error = (data) => {
|
|
@@ -323,7 +334,7 @@ const getStandardPayload = (payload) => {
|
|
|
323
334
|
referrer: getReferrer(),
|
|
324
335
|
search: getSearch(),
|
|
325
336
|
locale: getLocale(),
|
|
326
|
-
sdkVersion: "0.26.
|
|
337
|
+
sdkVersion: "0.26.3" ,
|
|
327
338
|
...(payload || {}),
|
|
328
339
|
};
|
|
329
340
|
let storage = {};
|
|
@@ -431,7 +442,64 @@ const getConsent = () => {
|
|
|
431
442
|
return memoryConsent;
|
|
432
443
|
};
|
|
433
444
|
|
|
434
|
-
const
|
|
445
|
+
const isBool = (v) => typeof v == 'boolean';
|
|
446
|
+
const isRecord = (v) => !!v && typeof v == 'object';
|
|
447
|
+
/**
|
|
448
|
+
* This function validates user consent for a given provider and tag name.
|
|
449
|
+
* It should be used in conjunction with `UserConsent`, not `ProvidersConfig`.
|
|
450
|
+
*/
|
|
451
|
+
const hasUserConsent = (consent, provider, tagName) => {
|
|
452
|
+
if (!isRecord(consent)) {
|
|
453
|
+
return false;
|
|
454
|
+
}
|
|
455
|
+
let allowed = isBool(consent.all) ? consent.all : false;
|
|
456
|
+
if (provider in consent) {
|
|
457
|
+
const providerSpecific = consent[provider];
|
|
458
|
+
if (isBool(providerSpecific)) {
|
|
459
|
+
allowed = providerSpecific;
|
|
460
|
+
}
|
|
461
|
+
else if (isRecord(providerSpecific)) {
|
|
462
|
+
if ('all' in providerSpecific && isBool(providerSpecific.all)) {
|
|
463
|
+
allowed = providerSpecific.all;
|
|
464
|
+
}
|
|
465
|
+
if (tagName in providerSpecific && isBool(providerSpecific[tagName])) {
|
|
466
|
+
allowed = providerSpecific[tagName];
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
return allowed;
|
|
471
|
+
};
|
|
472
|
+
/**
|
|
473
|
+
* This function validates provider allowance for a given provider and tag name.
|
|
474
|
+
* It should not be used to validate `UserConsent`.
|
|
475
|
+
*/
|
|
476
|
+
const isProviderInstanceAllowed = (providersConfig, provider, tagName) => {
|
|
477
|
+
if (!isRecord(providersConfig)) {
|
|
478
|
+
return true;
|
|
479
|
+
}
|
|
480
|
+
let allowed = isBool(providersConfig.all) ? providersConfig.all : true;
|
|
481
|
+
if (provider in providersConfig) {
|
|
482
|
+
const providerSpecific = providersConfig[provider];
|
|
483
|
+
if (isBool(providerSpecific)) {
|
|
484
|
+
allowed = providerSpecific;
|
|
485
|
+
}
|
|
486
|
+
else if (isRecord(providerSpecific)) {
|
|
487
|
+
if ('all' in providerSpecific && isBool(providerSpecific.all)) {
|
|
488
|
+
allowed = providerSpecific.all;
|
|
489
|
+
}
|
|
490
|
+
if (tagName in providerSpecific && isBool(providerSpecific[tagName])) {
|
|
491
|
+
allowed = providerSpecific[tagName];
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
return allowed;
|
|
496
|
+
};
|
|
497
|
+
|
|
498
|
+
const upsert = (map, key, update, createDefault) => {
|
|
499
|
+
const currentValue = map.has(key) ? map.get(key) : createDefault();
|
|
500
|
+
return map.set(key, update(currentValue));
|
|
501
|
+
};
|
|
502
|
+
|
|
435
503
|
let initialized = false;
|
|
436
504
|
const providersPackages = {};
|
|
437
505
|
const setPreferences = (preferences) => {
|
|
@@ -471,12 +539,9 @@ const isInitialized = () => initialized;
|
|
|
471
539
|
const setInitialized = () => {
|
|
472
540
|
initialized = true;
|
|
473
541
|
};
|
|
474
|
-
const
|
|
475
|
-
const
|
|
476
|
-
|
|
477
|
-
allowedProvider.add(provider);
|
|
478
|
-
}
|
|
479
|
-
};
|
|
542
|
+
const configuredTags = new Map();
|
|
543
|
+
const addConfiguredTag = (pkg, tagName) => upsert(configuredTags, pkg, (names) => names.add(tagName), () => new Set());
|
|
544
|
+
const getConfiguredTags = () => configuredTags;
|
|
480
545
|
|
|
481
546
|
const manifestVariables = {};
|
|
482
547
|
const addProviderVariable = (name, variables, tagName) => {
|
|
@@ -511,59 +576,6 @@ const processStubs = () => {
|
|
|
511
576
|
}
|
|
512
577
|
};
|
|
513
578
|
|
|
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;
|
|
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
579
|
const sendTag = ({ eventName, eventId, data, providerData, providers, options, }) => {
|
|
568
580
|
const payload = {
|
|
569
581
|
eventName,
|
|
@@ -590,47 +602,44 @@ const handleTag = (eventName, data = {}, providers, options) => {
|
|
|
590
602
|
eventId = generateEventId(eventName);
|
|
591
603
|
}
|
|
592
604
|
const providerPackages = getProvidersPackage();
|
|
605
|
+
const configuredTags = getConfiguredTags();
|
|
593
606
|
const userId = handleGetUserId();
|
|
594
607
|
const providerData = {};
|
|
595
608
|
const consent = getConsent();
|
|
596
|
-
const
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
609
|
+
for (const pkg of Object.values(providerPackages)) {
|
|
610
|
+
if (!pkg || !pkg.name || !pkg.tag) {
|
|
611
|
+
continue;
|
|
612
|
+
}
|
|
613
|
+
if (!configuredTags.has(pkg.name)) {
|
|
614
|
+
log(`Provider ${pkg.name} is not in allow list`);
|
|
615
|
+
continue;
|
|
616
|
+
}
|
|
617
|
+
const variables = getProviderVariables(pkg.name);
|
|
618
|
+
const result = {};
|
|
619
|
+
const providerVariables = Object.entries(variables);
|
|
620
|
+
const executionContext = new Map();
|
|
621
|
+
for (const [tagName, variableSet] of providerVariables) {
|
|
622
|
+
if (!isProviderInstanceAllowed(providers, pkg.name, tagName)) {
|
|
623
|
+
log(`Provider instance is not allowed (${pkg.name}: ${tagName})`);
|
|
601
624
|
continue;
|
|
602
625
|
}
|
|
603
|
-
if (!
|
|
626
|
+
if (!hasUserConsent(consent, pkg.name, tagName)) {
|
|
627
|
+
log(`Consent is missing (${pkg.name}: ${tagName})`);
|
|
604
628
|
continue;
|
|
605
629
|
}
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
if (!hasUserConsent(consent, pkg.name, tagName)) {
|
|
616
|
-
log(`Consent is missing (${pkg.name}: ${tagName})`);
|
|
617
|
-
continue;
|
|
618
|
-
}
|
|
619
|
-
anyProviderCalled = true;
|
|
620
|
-
result[tagName] = pkg.tag({
|
|
621
|
-
userId,
|
|
622
|
-
eventName,
|
|
623
|
-
eventId,
|
|
624
|
-
data: JSON.parse(JSON.stringify(data)),
|
|
625
|
-
sendTag,
|
|
626
|
-
manifestVariables: variableSet,
|
|
627
|
-
executionContext,
|
|
628
|
-
});
|
|
629
|
-
}
|
|
630
|
-
providerData[pkg.name] = result;
|
|
630
|
+
result[tagName] = pkg.tag({
|
|
631
|
+
userId,
|
|
632
|
+
eventName,
|
|
633
|
+
eventId,
|
|
634
|
+
data: JSON.parse(JSON.stringify(data)),
|
|
635
|
+
sendTag,
|
|
636
|
+
manifestVariables: variableSet,
|
|
637
|
+
executionContext,
|
|
638
|
+
});
|
|
631
639
|
}
|
|
640
|
+
providerData[pkg.name] = result;
|
|
632
641
|
}
|
|
633
|
-
if (!
|
|
642
|
+
if (!hasAllowedManifestTags(configuredTags, consent, providers)) {
|
|
634
643
|
return;
|
|
635
644
|
}
|
|
636
645
|
sendTag({
|
|
@@ -642,6 +651,17 @@ const handleTag = (eventName, data = {}, providers, options) => {
|
|
|
642
651
|
options,
|
|
643
652
|
});
|
|
644
653
|
};
|
|
654
|
+
const hasAllowedManifestTags = (tags, consent, providersConfig) => {
|
|
655
|
+
for (const [pkg, tagNames] of tags) {
|
|
656
|
+
for (const tagName of tagNames) {
|
|
657
|
+
if (hasUserConsent(consent, pkg, tagName) &&
|
|
658
|
+
isProviderInstanceAllowed(providersConfig, pkg, tagName)) {
|
|
659
|
+
return true;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
return false;
|
|
664
|
+
};
|
|
645
665
|
|
|
646
666
|
const handleData = (data, providers, options) => {
|
|
647
667
|
if (!data || Object.keys(data).length === 0) {
|
|
@@ -650,33 +670,32 @@ const handleData = (data, providers, options) => {
|
|
|
650
670
|
}
|
|
651
671
|
saveKV(data);
|
|
652
672
|
const providerPackages = getProvidersPackage();
|
|
673
|
+
const configuredTags = getConfiguredTags();
|
|
653
674
|
const userId = handleGetUserId();
|
|
654
675
|
const consent = getConsent();
|
|
655
|
-
const
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
676
|
+
for (const pkg of Object.values(providerPackages)) {
|
|
677
|
+
if (!pkg || !pkg.user || !pkg.name) {
|
|
678
|
+
continue;
|
|
679
|
+
}
|
|
680
|
+
if (!configuredTags.has(pkg.name)) {
|
|
681
|
+
log(`Provider ${pkg.name} is not in allow list`);
|
|
682
|
+
continue;
|
|
683
|
+
}
|
|
684
|
+
const variables = getProviderVariables(pkg.name);
|
|
685
|
+
for (const [tagName, variableSet] of Object.entries(variables)) {
|
|
686
|
+
if (!isProviderInstanceAllowed(providers, pkg.name, tagName)) {
|
|
687
|
+
log(`Data not allowed for ${pkg.name} (${tagName})`);
|
|
659
688
|
continue;
|
|
660
689
|
}
|
|
661
|
-
if (!
|
|
690
|
+
if (!hasUserConsent(consent, pkg.name, tagName)) {
|
|
691
|
+
log(`Consent is missing for ${pkg.name} (${tagName})`);
|
|
662
692
|
continue;
|
|
663
693
|
}
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
}
|
|
670
|
-
if (!hasUserConsent(consent, pkg.name, tagName)) {
|
|
671
|
-
log(`Consent is missing for ${pkg.name} (${tagName})`);
|
|
672
|
-
continue;
|
|
673
|
-
}
|
|
674
|
-
pkg.user({
|
|
675
|
-
userId,
|
|
676
|
-
data,
|
|
677
|
-
manifestVariables: variableSet,
|
|
678
|
-
});
|
|
679
|
-
}
|
|
694
|
+
pkg.user({
|
|
695
|
+
userId,
|
|
696
|
+
data,
|
|
697
|
+
manifestVariables: variableSet,
|
|
698
|
+
});
|
|
680
699
|
}
|
|
681
700
|
}
|
|
682
701
|
postRequest(getDataURL(), { data, providers }, options).catch(error);
|
|
@@ -779,8 +798,8 @@ const handleGetData = (keys, callback) => {
|
|
|
779
798
|
const handleManifest = (manifest) => {
|
|
780
799
|
const providerPackages = getProvidersPackage();
|
|
781
800
|
const userId = handleGetUserId();
|
|
782
|
-
setAllowedProviders(manifest.map((provider) => provider.package));
|
|
783
801
|
manifest.forEach((provider) => {
|
|
802
|
+
addConfiguredTag(provider.package, provider.tagName);
|
|
784
803
|
addProviderVariable(provider.package, provider.variables, provider.tagName);
|
|
785
804
|
if (provider.rules) {
|
|
786
805
|
Object.entries(provider.rules).forEach(([name, recipe]) => {
|
|
@@ -792,18 +811,16 @@ const handleManifest = (manifest) => {
|
|
|
792
811
|
}
|
|
793
812
|
});
|
|
794
813
|
}
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
});
|
|
806
|
-
}
|
|
814
|
+
const pkg = providerPackages[provider.package];
|
|
815
|
+
if (pkg && pkg.name && pkg.init) {
|
|
816
|
+
pkg.init({
|
|
817
|
+
userId,
|
|
818
|
+
manifest: provider,
|
|
819
|
+
sendTag,
|
|
820
|
+
sendEdgeData: handleData,
|
|
821
|
+
getEdgeData: handleGetData,
|
|
822
|
+
keyName: `${keyPrefix}Store`,
|
|
823
|
+
});
|
|
807
824
|
}
|
|
808
825
|
});
|
|
809
826
|
setInitialized();
|
|
@@ -830,7 +847,7 @@ const handleInit = (preferences) => {
|
|
|
830
847
|
getRequest(url.href)
|
|
831
848
|
.then((result) => {
|
|
832
849
|
if (!result) {
|
|
833
|
-
|
|
850
|
+
error('Initialization failed');
|
|
834
851
|
return;
|
|
835
852
|
}
|
|
836
853
|
if (result.userId) {
|
|
@@ -853,35 +870,33 @@ const handleUser = (key, value, providers, options) => {
|
|
|
853
870
|
saveKV({
|
|
854
871
|
[key]: value,
|
|
855
872
|
});
|
|
856
|
-
const consent = getConsent();
|
|
857
|
-
const allowedProviders = getAllowedProviders();
|
|
858
873
|
const providerPackages = getProvidersPackage();
|
|
874
|
+
const configuredTags = getConfiguredTags();
|
|
875
|
+
const consent = getConsent();
|
|
859
876
|
const userId = handleGetUserId();
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
877
|
+
for (const pkg of Object.values(providerPackages)) {
|
|
878
|
+
if (!pkg || !pkg.name || !pkg.user) {
|
|
879
|
+
continue;
|
|
880
|
+
}
|
|
881
|
+
if (!configuredTags.has(pkg.name)) {
|
|
882
|
+
log(`Provider ${pkg.name} is not in allow list`);
|
|
883
|
+
continue;
|
|
884
|
+
}
|
|
885
|
+
const variables = getProviderVariables(pkg.name);
|
|
886
|
+
for (const [tagName, variableSet] of Object.entries(variables)) {
|
|
887
|
+
if (!isProviderInstanceAllowed(providers, pkg.name, tagName)) {
|
|
888
|
+
log(`User not allowed for ${pkg.name} (${tagName})`);
|
|
863
889
|
continue;
|
|
864
890
|
}
|
|
865
|
-
if (!
|
|
891
|
+
if (!hasUserConsent(consent, pkg.name, tagName)) {
|
|
892
|
+
log(`User doesn't have consent for ${pkg.name} (${tagName})`);
|
|
866
893
|
continue;
|
|
867
894
|
}
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
continue;
|
|
874
|
-
}
|
|
875
|
-
if (!hasUserConsent(consent, pkg.name, tagName)) {
|
|
876
|
-
log(`User doesn't have consent for ${pkg.name} (${tagName})`);
|
|
877
|
-
continue;
|
|
878
|
-
}
|
|
879
|
-
pkg.user({
|
|
880
|
-
userId,
|
|
881
|
-
data: { [key]: value },
|
|
882
|
-
manifestVariables: variableSet,
|
|
883
|
-
});
|
|
884
|
-
}
|
|
895
|
+
pkg.user({
|
|
896
|
+
userId,
|
|
897
|
+
data: { [key]: value },
|
|
898
|
+
manifestVariables: variableSet,
|
|
899
|
+
});
|
|
885
900
|
}
|
|
886
901
|
}
|
|
887
902
|
postRequest(getUserURL(), {
|
package/index.esm.js
CHANGED
|
@@ -87,7 +87,18 @@ const getMessage = (error) => {
|
|
|
87
87
|
return error;
|
|
88
88
|
}
|
|
89
89
|
};
|
|
90
|
+
const allowLog = () => {
|
|
91
|
+
try {
|
|
92
|
+
return localStorage.getItem('edgeTagDebug') === '1';
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
};
|
|
90
98
|
const log = (data) => {
|
|
99
|
+
if (!allowLog()) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
91
102
|
console.log('[EdgeTag]', getMessage(data));
|
|
92
103
|
};
|
|
93
104
|
const error = (data) => {
|
|
@@ -321,7 +332,7 @@ const getStandardPayload = (payload) => {
|
|
|
321
332
|
referrer: getReferrer(),
|
|
322
333
|
search: getSearch(),
|
|
323
334
|
locale: getLocale(),
|
|
324
|
-
sdkVersion: "0.26.
|
|
335
|
+
sdkVersion: "0.26.3" ,
|
|
325
336
|
...(payload || {}),
|
|
326
337
|
};
|
|
327
338
|
let storage = {};
|
|
@@ -429,7 +440,64 @@ const getConsent = () => {
|
|
|
429
440
|
return memoryConsent;
|
|
430
441
|
};
|
|
431
442
|
|
|
432
|
-
const
|
|
443
|
+
const isBool = (v) => typeof v == 'boolean';
|
|
444
|
+
const isRecord = (v) => !!v && typeof v == 'object';
|
|
445
|
+
/**
|
|
446
|
+
* This function validates user consent for a given provider and tag name.
|
|
447
|
+
* It should be used in conjunction with `UserConsent`, not `ProvidersConfig`.
|
|
448
|
+
*/
|
|
449
|
+
const hasUserConsent = (consent, provider, tagName) => {
|
|
450
|
+
if (!isRecord(consent)) {
|
|
451
|
+
return false;
|
|
452
|
+
}
|
|
453
|
+
let allowed = isBool(consent.all) ? consent.all : false;
|
|
454
|
+
if (provider in consent) {
|
|
455
|
+
const providerSpecific = consent[provider];
|
|
456
|
+
if (isBool(providerSpecific)) {
|
|
457
|
+
allowed = providerSpecific;
|
|
458
|
+
}
|
|
459
|
+
else if (isRecord(providerSpecific)) {
|
|
460
|
+
if ('all' in providerSpecific && isBool(providerSpecific.all)) {
|
|
461
|
+
allowed = providerSpecific.all;
|
|
462
|
+
}
|
|
463
|
+
if (tagName in providerSpecific && isBool(providerSpecific[tagName])) {
|
|
464
|
+
allowed = providerSpecific[tagName];
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
return allowed;
|
|
469
|
+
};
|
|
470
|
+
/**
|
|
471
|
+
* This function validates provider allowance for a given provider and tag name.
|
|
472
|
+
* It should not be used to validate `UserConsent`.
|
|
473
|
+
*/
|
|
474
|
+
const isProviderInstanceAllowed = (providersConfig, provider, tagName) => {
|
|
475
|
+
if (!isRecord(providersConfig)) {
|
|
476
|
+
return true;
|
|
477
|
+
}
|
|
478
|
+
let allowed = isBool(providersConfig.all) ? providersConfig.all : true;
|
|
479
|
+
if (provider in providersConfig) {
|
|
480
|
+
const providerSpecific = providersConfig[provider];
|
|
481
|
+
if (isBool(providerSpecific)) {
|
|
482
|
+
allowed = providerSpecific;
|
|
483
|
+
}
|
|
484
|
+
else if (isRecord(providerSpecific)) {
|
|
485
|
+
if ('all' in providerSpecific && isBool(providerSpecific.all)) {
|
|
486
|
+
allowed = providerSpecific.all;
|
|
487
|
+
}
|
|
488
|
+
if (tagName in providerSpecific && isBool(providerSpecific[tagName])) {
|
|
489
|
+
allowed = providerSpecific[tagName];
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
return allowed;
|
|
494
|
+
};
|
|
495
|
+
|
|
496
|
+
const upsert = (map, key, update, createDefault) => {
|
|
497
|
+
const currentValue = map.has(key) ? map.get(key) : createDefault();
|
|
498
|
+
return map.set(key, update(currentValue));
|
|
499
|
+
};
|
|
500
|
+
|
|
433
501
|
let initialized = false;
|
|
434
502
|
const providersPackages = {};
|
|
435
503
|
const setPreferences = (preferences) => {
|
|
@@ -469,12 +537,9 @@ const isInitialized = () => initialized;
|
|
|
469
537
|
const setInitialized = () => {
|
|
470
538
|
initialized = true;
|
|
471
539
|
};
|
|
472
|
-
const
|
|
473
|
-
const
|
|
474
|
-
|
|
475
|
-
allowedProvider.add(provider);
|
|
476
|
-
}
|
|
477
|
-
};
|
|
540
|
+
const configuredTags = new Map();
|
|
541
|
+
const addConfiguredTag = (pkg, tagName) => upsert(configuredTags, pkg, (names) => names.add(tagName), () => new Set());
|
|
542
|
+
const getConfiguredTags = () => configuredTags;
|
|
478
543
|
|
|
479
544
|
const manifestVariables = {};
|
|
480
545
|
const addProviderVariable = (name, variables, tagName) => {
|
|
@@ -509,59 +574,6 @@ const processStubs = () => {
|
|
|
509
574
|
}
|
|
510
575
|
};
|
|
511
576
|
|
|
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;
|
|
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
577
|
const sendTag = ({ eventName, eventId, data, providerData, providers, options, }) => {
|
|
566
578
|
const payload = {
|
|
567
579
|
eventName,
|
|
@@ -588,47 +600,44 @@ const handleTag = (eventName, data = {}, providers, options) => {
|
|
|
588
600
|
eventId = generateEventId(eventName);
|
|
589
601
|
}
|
|
590
602
|
const providerPackages = getProvidersPackage();
|
|
603
|
+
const configuredTags = getConfiguredTags();
|
|
591
604
|
const userId = handleGetUserId();
|
|
592
605
|
const providerData = {};
|
|
593
606
|
const consent = getConsent();
|
|
594
|
-
const
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
607
|
+
for (const pkg of Object.values(providerPackages)) {
|
|
608
|
+
if (!pkg || !pkg.name || !pkg.tag) {
|
|
609
|
+
continue;
|
|
610
|
+
}
|
|
611
|
+
if (!configuredTags.has(pkg.name)) {
|
|
612
|
+
log(`Provider ${pkg.name} is not in allow list`);
|
|
613
|
+
continue;
|
|
614
|
+
}
|
|
615
|
+
const variables = getProviderVariables(pkg.name);
|
|
616
|
+
const result = {};
|
|
617
|
+
const providerVariables = Object.entries(variables);
|
|
618
|
+
const executionContext = new Map();
|
|
619
|
+
for (const [tagName, variableSet] of providerVariables) {
|
|
620
|
+
if (!isProviderInstanceAllowed(providers, pkg.name, tagName)) {
|
|
621
|
+
log(`Provider instance is not allowed (${pkg.name}: ${tagName})`);
|
|
599
622
|
continue;
|
|
600
623
|
}
|
|
601
|
-
if (!
|
|
624
|
+
if (!hasUserConsent(consent, pkg.name, tagName)) {
|
|
625
|
+
log(`Consent is missing (${pkg.name}: ${tagName})`);
|
|
602
626
|
continue;
|
|
603
627
|
}
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
if (!hasUserConsent(consent, pkg.name, tagName)) {
|
|
614
|
-
log(`Consent is missing (${pkg.name}: ${tagName})`);
|
|
615
|
-
continue;
|
|
616
|
-
}
|
|
617
|
-
anyProviderCalled = true;
|
|
618
|
-
result[tagName] = pkg.tag({
|
|
619
|
-
userId,
|
|
620
|
-
eventName,
|
|
621
|
-
eventId,
|
|
622
|
-
data: JSON.parse(JSON.stringify(data)),
|
|
623
|
-
sendTag,
|
|
624
|
-
manifestVariables: variableSet,
|
|
625
|
-
executionContext,
|
|
626
|
-
});
|
|
627
|
-
}
|
|
628
|
-
providerData[pkg.name] = result;
|
|
628
|
+
result[tagName] = pkg.tag({
|
|
629
|
+
userId,
|
|
630
|
+
eventName,
|
|
631
|
+
eventId,
|
|
632
|
+
data: JSON.parse(JSON.stringify(data)),
|
|
633
|
+
sendTag,
|
|
634
|
+
manifestVariables: variableSet,
|
|
635
|
+
executionContext,
|
|
636
|
+
});
|
|
629
637
|
}
|
|
638
|
+
providerData[pkg.name] = result;
|
|
630
639
|
}
|
|
631
|
-
if (!
|
|
640
|
+
if (!hasAllowedManifestTags(configuredTags, consent, providers)) {
|
|
632
641
|
return;
|
|
633
642
|
}
|
|
634
643
|
sendTag({
|
|
@@ -640,6 +649,17 @@ const handleTag = (eventName, data = {}, providers, options) => {
|
|
|
640
649
|
options,
|
|
641
650
|
});
|
|
642
651
|
};
|
|
652
|
+
const hasAllowedManifestTags = (tags, consent, providersConfig) => {
|
|
653
|
+
for (const [pkg, tagNames] of tags) {
|
|
654
|
+
for (const tagName of tagNames) {
|
|
655
|
+
if (hasUserConsent(consent, pkg, tagName) &&
|
|
656
|
+
isProviderInstanceAllowed(providersConfig, pkg, tagName)) {
|
|
657
|
+
return true;
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
return false;
|
|
662
|
+
};
|
|
643
663
|
|
|
644
664
|
const handleData = (data, providers, options) => {
|
|
645
665
|
if (!data || Object.keys(data).length === 0) {
|
|
@@ -648,33 +668,32 @@ const handleData = (data, providers, options) => {
|
|
|
648
668
|
}
|
|
649
669
|
saveKV(data);
|
|
650
670
|
const providerPackages = getProvidersPackage();
|
|
671
|
+
const configuredTags = getConfiguredTags();
|
|
651
672
|
const userId = handleGetUserId();
|
|
652
673
|
const consent = getConsent();
|
|
653
|
-
const
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
674
|
+
for (const pkg of Object.values(providerPackages)) {
|
|
675
|
+
if (!pkg || !pkg.user || !pkg.name) {
|
|
676
|
+
continue;
|
|
677
|
+
}
|
|
678
|
+
if (!configuredTags.has(pkg.name)) {
|
|
679
|
+
log(`Provider ${pkg.name} is not in allow list`);
|
|
680
|
+
continue;
|
|
681
|
+
}
|
|
682
|
+
const variables = getProviderVariables(pkg.name);
|
|
683
|
+
for (const [tagName, variableSet] of Object.entries(variables)) {
|
|
684
|
+
if (!isProviderInstanceAllowed(providers, pkg.name, tagName)) {
|
|
685
|
+
log(`Data not allowed for ${pkg.name} (${tagName})`);
|
|
657
686
|
continue;
|
|
658
687
|
}
|
|
659
|
-
if (!
|
|
688
|
+
if (!hasUserConsent(consent, pkg.name, tagName)) {
|
|
689
|
+
log(`Consent is missing for ${pkg.name} (${tagName})`);
|
|
660
690
|
continue;
|
|
661
691
|
}
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
}
|
|
668
|
-
if (!hasUserConsent(consent, pkg.name, tagName)) {
|
|
669
|
-
log(`Consent is missing for ${pkg.name} (${tagName})`);
|
|
670
|
-
continue;
|
|
671
|
-
}
|
|
672
|
-
pkg.user({
|
|
673
|
-
userId,
|
|
674
|
-
data,
|
|
675
|
-
manifestVariables: variableSet,
|
|
676
|
-
});
|
|
677
|
-
}
|
|
692
|
+
pkg.user({
|
|
693
|
+
userId,
|
|
694
|
+
data,
|
|
695
|
+
manifestVariables: variableSet,
|
|
696
|
+
});
|
|
678
697
|
}
|
|
679
698
|
}
|
|
680
699
|
postRequest(getDataURL(), { data, providers }, options).catch(error);
|
|
@@ -777,8 +796,8 @@ const handleGetData = (keys, callback) => {
|
|
|
777
796
|
const handleManifest = (manifest) => {
|
|
778
797
|
const providerPackages = getProvidersPackage();
|
|
779
798
|
const userId = handleGetUserId();
|
|
780
|
-
setAllowedProviders(manifest.map((provider) => provider.package));
|
|
781
799
|
manifest.forEach((provider) => {
|
|
800
|
+
addConfiguredTag(provider.package, provider.tagName);
|
|
782
801
|
addProviderVariable(provider.package, provider.variables, provider.tagName);
|
|
783
802
|
if (provider.rules) {
|
|
784
803
|
Object.entries(provider.rules).forEach(([name, recipe]) => {
|
|
@@ -790,18 +809,16 @@ const handleManifest = (manifest) => {
|
|
|
790
809
|
}
|
|
791
810
|
});
|
|
792
811
|
}
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
});
|
|
804
|
-
}
|
|
812
|
+
const pkg = providerPackages[provider.package];
|
|
813
|
+
if (pkg && pkg.name && pkg.init) {
|
|
814
|
+
pkg.init({
|
|
815
|
+
userId,
|
|
816
|
+
manifest: provider,
|
|
817
|
+
sendTag,
|
|
818
|
+
sendEdgeData: handleData,
|
|
819
|
+
getEdgeData: handleGetData,
|
|
820
|
+
keyName: `${keyPrefix}Store`,
|
|
821
|
+
});
|
|
805
822
|
}
|
|
806
823
|
});
|
|
807
824
|
setInitialized();
|
|
@@ -828,7 +845,7 @@ const handleInit = (preferences) => {
|
|
|
828
845
|
getRequest(url.href)
|
|
829
846
|
.then((result) => {
|
|
830
847
|
if (!result) {
|
|
831
|
-
|
|
848
|
+
error('Initialization failed');
|
|
832
849
|
return;
|
|
833
850
|
}
|
|
834
851
|
if (result.userId) {
|
|
@@ -851,35 +868,33 @@ const handleUser = (key, value, providers, options) => {
|
|
|
851
868
|
saveKV({
|
|
852
869
|
[key]: value,
|
|
853
870
|
});
|
|
854
|
-
const consent = getConsent();
|
|
855
|
-
const allowedProviders = getAllowedProviders();
|
|
856
871
|
const providerPackages = getProvidersPackage();
|
|
872
|
+
const configuredTags = getConfiguredTags();
|
|
873
|
+
const consent = getConsent();
|
|
857
874
|
const userId = handleGetUserId();
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
875
|
+
for (const pkg of Object.values(providerPackages)) {
|
|
876
|
+
if (!pkg || !pkg.name || !pkg.user) {
|
|
877
|
+
continue;
|
|
878
|
+
}
|
|
879
|
+
if (!configuredTags.has(pkg.name)) {
|
|
880
|
+
log(`Provider ${pkg.name} is not in allow list`);
|
|
881
|
+
continue;
|
|
882
|
+
}
|
|
883
|
+
const variables = getProviderVariables(pkg.name);
|
|
884
|
+
for (const [tagName, variableSet] of Object.entries(variables)) {
|
|
885
|
+
if (!isProviderInstanceAllowed(providers, pkg.name, tagName)) {
|
|
886
|
+
log(`User not allowed for ${pkg.name} (${tagName})`);
|
|
861
887
|
continue;
|
|
862
888
|
}
|
|
863
|
-
if (!
|
|
889
|
+
if (!hasUserConsent(consent, pkg.name, tagName)) {
|
|
890
|
+
log(`User doesn't have consent for ${pkg.name} (${tagName})`);
|
|
864
891
|
continue;
|
|
865
892
|
}
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
continue;
|
|
872
|
-
}
|
|
873
|
-
if (!hasUserConsent(consent, pkg.name, tagName)) {
|
|
874
|
-
log(`User doesn't have consent for ${pkg.name} (${tagName})`);
|
|
875
|
-
continue;
|
|
876
|
-
}
|
|
877
|
-
pkg.user({
|
|
878
|
-
userId,
|
|
879
|
-
data: { [key]: value },
|
|
880
|
-
manifestVariables: variableSet,
|
|
881
|
-
});
|
|
882
|
-
}
|
|
893
|
+
pkg.user({
|
|
894
|
+
userId,
|
|
895
|
+
data: { [key]: value },
|
|
896
|
+
manifestVariables: variableSet,
|
|
897
|
+
});
|
|
883
898
|
}
|
|
884
899
|
}
|
|
885
900
|
postRequest(getUserURL(), {
|