simple webirc integration, debug mode

This commit is contained in:
Evert Prants 2016-09-25 16:09:55 +03:00
parent be6151be6b
commit 2d22402cb0
9 changed files with 126 additions and 22 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
/node_modules/
/build/
/client.config.toml
/webirc.data.json

View File

@ -10,10 +10,13 @@ This application requires [node.js](https://nodejs.org/) to be installed.
The client will be accessible at http://localhost:8080/
### WebIRC
The server will look for passwords in `webirc.data.json`. The format is: `"server-ip-address": "server webirc password"`
###The (non-complete) TODO List (of things left to do)
* [HIGH] Settings menu
* [HIGH] WebIRC protocol integration
* [MEDIUM] Theme engine
* [NORMAL] CAP negotiation
* [LOW] Better input

View File

@ -1,5 +1,6 @@
[server]
port=8080
debug=true
[client]
username="teemant"

View File

@ -180,7 +180,7 @@ body {
bottom: 46px;
}
.ircclient #chat .ircwrapper .chatarea .smsc-nicklistbtn {
background-image: url("/image/users.svg");
background-image: url("image/users.svg");
background-repeat: no-repeat;
background-size: contain;
width: 46px;
@ -313,7 +313,7 @@ body {
box-shadow: inset 4px 4px 8px #d8d8d8;
}
.ircclient #chat .ircwrapper .input .sendbutton {
background-image: url("/image/send.svg");
background-image: url("image/send.svg");
background-repeat: no-repeat;
background-size: contain;
width: 32px;

View File

@ -602,7 +602,8 @@ class Buffer {
appendMessage(meta) {
let mesgConstr = composer.message[irc.chatType](meta.time, meta.sender, meta.message, meta.type);
if((meta.type == "privmsg" || meta.type == "notice") && meta.message.indexOf(irc.serverData[this.server].my_nick) != -1)
if((meta.type == "privmsg" || meta.type == "notice" || meta.type == "action") &&
meta.message.indexOf(irc.serverData[this.server].my_nick) != -1)
addClass(mesgConstr, "mentioned");
clientdom.letterbox.appendChild(mesgConstr);
@ -630,7 +631,8 @@ class Buffer {
this.appendMessage(mesg);
} else {
this.unreadCount += 1;
if((type == "privmsg" || type == "notice") && message.indexOf(irc.serverData[this.server].my_nick) != -1)
if((type == "privmsg" || type == "notice" || type == "action") &&
message.indexOf(irc.serverData[this.server].my_nick) != -1)
console.log("TODO: notify user of mentioned");
}

View File

@ -161,7 +161,7 @@ body
width: 100%;
bottom: 46px;
.smsc-nicklistbtn
background-image: url(/image/users.svg);
background-image: url(image/users.svg);
background-repeat: no-repeat;
background-size: contain;
width: 46px;
@ -277,7 +277,7 @@ body
border-left: 0
box-shadow: inset 4px 4px 8px #d8d8d8
.sendbutton
background-image: url(/image/send.svg);
background-image: url(image/send.svg);
background-repeat: no-repeat;
background-size: contain;
width: 32px;

View File

@ -2,6 +2,7 @@ let EventEmitter = require('events').EventEmitter;
let net = require('net');
let configuration = require(__dirname+"/config");
let parse = require(__dirname+"/parser");
let webirc = require(__dirname+"/webirc");
if (!String.prototype.format) {
String.prototype.format = function() {
@ -18,7 +19,6 @@ class IRCConnectionHandler {
}
handleUserLine(data) {
console.log(data);
switch(data.command) {
case "kick":
case "part":
@ -68,7 +68,6 @@ class IRCConnectionHandler {
}
handleServerLine(line) {
console.log(line);
if(this.conn.queue["supportsmsg"] && line.command != "005") {
delete this.conn.queue["supportsmsg"];
@ -334,7 +333,7 @@ class IRCConnectionHandler {
}
class IRCConnection extends EventEmitter {
constructor(providedInfo) {
constructor(providedInfo, userInfo) {
super();
this.config = {
@ -349,6 +348,8 @@ class IRCConnection extends EventEmitter {
address: "0.0.0.0"
};
this.userInfo = userInfo;
for(let a in providedInfo) {
this.config[a] = providedInfo[a];
}
@ -429,7 +430,11 @@ class IRCConnection extends EventEmitter {
if (this.config.password)
this.socket.write('PASS {0}\r\n'.format(this.config.password));
// TODO: WebIRC
let serverpass = webirc.get_password(this.config.address);
if(serverpass)
this.socket.write('WEBIRC {0} cgiirc {1} {2}\r\n'.format(serverpass, this.userInfo.hostname, this.userInfo.ipaddr));
this.socket.write('USER {0} 8 * :{1}\r\n'.format(this.config.username, this.config.realname));
this.socket.write('NICK {0}\r\n'.format(this.config.nickname));
}

45
server/webirc.js Normal file
View File

@ -0,0 +1,45 @@
let dns = require("dns");
let fs = require("fs");
let path = require("path");
let config = require(__dirname+'/config');
let webirc_data_path = path.resolve(__dirname+'/../webirc.data.json');
let webirc_data = {};
function writeToFile() {
fs.writeFile(webirc_data_path, JSON.stringify(webirc_data, null, '\t'), function (err) {if (err) throw err;});
}
function reload() {
try {
fs.accessSync(webirc_data_path, fs.F_OK);
webirc_data = require(webirc_data_path);
if (require.cache && require.cache[webirc_data_path]) {
delete require.cache[webirc_data_path];
}
} catch(e) {
writeToFile();
}
}
function get_password(server_ip) {
if(webirc_data[server_ip] != null)
return webirc_data[server_ip];
return null;
}
module.exports = {
reload: reload,
get_password: get_password,
writeToFile: writeToFile
}
process.on('SIGUSR1', () => {
console.log("!!! Received SIGUSR1; Reloading webirc data.. !!!");
reload();
});
reload();

View File

@ -6,7 +6,7 @@ let sockio = require("socket.io");
let dns = require("dns");
let app = express();
let pubdir = path.join(__dirname+"/public");
let pubdir = path.join(__dirname, "public");
let config = require(__dirname+'/server/config');
let ircclient = require(__dirname+'/server/irc');
@ -14,6 +14,8 @@ let port = config.server.port || 8080;
let connections = {};
process.stdin.resume();
app.get("/", function(req, res){
res.sendFile(pubdir+"/index.html");
});
@ -21,31 +23,54 @@ app.get("/", function(req, res){
app.use(express.static(__dirname + '/public'));
let io = sockio.listen(app.listen(port, function() {
console.log("*** Listening on port " + port);
console.log("*** Listening on http://localhost:" + port + "/");
}));
function resolveHostname(hostname) {
function resolveHostname(ipaddr) {
let promise = new Promise(function(resolve, reject) {
dns.lookup(hostname, function(err, address, family) {
dns.reverse(ipaddr, function(err, hostnames) {
if(err != null) return reject(err);
resolve(address);
resolve(hostnames);
});
});
return promise;
}
io.sockets.on('connection', function (socket) {
console.log('clientID: '+socket.id+' connection: ', socket.request.connection._peername);
connections[socket.id] = {}
let userip = socket.handshake.headers['x-real-ip'] || socket.handshake.headers['x-forwarded-for'] ||
socket.request.connection._peername.address || "127.0.0.1";
if(config.server.debug)
console.log('clientID: '+socket.id+' from: ', userip);
// New object for connections
connections[socket.id] = {
host: {
ipaddr: userip,
hostname: "localhost"
}
}
// Get the hostname of the connecting user
let hostQuery = resolveHostname(userip);
hostQuery.then((arr) => {
if(arr.length > 0)
connections[socket.id].host.hostname = arr[0];
if(config.server.debug)
console.log("Hostname of "+socket.id+" was determined to be "+connections[socket.id].host.hostname);
}).catch((err) => { console.log("Host resolve for "+socket.id+" failed: ", err); });
socket.on('disconnect', function() {
for (let d in connections[socket.id])
for (let d in connections[socket.id]) {
if(connections[socket.id][d].ipaddr) continue;
if(connections[socket.id][d].connected == true)
connections[socket.id][d].disconnect();
}
delete connections[socket.id];
console.log('clientID: '+socket.id+' disconnect');
if(config.server.debug)
console.log('clientID: '+socket.id+' disconnect');
});
socket.on('error', (e) => {
@ -57,14 +82,19 @@ io.sockets.on('connection', function (socket) {
if(!serv) return;
if(serv.authenticated == false) return;
if(config.server.debug)
console.log("["+socket.id+"] ->", data);
serv.handler.handleUserLine(data);
})
socket.on('irc_create', function(connectiondata) {
console.log(socket.id+" created irc connection: ", connectiondata);
if(config.server.debug)
console.log(socket.id+" created irc connection: ", connectiondata);
socket.emit('act_client', {type: 'connect_message', message: "Connecting to server..", error: false});
let newConnection = new ircclient(connectiondata);
let newConnection = new ircclient(connectiondata, connections[socket.id].host);
newConnection.connect();
connections[socket.id][connectiondata.server] = newConnection;
@ -75,6 +105,12 @@ io.sockets.on('connection', function (socket) {
max_channel_length: newConnection.data.max_channel_length});
});
if(config.server.debug) {
newConnection.on('line', function(line) {
console.log("["+socket.id+"] <-", line);
});
}
newConnection.on('connerror', (data) => {
let message = "An error occured";
let inconnect = true;
@ -110,3 +146,14 @@ io.sockets.on('connection', function (socket) {
});
});
});
process.on('SIGINT', () => {
console.log('!!! Received SIGINT; Terminating all IRC connections and exiting.. !!!');
for(let c in connections) {
for(let ircconn in connections[c]) {
if(connections[c][ircconn].ipaddr) continue;
connections[c][ircconn].disconnect();
}
}
process.exit();
});