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
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
timeout=3000
encoding="utf-8"
[tls]
rejectUnauthorized=false
rejectUnauthorizedCertificates=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 net = require('net');
let tls = require('tls');
let configuration = require(__dirname+"/config");
let pkg = require(__dirname+"/../package.json");
let parse = require(__dirname+"/parser");
let webirc = require(__dirname+"/webirc");
if (!String.prototype.format) {
String.prototype.format = function() {
@ -39,7 +37,8 @@ class IRCConnectionHandler {
this.conn.write('{0} {1}'.format(data.command.toUpperCase(), data.arguments[0]));
break;
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;
case "privmsg":
this.conn.write('PRIVMSG {0} :{1}'.format(data.arguments[0], data.message));
@ -89,25 +88,18 @@ class IRCConnectionHandler {
ctcpManage(data) {
let line = data.trailing.replace(/\x01/g, '').trim().split(' ');
if(!line[0]) return;
line[0] = line[0].toUpperCase();
let resp = "\x01"+line[0]+" {0}\x01";
switch(line[0].toLowerCase()) {
case "ping":
if(line[1] != null && line[1] != '')
resp = resp.format(line.slice(1).join(' '));
else
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(line[0] == "PING" && line[1] != null && line[1] != '') {
resp = resp.format(line.slice(1).join(' '));
} else if(this.conn.extras.ctcps && this.conn.extras.ctcps[line[0]] != null) {
resp = resp.format(this.conn.extras.ctcps[line[0]](data, this.conn));
} else {
resp = null;
}
if (resp != null)
@ -418,24 +410,24 @@ class IRCConnectionHandler {
}
class IRCConnection extends EventEmitter {
constructor(providedInfo, userInfo) {
constructor(providedInfo, globalConfig, extras) {
super();
this.globalConfig = globalConfig;
this.extras = extras || { authenticationSteps: [], ctcps: {} };
this.config = {
nickname: "teemant",
username: configuration.client.username,
realname: configuration.client.realname,
username: globalConfig.username,
realname: globalConfig.realname,
server: "localhost",
port: 6667,
autojoin: [],
secure: configuration.client.secure_by_default,
secure: globalConfig.secure_by_default,
password: "",
address: "0.0.0.0",
rejectUnauthorized: configuration.tls.rejectUnauthorized
rejectUnauthorized: globalConfig.rejectUnauthorizedCertificates
};
this.userInfo = userInfo;
for(let a in providedInfo) {
this.config[a] = providedInfo[a];
}
@ -472,8 +464,8 @@ class IRCConnection extends EventEmitter {
this.authenticate();
});
this.socket.setEncoding(configuration.client.encoding);
this.socket.setTimeout(configuration.client.timeout);
this.socket.setEncoding(this.globalConfig.encoding);
this.socket.setTimeout(this.globalConfig.timeout);
this.socket.on('error', (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)
this.socket.write('PASS {0}\r\n'.format(this.config.password));
let serverpass = webirc.get_password(this.config.address);
if(serverpass)
this.socket.write('WEBIRC {0} {1} {2} {3}\r\n'.format(serverpass, this.config.username, this.userInfo.hostname, this.userInfo.ipaddr));
if(this.extras.authenticationSteps) {
for(let i in this.extras.authenticationSteps) {
let step = this.extras.authenticationSteps[i];
step.authenticate(this);
}
}
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));
@ -534,7 +528,7 @@ class IRCConnection extends EventEmitter {
}
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) {

View File

@ -31,8 +31,22 @@ function get_password(server_ip) {
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 = {
reload: reload,
authenticator: WebIRCAuthenticator,
get_password: get_password,
writeToFile: writeToFile
}

View File

@ -8,8 +8,11 @@ let app = express();
let router = express.Router();
let pubdir = path.join(__dirname, "public");
let pkg = require(__dirname+"/package.json");
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;
@ -19,6 +22,15 @@ let runtime_stats = {
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();
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});
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();
connections[socket.id][connectiondata.server] = newConnection;