-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Conversant: add new Publink user id module
- Loading branch information
Showing
4 changed files
with
259 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/** | ||
* This module adds the PublinkId to the User ID module | ||
* The {@link module:modules/userId} module is required | ||
* @module modules/conversantIdSystem | ||
* @requires module:modules/userId | ||
*/ | ||
|
||
import {submodule} from '../src/hook.js'; | ||
import {getStorageManager} from '../src/storageManager.js'; | ||
import {ajax} from '../src/ajax.js'; | ||
import * as utils from '../src/utils.js'; | ||
import {uspDataHandler} from '../src/adapterManager.js'; | ||
|
||
const MODULE_NAME = 'publink'; | ||
const GVLID = 24; | ||
|
||
export const storage = getStorageManager(GVLID); | ||
|
||
function publinkIdUrl(params, consentData) { | ||
let url = utils.parseUrl('https://proc.ad.cpe.dotomi.com/cvx/client/sync/publink'); | ||
url.search = { | ||
deh: params.e, | ||
mpn: 'Prebid.js', | ||
mpv: '$prebid.version$', | ||
}; | ||
if (consentData) { | ||
url.search.gdpr = (consentData.gdprApplies) ? 1 : 0; | ||
url.search.gdpr_consent = consentData.consentString; | ||
} | ||
|
||
const usPrivacyString = uspDataHandler.getConsentData(); | ||
if (usPrivacyString && typeof usPrivacyString === 'string') { | ||
url.search.us_privacy = usPrivacyString; | ||
} | ||
|
||
return utils.buildUrl(url); | ||
} | ||
|
||
function makeCallback(config = {}, consentData) { | ||
return function(prebidCallback) { | ||
const options = {method: 'GET', withCredentials: true}; | ||
let handleResponse = function(responseText, xhr) { | ||
if (xhr.status === 200) { | ||
let response = JSON.parse(responseText); | ||
if (response) { | ||
prebidCallback(response.publink); | ||
} | ||
} | ||
}; | ||
if (window.coreid && typeof window.coreid.getPublinkId === 'function') { | ||
window.coreid.getPublinkId((newId) => { | ||
if (newId) { | ||
prebidCallback(newId); | ||
} else { | ||
if (config.params && config.params.e) { | ||
ajax(publinkIdUrl(config.params, consentData), handleResponse, undefined, options); | ||
} | ||
} | ||
}); | ||
} else { | ||
if (config.params && config.params.e) { | ||
ajax(publinkIdUrl(config.params, consentData), handleResponse, undefined, options); | ||
} | ||
} | ||
}; | ||
} | ||
|
||
/** @type {Submodule} */ | ||
export const publinkIdSubmodule = { | ||
/** | ||
* used to link submodule with config | ||
* @type {string} | ||
*/ | ||
name: MODULE_NAME, | ||
gvlid: GVLID, | ||
|
||
/** | ||
* decode the stored id value for passing to bid requests | ||
* @function | ||
* @param {string} id encrypted userid | ||
* @returns {{publinkId: string} | undefined} | ||
*/ | ||
decode(publinkId) { | ||
return {publink: publinkId}; | ||
}, | ||
|
||
/** | ||
* performs action to obtain id | ||
* @function | ||
* @param {SubmoduleConfig} [config] Config object with params and storage properties | ||
* @returns {IdResponse} | ||
*/ | ||
getId: function(config, consentData, storedId) { | ||
let result = {}; | ||
if (storedId) { | ||
result.id = storedId; | ||
} | ||
result.callback = makeCallback(config, consentData); | ||
return result; | ||
} | ||
}; | ||
submodule('userId', publinkIdSubmodule); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
## Publink User ID Submodule | ||
|
||
Publink user id module | ||
|
||
## Configuration Descriptions for the `userId` Configuration Section | ||
|
||
| Param Name | Required | Type | Description | Example | | ||
| --- | --- | --- | --- | --- | | ||
| name | Yes | String | module identifier | `"publinkId"` | | ||
| params.e | Yes | String | hashed email address | `"e80b5017098950fc58aad83c8c14978e"` | | ||
|
||
### Example configuration for Publink | ||
``` | ||
pbjs.setConfig({ | ||
userSync: { | ||
userIds: [{ | ||
name: "publinkId", | ||
storage: { | ||
name: "pbjs_publink", | ||
type: "html5" | ||
}, | ||
params: { | ||
e: "e80b5017098950fc58aad83c8c14978e", // example hashed email (md5) | ||
} | ||
}], | ||
} | ||
}); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
import {publinkIdSubmodule} from 'modules/publinkIdSystem.js'; | ||
import {getStorageManager} from '../../../src/storageManager'; | ||
import {server} from 'test/mocks/xhr.js'; | ||
import sinon from 'sinon'; | ||
import {uspDataHandler} from '../../../src/adapterManager'; | ||
|
||
export const storage = getStorageManager(24); | ||
const TEST_COOKIE_VALUE = 'cookievalue'; | ||
describe('PublinkIdSystem', () => { | ||
describe('decode', () => { | ||
it('decode', () => { | ||
const result = publinkIdSubmodule.decode(TEST_COOKIE_VALUE); | ||
expect(result).deep.equals({publink: TEST_COOKIE_VALUE}); | ||
}); | ||
}); | ||
|
||
describe('getId', () => { | ||
const serverResponse = {publink: 'ec0xHT3yfAOnykP64Qf0ORSi7LjNT1wju04ZSCsoPBekOJdBwK-0Zl_lXKDNnzhauC4iszBc-PvA1Be6IMlh1QocA'}; | ||
it('no config', () => { | ||
const result = publinkIdSubmodule.getId(); | ||
expect(result).to.exist; | ||
expect(result.callback).to.be.a('function'); | ||
}); | ||
it('Use local id', () => { | ||
const result = publinkIdSubmodule.getId({}, undefined, TEST_COOKIE_VALUE); | ||
expect(result).to.exist; | ||
expect(result.id).to.equal(TEST_COOKIE_VALUE); | ||
expect(result.callback).to.be.a('function'); | ||
}); | ||
|
||
describe('callout for id', () => { | ||
let callbackSpy = sinon.spy(); | ||
|
||
beforeEach(() => { | ||
callbackSpy.resetHistory(); | ||
}); | ||
|
||
it('Fetch with consent data', () => { | ||
const config = {storage: {type: 'cookie'}, params: {e: 'hashedemailvalue'}}; | ||
const consentData = {gdprApplies: 1, consentString: 'myconsentstring'}; | ||
let submoduleCallback = publinkIdSubmodule.getId(config, consentData).callback; | ||
submoduleCallback(callbackSpy); | ||
|
||
let request = server.requests[0]; | ||
expect(request.url).to.equal('https://proc.ad.cpe.dotomi.com/cvx/client/sync/publink?deh=hashedemailvalue&mpn=Prebid.js&mpv=$prebid.version$&gdpr=1&gdpr_consent=myconsentstring'); | ||
|
||
request.respond(200, {}, JSON.stringify(serverResponse)); | ||
expect(callbackSpy.calledOnce).to.be.true; | ||
expect(callbackSpy.lastCall.lastArg).to.equal(serverResponse.publink); | ||
}); | ||
|
||
it('server doesnt respond', () => { | ||
const config = {storage: {type: 'cookie'}, params: {e: 'hashedemailvalue'}}; | ||
let submoduleCallback = publinkIdSubmodule.getId(config).callback; | ||
submoduleCallback(callbackSpy); | ||
|
||
let request = server.requests[0]; | ||
expect(request.url).to.equal('https://proc.ad.cpe.dotomi.com/cvx/client/sync/publink?deh=hashedemailvalue&mpn=Prebid.js&mpv=$prebid.version$'); | ||
|
||
request.respond(204, {}, JSON.stringify(serverResponse)); | ||
expect(callbackSpy.calledOnce).to.be.false; | ||
}); | ||
}); | ||
|
||
describe('usPrivacy', () => { | ||
let callbackSpy = sinon.spy(); | ||
const oldPrivacy = uspDataHandler.getConsentData(); | ||
before(() => { | ||
uspDataHandler.setConsentData('1YNN'); | ||
}); | ||
after(() => { | ||
uspDataHandler.setConsentData(oldPrivacy); | ||
callbackSpy.resetHistory(); | ||
}); | ||
|
||
it('Fetch with usprivacy data', () => { | ||
const config = {storage: {type: 'cookie'}, params: {e: 'hashedemailvalue'}}; | ||
let submoduleCallback = publinkIdSubmodule.getId(config).callback; | ||
submoduleCallback(callbackSpy); | ||
|
||
let request = server.requests[0]; | ||
expect(request.url).to.equal('https://proc.ad.cpe.dotomi.com/cvx/client/sync/publink?deh=hashedemailvalue&mpn=Prebid.js&mpv=$prebid.version$&us_privacy=1YNN'); | ||
|
||
request.respond(200, {}, JSON.stringify(serverResponse)); | ||
expect(callbackSpy.calledOnce).to.be.true; | ||
expect(callbackSpy.lastCall.lastArg).to.equal(serverResponse.publink); | ||
}); | ||
}); | ||
describe('fetch from coreid', () => { | ||
let callbackSpy = sinon.spy(); | ||
afterEach(() => { | ||
callbackSpy.resetHistory(); | ||
delete window.coreid; | ||
}); | ||
it('get id', () => { | ||
window.coreid = {}; | ||
window.coreid.getPublinkId = (cb) => { cb(TEST_COOKIE_VALUE) }; | ||
const submoduleCallback = publinkIdSubmodule.getId({}).callback; | ||
submoduleCallback(callbackSpy); | ||
expect(callbackSpy.calledOnce).to.be.true; | ||
expect(callbackSpy.lastCall.lastArg).to.equal(TEST_COOKIE_VALUE); | ||
}); | ||
it('coreid fails', () => { | ||
window.coreid = {}; | ||
window.coreid.getPublinkId = (cb) => { cb() }; | ||
const submoduleCallback = publinkIdSubmodule.getId({params: {e: 'hashedemailvalue'}}).callback; | ||
submoduleCallback(callbackSpy); | ||
let request = server.requests[0]; | ||
expect(request.url).to.equal('https://proc.ad.cpe.dotomi.com/cvx/client/sync/publink?deh=hashedemailvalue&mpn=Prebid.js&mpv=$prebid.version$'); | ||
request.respond(200, {}, JSON.stringify(serverResponse)); | ||
expect(callbackSpy.calledOnce).to.be.true; | ||
expect(callbackSpy.lastCall.lastArg).to.equal(serverResponse.publink); | ||
}); | ||
it('no hashed email param', () => { | ||
window.coreid = {}; | ||
window.coreid.getPublinkId = (cb) => { cb() }; | ||
const submoduleCallback = publinkIdSubmodule.getId({params: {}}).callback; | ||
submoduleCallback(callbackSpy); | ||
let request = server.requests[0]; | ||
expect(request).to.be.undefined; | ||
expect(callbackSpy.calledOnce).to.be.false; | ||
}); | ||
}); | ||
}); | ||
}); |