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