echo.io
Version:
A socket.io server implementation for laravel-echo
257 lines (214 loc) • 7.2 kB
JavaScript
;
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var _verify = require('../auth/jwt-verify.js');
var Subscribe = function () {
/**
* Constructor.
*
* @param server
*/
function Subscribe(server) {
_classCallCheck(this, Subscribe);
this.server = server;
}
/**
* Get an instance of the class.
*
* @param server
*
* @return {OnSubscribe}
*/
_createClass(Subscribe, [{
key: 'handle',
/**
* Middleware handler.
*
* @param socket
* @param next
*/
value: function handle(socket, next) {
this.addListeners(socket);
return next();
}
/**
* Add a new socket event listener.
*
* @param socket
*/
}, {
key: 'addListeners',
value: function addListeners(socket) {
var _this = this;
socket.on('unsubscribe', function (_ref) {
var channel = _ref.channel;
return _this.unsubscribe(socket, channel);
});
socket.on('subscribe', function (_ref2) {
var channel = _ref2.channel,
key = _ref2.key,
status = _ref2.status;
return _this.subscribe(socket, channel, key, status);
});
}
/**
* On unsubscribe callback handler.
*
* @param socket
* @param channel
*
* @return {void}
*/
}, {
key: 'unsubscribe',
value: function unsubscribe(socket, channel) {
if ('presence' === this.scope(channel)) {
this.server.unsubscribePresence(socket, channel);
} else {
socket.leave(channel);
}
}
/**
* On subscribe callback handler.
*
* @param socket
* @param channel
* @param key
* @param status
*
* @return {void}
*/
}, {
key: 'subscribe',
value: function subscribe(socket, channel, key, status) {
var scope = this.scope(channel);
if (scope && (key || status)) {
this.handleScopedSubscription(scope, socket, channel, key, status);
} else if (null == scope) {
this.handleSubscription(socket, channel);
}
}
/**
* Handle subcription for a private or presence channel.
*
* @param scope
* @param socket
* @param channel
* @param key
* @param status
*
* @return {void}
*/
}, {
key: 'handleScopedSubscription',
value: function handleScopedSubscription(scope, socket, channel, key, status) {
status = this.verify(key || status, channel);
if (status) {
return this['on' + scope + 'subscription'](socket, channel, status.channel_data);
}
// handle failed verify
}
/**
* Add a socket to a channel room.
*
* @param socket
* @param channel
*
* @return {void}
*/
}, {
key: 'handleSubscription',
value: function handleSubscription(socket, channel) {
socket.join(channel);
}
/**
* handle presence subscription.
*
* @param socket
* @param channel
* @param status
*
* @return {void}
*/
}, {
key: 'onpresencesubscription',
value: function onpresencesubscription(socket, channel, status) {
if (status && 'object' === (typeof status === 'undefined' ? 'undefined' : _typeof(status))) {
this.server.subscribePresence(status.user_id, channel, socket, { user_info: status.user_info });
}
}
/**
* handle private subscription.
*
* @param socket
* @param channel
* @param status
*
* @return {void}
*/
}, {
key: 'onprivatesubscription',
value: function onprivatesubscription(socket, channel) {
this.handleSubscription(socket, channel);
}
/**
* Json web token based authentication.
*
* @param token
* @param channel
*
* @return {Boolean|Object}
*/
}, {
key: 'verify',
value: function verify(token, channel) {
if (!(token = this.token(token))) {
return false;
}
// JWT authentication.
var status = _verify(token, this.server.auth());
// The channel should also match.
if (status && status.channel_name === channel) {
return status;
}
return false;
}
/**
* Extract token string from data.
*
* @param data
*
* @return {String|undefined}
*/
}, {
key: 'token',
value: function token(data) {
if ((typeof data === 'undefined' ? 'undefined' : _typeof(data)) === 'object') {
data = data.key || data.token;
}
if (typeof data === 'string' && data.length) {
return data;
}
}
/**
* If the channel name starts with 'private-' or 'presence-'.
*
* @param channel
*
* @return {string|null}
*/
}, {
key: 'scope',
value: function scope(channel) {
return (/^(private|presence)-.+/.exec(channel) || { 1: null })[1];
}
}], [{
key: 'getInstance',
value: function getInstance(server) {
return new Subscribe(server);
}
}]);
return Subscribe;
}();
module.exports = Subscribe;