prebid.js 9.4.0 → 9.5.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 (363) hide show
  1. package/.eslintrc.js +31 -5
  2. package/.github/workflows/jscpd.yml +2 -2
  3. package/.github/workflows/linter.yml +107 -0
  4. package/creative/crossDomain.js +6 -3
  5. package/dist/33acrossAnalyticsAdapter.js +1 -1
  6. package/dist/33acrossBidAdapter.js +1 -1
  7. package/dist/33acrossIdSystem.js +1 -1
  8. package/dist/BTBidAdapter.js +1 -1
  9. package/dist/adagioAnalyticsAdapter.js +1 -1
  10. package/dist/adagioBidAdapter.js +1 -1
  11. package/dist/adagioRtdProvider.js +1 -1
  12. package/dist/adagioUtils.js +1 -1
  13. package/dist/addefendBidAdapter.js +1 -1
  14. package/dist/adgenerationBidAdapter.js +1 -1
  15. package/dist/adkernelAdnBidAdapter.js +1 -1
  16. package/dist/adkernelBidAdapter.js +1 -1
  17. package/dist/adkernelUtils.js +1 -0
  18. package/dist/adlooxRtdProvider.js +1 -1
  19. package/dist/admixerBidAdapter.js +1 -1
  20. package/dist/adqueryBidAdapter.js +1 -1
  21. package/dist/adrelevantisBidAdapter.js +1 -1
  22. package/dist/adstirBidAdapter.js +1 -1
  23. package/dist/adtrgtmeBidAdapter.js +1 -1
  24. package/dist/advRedAnalyticsAdapter.js +1 -0
  25. package/dist/adxcgAnalyticsAdapter.js +1 -1
  26. package/dist/adxcgBidAdapter.js +1 -1
  27. package/dist/adyoulikeBidAdapter.js +1 -1
  28. package/dist/agmaAnalyticsAdapter.js +1 -1
  29. package/dist/ajaBidAdapter.js +1 -1
  30. package/dist/akamaiDapRtdProvider.js +1 -1
  31. package/dist/amxBidAdapter.js +1 -1
  32. package/dist/amxIdSystem.js +1 -1
  33. package/dist/anonymisedRtdProvider.js +1 -1
  34. package/dist/apacdexBidAdapter.js +1 -1
  35. package/dist/appierAnalyticsAdapter.js +1 -1
  36. package/dist/appnexusBidAdapter.js +1 -1
  37. package/dist/asoBidAdapter.js +1 -1
  38. package/dist/axonixBidAdapter.js +1 -1
  39. package/dist/azerionedgeRtdProvider.js +1 -1
  40. package/dist/bidglassBidAdapter.js +1 -1
  41. package/dist/big-richmediaBidAdapter.js +1 -1
  42. package/dist/bridBidAdapter.js +1 -1
  43. package/dist/bridgewellBidAdapter.js +1 -1
  44. package/dist/brightMountainMediaBidAdapter.js +1 -1
  45. package/dist/carodaBidAdapter.js +1 -1
  46. package/dist/chtnwBidAdapter.js +1 -1
  47. package/dist/chunk-core.js +1 -1
  48. package/dist/concertBidAdapter.js +1 -1
  49. package/dist/connatixBidAdapter.js +1 -1
  50. package/dist/connectadBidAdapter.js +1 -1
  51. package/dist/consumableBidAdapter.js +1 -1
  52. package/dist/contxtfulRtdProvider.js +1 -1
  53. package/dist/conversantAnalyticsAdapter.js +1 -1
  54. package/dist/conversantBidAdapter.js +1 -1
  55. package/dist/craftBidAdapter.js +1 -1
  56. package/dist/criteoBidAdapter.js +1 -1
  57. package/dist/currencyUtils.js +1 -1
  58. package/dist/cwireBidAdapter.js +1 -1
  59. package/dist/dailymotionBidAdapter.js +1 -1
  60. package/dist/debugging-standalone.js +1 -1
  61. package/dist/dependencies.json +43 -7
  62. package/dist/dfpAdServerVideo.js +1 -1
  63. package/dist/dfpAdpod.js +1 -1
  64. package/dist/dfpUtils.js +1 -1
  65. package/dist/discoveryBidAdapter.js +1 -1
  66. package/dist/dspxBidAdapter.js +1 -1
  67. package/dist/dxkultureBidAdapter.js +1 -1
  68. package/dist/eightPodAnalyticsAdapter.js +1 -1
  69. package/dist/eightPodBidAdapter.js +1 -1
  70. package/dist/eplanningBidAdapter.js +1 -1
  71. package/dist/euidIdSystem.js +1 -1
  72. package/dist/exadsBidAdapter.js +1 -1
  73. package/dist/feedadBidAdapter.js +1 -1
  74. package/dist/finativeBidAdapter.js +1 -1
  75. package/dist/fintezaAnalyticsAdapter.js +1 -1
  76. package/dist/fpdUtils.js +1 -0
  77. package/dist/freewheel-sspBidAdapter.js +1 -1
  78. package/dist/gmosspBidAdapter.js +1 -1
  79. package/dist/goldbachBidAdapter.js +1 -1
  80. package/dist/gptPreAuction.js +1 -1
  81. package/dist/gptUtils.js +1 -1
  82. package/dist/greenbidsAnalyticsAdapter.js +1 -1
  83. package/dist/greenbidsRtdProvider.js +1 -1
  84. package/dist/gridBidAdapter.js +1 -1
  85. package/dist/growthCodeAnalyticsAdapter.js +1 -1
  86. package/dist/growthCodeRtdProvider.js +1 -1
  87. package/dist/gumgumBidAdapter.js +1 -1
  88. package/dist/h12mediaBidAdapter.js +1 -1
  89. package/dist/hypelabBidAdapter.js +1 -1
  90. package/dist/id5AnalyticsAdapter.js +1 -1
  91. package/dist/id5IdSystem.js +1 -1
  92. package/dist/imdsBidAdapter.js +1 -1
  93. package/dist/improvedigitalBidAdapter.js +1 -1
  94. package/dist/insticatorBidAdapter.js +1 -1
  95. package/dist/intentIqAnalyticsAdapter.js +1 -0
  96. package/dist/ixBidAdapter.js +1 -1
  97. package/dist/jixieBidAdapter.js +1 -1
  98. package/dist/justpremiumBidAdapter.js +1 -1
  99. package/dist/jwplayerBidAdapter.js +1 -1
  100. package/dist/jwplayerRtdProvider.js +1 -1
  101. package/dist/kargoBidAdapter.js +1 -1
  102. package/dist/kimberliteBidAdapter.js +1 -1
  103. package/dist/konduitAnalyticsAdapter.js +1 -1
  104. package/dist/kueezBidAdapter.js +1 -1
  105. package/dist/lassoBidAdapter.js +1 -1
  106. package/dist/lifestreetBidAdapter.js +1 -1
  107. package/dist/liveIntentIdSystem.js +1 -1
  108. package/dist/logicadBidAdapter.js +1 -1
  109. package/dist/loglyliftBidAdapter.js +1 -1
  110. package/dist/luceadBidAdapter.js +1 -1
  111. package/dist/mabidderBidAdapter.js +1 -1
  112. package/dist/magniteAnalyticsAdapter.js +1 -1
  113. package/dist/malltvAnalyticsAdapter.js +1 -1
  114. package/dist/marsmediaBidAdapter.js +1 -1
  115. package/dist/mediafuseBidAdapter.js +1 -1
  116. package/dist/mediagoBidAdapter.js +1 -1
  117. package/dist/medianetAnalyticsAdapter.js +1 -1
  118. package/dist/medianetBidAdapter.js +1 -1
  119. package/dist/mediasquareBidAdapter.js +1 -1
  120. package/dist/mgidBidAdapter.js +1 -1
  121. package/dist/minutemediaBidAdapter.js +1 -1
  122. package/dist/missenaBidAdapter.js +1 -1
  123. package/dist/mobianRtdProvider.js +1 -1
  124. package/dist/nextMillenniumBidAdapter.js +1 -1
  125. package/dist/nexx360BidAdapter.js +1 -1
  126. package/dist/nobidAnalyticsAdapter.js +1 -1
  127. package/dist/nobidBidAdapter.js +1 -1
  128. package/dist/not-for-prod/prebid.js +201 -193
  129. package/dist/oguryBidAdapter.js +1 -1
  130. package/dist/onetagBidAdapter.js +1 -1
  131. package/dist/ooloAnalyticsAdapter.js +1 -1
  132. package/dist/openwebBidAdapter.js +1 -1
  133. package/dist/openxBidAdapter.js +1 -1
  134. package/dist/optidigitalBidAdapter.js +1 -1
  135. package/dist/optoutBidAdapter.js +1 -1
  136. package/dist/orbidderBidAdapter.js +1 -1
  137. package/dist/outbrainBidAdapter.js +1 -1
  138. package/dist/paapi.js +1 -1
  139. package/dist/permutiveRtdProvider.js +1 -1
  140. package/dist/pixfutureBidAdapter.js +1 -1
  141. package/dist/playdigoBidAdapter.js +1 -1
  142. package/dist/prebidServerBidAdapter.js +1 -1
  143. package/dist/programmaticaBidAdapter.js +1 -1
  144. package/dist/publinkIdSystem.js +1 -1
  145. package/dist/publirBidAdapter.js +1 -1
  146. package/dist/pubmaticAnalyticsAdapter.js +1 -1
  147. package/dist/pubmaticBidAdapter.js +1 -1
  148. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  149. package/dist/pubxaiAnalyticsAdapter.js +1 -1
  150. package/dist/pxyzBidAdapter.js +1 -1
  151. package/dist/quantcastBidAdapter.js +1 -1
  152. package/dist/readpeakBidAdapter.js +1 -1
  153. package/dist/relaidoBidAdapter.js +1 -1
  154. package/dist/relevatehealthBidAdapter.js +1 -1
  155. package/dist/retailspotBidAdapter.js +1 -1
  156. package/dist/rhythmoneBidAdapter.js +1 -1
  157. package/dist/ringieraxelspringerBidAdapter.js +1 -1
  158. package/dist/riseBidAdapter.js +1 -1
  159. package/dist/rubiconBidAdapter.js +1 -1
  160. package/dist/schainSerializer.js +1 -0
  161. package/dist/seedingAllianceBidAdapter.js +1 -1
  162. package/dist/seedtagBidAdapter.js +1 -1
  163. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  164. package/dist/sharethroughBidAdapter.js +1 -1
  165. package/dist/shinezBidAdapter.js +1 -1
  166. package/dist/sizeMapping.js +1 -1
  167. package/dist/sizeUtils.js +1 -1
  168. package/dist/smaatoBidAdapter.js +1 -1
  169. package/dist/smartadserverBidAdapter.js +1 -1
  170. package/dist/smartxBidAdapter.js +1 -1
  171. package/dist/smilewantedBidAdapter.js +1 -1
  172. package/dist/snigelBidAdapter.js +1 -1
  173. package/dist/sonobiBidAdapter.js +1 -1
  174. package/dist/sovrnBidAdapter.js +1 -1
  175. package/dist/sspBCBidAdapter.js +1 -1
  176. package/dist/stnBidAdapter.js +1 -1
  177. package/dist/stvBidAdapter.js +1 -1
  178. package/dist/sublimeBidAdapter.js +1 -1
  179. package/dist/symitriDapRtdProvider.js +1 -0
  180. package/dist/taboolaBidAdapter.js +1 -1
  181. package/dist/tappxBidAdapter.js +1 -1
  182. package/dist/targetVideoBidAdapter.js +1 -1
  183. package/dist/targetVideoUtils.js +1 -0
  184. package/dist/teadsBidAdapter.js +1 -1
  185. package/dist/terceptAnalyticsAdapter.js +1 -1
  186. package/dist/themoneytizerBidAdapter.js +1 -1
  187. package/dist/trionBidAdapter.js +1 -1
  188. package/dist/tripleliftBidAdapter.js +1 -1
  189. package/dist/ttdBidAdapter.js +1 -1
  190. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  191. package/dist/uid2IdSystem.js +1 -1
  192. package/dist/underdogmediaBidAdapter.js +1 -1
  193. package/dist/undertoneBidAdapter.js +1 -1
  194. package/dist/unrulyBidAdapter.js +1 -1
  195. package/dist/userAgentUtils.js +1 -0
  196. package/dist/utiqIdSystem.js +1 -1
  197. package/dist/vidazooUtils.js +1 -1
  198. package/dist/videobyteBidAdapter.js +1 -1
  199. package/dist/visxBidAdapter.js +1 -1
  200. package/dist/vuukleBidAdapter.js +1 -1
  201. package/dist/widespaceBidAdapter.js +1 -1
  202. package/dist/winrBidAdapter.js +1 -1
  203. package/dist/yahooAdsBidAdapter.js +1 -1
  204. package/dist/yandexIdSystem.js +1 -1
  205. package/dist/yieldmoBidAdapter.js +1 -1
  206. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  207. package/integrationExamples/gpt/x-domain/creative.html +1 -1
  208. package/libraries/adkernelUtils/adkernelUtils.js +11 -0
  209. package/libraries/currencyUtils/floor.js +23 -0
  210. package/libraries/dfpUtils/dfpUtils.js +7 -0
  211. package/libraries/fpdUtils/deviceInfo.js +58 -0
  212. package/libraries/fpdUtils/pageInfo.js +73 -0
  213. package/libraries/gptUtils/gptUtils.js +23 -1
  214. package/libraries/schainSerializer/schainSerializer.js +24 -0
  215. package/libraries/sizeUtils/tranformSize.js +43 -0
  216. package/libraries/targetVideoUtils/bidderUtils.js +178 -0
  217. package/libraries/targetVideoUtils/constants.js +23 -0
  218. package/libraries/userAgentUtils/index.js +58 -0
  219. package/libraries/userAgentUtils/userAgentTypes.enums.js +22 -0
  220. package/modules/.submodules.json +1 -0
  221. package/modules/33acrossAnalyticsAdapter.js +2 -0
  222. package/modules/adagioBidAdapter.js +1 -1
  223. package/modules/adagioRtdProvider.js +18 -4
  224. package/modules/adkernelAdnBidAdapter.js +1 -12
  225. package/modules/adkernelBidAdapter.js +4 -13
  226. package/modules/adlooxAnalyticsAdapter.js +1 -0
  227. package/modules/admixerBidAdapter.js +10 -6
  228. package/modules/admixerBidAdapter.md +7 -10
  229. package/modules/adtrgtmeBidAdapter.js +1 -1
  230. package/modules/advRedAnalyticsAdapter.js +198 -0
  231. package/modules/advRedAnalyticsAdapter.md +30 -0
  232. package/modules/akamaiDapRtdProvider.js +19 -798
  233. package/modules/anonymisedRtdProvider.js +5 -1
  234. package/modules/anonymisedRtdProvider.md +1 -1
  235. package/modules/apacdexBidAdapter.js +1 -1
  236. package/modules/appnexusBidAdapter.js +56 -2
  237. package/modules/automatadAnalyticsAdapter.js +2 -0
  238. package/modules/azerionedgeRtdProvider.js +13 -3
  239. package/modules/azerionedgeRtdProvider.md +0 -17
  240. package/modules/bridBidAdapter.js +47 -47
  241. package/modules/cleanioRtdProvider.js +1 -0
  242. package/modules/concertBidAdapter.js +1 -1
  243. package/modules/connatixBidAdapter.js +36 -8
  244. package/modules/connectIdSystem.js +3 -1
  245. package/modules/contxtfulRtdProvider.js +20 -2
  246. package/modules/contxtfulRtdProvider.md +1 -0
  247. package/modules/craftBidAdapter.js +1 -1
  248. package/modules/criteoBidAdapter.js +1 -1
  249. package/modules/cwireBidAdapter.js +5 -1
  250. package/modules/dailymotionBidAdapter.js +85 -65
  251. package/modules/debugging/debugging.js +3 -0
  252. package/modules/dfpAdServerVideo.js +15 -33
  253. package/modules/dfpAdpod.js +2 -6
  254. package/modules/dgkeywordRtdProvider.js +2 -0
  255. package/modules/discoveryBidAdapter.js +26 -210
  256. package/modules/dspxBidAdapter.js +176 -54
  257. package/modules/eightPodAnalyticsAdapter.js +28 -34
  258. package/modules/eightPodBidAdapter.js +113 -57
  259. package/modules/fintezaAnalyticsAdapter.js +9 -4
  260. package/modules/goldbachBidAdapter.js +1 -1
  261. package/modules/gptPreAuction.js +63 -4
  262. package/modules/growthCodeAnalyticsAdapter.js +1 -1
  263. package/modules/growthCodeRtdProvider.js +1 -1
  264. package/modules/gumgumBidAdapter.js +14 -10
  265. package/modules/improvedigitalBidAdapter.js +1 -1
  266. package/modules/intentIqAnalyticsAdapter.js +234 -0
  267. package/modules/intentIqAnalyticsAdapter.md +27 -0
  268. package/modules/intentIqIdSystem.md +0 -0
  269. package/modules/jwplayerBidAdapter.js +1 -1
  270. package/modules/jwplayerRtdProvider.js +26 -6
  271. package/modules/jwplayerVideoProvider.js +6 -0
  272. package/modules/mediafuseBidAdapter.js +1 -1
  273. package/modules/mediagoBidAdapter.js +7 -176
  274. package/modules/medianetBidAdapter.js +101 -40
  275. package/modules/mgidBidAdapter.js +3 -1
  276. package/modules/mobianRtdProvider.js +16 -2
  277. package/modules/nextMillenniumBidAdapter.js +1 -27
  278. package/modules/nobidBidAdapter.js +1 -1
  279. package/modules/optoutBidAdapter.js +1 -1
  280. package/modules/paapi.js +48 -35
  281. package/modules/permutiveRtdProvider.js +72 -22
  282. package/modules/playdigoBidAdapter.js +4 -2
  283. package/modules/prebidServerBidAdapter/index.js +4 -2
  284. package/modules/prebidServerBidAdapter/ortbConverter.js +1 -0
  285. package/modules/programmaticaBidAdapter.js +1 -1
  286. package/modules/pubmaticBidAdapter.js +12 -0
  287. package/modules/pubxaiAnalyticsAdapter.js +306 -164
  288. package/modules/relevatehealthBidAdapter.js +2 -1
  289. package/modules/richaudienceBidAdapter.js +1 -1
  290. package/modules/rtdModule/index.js +5 -3
  291. package/modules/sirdataRtdProvider.js +2 -0
  292. package/modules/sizeMapping.js +2 -5
  293. package/modules/smaatoBidAdapter.js +18 -1
  294. package/modules/smilewantedBidAdapter.js +26 -22
  295. package/modules/snigelBidAdapter.js +1 -1
  296. package/modules/sonobiBidAdapter.js +5 -10
  297. package/modules/symitriDapRtdProvider.js +812 -0
  298. package/modules/symitriDapRtdProvider.md +49 -0
  299. package/modules/targetVideoBidAdapter.js +120 -152
  300. package/modules/targetVideoBidAdapter.md +20 -3
  301. package/modules/userId/eids.js +3 -0
  302. package/modules/utiqIdSystem.js +12 -10
  303. package/modules/validationFpdModule/index.js +22 -17
  304. package/modules/videojsVideoProvider.js +3 -0
  305. package/modules/visxBidAdapter.js +1 -1
  306. package/modules/winrBidAdapter.js +2 -27
  307. package/modules/yahooAdsBidAdapter.js +1 -1
  308. package/modules/yandexIdSystem.js +1 -1
  309. package/package.json +4 -4
  310. package/plugins/eslint/index.js +73 -45
  311. package/src/adRendering.js +7 -3
  312. package/src/adloader.js +1 -0
  313. package/src/ajax.js +15 -0
  314. package/src/config.js +0 -4
  315. package/src/debugging.js +1 -0
  316. package/src/secureCreatives.js +1 -1
  317. package/src/storageManager.js +62 -73
  318. package/src/targeting.js +26 -20
  319. package/src/utils.js +9 -0
  320. package/test/pages/banner_sync.html +97 -0
  321. package/test/pages/consent_mgt_gdpr.html +1 -1
  322. package/test/spec/ajax_spec.js +11 -0
  323. package/test/spec/creative/crossDomainCreative_spec.js +26 -9
  324. package/test/spec/e2e/banner/basic_banner_ad.spec.js +20 -14
  325. package/test/spec/fpd/gdpr_spec.js +1 -1
  326. package/test/spec/libraries/userAgentUtils_spec.js +109 -0
  327. package/test/spec/modules/adagioRtdProvider_spec.js +72 -0
  328. package/test/spec/modules/admixerBidAdapter_spec.js +21 -17
  329. package/test/spec/modules/advRedAnalyticsAdapter_spec.js +114 -0
  330. package/test/spec/modules/adxcgBidAdapter_spec.js +1 -1
  331. package/test/spec/modules/appnexusBidAdapter_spec.js +36 -0
  332. package/test/spec/modules/azerionedgeRtdProvider_spec.js +36 -21
  333. package/test/spec/modules/connatixBidAdapter_spec.js +55 -2
  334. package/test/spec/modules/consentManagement_spec.js +1 -1
  335. package/test/spec/modules/contxtfulRtdProvider_spec.js +6 -0
  336. package/test/spec/modules/dailymotionBidAdapter_spec.js +497 -4
  337. package/test/spec/modules/discoveryBidAdapter_spec.js +9 -6
  338. package/test/spec/modules/dspxBidAdapter_spec.js +188 -7
  339. package/test/spec/modules/eightPodAnalyticsAdapter_spec.js +22 -13
  340. package/test/spec/modules/gptPreAuction_spec.js +143 -1
  341. package/test/spec/modules/gumgumBidAdapter_spec.js +17 -0
  342. package/test/spec/modules/intentIqAnalyticsAdapter_spec.js +172 -0
  343. package/test/spec/modules/jwplayerRtdProvider_spec.js +61 -0
  344. package/test/spec/modules/mediagoBidAdapter_spec.js +34 -37
  345. package/test/spec/modules/medianetBidAdapter_spec.js +297 -16
  346. package/test/spec/modules/mgidBidAdapter_spec.js +15 -5
  347. package/test/spec/modules/mobianRtdProvider_spec.js +1 -3
  348. package/test/spec/modules/paapi_spec.js +177 -111
  349. package/test/spec/modules/permutiveRtdProvider_spec.js +42 -8
  350. package/test/spec/modules/prebidServerBidAdapter_spec.js +17 -3
  351. package/test/spec/modules/proxistoreBidAdapter_spec.js +1 -1
  352. package/test/spec/modules/pubmaticBidAdapter_spec.js +40 -0
  353. package/test/spec/modules/pubxaiAnalyticsAdapter_spec.js +970 -603
  354. package/test/spec/modules/pulsepointBidAdapter_spec.js +4 -4
  355. package/test/spec/modules/smaatoBidAdapter_spec.js +36 -1
  356. package/test/spec/modules/smilewantedBidAdapter_spec.js +57 -1
  357. package/test/spec/modules/symitriDapRtdProvider_spec.js +600 -0
  358. package/test/spec/modules/targetVideoBidAdapter_spec.js +112 -11
  359. package/test/spec/modules/yandexIdSystem_spec.js +6 -1
  360. package/test/spec/schainSerializer/schainSerializer_spec.js +138 -0
  361. package/test/spec/unit/core/storageManager_spec.js +68 -51
  362. package/test/spec/utils_spec.js +19 -0
  363. /package/src/utils/{gpdr.js → gdpr.js} +0 -0
