UNPKG

echo.io

Version:

A socket.io server implementation for laravel-echo

257 lines (214 loc) 7.2 kB
'use strict'; 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;