From 43c726a02a52cf29c8cfeb0270c889e19645bbc2 Mon Sep 17 00:00:00 2001 From: pm-azhar-mulla Date: Mon, 19 Aug 2024 16:50:15 +0530 Subject: [PATCH 1/2] Initial code for injecting tracker for IMA --- modules/pubmaticAnalyticsAdapter.js | 48 +++++++++++++++++++++++++---- src/videoCache.js | 5 +-- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/modules/pubmaticAnalyticsAdapter.js b/modules/pubmaticAnalyticsAdapter.js index 9bcbdfab0e1..3b1c1b1caf9 100755 --- a/modules/pubmaticAnalyticsAdapter.js +++ b/modules/pubmaticAnalyticsAdapter.js @@ -606,7 +606,7 @@ function executeBidsLoggerCall(e, highestCpmBids) { ); } -function executeBidWonLoggerCall(auctionId, adUnitId) { +function executeBidWonLoggerCall(auctionId, adUnitId, isIma) { const winningBidId = cache.auctions[auctionId].adUnitCodes[adUnitId].bidWon; const winningBids = cache.auctions[auctionId].adUnitCodes[adUnitId].bids[winningBidId]; if (!winningBids) { @@ -653,7 +653,7 @@ function executeBidWonLoggerCall(auctionId, adUnitId) { pixelURL += '&rf=' + enc(origAdUnit?.pubmaticAutoRefresh?.isRefreshed ? 1 : 0); pixelURL += '&origbidid=' + enc(winningBid?.bidResponse?.partnerImpId || winningBid?.bidResponse?.prebidBidId || winningBid.bidId); pixelURL += '&di=' + enc(winningBid?.bidResponse?.dealId || OPEN_AUCTION_DEAL_ID); - pixelURL += '&pb=' + enc(pg); + pg && (pixelURL += '&pb=' + enc(pg)); pixelURL += '&plt=' + enc(getDevicePlatform()); pixelURL += '&psz=' + enc((winningBid?.bidResponse?.dimensions?.width || '0') + 'x' + @@ -666,6 +666,10 @@ function executeBidWonLoggerCall(auctionId, adUnitId) { pixelURL += '&af=' + enc(winningBid.bidResponse ? (winningBid.bidResponse.mediaType || undefined) : undefined); pixelURL += '&cds=' + getCDSDataLoggerStr(); // encoded string is returned from function + if (isIma) { + return pixelURL; + } + ajax( pixelURL, null, @@ -791,12 +795,44 @@ function bidderDoneHandler(args) { } function bidWonHandler(args) { - let auctionCache = cache.auctions[args.auctionId]; - auctionCache.adUnitCodes[args.adUnitCode].bidWon = args.originalRequestId || args.requestId; - auctionCache.adUnitCodes[args.adUnitCode].bidWonAdId = args.adId; - executeBidWonLoggerCall(args.auctionId, args.adUnitCode); + generateBidWonLogger(args, false); +} + +function generateBidWonLogger(bid, isIma) { + var auctionCache = cache.auctions[bid.auctionId]; + auctionCache.adUnitCodes[bid.adUnitCode].bidWon = bid.requestId; + auctionCache.adUnitCodes[bid.adUnitCode].bidWonAdId = bid.adId; + return executeBidWonLoggerCall(bid.auctionId, bid.adUnitCode, isIma); } +getGlobal().injectTrackerForIMA = function (args, vast) { + var bid = cache.auctions[args.auctionId].adUnitCodes[args.adUnitCode].bids[args.requestId][0]; + if (!bid) { + logError(LOG_PRE_FIX + 'Could not find associated bid request for bid response with requestId: ', args.requestId); + return; + } + bid.adId = args.adId; + bid.auctionId = args.auctionId; + bid.adUnitCode = args.adUnitCode; + bid.requestId = args.requestId; + bid.bidResponse = parseBidResponse(args); + try { + var domParser = new DOMParser(); + var parsedVast = domParser.parseFromString(vast, 'application/xml'); + var impEle = parsedVast.createElement('Impression'); + impEle.innerHTML = ''; + if (parsedVast.getElementsByTagName('Wrapper').length == 1) { + parsedVast.getElementsByTagName('Wrapper')[0].appendChild(impEle); + } else if (parsedVast.getElementsByTagName('InLine').length == 1) { + parsedVast.getElementsByTagName('InLine')[0].appendChild(impEle); + } + return new XMLSerializer().serializeToString(parsedVast); + } catch (ex) { + logError(LOG_PRE_FIX + ' Exception in injecting tracker for IMA ', ex); + return vast; + } +}; + function auctionEndHandler(args) { // if for the given auction bidderDonePendingCount == 0 then execute logger call sooners let highestCpmBids = getGlobal().getHighestCpmBids() || []; diff --git a/src/videoCache.js b/src/videoCache.js index 6bb0dae1be9..fb2fff21ffa 100644 --- a/src/videoCache.js +++ b/src/videoCache.js @@ -14,6 +14,7 @@ import {config} from './config.js'; import {auctionManager} from './auctionManager.js'; import {logError, logWarn} from './utils.js'; import {addBidToAuction} from './auction.js'; +import {getGlobal} from '../src/prebidGlobal.js'; /** * Might be useful to be configurable in the future @@ -75,8 +76,8 @@ function toStorageRequest(bid, {index = auctionManager.index} = {}) { let vastValue = bid.vastXml ? bid.vastXml : wrapURI(bid.vastUrl, bid.vastImpUrl); const auction = index.getAuction(bid); /* istanbul ignore next */ - if (window && window.PWT) { - vastValue = window.PWT.UpdateVastWithTracker(bid, vastValue); + if (window && window.ima) { + vastValue = getGlobal().injectTrackerForIMA(bid, vastValue); } const ttlWithBuffer = Number(bid.ttl) + ttlBufferInSeconds; let payload = { From d3a0ce3e765e65c894fcd35e3e202daf1622cc49 Mon Sep 17 00:00:00 2001 From: Nitin Nimbalkar <96475150+pm-nitin-nimbalkar@users.noreply.github.com> Date: Tue, 15 Oct 2024 19:14:43 +0530 Subject: [PATCH 2/2] Fix/uid2 id5 issue (#953) * IDNT-928: Email hash support in uid2 * UID2 email hash issue * UID-SHA256 handling of both HEX and BASE64 output encoding * UID2: Warning message added instead of throwing Error * Merged conflicts * UID2: Warning message changed --- modules/userId/index.js | 34 +++++++++++++++++++++++++++++++++- src/constants.js | 11 +++++++++-- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/modules/userId/index.js b/modules/userId/index.js index 2cc454dbb22..7b32e940c04 100644 --- a/modules/userId/index.js +++ b/modules/userId/index.js @@ -842,6 +842,26 @@ export function getRawPDString(emailHashes, userID) { return btoa(pdString); }; +function hexToBytes(hex) { + return Uint8Array.from( + hex.match(/.{1,2}/g).map(byte => parseInt(byte, 16)) + ); +} + +// Module to convert byte array to Base64 +function bytesToBase64(bytes) { + const binaryString = String.fromCharCode(...bytes); + return btoa(binaryString); +} + +export function getHexToBase64(hex) { + if (!hex || typeof hex !== 'string' || hex.trim() === '') { + logWarn(`Invalid hex input: hex string is undefined, null, or empty. This message applies only to UID2 client-side integration.`); + return undefined; + } + return bytesToBase64(hexToBytes(hex)); // Convert byte array to Base64 +} + export function updateModuleParams(moduleToUpdate) { let params = MODULE_PARAM_TO_UPDATE_FOR_SSO[moduleToUpdate.name]; if (!params) return; @@ -850,7 +870,19 @@ export function updateModuleParams(moduleToUpdate) { let enableSSO = (window.IHPWT && window.IHPWT.ssoEnabled) || (window.PWT && window.PWT.ssoEnabled) || false; let emailHashes = enableSSO && userIdentity.emailHash ? userIdentity.emailHash : userIdentity.pubProvidedEmailHash ? userIdentity.pubProvidedEmailHash : undefined; params.forEach(function(param) { - moduleToUpdate.params[param.key] = (moduleToUpdate.name === 'id5Id' ? getRawPDString(emailHashes, userIdentity.userID) : emailHashes ? emailHashes[param.hashType] : undefined); + switch (moduleToUpdate.name) { + case 'id5Id': + moduleToUpdate.params[param.key] = getRawPDString(emailHashes, userIdentity.userID); + break; + case 'uid2': + moduleToUpdate.params[param.key] = emailHashes && emailHashes[param.hashType] + ? emailHashes[param.hashType] + : getHexToBase64(emailHashes?.SHA256); + break; + default: + moduleToUpdate.params[param.key] = emailHashes ? emailHashes[param.hashType] : undefined; + break; + } }); } diff --git a/src/constants.js b/src/constants.js index 1e30fe157e2..122217f9305 100644 --- a/src/constants.js +++ b/src/constants.js @@ -120,7 +120,8 @@ export const REFRESH_IDMODULES_LIST = { 'id5Id', 'publinkId', 'connectId', - 'liveIntentId' + 'liveIntentId', + 'uid2' ], SCRIPT_BASED_MODULES: [ 'zeotapIdPlus', @@ -150,7 +151,13 @@ export const MODULE_PARAM_TO_UPDATE_FOR_SSO = { liveIntentId: [ { key: 'emailHash', - hashType: 'SHA256' + hashType: 'SHA256' // Default Hex encoding + } + ], + uid2: [ + { + key: 'emailHash', + hashType: 'SHA256_BASE64' // SHA256 Base64 encoding } ] };