diff --git a/README.md b/README.md index 757a0b51..246a2f5d 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,7 @@ Edit the default configuration of the server by adding options to your **laravel | `database` | `redis` | Database used to store data that should persist, like presence channel members. Options are currently `redis` and `sqlite` | | `databaseConfig` | `{}` | Configurations for the different database drivers [Example](#database) | | `devMode` | `false` | Adds additional logging for development purposes | +| `logLevel` | `1` | Log level, lower means more logs, enter 6 for errors only, 5 for warnings and errors | | `host` | `null` | The host of the socket.io server ex.`app.dev`. `null` will accept connections on any IP-address | | `port` | `6001` | The port that the socket.io server should run on | | `protocol` | `http` | Must be either `http` or `https` | @@ -102,6 +103,7 @@ file, the following options can be overridden: - `host`: `LARAVEL_ECHO_SERVER_HOST` - `port`: `LARAVEL_ECHO_SERVER_PORT` - `devMode`: `LARAVEL_ECHO_SERVER_DEBUG` +- `devMlogLevelode`: `LARAVEL_ECHO_SERVER_LOGLEVEL` - `databaseConfig.redis.host`: `LARAVEL_ECHO_SERVER_REDIS_HOST` - `databaseConfig.redis.port`: `LARAVEL_ECHO_SERVER_REDIS_PORT` - `databaseConfig.redis.password`: `LARAVEL_ECHO_SERVER_REDIS_PASSWORD` diff --git a/src/api/http-api.ts b/src/api/http-api.ts index 58477394..f26a48d2 100644 --- a/src/api/http-api.ts +++ b/src/api/http-api.ts @@ -158,11 +158,25 @@ export class HttpApi { } this.channel.presence.getMembers(channelName).then(members => { - let users = []; - - _.uniqBy(members, 'user_id').forEach((member: any) => { - users.push({ id: member.user_id, user_info: member.user_info }); - }); + const membersDic = members.reduce((dic, member) => { + if (!dic[member.user_id]) { + dic[member.user_id] = { + id: member.user_id, + user_info: member.user_info, + ips: [member.ip], + sessions: 1, + } + } else { + const user_data = dic[member.user_id]; + if (!user_data.ips.includes(member.ip)) { + user_data.ips.push(member.ip) + } + user_data.sessions += 1 + } + return dic + }, {}) + + const users = Object.keys(membersDic).map(key => membersDic[key]) res.json({ users: users }); }, error => Log.error(error)); diff --git a/src/channels/presence-channel.ts b/src/channels/presence-channel.ts index 7b618720..10204a55 100644 --- a/src/channels/presence-channel.ts +++ b/src/channels/presence-channel.ts @@ -122,16 +122,18 @@ export class PresenceChannel { let member = members.find( (member) => member.socketId == socket.id ); - members = members.filter((m) => m.socketId != member.socketId); + if (member) { + members = members.filter((m) => m.socketId != member.socketId); - this.db.set(channel + ":members", members); - - this.isMember(channel, member).then((is_member) => { - if (!is_member) { - delete member.socketId; - this.onLeave(channel, member); - } - }); + this.db.set(channel + ":members", members); + + this.isMember(channel, member).then((is_member) => { + if (!is_member) { + delete member.socketId; + this.onLeave(channel, member); + } + }); + } }, (error) => Log.error(error) ); diff --git a/src/channels/private-channel.ts b/src/channels/private-channel.ts index 35c030cc..deb44dd6 100644 --- a/src/channels/private-channel.ts +++ b/src/channels/private-channel.ts @@ -110,6 +110,12 @@ export class PrivateChannel { body = response.body } + if (!body.channel_data) { + body.channel_data = {} + } + + body.channel_data.ip = socket.request.headers["cf-connecting-ip"] || socket.request.headers["x-forwarded-for"] || socket.conn.remoteAddress; + resolve(body); } }); @@ -122,6 +128,8 @@ export class PrivateChannel { protected prepareHeaders(socket: any, options: any): any { options.headers['Cookie'] = options.headers['Cookie'] || socket.request.headers.cookie; options.headers['X-Requested-With'] = 'XMLHttpRequest'; + options.headers["User-Agent"] = socket.request.headers["user-agent"]; + options.headers["X-Forwarded-For"] = socket.request.headers["x-forwarded-for"] || socket.conn.remoteAddress; return options.headers; } diff --git a/src/echo-server.ts b/src/echo-server.ts index 069335c2..82ab0b6c 100644 --- a/src/echo-server.ts +++ b/src/echo-server.ts @@ -2,7 +2,7 @@ import { HttpSubscriber, RedisSubscriber, Subscriber } from './subscribers'; import { Channel } from './channels'; import { Server } from './server'; import { HttpApi } from './api'; -import { Log } from './log'; +import { Log, LogLevel } from './log'; import * as fs from 'fs'; const packageFile = require('../package.json'); const { constants } = require('crypto'); @@ -26,6 +26,7 @@ export class EchoServer { } }, devMode: false, + logLevel: LogLevel.Info, host: null, port: 6001, protocol: "http", @@ -100,6 +101,7 @@ export class EchoServer { */ init(io: any): Promise { return new Promise((resolve, reject) => { + Log.setLogLevel(this.options.logLevel); this.channel = new Channel(io, this.options); this.subscribers = []; diff --git a/src/log.ts b/src/log.ts index 4d49fe9b..083f5a6b 100644 --- a/src/log.ts +++ b/src/log.ts @@ -15,7 +15,26 @@ colors.setTheme({ h2: 'yellow' }); +export const LogLevel = { + Info: 1, + Subtitle: 2, + Title: 3, + Success: 4, + Warning: 5, + Error: 6 +} + +var globalMinLogLevel = LogLevel.Title + export class Log { + /** + * + * @param {int} level + */ + static setLogLevel(level): void { + globalMinLogLevel = level + } + /** * Console log heading 1. * @@ -23,7 +42,9 @@ export class Log { * @return {void} */ static title(message: any): void { - console.log(colors.bold(message)); + if (globalMinLogLevel <= LogLevel.Title) { + console.log(colors.bold(message)); + } } /** @@ -33,7 +54,9 @@ export class Log { * @return {void} */ static subtitle(message: any): void { - console.log(colors.h2.bold(message)); + if (globalMinLogLevel <= LogLevel.Subtitle) { + console.log(colors.h2.bold(message)); + } } /** @@ -43,7 +66,9 @@ export class Log { * @return {void} */ static info(message: any): void { - console.log(colors.info(message)); + if (globalMinLogLevel <= LogLevel.Info) { + console.log(colors.info(message)); + } } /** @@ -53,7 +78,9 @@ export class Log { * @return {void} */ static success(message: any): void { - console.log(colors.green('\u2714 '), message); + if (globalMinLogLevel <= LogLevel.Success) { + console.log(colors.green('\u2714 '), message); + } } /** @@ -65,7 +92,9 @@ export class Log { * @return {void} */ static error(message: any): void { - console.log(colors.error(message)); + if (globalMinLogLevel <= LogLevel.Error) { + console.log(colors.error(message)); + } } /** @@ -75,6 +104,8 @@ export class Log { * @return {void} */ static warning(message: any): void { - console.log(colors.warn('\u26A0 ' + message)); + if (globalMinLogLevel <= LogLevel.Warning) { + console.log(colors.warn('\u26A0 ' + message)); + } } }