@@ -0,0 +1,812 @@
1
+ /**
2
+ * This module adds the Symitri DAP RTD provider to the real time data module
3
+ * The {@link module:modules/realTimeData} module is required
4
+ * The module will fetch real-time data from DAP
5
+ * @module modules/symitriDapRtdProvider
6
+ * @requires module:modules/realTimeData
7
+ */
8
+ import {ajax} from '../src/ajax.js';
9
+ import {getStorageManager} from '../src/storageManager.js';
10
+ import {submodule} from '../src/hook.js';
11
+ import {isPlainObject, mergeDeep, logMessage, logInfo, logError} from '../src/utils.js';
12
+ import { loadExternalScript } from '../src/adloader.js';
13
+ import {MODULE_TYPE_RTD} from '../src/activities/modules.js';
14
+
15
+ /**
16
+ * @typedef {import('../modules/rtdModule/index.js').RtdSubmodule} RtdSubmodule
17
+ */
18
+ export function createRtdProvider(moduleName, moduleCode, headerPrefix) {
19
+ const MODULE_NAME = 'realTimeData';
20
+ const SUBMODULE_NAME = moduleName;
21
+ const MODULE_CODE = moduleCode;
22
+
23
+ const DAP_TOKEN = 'async_dap_token';
24
+ const DAP_MEMBERSHIP = 'async_dap_membership';
25
+ const DAP_ENCRYPTED_MEMBERSHIP = 'encrypted_dap_membership';
26
+ const DAP_SS_ID = 'dap_ss_id';
27
+ const DAP_DEFAULT_TOKEN_TTL = 3600; // in seconds
28
+ const DAP_MAX_RETRY_TOKENIZE = 1;
29
+ const DAP_CLIENT_ENTROPY = 'dap_client_entropy'
30
+
31
+ const storage = getStorageManager({moduleType: MODULE_TYPE_RTD, moduleName: SUBMODULE_NAME});
32
+ let dapRetryTokenize = 0;
33
+
34
+ /**
35
+ * Lazy merge objects.
36
+ * @param {String} target
37
+ * @param {String} source
38
+ */
39
+ function mergeLazy(target, source) {
40
+ if (!isPlainObject(target)) {
41
+ target = {};
42
+ }
43
+ if (!isPlainObject(source)) {
44
+ source = {};
45
+ }
46
+ return mergeDeep(target, source);
47
+ }
48
+
49
+ /**
50
+ * Add real-time data & merge segments.
51
+ * @param {Object} ortb2 destination object to merge RTD into
52
+ * @param {Object} rtd
53
+ */
54
+ function addRealTimeData(ortb2, rtd) {
55
+ logInfo('DEBUG(addRealTimeData) - ENTER');
56
+ if (isPlainObject(rtd.ortb2)) {
57
+ logMessage('DEBUG(addRealTimeData): merging original: ', ortb2);
58
+ logMessage('DEBUG(addRealTimeData): merging in: ', rtd.ortb2);
59
+ mergeLazy(ortb2, rtd.ortb2);
60
+ }
61
+ logInfo('DEBUG(addRealTimeData) - EXIT');
62
+ }
63
+
64
+ /**
65
+ * Real-time data retrieval from Audigent
66
+ * @param {Object} bidConfig
67
+ * @param {function} onDone
68
+ * @param {Object} rtdConfig
69
+ * @param {Object} userConsent
70
+ */
71
+ function getRealTimeData(bidConfig, onDone, rtdConfig, userConsent) {
72
+ let entropyDict = JSON.parse(storage.getDataFromLocalStorage(DAP_CLIENT_ENTROPY));
73
+ let loadScriptPromise = new Promise((resolve, reject) => {
74
+ if (rtdConfig && rtdConfig.params && rtdConfig.params.dapEntropyTimeout && Number.isInteger(rtdConfig.params.dapEntropyTimeout)) {
75
+ setTimeout(reject, rtdConfig.params.dapEntropyTimeout, Error('DapEntropy script could not be loaded'));
76
+ }
77
+ if (entropyDict && entropyDict.expires_at > Math.round(Date.now() / 1000.0)) {
78
+ logMessage('Using cached entropy');
79
+ resolve();
80
+ } else {
81
+ if (typeof window.dapCalculateEntropy === 'function') {
82
+ window.dapCalculateEntropy(resolve, reject);
83
+ } else {
84
+ if (rtdConfig && rtdConfig.params && dapUtils.isValidHttpsUrl(rtdConfig.params.dapEntropyUrl)) {
85
+ loadExternalScript(rtdConfig.params.dapEntropyUrl, MODULE_CODE, () => { dapUtils.dapGetEntropy(resolve, reject) });
86
+ } else {
87
+ reject(Error('Please check if dapEntropyUrl is specified and is valid under config.params'));
88
+ }
89
+ }
90
+ }
91
+ });
92
+ loadScriptPromise
93
+ .catch((error) => {
94
+ logError('Entropy could not be calculated due to: ', error.message);
95
+ })
96
+ .finally(() => {
97
+ generateRealTimeData(bidConfig, onDone, rtdConfig, userConsent);
98
+ });
99
+ }
100
+
101
+ function generateRealTimeData(bidConfig, onDone, rtdConfig, userConsent) {
102
+ logInfo('DEBUG(generateRealTimeData) - ENTER');
103
+ logMessage(' - apiHostname: ' + rtdConfig.params.apiHostname);
104
+ logMessage(' - apiVersion: ' + rtdConfig.params.apiVersion);
105
+ dapRetryTokenize = 0;
106
+ var jsonData = null;
107
+ if (rtdConfig && isPlainObject(rtdConfig.params)) {
108
+ if (rtdConfig.params.segtax == 504) {
109
+ let encMembership = dapUtils.dapGetEncryptedMembershipFromLocalStorage();
110
+ if (encMembership) {
111
+ jsonData = dapUtils.dapGetEncryptedRtdObj(encMembership, rtdConfig.params.segtax)
112
+ }
113
+ } else {
114
+ let membership = dapUtils.dapGetMembershipFromLocalStorage();
115
+ if (membership) {
116
+ jsonData = dapUtils.dapGetRtdObj(membership, rtdConfig.params.segtax)
117
+ }
118
+ }
119
+ }
120
+ if (jsonData) {
121
+ if (jsonData.rtd) {
122
+ addRealTimeData(bidConfig.ortb2Fragments?.global, jsonData.rtd);
123
+ onDone();
124
+ logInfo('DEBUG(generateRealTimeData) - 1');
125
+ // Don't return - ensure the data is always fresh.
126
+ }
127
+ }
128
+ // Calling setTimeout to release the main thread so that the bid request could be sent.
129
+ setTimeout(dapUtils.callDapAPIs, 0, bidConfig, onDone, rtdConfig, userConsent);
130
+ }
131
+
132
+ /**
133
+ * Module init
134
+ * @param {Object} provider
135
+ * @param {Object} userConsent
136
+ * @return {boolean}
137
+ */
138
+ function init(provider, userConsent) {
139
+ if (dapUtils.checkConsent(userConsent) === false) {
140
+ return false;
141
+ }
142
+ return true;
143
+ }
144
+
145
+ /** @type {RtdSubmodule} */
146
+ const rtdSubmodule = {
147
+ name: SUBMODULE_NAME,
148
+ getBidRequestData: getRealTimeData,
149
+ init: init
150
+ };
151
+
152
+ submodule(MODULE_NAME, rtdSubmodule);
153
+ const dapUtils = {
154
+
155
+ callDapAPIs: function(bidConfig, onDone, rtdConfig, userConsent) {
156
+ if (rtdConfig && isPlainObject(rtdConfig.params)) {
157
+ let config = {
158
+ api_hostname: rtdConfig.params.apiHostname,
159
+ api_version: rtdConfig.params.apiVersion,
160
+ domain: rtdConfig.params.domain,
161
+ segtax: rtdConfig.params.segtax,
162
+ identity: {type: rtdConfig.params.identityType}
163
+ };
164
+ let refreshMembership = true;
165
+ let token = dapUtils.dapGetTokenFromLocalStorage();
166
+ const ortb2 = bidConfig.ortb2Fragments.global;
167
+ logMessage('token is: ', token);
168
+ if (token !== null) { // If token is not null then check the membership in storage and add the RTD object
169
+ if (config.segtax == 504) { // Follow the encrypted membership path
170
+ dapUtils.dapRefreshEncryptedMembership(ortb2, config, token, onDone) // Get the encrypted membership from server
171
+ refreshMembership = false;
172
+ } else {
173
+ dapUtils.dapRefreshMembership(ortb2, config, token, onDone) // Get the membership from server
174
+ refreshMembership = false;
175
+ }
176
+ }
177
+ dapUtils.dapRefreshToken(ortb2, config, refreshMembership, onDone) // Refresh Token and membership in all the cases
178
+ }
179
+ },
180
+ dapGetEntropy: function(resolve, reject) {
181
+ if (typeof window.dapCalculateEntropy === 'function') {
182
+ window.dapCalculateEntropy(resolve, reject);
183
+ } else {
184
+ reject(Error('window.dapCalculateEntropy function is not defined'))
185
+ }
186
+ },
187
+
188
+ dapGetTokenFromLocalStorage: function(ttl) {
189
+ let now = Math.round(Date.now() / 1000.0); // in seconds
190
+ let token = null;
191
+ let item = JSON.parse(storage.getDataFromLocalStorage(DAP_TOKEN));
192
+ if (item) {
193
+ if (now < item.expires_at) {
194
+ token = item.token;
195
+ }
196
+ }
197
+ return token;
198
+ },
199
+
200
+ dapRefreshToken: function(ortb2, config, refreshMembership, onDone) {
201
+ dapUtils.dapLog('Token missing or expired, fetching a new one...');
202
+ // Trigger a refresh
203
+ let now = Math.round(Date.now() / 1000.0); // in seconds
204
+ let item = {}
205
+ let configAsync = {...config};
206
+ dapUtils.dapTokenize(configAsync, config.identity, onDone,
207
+ function(token, status, xhr, onDone) {
208
+ item.expires_at = now + DAP_DEFAULT_TOKEN_TTL;
209
+ let exp = dapUtils.dapExtractExpiryFromToken(token);
210
+ if (typeof exp == 'number') {
211
+ item.expires_at = exp - 10;
212
+ }
213
+ item.token = token;
214
+ storage.setDataInLocalStorage(DAP_TOKEN, JSON.stringify(item));
215
+ dapUtils.dapLog('Successfully updated and stored token; expires at ' + item.expires_at);
216
+ let dapSSID = xhr.getResponseHeader(headerPrefix + '-DAP-SS-ID');
217
+ if (dapSSID) {
218
+ storage.setDataInLocalStorage(DAP_SS_ID, JSON.stringify(dapSSID));
219
+ }
220
+ let deviceId100 = xhr.getResponseHeader(headerPrefix + '-DAP-100');
221
+ if (deviceId100 != null) {
222
+ storage.setDataInLocalStorage('dap_deviceId100', deviceId100);
223
+ dapUtils.dapLog('Successfully stored DAP 100 Device ID: ' + deviceId100);
224
+ }
225
+ if (refreshMembership) {
226
+ if (config.segtax == 504) {
227
+ dapUtils.dapRefreshEncryptedMembership(ortb2, config, token, onDone);
228
+ } else {
229
+ dapUtils.dapRefreshMembership(ortb2, config, token, onDone);
230
+ }
231
+ }
232
+ },
233
+ function(xhr, status, error, onDone) {
234
+ logError('ERROR(' + error + '): failed to retrieve token! ' + status);
235
+ onDone()
236
+ }
237
+ );
238
+ },
239
+
240
+ dapGetMembershipFromLocalStorage: function() {
241
+ let now = Math.round(Date.now() / 1000.0); // in seconds
242
+ let membership = null;
243
+ let item = JSON.parse(storage.getDataFromLocalStorage(DAP_MEMBERSHIP));
244
+ if (item) {
245
+ if (now < item.expires_at) {
246
+ membership = {
247
+ said: item.said,
248
+ cohorts: item.cohorts,
249
+ attributes: null
250
+ };
251
+ }
252
+ }
253
+ return membership;
254
+ },
255
+
256
+ dapRefreshMembership: function(ortb2, config, token, onDone) {
257
+ let now = Math.round(Date.now() / 1000.0); // in seconds
258
+ let item = {}
259
+ let configAsync = {...config};
260
+ dapUtils.dapMembership(configAsync, token, onDone,
261
+ function(membership, status, xhr, onDone) {
262
+ item.expires_at = now + DAP_DEFAULT_TOKEN_TTL;
263
+ let exp = dapUtils.dapExtractExpiryFromToken(membership.said)
264
+ if (typeof exp == 'number') {
265
+ item.expires_at = exp - 10;
266
+ }
267
+ item.said = membership.said;
268
+ item.cohorts = membership.cohorts;
269
+ storage.setDataInLocalStorage(DAP_MEMBERSHIP, JSON.stringify(item));
270
+ dapUtils.dapLog('Successfully updated and stored membership:');
271
+ dapUtils.dapLog(item);
272
+
273
+ let data = dapUtils.dapGetRtdObj(item, config.segtax)
274
+ dapUtils.checkAndAddRealtimeData(ortb2, data, config.segtax);
275
+ onDone();
276
+ },
277
+ function(xhr, status, error, onDone) {
278
+ logError('ERROR(' + error + '): failed to retrieve membership! ' + status);
279
+ if (status == 403 && dapRetryTokenize < DAP_MAX_RETRY_TOKENIZE) {
280
+ dapRetryTokenize++;
281
+ dapUtils.dapRefreshToken(ortb2, config, true, onDone);
282
+ } else {
283
+ onDone();
284
+ }
285
+ }
286
+ );
287
+ },
288
+
289
+ dapGetEncryptedMembershipFromLocalStorage: function() {
290
+ let now = Math.round(Date.now() / 1000.0); // in seconds
291
+ let encMembership = null;
292
+ let item = JSON.parse(storage.getDataFromLocalStorage(DAP_ENCRYPTED_MEMBERSHIP));
293
+ if (item) {
294
+ if (now < item.expires_at) {
295
+ encMembership = {
296
+ encryptedSegments: item.encryptedSegments
297
+ };
298
+ }
299
+ }
300
+ return encMembership;
301
+ },
302
+
303
+ dapRefreshEncryptedMembership: function(ortb2, config, token, onDone) {
304
+ let now = Math.round(Date.now() / 1000.0); // in seconds
305
+ let item = {};
306
+ let configAsync = {...config};
307
+ dapUtils.dapEncryptedMembership(configAsync, token, onDone,
308
+ function(encToken, status, xhr, onDone) {
309
+ item.expires_at = now + DAP_DEFAULT_TOKEN_TTL;
310
+ let exp = dapUtils.dapExtractExpiryFromToken(encToken);
311
+ if (typeof exp == 'number') {
312
+ item.expires_at = exp - 10;
313
+ }
314
+ item.encryptedSegments = encToken;
315
+ storage.setDataInLocalStorage(DAP_ENCRYPTED_MEMBERSHIP, JSON.stringify(item));
316
+ dapUtils.dapLog('Successfully updated and stored encrypted membership:');
317
+ dapUtils.dapLog(item);
318
+
319
+ let encData = dapUtils.dapGetEncryptedRtdObj(item, config.segtax);
320
+ dapUtils.checkAndAddRealtimeData(ortb2, encData, config.segtax);
321
+ onDone();
322
+ },
323
+ function(xhr, status, error, onDone) {
324
+ logError('ERROR(' + error + '): failed to retrieve encrypted membership! ' + status);
325
+ if (status == 403 && dapRetryTokenize < DAP_MAX_RETRY_TOKENIZE) {
326
+ dapRetryTokenize++;
327
+ dapUtils.dapRefreshToken(ortb2, config, true, onDone);
328
+ } else {
329
+ onDone();
330
+ }
331
+ }
332
+ );
333
+ },
334
+
335
+ /**
336
+ * DESCRIPTION
337
+ * Extract expiry value from a token
338
+ */
339
+ dapExtractExpiryFromToken: function(token) {
340
+ let exp = null;
341
+ if (token) {
342
+ const tokenArray = token.split('..');
343
+ if (tokenArray && tokenArray.length > 0) {
344
+ let decode = atob(tokenArray[0])
345
+ let header = JSON.parse(decode.replace(/&quot;/g, '"'));
346
+ exp = header.exp;
347
+ }
348
+ }
349
+ return exp
350
+ },
351
+
352
+ /**
353
+ * DESCRIPTION
354
+ *
355
+ * Convert a DAP membership response to an OpenRTB2 segment object suitable
356
+ * for insertion into user.data.segment or site.data.segment and add it to the rtd obj.
357
+ */
358
+ dapGetRtdObj: function(membership, segtax) {
359
+ let segment = {
360
+ name: 'dap.symitri.com',
361
+ ext: {
362
+ 'segtax': segtax
363
+ },
364
+ segment: []
365
+ };
366
+ if (membership != null) {
367
+ for (const i of membership.cohorts) {
368
+ segment.segment.push({ id: i });
369
+ }
370
+ }
371
+ let data = {
372
+ rtd: {
373
+ ortb2: {
374
+ user: {
375
+ data: [
376
+ segment
377
+ ]
378
+ },
379
+ site: {
380
+ ext: {
381
+ data: {
382
+ dapSAID: membership.said
383
+ }
384
+ }
385
+ }
386
+ }
387
+ }
388
+ };
389
+ return data;
390
+ },
391
+
392
+ /**
393
+ * DESCRIPTION
394
+ *
395
+ * Convert a DAP membership response to an OpenRTB2 segment object suitable
396
+ * for insertion into user.data.segment or site.data.segment and add it to the rtd obj.
397
+ */
398
+ dapGetEncryptedRtdObj: function(encToken, segtax) {
399
+ let segment = {
400
+ name: 'dap.symitri.com',
401
+ ext: {
402
+ 'segtax': segtax
403
+ },
404
+ segment: []
405
+ };
406
+ if (encToken != null) {
407
+ segment.segment.push({ id: encToken.encryptedSegments });
408
+ }
409
+ let encData = {
410
+ rtd: {
411
+ ortb2: {
412
+ user: {
413
+ data: [
414
+ segment
415
+ ]
416
+ }
417
+ }
418
+ }
419
+ };
420
+ return encData;
421
+ },
422
+
423
+ checkAndAddRealtimeData: function(ortb2, data, segtax) {
424
+ if (data.rtd) {
425
+ if (segtax == 504 && dapUtils.checkIfSegmentsAlreadyExist(ortb2, data.rtd, 504)) {
426
+ logMessage('DEBUG(handleInit): rtb Object already added');
427
+ } else {
428
+ addRealTimeData(ortb2, data.rtd);
429
+ }
430
+ logInfo('DEBUG(checkAndAddRealtimeData) - 1');
431
+ }
432
+ },
433
+
434
+ checkIfSegmentsAlreadyExist: function(ortb2, rtd, segtax) {
435
+ let segmentsExist = false
436
+ if (ortb2.user && ortb2.user.data && ortb2.user.data.length > 0) {
437
+ for (let i = 0; i < ortb2.user.data.length; i++) {
438
+ let element = ortb2.user.data[i]
439
+ if (element.ext && element.ext.segtax == segtax) {
440
+ segmentsExist = true
441
+ logMessage('DEBUG(checkIfSegmentsAlreadyExist): rtb Object already added: ', ortb2.user.data);
442
+ break;
443
+ }
444
+ }
445
+ }
446
+ return segmentsExist
447
+ },
448
+
449
+ dapLog: function(args) {
450
+ let css = '';
451
+ css += 'display: inline-block;';
452
+ css += 'color: #fff;';
453
+ css += 'background: #F28B20;';
454
+ css += 'padding: 1px 4px;';
455
+ css += 'border-radius: 3px';
456
+
457
+ logInfo('%cDAP Client', css, args);
458
+ },
459
+
460
+ isValidHttpsUrl: function(urlString) {
461
+ let url;
462
+ try {
463
+ url = new URL(urlString);
464
+ } catch (_) {
465
+ return false;
466
+ }
467
+ return url.protocol === 'https:';
468
+ },
469
+
470
+ checkConsent: function(userConsent) {
471
+ let consent = true;
472
+
473
+ if (userConsent && userConsent.gdpr && userConsent.gdpr.gdprApplies) {
474
+ const gdpr = userConsent.gdpr;
475
+ const hasGdpr = (gdpr && typeof gdpr.gdprApplies === 'boolean' && gdpr.gdprApplies) ? 1 : 0;
476
+ const gdprConsentString = hasGdpr ? gdpr.consentString : '';
477
+ if (hasGdpr && (!gdprConsentString || gdprConsentString === '')) {
478
+ logError('symitriDapRtd submodule requires consent string to call API');
479
+ consent = false;
480
+ }
481
+ } else if (userConsent && userConsent.usp) {
482
+ const usp = userConsent.usp;
483
+ consent = usp[1] !== 'N' && usp[2] !== 'Y';
484
+ }
485
+
486
+ return consent;
487
+ },
488
+
489
+ /*******************************************************************************
490
+ *
491
+ * V2 (And Beyond) API
492
+ *
493
+ ******************************************************************************/
494
+
495
+ dapValidationHelper: function(config, onDone, token, onError) {
496
+ if (onError == null) {
497
+ onError = function(xhr, status, error, onDone) {};
498
+ }
499
+
500
+ if (config == null || typeof (config) == typeof (undefined)) {
501
+ onError(null, 'Invalid config object', 'ClientError', onDone);
502
+ return [ config, true ];
503
+ }
504
+
505
+ if (!('api_version' in config) || (typeof (config.api_version) == 'string' && config.api_version.length == 0)) {
506
+ config.api_version = 'x1';
507
+ }
508
+
509
+ if (typeof (config.api_version) != 'string') {
510
+ onError(null, "Invalid api_version: must be a string like 'x1', etc.", 'ClientError', onDone);
511
+ return [ config, true ];
512
+ }
513
+
514
+ if (!(('api_hostname') in config) || typeof (config.api_hostname) != 'string' || config.api_hostname.length == 0) {
515
+ onError(null, 'Invalid api_hostname: must be a non-empty string', 'ClientError', onDone);
516
+ return [ config, true ];
517
+ }
518
+
519
+ if (token) {
520
+ if (typeof (token) != 'string') {
521
+ onError(null, 'Invalid token: must be a non-null string', 'ClientError', onDone);
522
+ return [ config, true ];
523
+ }
524
+ }
525
+
526
+ return [ config, false ];
527
+ },
528
+
529
+ /**
530
+ * SYNOPSIS
531
+ *
532
+ * dapTokenize( config, identity );
533
+ *
534
+ * DESCRIPTION
535
+ *
536
+ * Tokenize an identity into a secure, privacy safe pseudonymiziation.
537
+ *
538
+ * PARAMETERS
539
+ *
540
+ * config: an array of system configuration parameters
541
+ *
542
+ * identity: an array of identity parameters passed to the tokenizing system
543
+ *
544
+ * EXAMPLE
545
+ *
546
+ * config = {
547
+ * api_hostname: "prebid.dap.akadns.net", // required
548
+ * domain: "prebid.org", // required
549
+ * api_version: "x1", // optional, default "x1"
550
+ * };
551
+ *
552
+ * token = null;
553
+ * identity_email = {
554
+ * type: "email",
555
+ * identity: "obiwan@jedi.com"
556
+ * attributes: { cohorts: [ "100:1641013200", "101:1641013200", "102":3:1641013200" ] },
557
+ * };
558
+ * dap_x1_tokenize( config, identity_email,
559
+ * function( response, status, xhr ) { token = response; },
560
+ * function( xhr, status, error ) { ; } // handle error
561
+ *
562
+ * token = null;
563
+ * identity_signature = { type: "signature:1.0.0" };
564
+ * dap_x1_tokenize( config, identity_signature,
565
+ * function( response, status, xhr } { token = response; },
566
+ * function( xhr, status, error ) { ; } // handle error
567
+ */
568
+ dapTokenize: function(config, identity, onDone, onSuccess = null, onError = null) {
569
+ let hasTokenizeError;
570
+ [ config, hasTokenizeError ] = this.dapValidationHelper(config, onDone, null, onError);
571
+ if (hasTokenizeError) { return; }
572
+
573
+ if (typeof (config.domain) != 'string') {
574
+ onError(null, 'Invalid config.domain: must be a string', 'ClientError', onDone);
575
+ return;
576
+ }
577
+
578
+ if (config.domain.length <= 0) {
579
+ onError(null, 'Invalid config.domain: must have non-zero length', 'ClientError', onDone);
580
+ return;
581
+ }
582
+
583
+ if (identity == null || typeof (identity) == typeof (undefined)) {
584
+ onError(null, 'Invalid identity object', 'ClientError', onDone);
585
+ return;
586
+ }
587
+
588
+ if (!('type' in identity) || typeof (identity.type) != 'string' || identity.type.length <= 0) {
589
+ onError(null, "Identity must contain a valid 'type' field", 'ClientError', onDone);
590
+ return;
591
+ }
592
+
593
+ let apiParams = {
594
+ 'type': identity.type,
595
+ };
596
+
597
+ if (typeof (identity.identity) != typeof (undefined)) {
598
+ apiParams.identity = identity.identity;
599
+ }
600
+ if (typeof (identity.attributes) != typeof (undefined)) {
601
+ apiParams.attributes = identity.attributes;
602
+ }
603
+
604
+ let entropyDict = JSON.parse(storage.getDataFromLocalStorage(DAP_CLIENT_ENTROPY));
605
+ if (entropyDict && entropyDict.entropy) {
606
+ apiParams.entropy = entropyDict.entropy;
607
+ }
608
+
609
+ let method;
610
+ let body;
611
+ let path;
612
+ switch (config.api_version) {
613
+ case 'x1':
614
+ case 'x1-dev':
615
+ method = 'POST';
616
+ path = '/data-activation/' + config.api_version + '/domain/' + config.domain + '/identity/tokenize';
617
+ body = JSON.stringify(apiParams);
618
+ break;
619
+ default:
620
+ onError(null, 'Invalid api_version: ' + config.api_version, 'ClientError', onDone);
621
+ return;
622
+ }
623
+
624
+ let customHeaders = {'Content-Type': 'application/json'};
625
+ let dapSSID = JSON.parse(storage.getDataFromLocalStorage(DAP_SS_ID));
626
+ if (dapSSID) {
627
+ customHeaders[headerPrefix + '-DAP-SS-ID'] = dapSSID;
628
+ }
629
+
630
+ let url = 'https://' + config.api_hostname + path;
631
+ let cb = {
632
+ success: (response, request) => {
633
+ let token = null;
634
+ switch (config.api_version) {
635
+ case 'x1':
636
+ case 'x1-dev':
637
+ token = request.getResponseHeader(headerPrefix + '-DAP-Token');
638
+ break;
639
+ }
640
+ onSuccess(token, request.status, request, onDone);
641
+ },
642
+ error: (request, error) => {
643
+ onError(request, request.statusText, error, onDone);
644
+ }
645
+ };
646
+
647
+ ajax(url, cb, body, {
648
+ method: method,
649
+ customHeaders: customHeaders
650
+ });
651
+ },
652
+
653
+ /**
654
+ * SYNOPSIS
655
+ *
656
+ * dapMembership( config, token, onSuccess, onError );
657
+ *
658
+ * DESCRIPTION
659
+ *
660
+ * Return the audience segment membership along with a new Secure Advertising
661
+ * ID for this token.
662
+ *
663
+ * PARAMETERS
664
+ *
665
+ * config: an array of system configuration parameters
666
+ *
667
+ * token: the token previously returned from the tokenize API
668
+ *
669
+ * EXAMPLE
670
+ *
671
+ * config = {
672
+ * api_hostname: 'api.dap.akadns.net',
673
+ * };
674
+ *
675
+ * // token from dap_tokenize
676
+ *
677
+ * dapMembership( config, token,
678
+ * function( membership, status, xhr ) {
679
+ * // Run auction with membership.segments and membership.said
680
+ * },
681
+ * function( xhr, status, error ) {
682
+ * // error
683
+ * } );
684
+ *
685
+ */
686
+ dapMembership: function(config, token, onDone, onSuccess = null, onError = null) {
687
+ let hasMembershipError;
688
+ [ config, hasMembershipError ] = this.dapValidationHelper(config, onDone, token, onError);
689
+ if (hasMembershipError) { return; }
690
+
691
+ if (typeof (config.domain) != 'string') {
692
+ onError(null, 'Invalid config.domain: must be a string', 'ClientError', onDone);
693
+ return;
694
+ }
695
+
696
+ let path = '/data-activation/' +
697
+ config.api_version +
698
+ '/token/' + token +
699
+ '/membership';
700
+
701
+ let url = 'https://' + config.api_hostname + path;
702
+
703
+ let cb = {
704
+ success: (response, request) => {
705
+ onSuccess(JSON.parse(response), request.status, request, onDone);
706
+ },
707
+ error: (error, request) => {
708
+ onError(request, request.status, error, onDone);
709
+ }
710
+ };
711
+
712
+ ajax(url, cb, undefined, {
713
+ method: 'GET',
714
+ customHeaders: {}
715
+ });
716
+ },
717
+
718
+ /**
719
+ * SYNOPSIS
720
+ *
721
+ * dapEncryptedMembership( config, token, onSuccess, onError );
722
+ *
723
+ * DESCRIPTION
724
+ *
725
+ * Return the audience segment membership along with a new Secure Advertising
726
+ * ID for this token in encrypted format.
727
+ *
728
+ * PARAMETERS
729
+ *
730
+ * config: an array of system configuration parameters
731
+ *
732
+ * token: the token previously returned from the tokenize API
733
+ *
734
+ * EXAMPLE
735
+ *
736
+ * config = {
737
+ * api_hostname: 'api.dap.akadns.net',
738
+ * };
739
+ *
740
+ * // token from dap_tokenize
741
+ *
742
+ * dapEncryptedMembership( config, token,
743
+ * function( membership, status, xhr ) {
744
+ * // Run auction with membership.segments and membership.said after decryption
745
+ * },
746
+ * function( xhr, status, error ) {
747
+ * // error
748
+ * } );
749
+ *
750
+ */
751
+ dapEncryptedMembership: function(config, token, onDone, onSuccess = null, onError = null) {
752
+ let hasEncryptedMembershipError;
753
+ [ config, hasEncryptedMembershipError ] = this.dapValidationHelper(config, onDone, token, onError);
754
+ if (hasEncryptedMembershipError) { return; }
755
+
756
+ let cb = {
757
+ success: (response, request) => {
758
+ let encToken = request.getResponseHeader(headerPrefix + '-DAP-Token');
759
+ onSuccess(encToken, request.status, request, onDone);
760
+ },
761
+ error: (error, request) => { onError(request, request.status, error, onDone); }
762
+ };
763
+
764
+ let path = '/data-activation/' +
765
+ config.api_version +
766
+ '/token/' + token +
767
+ '/membership/encrypt';
768
+
769
+ let url = 'https://' + config.api_hostname + path;
770
+
771
+ ajax(url, cb, undefined, {
772
+ method: 'GET',
773
+ customHeaders: {
774
+ 'Content-Type': 'application/json',
775
+ 'Pragma': 'akamai-x-get-extracted-values'
776
+ }
777
+ });
778
+ }
779
+ }
780
+
781
+ return {
782
+ addRealTimeData,
783
+ getRealTimeData,
784
+ generateRealTimeData,
785
+ rtdSubmodule,
786
+ storage,
787
+ dapUtils,
788
+ DAP_TOKEN,
789
+ DAP_MEMBERSHIP,
790
+ DAP_ENCRYPTED_MEMBERSHIP,
791
+ DAP_SS_ID,
792
+ DAP_DEFAULT_TOKEN_TTL,
793
+ DAP_MAX_RETRY_TOKENIZE,
794
+ DAP_CLIENT_ENTROPY
795
+ };
796
+ }
797
+
798
+ export const {
799
+ addRealTimeData,
800
+ getRealTimeData,
801
+ generateRealTimeData,
802
+ rtdSubmodule: symitriDapRtdSubmodule,
803
+ storage,
804
+ dapUtils,
805
+ DAP_TOKEN,
806
+ DAP_MEMBERSHIP,
807
+ DAP_ENCRYPTED_MEMBERSHIP,
808
+ DAP_SS_ID,
809
+ DAP_DEFAULT_TOKEN_TTL,
810
+ DAP_MAX_RETRY_TOKENIZE,
811
+ DAP_CLIENT_ENTROPY
812
+ } = createRtdProvider('symitriDap', 'symitridap', 'Symitri');