const esamsUtil = require('./esams-util');
const COOKIE_CONSTANTS = {
SESSION_ID: '**id',
SESSION_TOKEN: '****_session_token',
USER_NAME: '****user'
};
const Cookies = require('cookies');
const ebayEnv = require('environment-ebay');
const COOKIE_DOMAIN_EBAY = 'ebay.com';
const COOKIE_DOMAIN_DEVELOPER = 'developer.ebay.com';
const COOKIE_DOMAIN_QA = 'qa.ebay.com';
const COOKIE_DOMAIN_STAGING_DEVELOPER = 'staging.developer.ebay.com';
const _getExpiryinMilliSeconds = function getExpiryinMilliSeconds(expiry) {
const current = Date.now();
let expiryinMilliSeconds = 0;
if (expiry === undefined) {
expiryinMilliSeconds = 86400000;
} else {
expiryinMilliSeconds = expiry - current;
}
return expiryinMilliSeconds;
};
const setDefaultCookieOptions = function setDefaultCookieOptions(req, options) {
if (options.httpOnly === undefined) {
options.httpOnly = true;
}
if (options.path === undefined) {
options.path = '/';
}
return options;
};
const setCookie = function setCookie(req, cookies, name, value, options) {
const cookieOptions = setDefaultCookieOptions(req, options || {});
if (cookieOptions.domain === undefined) {
const isProdOrPreProd = ebayEnv.isProd() || ebayEnv.isPreProd();
if (!isProdOrPreProd) {
// In dev and QA - We will set in both qa.ebay.com and staging.developer.ebay.com domains
cookieOptions.domain = COOKIE_DOMAIN_QA;
cookies.set(name, value, cookieOptions);
cookieOptions.domain = COOKIE_DOMAIN_STAGING_DEVELOPER;
cookies.set(name, value, cookieOptions);
} else {
cookieOptions.domain = COOKIE_DOMAIN_EBAY;
cookies.set(name, value, cookieOptions);
}
} else {
cookies.set(name, value, cookieOptions);
}
};
const readFromCookie = function readFromCookie(req, name) {
const cookies = req.ebay.cookies;
return cookies ? cookies.getCookieValue(name) : '';
};
const setupCookies = function setupCookies(req, res) {
return new Cookies(req, res);
};
const getSessionId = function getSessionId(req) {
return readFromCookie(req, COOKIE_CONSTANTS.SESSION_ID);
};
const setCookieValue = function setCookieValue(req, res, name, value, options) {
const cookies = setupCookies(req, res);
setCookie(req, cookies, name, value, options);
};
const deleteCookie = function deleteCookie(req, res, name, domain) {
const options = { maxAge: -1, httpOnly: true };
if (domain) {
options.domain = domain;
}
setCookieValue(req, res, name, null, options);
};
const getDecryptedCookieData = function getDecryptedCookieData(req, cookieKey) {
const encryptedToken = readFromCookie(req, cookieKey);
return esamsUtil.decrypt(encryptedToken);
};
const setNonWhitelistedUserCookie = function setNonWhitelistedUserCookie(req, res) {
setCookieValue(req, res, COOKIE_CONSTANTS.NON_WHITELISTED_USER, '1', { maxAge: 300000, httpOnly: false });
};
const getFakeWhitelistedUserCookie = function getFakeWhitelistedUserCookie(req) {
return readFromCookie(req, COOKIE_CONSTANTS.FAKE_WHITELISTED_USER);
};
const setOauthTokenInfo = function setOauthTokenInfo(req, res, oauthTokenInfo, oauthTokenExpiry) {
return esamsUtil.encrypt(oauthTokenInfo).then((promiseData) => {
let cookieData = oauthTokenInfo;
if (promiseData.encryptedData) {
cookieData = promiseData.encryptedData;
}
const expiryinMilliSeconds = _getExpiryinMilliSeconds(oauthTokenExpiry);
setCookieValue(req, res, COOKIE_CONSTANTS.OAUTH_TOKEN, cookieData, { maxAge: expiryinMilliSeconds, httpOnly: true });
return true;
});
};
const setSessionTokenInCookie = function setSessionTokenInCookie(req, res, sessionToken, sessionTokenExpiry) {
return esamsUtil.encrypt(sessionToken).then((promiseData) => {
let cookieData = sessionToken;
if (promiseData.encryptedData) {
cookieData = promiseData.encryptedData;
}
const expiryinMilliSeconds = _getExpiryinMilliSeconds(sessionTokenExpiry);
setCookieValue(req, res, COOKIE_CONSTANTS.SESSION_TOKEN, cookieData, { maxAge: expiryinMilliSeconds, httpOnly: true });
return true;
});
};
const setFailedLoginAttemptsInCookie = function setFailedLoginAttemptsInCookie(req, res, failedLoginAttempts) {
return esamsUtil.encrypt(failedLoginAttempts).then((promiseData) => {
let cookieData = failedLoginAttempts;
if (promiseData.encryptedData) {
cookieData = promiseData.encryptedData;
}
setCookieValue(req, res, COOKIE_CONSTANTS.FAILED_LOGIN_ATTEMPTS, cookieData, { maxAge: 86400000, httpOnly: true });
return true;
});
};
const deleteSessionToken = function deleteSessionToken(req, res) {
deleteCookie(req, res, COOKIE_CONSTANTS.SESSION_TOKEN);
deleteCookie(req, res, COOKIE_CONSTANTS.SESSION_TOKEN, COOKIE_DOMAIN_DEVELOPER);
deleteCookie(req, res, COOKIE_CONSTANTS.SESSION_TOKEN, COOKIE_DOMAIN_EBAY);
deleteCookie(req, res, COOKIE_CONSTANTS.SESSION_TOKEN, COOKIE_DOMAIN_QA);
deleteCookie(req, res, COOKIE_CONSTANTS.SESSION_TOKEN, COOKIE_DOMAIN_STAGING_DEVELOPER);
};
const getSessionToken = function getSessionToken(req) {
const encryptedToken = readFromCookie(req, COOKIE_CONSTANTS.SESSION_TOKEN);
return esamsUtil.decrypt(encryptedToken);
};
const getFailedLoginAttempts = function getFailedLoginAttempts(req) {
return getDecryptedCookieData(req, COOKIE_CONSTANTS.FAILED_LOGIN_ATTEMPTS);
};
const deleteAllAuthCookies = function deleteAllAuthCookies(req, res) {
deleteSessionToken(req, res);
// deleteCookie(req, res, COOKIE_CONSTANTS.USER_NAME);
deleteCookie(req, res, COOKIE_CONSTANTS.NON_WHITELISTED_USER);
deleteCookie(req, res, COOKIE_CONSTANTS.FORCE_PREPROD);
deleteCookie(req, res, COOKIE_CONSTANTS.FAKE_WHITELISTED_USER);
deleteCookie(req, res, COOKIE_CONSTANTS.FAILED_LOGIN_ATTEMPTS);
deleteCookie(req, res, COOKIE_CONSTANTS.ACME_TICK);
deleteCookie(req, res, COOKIE_CONSTANTS.ACME_TICK, COOKIE_DOMAIN_DEVELOPER);
deleteCookie(req, res, COOKIE_CONSTANTS.ACME_TICK, COOKIE_DOMAIN_EBAY);
deleteCookie(req, res, COOKIE_CONSTANTS.ACME_TICK_EV);
deleteCookie(req, res, COOKIE_CONSTANTS.ACME_TICK_EV, COOKIE_DOMAIN_DEVELOPER);
deleteCookie(req, res, COOKIE_CONSTANTS.ACME_TICK_EV, COOKIE_DOMAIN_EBAY);
};
const deleteFailedLoginAttemptsInCookie = function deleteFailedLoginAttemptsInCookie(req, res) {
deleteCookie(req, res, COOKIE_CONSTANTS.FAILED_LOGIN_ATTEMPTS);
};
const getOauthTokenInfo = function getOauthTokenInfo(req) {
return getDecryptedCookieData(req, COOKIE_CONSTANTS.OAUTH_TOKEN);
};
const deleteOauthTokenInfo = function deleteOauthTokenInfo(req, res) {
deleteCookie(req, res, COOKIE_CONSTANTS.OAUTH_TOKEN);
deleteCookie(req, res, COOKIE_CONSTANTS.OAUTH_TOKEN, COOKIE_DOMAIN_DEVELOPER);
deleteCookie(req, res, COOKIE_CONSTANTS.OAUTH_TOKEN, COOKIE_DOMAIN_EBAY);
deleteCookie(req, res, COOKIE_CONSTANTS.OAUTH_TOKEN, COOKIE_DOMAIN_QA);
deleteCookie(req, res, COOKIE_CONSTANTS.OAUTH_TOKEN, COOKIE_DOMAIN_STAGING_DEVELOPER);
};
module.exports = {
deleteOauthTokenInfo,
getSessionId,
setCookieValue,
setNonWhitelistedUserCookie,
setFailedLoginAttemptsInCookie,
getFailedLoginAttempts,
deleteFailedLoginAttemptsInCookie,
getFakeWhitelistedUserCookie,
setSessionTokenInCookie,
deleteSessionToken,
getSessionToken,
deleteAllAuthCookies,
readFromCookie,
getOauthTokenInfo,
setOauthTokenInfo
};
// my ibsvc angular cookieUtils
// Begin: List of Methods added for token authorizaiton
static urlBase64Decode(str: string) {
let output = str.replace(/-/g, '+').replace(/_/g, '/');
switch (output.length % 4) {
case 0: { break; }
case 2: { output += '=='; break; }
case 3: { output += '='; break; }
default: {
throw new Error('Illegal base64url string!');
}
}
return decodeURIComponent((window.atob(output)));
}
static decodeToken(token: string) {
const parts = token.split('.');
if (parts.length !== 3) {
throw new Error('JWT must have 3 parts');
}
const decoded = this.urlBase64Decode(parts[1]);
if (!decoded) {
throw new Error('Cannot decode the token');
}
return JSON.parse(decoded);
}
static getTokenExpirationDate(token: string) {
const decoded = this.decodeToken(token);
if (typeof decoded.exp === 'undefined') {
return null;
}
const date = new Date(0); // The 0 here is the key, which sets the date to the epoch
date.setUTCSeconds(decoded.exp);
return date;
}
static isTokenExpired(token: string, offsetSeconds?: number) {
const date = this.getTokenExpirationDate(token);
offsetSeconds = offsetSeconds || 0;
if (date === null) {
return false;
}
// Token expired?
return !(date.valueOf() > (new Date().valueOf() + (offsetSeconds * 1000)));
}
// end of methods added for token authorizaiton
static getCookie(name: string) {
const ca: Array<string> = document.cookie.replace(/\s+/g, '').split(';');
const cookieName = name + '=';
let c: string;
let ret: string;
_.forEach(ca, function(cookie) {
c = cookie.replace(/^\s\+/g, '');
if (c.indexOf(cookieName) === 0) {
ret = c.substring(cookieName.length, c.length);
}
});
return ret;
}
static setCookie(name:string, value: string, expiredays: number){
var exdate=new Date();
exdate.setDate(exdate.getDate() + expiredays);
const expires = expiredays==null ? "" : `;expires=${exdate.toUTCString()}`;
document.cookie = `${name}=${value};path=/;domain=.ebay.com${expires}`;
}