Show:

File: platform/plugins/Users/classes/Users/Session.js

/**
 * Class representing session rows.
 *
 * @module Users
 */
var Q = require('Q');
var Db = Q.require('Db');
var Users = require('Users');

/**
 * Class representing 'Session' rows in the 'Users' database
 * <br/>This table is used to replicate PHP sessions information for
 * @namespace Users
 * @class Session
 * @extends Base.Users.Session
 * @constructor
 * @param fields {object} The fields values to initialize table row as
 * an associative array of `{column: value}` pairs
 */
function Users_Session (fields) {

	// Run constructors of mixed in objects
	Users_Session.constructors.apply(this, arguments);

	/*
	 * Add any privileged methods to the model class here.
	 * Public methods should probably be added further below.
	 * If file 'Session.js.inc' exists, its content is included
	 * * * */

	/* * * */
}

Users_Session.decodeId = function (id) {
	if (!id) {
		return [false, '', ''];
	}
	var secret = Q.Config.get(['Q', 'external', 'secret'], null);
	var result = '';
	var i = 0;
	var len = id.length;
	var r, c1, c2, a, b, c;
	var replacements = {
		'z': 'z',
		'a': '+',
		'b': '/',
		'c': '='
	};
	while (i < len-1) {
		r = id[i];
		c1 = id[i];
		++i;
		if (c1 == 'z') {
			c2 = id[i];
			if (replacements[c2]) {
				r = replacements[c2];
				++i;
			}
		}
		result += r;
	}
	if (i < len) {
		result += id[i];
	}
	result = bin2hex(base64_decode(result));
	a = result.substr(0, 32);
	b = result.substr(32, 32);
	c = secret !== undefined
		? (b === Q.Utils.signature(a, secret).substr(0, 32))
		: true;
	return [c, a, b];
};

/**
 * Pushes notifications to the device corresponding the session ids.
 * @method pushNotifications
 * @static
 * @param {String|Array} userIds A user id, or an array of them, 
 *	 in which case sessionIds would be an object of { userId: sessionId }
 *   in which case notifications would be an object of { userId: notification }
 * @param {String|Object} sessionIds A session id, or an object of them
 * @param {Object} notifications Please see Users.Device.pushNotification for the spec
 * @param {Function} [callback] A function to call after the push has been completed
 */
Users_Session.pushNotifications = function (userIds, sessionIds, notifications, callback) {
	var isArrayLike = Q.isArrayLike(userIds);
	Users.Device.SELECT('*').where({
		userId: userIds
	}).execute(function (err, devices) {
		if (err) {
			return callback(err);
		}
		var d = [];
		Q.each(devices, function (i) {
			var u = this.fields.userId;
			var n = isArrayLike ? notifications[u] : notifications;
			var s = isArrayLike ? sessionIds[u] : sessionIds;
			if (this.fields.sessionId === s) {
				this.pushNotification(n);
				d.push(this);
			}
		});
		callback(null, d, n);
	});
};

Q.mixin(Users_Session, Q.require('Base/Users/Session'));

/*
 * Add any public methods here by assigning them to Users_Session.prototype
 */

/**
 * The setUp() method is called the first time
 * an object of this class is constructed.
 * @method setUp
 */
Users_Session.prototype.setUp = function () {
	// put any code here
	// overrides the Base class
};

module.exports = Users_Session;





function bin2hex (s) {
	var o = '', i, l, n;
	s += '';
	for (i = 0, l = s.length; i < l; i++) {
		n = s.charCodeAt(i).toString(16);
		o += n.length < 2 ? '0'+n : n;
	}
	return o;
}

function base64_decode (encodedData) {
	var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
	var o1, o2, o3, h1, h2, h3, h4, bits;
	var i = 0, ac = 0, dec = '', tmpArr = [];
	if (!encodedData) {
		return encodedData
	}
	encodedData += '';
	do {
		// unpack four hexets into three octets using index points in b64
		h1 = b64.indexOf(encodedData.charAt(i++));
		h2 = b64.indexOf(encodedData.charAt(i++));
		h3 = b64.indexOf(encodedData.charAt(i++));
		h4 = b64.indexOf(encodedData.charAt(i++));
		bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
		o1 = bits >> 16 & 0xff;
		o2 = bits >> 8 & 0xff;
		o3 = bits & 0xff;
		if (h3 === 64) {
			tmpArr[ac++] = String.fromCharCode(o1);
		} else if (h4 === 64) {
			tmpArr[ac++] = String.fromCharCode(o1, o2);
		} else {
			tmpArr[ac++] = String.fromCharCode(o1, o2, o3);
		}
	} while (i < encodedData.length);
	dec = tmpArr.join('');
	return decodeURIComponent(encodeURIComponent(dec.replace(/\0+$/, '')));
}