/*
@author pavel.mash
*/
// *********** !!!!WARNING!!!!! **********************
// Module shared between server and client code
/**
* Internal class, returned as a result of {@link UBConnection#authorize UBConnection.authorize()}
* The main method is {@link UBSession#signature UBSession.signature}
*
* Developer never create this class directly.
* @class
* @protected
*/
function UBSession(authResponse, secretWord, authSchema){
var data = authResponse,
hexa8ID = hexa8(data.result.split('+')[0]),
userData = data.uData?JSON.parse(data.uData):{lang: 'en'},
//crc32SessionWord = crc32(secretWord),
sessionWord = data.result, // sessionID || '+' || privateKey
sessionPwdHash = secretWord || '',
//typeof window === 'undefined' -> UB.isServer
sessionSaltCRC = (typeof window === 'undefined') ? ncrc32(0, sessionWord + sessionPwdHash) : null;
/** @property {String} sessionID user session id converted to {@link UBSession#hexa8}
* @protected
* @readonly
*/
Object.defineProperty(this, 'sessionID', {enumerable: true, writable: false, value: hexa8ID});
/**
* User logon name. Better to access this value using {@link UBConnection#userLogin UBConnection.userLogin()} method.
* @type {String}
* @private
* @readonly
*/
this.logonname = data.logonname;
/** Contain custom user data. Usually filled inside **server** `onUserLogon` event handlers
*
* Do not use it directly, instead use helper method {@link UBConnection#userData UBConnection.userData()} instead.
*
* @type {Object}
* @protected
* @readonly
*/
this.userData = userData;
/**
* Name of authentication schema
* @type {String}
* @protected
* @readonly
*/
this.authSchema = authSchema || 'UB';
/**
* Session signature for authorized request. Can be added as LAST parameter in url, or to Authorization header (preferred way)
*
* $App.connection.authorize().then(function(session){
* // for URL
* return 'session_signature=' + session.signature()
* //for header
* return {Authorization: session.authSchema + ' ' + session.signature()}
* });
*
* @returns {string}
*/
this.signature = function() {
var
timeStampI, hexaTime;
if (this.authSchema === 'UBIP'){
return this.logonname
} else {
timeStampI = Math.floor((new Date()).getTime() / 1000);
hexaTime = hexa8(timeStampI);
return hexa8ID + hexaTime + hexa8((typeof window === 'undefined') ? ncrc32(sessionSaltCRC, hexaTime) : crc32(sessionWord + sessionPwdHash + hexaTime)); // + url?
}
// 1.7 return hexa8ID + hexa8(timeStampI) + hexa8(crc32(timeStampI + '' + crc32SessionWord ));
};
/**
* Return authorization header
*
* $App.connection.authorize().then(function(session){
* return {Authorization: session.authHeader()}
* });
*
* @returns {string}
*/
this.authHeader = function(){
return this.authSchema + ' ' + this.signature();
};
}
/**
* Return hexadecimal string of 8 character length from value
* @param {String|Number} value
* @returns {String}
*/
UBSession.prototype.hexa8 = function hexa8(value){
var num = parseInt(value, 10),
res = isNaN(num) ? '00000000' : num.toString(16);
while(res.length < 8) {
res = '0' + res;
}
return res;
};
var hexa8 = UBSession.prototype.hexa8;
var CRC32_POLYTABLES = {};
/*jslint bitwise: true */
/**
* Calculate CRC32 checksum for string
* @param {String} s string to calculate CRC32
* @param {Number} [polynomial] polynomial basis. default to 0x04C11DB7
* @param {Number} [initialValue] initial crc value. default to 0xFFFFFFFF
* @param {Number} [finalXORValue] default to 0xFFFFFFFF
* @returns {Number}
*/
UBSession.prototype.crc32 = function crc32(s, polynomial, initialValue, finalXORValue) {
var table, i, j, c, crc;
s = String(s);
polynomial = polynomial || 0x04C11DB7;
initialValue = initialValue || 0xFFFFFFFF;
finalXORValue = finalXORValue || 0xFFFFFFFF;
crc = initialValue;
table = CRC32_POLYTABLES[polynomial];
if (!table){
table = CRC32_POLYTABLES[polynomial] = (function build(){
var i, j, c, table = [],
reverse = function (x, n) {
var b = 0;
while (n) {
b = b * 2 + x % 2;
x /= 2;
x -= x % 1;
n--;
}
return b;
};
for (i = 255; i >= 0; i--) {
c = reverse(i, 32);
for (j = 0; j < 8; j++) {
c = ((c * 2) ^ (((c >>> 31) % 2) * polynomial)) >>> 0;
}
table[i] = reverse(c, 32);
}
return table;
})();
}
for (i = 0; i < s.length; i++) {
c = s.charCodeAt(i);
if (c > 255) {
throw new RangeError();
}
j = (crc % 256) ^ c;
crc = ((crc / 256) ^ table[j]) >>> 0;
}
return (crc ^ finalXORValue) >>> 0;
};
var crc32 = UBSession.prototype.crc32;
module.exports = UBSession;