Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

store users IP in channel, add LogLevel filtering #613

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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` |
Expand All @@ -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`
Expand Down
24 changes: 19 additions & 5 deletions src/api/http-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
20 changes: 11 additions & 9 deletions src/channels/presence-channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
);
Expand Down
8 changes: 8 additions & 0 deletions src/channels/private-channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
});
Expand All @@ -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;
}
Expand Down
4 changes: 3 additions & 1 deletion src/echo-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand All @@ -26,6 +26,7 @@ export class EchoServer {
}
},
devMode: false,
logLevel: LogLevel.Info,
host: null,
port: 6001,
protocol: "http",
Expand Down Expand Up @@ -100,6 +101,7 @@ export class EchoServer {
*/
init(io: any): Promise<any> {
return new Promise((resolve, reject) => {
Log.setLogLevel(this.options.logLevel);
this.channel = new Channel(io, this.options);

this.subscribers = [];
Expand Down
43 changes: 37 additions & 6 deletions src/log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,36 @@ 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.
*
* @param {string|object} message
* @return {void}
*/
static title(message: any): void {
console.log(colors.bold(message));
if (globalMinLogLevel <= LogLevel.Title) {
console.log(colors.bold(message));
}
}

/**
Expand All @@ -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));
}
}

/**
Expand All @@ -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));
}
}

/**
Expand All @@ -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);
}
}

/**
Expand All @@ -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));
}
}

/**
Expand All @@ -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));
}
}
}