const axios = require('axios');
const qs = require('qs');
const crypto = require('crypto');
const rootRequire = require('rpcm-root-require');
rootRequire('/platform-helpers/string-extensions');
/**
* IQ Helper class.
*
* @static
* @requires axios
* @requires qs
* @requires crypto
* @requires string-extensions
*/
class TiqHelper {
/**
* Keeps session details in-memory whilst instance is in use
* @private
*/
static sessionDetails = { utk: null, jsessionId: null };
/**
* Provides an object with one TIQ session details.
* Keeps session details in-memory throughout the context.
*
* @method
* @public
* @param {string} account the CDH profile to use for authentication / token generation
* @param {string} profile the CDH profile to use for authentication / token generation
* @param {string} tealUser the Tealium user email
* @param {string} tealPass the Tealium user pass
* @returns {object} { utk, jsessionId }
*/
static getTiqSessionDetails = async (account, profile, tealUser, tealPass) => {
const pingCallStatus = await TiqHelper.ping(account, profile, TiqHelper.sessionDetails.utk, TiqHelper.sessionDetails.jsessionId);
switch (pingCallStatus) {
case 200: {
return TiqHelper.sessionDetails;
}
case 401: {
const loginRequest = await TiqHelper.loginUser(tealUser, tealPass);
const setCookies = loginRequest.headers['set-cookie'] || [];
const re = /^JSESSIONID=([^;]*);/;
TiqHelper.sessionDetails = { utk: null, jsessionId: null };
if (loginRequest.data.utk) TiqHelper.sessionDetails.utk = loginRequest.data.utk;
for (let i = 0; i < setCookies.length; i++) {
const match = re.exec(setCookies[i]);
if (match && match[1]) {
TiqHelper.sessionDetails.jsessionId = match[1];
break;
}
}
return TiqHelper.sessionDetails;
}
default: {
TiqHelper.sessionDetails = { utk: null, jsessionId: null };
return TiqHelper.sessionDetails;
}
}
};
/**
* Sends a Teal TIQ login request.
*
* @method
* @param {string} email
* @param {string} pass
* @returns {object} An axios network call providing session details if successful
*/
static loginUser = async (email, pass) => {
return await axios.post('https://api.tealiumiq.com/v1/login', qs.stringify({
username: email,
password: pass
}), {
headers: { 'content-type': 'application/x-www-form-urlencoded' }
});
};
/**
* Pings Teal TIQ to check session status
*
* @method
* @param {string} account
* @param {string} profile
* @param {string} tiqUtk
* @param {string} jSessionId
* @returns {object} An axios network call
*/
static ping = async (account, profile, tiqUtk, jSessionId) => {
try {
const pingCall = await axios.post('https://my.tealiumiq.com/urest/ping?utk={0}'.format(tiqUtk), {
account: account,
profile: profile
}, {
headers: {
Cookie: 'JSESSIONID={0}'.format(jSessionId),
Accept: 'application/json'
}
});
return pingCall.status;
} catch (error) {
return error && error.response && error.response.status;
}
};
/**
* Provides a new GUID
*
* @method
* @returns {string} A new random GUID
*/
static generateNewVisitorId = () => {
return crypto.randomBytes(16).toString('hex');
};
/**
* Provides the UTAG environment based on the {{profile}} of the utag.js URL of the HTML script tag
*
* @method
* @param {Array} collection A collection of strings
*
* @example
* const rootRequire = require('rpcm-root-require');
* const tiqHelper = rootRequire('/platform-helpers/tiq-helper');
*
* // DOM query
* var collectionTags = jQuery("script").map((i, el)=> el.src);
*
* // get environment
* const env = tiqHelper.getTealiumEnvironment(collectionTags);
*
* // check
* console.log(env); // should print the environment
*
* @returns {string} The current tealium environment or undefined if not found
*/
static getTealiumEnvironment = (collection) => {
try {
const re = /\/([^/]*)\/utag\.js(\?.*)*$/;
for (let i = 0; i < collection.length; i++) {
const result = re.exec(collection[i]); // can be null
if (result && result[1]) { // [1] is the result of the match
return result[1];
}
}
} catch (error) {}
};
}
module.exports = TiqHelper;