Skip to content

Commit

Permalink
Yandex Id System: refactoring (#12219)
Browse files Browse the repository at this point in the history
  • Loading branch information
someden authored Sep 22, 2024
1 parent 8b1d121 commit 3bbf614
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 31 deletions.
6 changes: 3 additions & 3 deletions modules/userId/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
* It's permissible to return neither, one, or both fields.
* @callback getId
* @param {SubmoduleConfig} config
* @param {ConsentData|undefined} consentData
* @param {Object|undefined} cacheIdObj
* @param {ConsentData|undefined} [consentData]
* @param {Object|undefined} [cacheIdObj]
* @returns {IdResponse|undefined} A response object that contains id and/or callback.
*/

Expand All @@ -43,7 +43,7 @@
* Decode a stored value for passing to bid requests
* @callback decode
* @param {Object|string} value
* @param {SubmoduleConfig|undefined} config
* @param {SubmoduleConfig|undefined} [config]
* @returns {Object|undefined}
*/

Expand Down
8 changes: 6 additions & 2 deletions modules/yandexBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { registerBidder } from '../src/adapters/bidderFactory.js';
import { config } from '../src/config.js';
import { BANNER, NATIVE } from '../src/mediaTypes.js';
import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
import { _each, _map, deepAccess, deepSetValue, formatQS, triggerPixel } from '../src/utils.js';
import { _each, _map, deepAccess, deepSetValue, formatQS, triggerPixel, logInfo } from '../src/utils.js';

/**
* @typedef {import('../src/adapters/bidderFactory.js').Bid} Bid
Expand Down Expand Up @@ -181,7 +181,7 @@ export const spec = {
}

const queryParamsString = formatQS(queryParams);
return {
const request = {
method: 'POST',
url: BIDDER_URL + `/${pageId}?${queryParamsString}`,
data,
Expand All @@ -190,6 +190,10 @@ export const spec = {
},
bidRequest,
};

logInfo('ServerRequest', request);

return request;
});
},

Expand Down
60 changes: 37 additions & 23 deletions modules/yandexIdSystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

import { MODULE_TYPE_UID } from '../src/activities/modules.js';
import { submodule } from '../src/hook.js';
import { getStorageManager } from '../src/storageManager.js';
import { getStorageManager, STORAGE_TYPE_COOKIES } from '../src/storageManager.js';
import { logError, logInfo } from '../src/utils.js';

// .com suffix is just a convention for naming the bidder eids
Expand All @@ -23,7 +23,7 @@ export const YANDEX_ID_KEY = 'yandexId';
export const YANDEX_EXT_COOKIE_NAMES = ['_ym_fa'];
export const BIDDER_CODE = 'yandex';
export const YANDEX_USER_ID_KEY = '_ym_uid';
export const YANDEX_COOKIE_STORAGE_TYPE = 'cookie';
export const YANDEX_STORAGE_TYPE = STORAGE_TYPE_COOKIES;
export const YANDEX_MIN_EXPIRE_DAYS = 30;

export const PREBID_STORAGE = getStorageManager({
Expand All @@ -40,7 +40,7 @@ export const yandexIdSubmodule = {
* @param {string} value
*/
decode(value) {
logInfo('decoded value yandexId', value);
logInfo(`Decoded ${YANDEX_ID_KEY}`, value);

return { [YANDEX_ID_KEY]: value };
},
Expand All @@ -50,18 +50,24 @@ export const yandexIdSubmodule = {
}

if (storedId) {
logInfo('Got storedId', storedId);
return {
id: storedId
};
}

return {
id: new YandexUidGenerator().generateUid(),
id: new YandexIdGenerator().generate(),
};
},
eids: {
[YANDEX_ID_KEY]: {
source: BIDDER_EID_KEY,
/**
* Agent Type 1 means that it is an ID
* which is tied to a specific web browser or device (cookie-based, probabilistic, or other).
* @see https://github.com/InteractiveAdvertisingBureau/AdCOM/blob/main/AdCOM%20v1.0%20FINAL.md#list--agent-types-
*/
atype: 1,
getUidExt() {
if (PREBID_STORAGE.cookiesAreEnabled()) {
Expand All @@ -85,22 +91,22 @@ function checkConfigHasErrorsAndReport(submoduleConfig) {
const READABLE_MODULE_NAME = 'Yandex ID module';

if (submoduleConfig.storage == null) {
logError(`Misconfigured ${READABLE_MODULE_NAME}. "storage" is required.`)
logError(`Misconfigured ${READABLE_MODULE_NAME}. "storage" is required.`);
return true;
}

if (submoduleConfig.storage?.name !== YANDEX_USER_ID_KEY) {
logError(`Misconfigured ${READABLE_MODULE_NAME}, "storage.name" is required to be "${YANDEX_USER_ID_KEY}"`);
if (submoduleConfig.storage.name !== YANDEX_USER_ID_KEY) {
logError(`Misconfigured ${READABLE_MODULE_NAME}, "storage.name" is expected to be "${YANDEX_USER_ID_KEY}", actual is "${submoduleConfig.storage.name}"`);
error = true;
}

if (submoduleConfig.storage?.type !== YANDEX_COOKIE_STORAGE_TYPE) {
logError(`Misconfigured ${READABLE_MODULE_NAME}, "storage.type" is required to be "${YANDEX_COOKIE_STORAGE_TYPE}"`);
if (submoduleConfig.storage.type !== YANDEX_STORAGE_TYPE) {
logError(`Misconfigured ${READABLE_MODULE_NAME}, "storage.type" is expected to be "${YANDEX_STORAGE_TYPE}", actual is "${submoduleConfig.storage.type}"`);
error = true;
}

if ((submoduleConfig.storage?.expires ?? 0) < YANDEX_MIN_EXPIRE_DAYS) {
logError(`Misconfigured ${READABLE_MODULE_NAME}, "storage.expires" is required to be not less than "${YANDEX_MIN_EXPIRE_DAYS}"`);
if ((submoduleConfig.storage.expires ?? 0) < YANDEX_MIN_EXPIRE_DAYS) {
logError(`Misconfigured ${READABLE_MODULE_NAME}, "storage.expires" is expected not to be less than "${YANDEX_MIN_EXPIRE_DAYS}", actual is "${submoduleConfig.storage.expires}"`);
error = true;
}

Expand All @@ -111,28 +117,36 @@ function checkConfigHasErrorsAndReport(submoduleConfig) {
* Yandex-specific generator for uid. Needs to be compatible with Yandex Metrica tag.
* @see https://github.com/yandex/metrica-tag/blob/main/src/utils/uid/uid.ts#L51
*/
class YandexUidGenerator {
class YandexIdGenerator {
generate() {
const yandexId = [
this._getCurrentSecTimestamp(),
this._getRandomInteger(1000000, 999999999),
].join('');

logInfo(`Generated ${YANDEX_ID_KEY}`, yandexId);

return yandexId;
}

_getCurrentSecTimestamp() {
return Math.round(Date.now() / 1000);
}

/**
* @param {number} min
* @param {number} max
*/
_getRandomInteger(min, max) {
const generateRandom = this._getRandomGenerator();

/**
* Needs to be compatible with Yandex Metrica `getRandom` function.
* @see https://github.com/yandex/metrica-tag/blob/main/src/utils/number/random.ts#L12
*/
return Math.floor(generateRandom() * (max - min)) + min;
}

_getCurrentSecTimestamp() {
return Math.round(Date.now() / 1000);
}

generateUid() {
return [
this._getCurrentSecTimestamp(),
this._getRandomInteger(1000000, 999999999),
].join('');
}

_getRandomGenerator() {
if (window.crypto) {
return () => {
Expand Down
6 changes: 5 additions & 1 deletion src/storageManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export function newStorageManager({moduleName, moduleType} = {}, {isAllowed = is
* If not specified, defaults to the host portion of the current document location.
* If a domain is specified, subdomains are always included.
* Domain must match the domain of the JavaScript origin. Setting cookies to foreign domains will be silently ignored.
* @param {function} [done]
*/
const setCookie = function (key, value, expires, sameSite, domain, done) {
let cb = function (result) {
Expand All @@ -75,6 +76,7 @@ export function newStorageManager({moduleName, moduleType} = {}, {isAllowed = is

/**
* @param {string} name
* @param {function} [done]
* @returns {(string|null)}
*/
const getCookie = function(name, done) {
Expand All @@ -89,6 +91,7 @@ export function newStorageManager({moduleName, moduleType} = {}, {isAllowed = is
};

/**
* @param {function} [done]
* @returns {boolean}
*/
const cookiesAreEnabled = function (done) {
Expand Down Expand Up @@ -170,7 +173,8 @@ export function newStorageManager({moduleName, moduleType} = {}, {isAllowed = is
* Returns all cookie values from the jar whose names contain the `keyLike`
* Needs to exist in `utils.js` as it follows the StorageHandler interface defined in live-connect-js. If that module were to be removed, this function can go as well.
* @param {string} keyLike
* @return {[]}
* @param {function} [done]
* @returns {string[]}
*/
const findSimilarCookies = function(keyLike, done) {
let cb = function (result) {
Expand Down
4 changes: 2 additions & 2 deletions test/spec/modules/yandexIdSystem_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
YANDEX_EXT_COOKIE_NAMES,
BIDDER_CODE,
YANDEX_USER_ID_KEY,
YANDEX_COOKIE_STORAGE_TYPE,
YANDEX_STORAGE_TYPE,
YANDEX_MIN_EXPIRE_DAYS,
PREBID_STORAGE,
yandexIdSubmodule,
Expand All @@ -30,7 +30,7 @@ const CORRECT_SUBMODULE_CONFIG = {
storage: {
expires: YANDEX_MIN_EXPIRE_DAYS,
name: YANDEX_USER_ID_KEY,
type: YANDEX_COOKIE_STORAGE_TYPE,
type: YANDEX_STORAGE_TYPE,
refreshInSeconds: undefined,
},
params: undefined,
Expand Down

0 comments on commit 3bbf614

Please sign in to comment.