@Vandesm14/

LowChat

Nodejs

No description

fork
loading
Files
  • index.js
  • docs
  • .gitignore
  • app.js
  • db.json
  • LICENSE
  • package-lock.json
  • package.json
  • README.md
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/* jshint esversion: 6 */
const express = require('express');
const bodyParser = require('body-parser');
const fs = require('fs');
const camelCase = require('camelcase'); // NOTE: Unused

const app = express();
const http = require('http').Server(app);
const io = require('socket.io')(http);

fs.writeFile('db.json', '', 'utf8', () => {});
io.engine.generateId = function (req) {
	return randID();
};

var db = {
	users: {},
	rooms: {}
};

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
	extended: true
}));
app.use(express.static('docs'));

http.listen(3000, function () {
	console.log('listening on *:3000');
});

app.get('/', (req, res) => {
	res.sendFile(__dirname + '/docs/index.html');
});

app.get('/:room/', (req, res) => {
	res.sendFile(__dirname + '/docs/pages/room.html');
});

app.get('/:room/:user', (req, res) => {
	let room = req.params.room;
	let user = req.params.user;
	let ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
	ip = ip.replace('::ffff:', '');

	if (/\W/.test(user)) { // Illegal Username
		res.send('[LowChat] Error: Illegal characters present in username. The legal characters are "A-Z", "a-z", and "_".');
	} else if (/\W/.test(room)) { // Illegal Room Name
		res.send('[LowChat] Error: Illegal characters present in room name. The legal characters are "A-Z", "a-z", and "_".');
	} else if (Object.keys(db.users).find(obj => db.users[obj].room === room && obj === user && db.users[obj].ip !== ip)) { // Duplicate User
		res.send('[LowChat] Error: The user "' + user + '" already exists in the room. Please try a different username.');
	} else if (Object.keys(db.users).find(obj => db.users[obj].ip === ip && obj === user)) { // Duplicate IP as User
		res.send('[LowChat] Error: The user "' + user + '" is already assigned to an IP. Please try a different username.');
	} else if (!Object.keys(db.users).find(obj => db.users[obj].room === room && obj === user)) { // New User
		res.sendFile(__dirname + '/docs/pages/app.html');
	} else {
		res.status(501).send('[LowChat] Error: The server has encountered an error upon joining the room. Please return to the <a href="/">homepage</a>.');
	}
	fs.writeFile('db.json', JSON.stringify(db, null, "\t"), 'utf8', () => {});
});

app.get('*', (req, res) => {
	// res.sendFile(__dirname + '/docs/pages/error.html');
	res.status(404).send('Server Error: 404 Not Found');
});

app.get('*', (req, res) => {
	// res.sendFile(__dirname + '/docs/pages/error.html');
	res.status(404).send('Server Error: 404 Not Found');
});

io.on('connection', function (socket) {
	socket.on('init', function (data) {
		let user = data.user;
		let room = data.room;
		let ip = (socket.handshake.headers["x-real-ip"] || socket.conn.remoteAddress).replace('::ffff:', '');

		socket.join(room);
		socket.emit('init-back', randID());

		if (db.users[user] === undefined) { // User doesn't already exist, add ID, add IP
			db.users[user] = {
				room: room,
				id: socket.id,
				ip: ip
			};
		} else { // TODO: Determin wether to keep or delete this (it's never used)
			Object.keys(db.users).find((obj) => {
				if (db.users[obj].room === room && obj === user) { // Checks for current user
					db.users[obj].id = socket.id;
					db.users[obj].ip = ip;
					return;
				}
			});
		}
		socket.to(room).emit('server', `User ${user} has joined the channel`);
		console.log(`User ${socket.id} is now known as "${user}"`);
		fs.writeFile('db.json', JSON.stringify(db, null, "\t"), 'utf8', () => {});
	});

	socket.on('message', function (data) {
		let ip = (socket.handshake.headers["x-real-ip"] || socket.conn.remoteAddress).replace('::ffff:', '');
		let room;

		Object.keys(db.users).find((obj) => { // Find room in which user is in
			if (db.users[obj].id === socket.id && obj === data.user) {
				room = db.users[obj].room;
				return;
			}
		});

		if (data.message[0] === '/') { // If message is a command
			switch (data.message.split(' ')[0]) {
				case '/users':
					let message = [];
					Object.keys(db.users).find((obj) => {
						if (db.users[obj].room === room) {
							message.push(obj);
						}
					});
					socket.emit('server', message.join(', '));
					break;
			}
		} else {
			socket.to(room).emit('message', {
				user: data.user,
				message: sanitize(data.message)
			});
		}
	});

	socket.on('disconnect', function () {
		let ip = (socket.handshake.headers["x-real-ip"] || socket.conn.remoteAddress).replace('::ffff:', '');
		Object.keys(db.users).find((obj) => {
			if (db.users[obj].id === socket.id) { // Note SocketID is unique so checking for room isn't needed
				socket.to(db.users[obj].room).emit('server', `User ${obj} has left the channel`);
				delete db.users[obj];
				console.log(`User ${socket.id} (${obj}) has disconnected`);
				return;
			}
		});
		fs.writeFile('db.json', JSON.stringify(db, null, "\t"), 'utf8', () => {});
	});
});

function sanitize(text) {
	return text.replace(/<(?:.|\n)*>/gi, '[html]');
}

function randID() {
	return Math.random().toString(36).substr(2) + Math.random().toString(36).substr(2);
}
node v10.16.0