modulize the irc connector

This commit is contained in:
Evert Prants 2016-10-02 15:08:36 +03:00
parent 871f5ae975
commit c54a92896f
7 changed files with 65 additions and 46 deletions

View File

@ -13,11 +13,3 @@ The client will be accessible at http://localhost:8080/
### WebIRC ### WebIRC
The server will look for passwords in `webirc.data.json`. The format is: `"server-ip-address": "server webirc password"` 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)
* [NORMAL] CAP negotiation
* [LOW] Better input
* [LOW] irc:// URL scheme handling
* [LOW] Connection presets
* [LOW] More command handling (use /quote for non-integrated commands)

View File

@ -10,6 +10,4 @@
secure_by_default=false secure_by_default=false
timeout=3000 timeout=3000
encoding="utf-8" encoding="utf-8"
rejectUnauthorizedCertificates=false
[tls]
rejectUnauthorized=false

View File

@ -0,0 +1,7 @@
let connector = require(__dirname+'/irc.js');
let parser = require(__dirname+'/parser.js');
module.exports = {
IRCConnection: connector,
Parser: parser
}

View File

@ -1,10 +1,8 @@
let EventEmitter = require('events').EventEmitter; let EventEmitter = require('events').EventEmitter;
let net = require('net'); let net = require('net');
let tls = require('tls'); let tls = require('tls');
let configuration = require(__dirname+"/config");
let pkg = require(__dirname+"/../package.json");
let parse = require(__dirname+"/parser"); let parse = require(__dirname+"/parser");
let webirc = require(__dirname+"/webirc");
if (!String.prototype.format) { if (!String.prototype.format) {
String.prototype.format = function() { String.prototype.format = function() {
@ -39,7 +37,8 @@ class IRCConnectionHandler {
this.conn.write('{0} {1}'.format(data.command.toUpperCase(), data.arguments[0])); this.conn.write('{0} {1}'.format(data.command.toUpperCase(), data.arguments[0]));
break; break;
case "quit": case "quit":
this.conn.write('{0} :{1}'.format(data.command.toUpperCase(), (data.message == '' ? configuration.client.default_quit_msg : data.message))); this.conn.write('{0} :{1}'.format(data.command.toUpperCase(), (data.message == '' ?
this.conn.globalConfig.default_quit_msg : data.message)));
break; break;
case "privmsg": case "privmsg":
this.conn.write('PRIVMSG {0} :{1}'.format(data.arguments[0], data.message)); this.conn.write('PRIVMSG {0} :{1}'.format(data.arguments[0], data.message));
@ -89,25 +88,18 @@ class IRCConnectionHandler {
ctcpManage(data) { ctcpManage(data) {
let line = data.trailing.replace(/\x01/g, '').trim().split(' '); let line = data.trailing.replace(/\x01/g, '').trim().split(' ');
if(!line[0]) return; if(!line[0]) return;
line[0] = line[0].toUpperCase();
let resp = "\x01"+line[0]+" {0}\x01"; let resp = "\x01"+line[0]+" {0}\x01";
switch(line[0].toLowerCase()) { if(line[0] == "PING" && line[1] != null && line[1] != '') {
case "ping": resp = resp.format(line.slice(1).join(' '));
if(line[1] != null && line[1] != '') } else if(this.conn.extras.ctcps && this.conn.extras.ctcps[line[0]] != null) {
resp = resp.format(line.slice(1).join(' ')); resp = resp.format(this.conn.extras.ctcps[line[0]](data, this.conn));
else } else {
resp = null; resp = null;
break;
case "version":
resp = resp.format("TeemantIRC ver. {0} - {1} - https://teemant.icynet.ml/".format(pkg.version, pkg.description));
break;
case "source":
resp = resp.format("https://github.com/DiamondtechDev/TeemantIRC");
break;
default:
resp = null;
} }
if (resp != null) if (resp != null)
@ -418,24 +410,24 @@ class IRCConnectionHandler {
} }
class IRCConnection extends EventEmitter { class IRCConnection extends EventEmitter {
constructor(providedInfo, userInfo) { constructor(providedInfo, globalConfig, extras) {
super(); super();
this.globalConfig = globalConfig;
this.extras = extras || { authenticationSteps: [], ctcps: {} };
this.config = { this.config = {
nickname: "teemant", nickname: "teemant",
username: configuration.client.username, username: globalConfig.username,
realname: configuration.client.realname, realname: globalConfig.realname,
server: "localhost", server: "localhost",
port: 6667, port: 6667,
autojoin: [], autojoin: [],
secure: configuration.client.secure_by_default, secure: globalConfig.secure_by_default,
password: "", password: "",
address: "0.0.0.0", address: "0.0.0.0",
rejectUnauthorized: configuration.tls.rejectUnauthorized rejectUnauthorized: globalConfig.rejectUnauthorizedCertificates
}; };
this.userInfo = userInfo;
for(let a in providedInfo) { for(let a in providedInfo) {
this.config[a] = providedInfo[a]; this.config[a] = providedInfo[a];
} }
@ -472,8 +464,8 @@ class IRCConnection extends EventEmitter {
this.authenticate(); this.authenticate();
}); });
this.socket.setEncoding(configuration.client.encoding); this.socket.setEncoding(this.globalConfig.encoding);
this.socket.setTimeout(configuration.client.timeout); this.socket.setTimeout(this.globalConfig.timeout);
this.socket.on('error', (data) => { this.socket.on('error', (data) => {
this.emit('connerror', {type: "sock_error", message: "A socket error occured.", raw: data}); this.emit('connerror', {type: "sock_error", message: "A socket error occured.", raw: data});
@ -518,10 +510,12 @@ class IRCConnection extends EventEmitter {
if (this.config.password) if (this.config.password)
this.socket.write('PASS {0}\r\n'.format(this.config.password)); this.socket.write('PASS {0}\r\n'.format(this.config.password));
let serverpass = webirc.get_password(this.config.address); if(this.extras.authenticationSteps) {
for(let i in this.extras.authenticationSteps) {
if(serverpass) let step = this.extras.authenticationSteps[i];
this.socket.write('WEBIRC {0} {1} {2} {3}\r\n'.format(serverpass, this.config.username, this.userInfo.hostname, this.userInfo.ipaddr)); step.authenticate(this);
}
}
this.socket.write('USER {0} 8 * :{1}\r\n'.format(this.config.username, this.config.realname)); 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)); this.socket.write('NICK {0}\r\n'.format(this.config.nickname));
@ -534,7 +528,7 @@ class IRCConnection extends EventEmitter {
} }
this.queue['close'] = true; this.queue['close'] = true;
this.socket.write('QUIT :{0}\r\n'.format(message != null ? message : configuration.client.default_quit_msg)); this.socket.write('QUIT :{0}\r\n'.format(message != null ? message : this.globalConfig.default_quit_msg));
} }
write(message) { write(message) {

View File

@ -31,8 +31,22 @@ function get_password(server_ip) {
return null; return null;
} }
class WebIRCAuthenticator {
constructor(userInfo) {
this.userInfo = userInfo;
}
authenticate(connection) {
let serverpass = get_password(connection.config.address);
if(serverpass)
connection.socket.write('WEBIRC '+serverpass+' '+connection.config.username+
' '+this.userInfo.hostname+' '+this.userInfo.ipaddr+'\r\n');
}
}
module.exports = { module.exports = {
reload: reload, reload: reload,
authenticator: WebIRCAuthenticator,
get_password: get_password, get_password: get_password,
writeToFile: writeToFile writeToFile: writeToFile
} }

View File

@ -8,8 +8,11 @@ let app = express();
let router = express.Router(); let router = express.Router();
let pubdir = path.join(__dirname, "public"); let pubdir = path.join(__dirname, "public");
let pkg = require(__dirname+"/package.json");
let config = require(__dirname+'/server/config'); let config = require(__dirname+'/server/config');
let ircclient = require(__dirname+'/server/irc'); let irclib = require(__dirname+'/server/teemant_irc');
let webirc = require(__dirname+'/server/webirc');
let port = config.server.port || 8080; let port = config.server.port || 8080;
@ -19,6 +22,15 @@ let runtime_stats = {
let connections = {}; let connections = {};
let customCTCPs = {
VERSION: function(data, connection) {
return "TeemantIRC ver. "+pkg.version+" - "+pkg.description+" - https://teemant.icynet.ml/";
},
SOURCE: function(data, connection) {
return "https://github.com/DiamondtechDev/TeemantIRC";
}
}
process.stdin.resume(); process.stdin.resume();
router.get("/", function(req, res){ router.get("/", function(req, res){
@ -135,7 +147,9 @@ io.sockets.on('connection', function (socket) {
socket.emit('act_client', {type: 'connect_message', message: "Connecting to server..", error: false}); socket.emit('act_client', {type: 'connect_message', message: "Connecting to server..", error: false});
let newConnection = new ircclient(connectiondata, connections[socket.id].host); let newConnection = new irclib.IRCConnection(connectiondata, config.client,
{authenticationSteps: [new webirc.authenticator(connections[socket.id].host)], ctcps: customCTCPs});
newConnection.connect(); newConnection.connect();
connections[socket.id][connectiondata.server] = newConnection; connections[socket.id][connectiondata.server] = newConnection;