Correctly reading restrict_server_ssl from config
[KiwiIRC.git] / server / client.js
CommitLineData
f3dbbd91
D
1var util = require('util'),
2 events = require('events'),
c36ed4eb 3 crypto = require('crypto'),
f9ff7686 4 _ = require('lodash'),
ce6a4656 5 State = require('./irc/state.js'),
2a8e95d1 6 IrcConnection = require('./irc/connection.js').IrcConnection,
c36ed4eb 7 ClientCommands = require('./clientcommands.js');
a8bf3ea4 8
772a4bb6 9
a8bf3ea4 10var Client = function (websocket) {
772a4bb6 11 var that = this;
a8bf3ea4
JA
12
13 events.EventEmitter.call(this);
14 this.websocket = websocket;
26322e8f
D
15
16 // Clients address
c36ed4eb 17 this.real_address = this.websocket.handshake.real_address;
26322e8f
D
18
19 // A hash to identify this client instance
ad01b1a7
D
20 this.hash = crypto.createHash('sha256')
21 .update(this.real_address)
22 .update('' + Date.now())
23 .update(Math.floor(Math.random() * 100000).toString())
24 .digest('hex');
a8bf3ea4 25
76ff1063 26 this.state = new State(this);
a8bf3ea4
JA
27
28 this.buffer = {
29 list: [],
30 motd: ''
31 };
32
f3dbbd91 33 // Handler for any commands sent from the client
2a8e95d1 34 this.client_commands = new ClientCommands(this);
f3dbbd91 35
a8bf3ea4 36 websocket.on('irc', function () {
772a4bb6 37 handleClientMessage.apply(that, arguments);
a8bf3ea4
JA
38 });
39 websocket.on('kiwi', function () {
772a4bb6 40 kiwiCommand.apply(that, arguments);
a8bf3ea4
JA
41 });
42 websocket.on('disconnect', function () {
772a4bb6 43 websocketDisconnect.apply(that, arguments);
a8bf3ea4
JA
44 });
45 websocket.on('error', function () {
772a4bb6 46 websocketError.apply(that, arguments);
a8bf3ea4 47 });
7d1ad2df
JA
48
49 this.disposed = false;
a8bf3ea4
JA
50};
51util.inherits(Client, events.EventEmitter);
52
53module.exports.Client = Client;
54
55// Callback API:
56// Callbacks SHALL accept 2 arguments, error and response, in that order.
57// error MUST be null where the command is successul.
58// error MUST otherwise be a truthy value and SHOULD be a string where the cause of the error is known.
59// response MAY be given even if error is truthy
60
2f1e8a71 61Client.prototype.sendIrcCommand = function (command, data, callback) {
a8bf3ea4 62 var c = {command: command, data: data};
a8bf3ea4
JA
63 this.websocket.emit('irc', c, callback);
64};
65
d2d91c10
D
66Client.prototype.sendKiwiCommand = function (command, data, callback) {
67 var c = {command: command, data: data};
68 this.websocket.emit('kiwi', c, callback);
a8bf3ea4
JA
69};
70
c08717da 71Client.prototype.dispose = function () {
7d1ad2df 72 this.disposed = true;
5befab98 73 this.emit('dispose');
c08717da
D
74 this.removeAllListeners();
75};
76
772a4bb6 77function handleClientMessage(msg, callback) {
760fa05a 78 var server;
f3dbbd91
D
79
80 // Make sure we have a server number specified
81 if ((msg.server === null) || (typeof msg.server !== 'number')) {
40af34d4 82 return (typeof callback === 'function') ? callback('server not specified') : undefined;
76ff1063 83 } else if (!this.state.irc_connections[msg.server]) {
40af34d4 84 return (typeof callback === 'function') ? callback('not connected to server') : undefined;
a8bf3ea4 85 }
f3dbbd91
D
86
87 // The server this command is directed to
76ff1063 88 server = this.state.irc_connections[msg.server];
f3dbbd91
D
89
90 if (typeof callback !== 'function') {
91 callback = null;
40ce1c01 92 }
f3dbbd91
D
93
94 try {
95 msg.data = JSON.parse(msg.data);
96 } catch (e) {
97 kiwi.log('[handleClientMessage] JSON parsing error ' + msg.data);
98 return;
a8bf3ea4 99 }
f3dbbd91
D
100
101 // Run the client command
102 this.client_commands.run(msg.data.method, msg.data.args, server, callback);
d2d91c10 103}
a8bf3ea4 104
f3dbbd91
D
105
106
107
772a4bb6 108function kiwiCommand(command, callback) {
a8bf3ea4
JA
109 if (typeof callback !== 'function') {
110 callback = function () {};
111 }
760fa05a 112
a8bf3ea4 113 switch (command.command) {
93e84f75
D
114 case 'connect':
115 if (command.hostname && command.port && command.nick) {
116 var con;
117
c3204224
PV
118 this.state.connect(
119 (global.config.restrict_server || command.hostname),
120 (global.config.restrict_server_port || command.port),
52b27d90
D
121 (typeof global.config.restrict_server_ssl !== 'undefined' ?
122 global.config.restrict_server_ssl :
123 command.ssl),
c3204224
PV
124 command.nick,
125 {hostname: this.websocket.handshake.revdns, address: this.websocket.handshake.real_address},
126 (global.config.restrict_server_password || command.password),
127 callback);
93e84f75
D
128 } else {
129 return callback('Hostname, port and nickname must be specified');
130 }
131 break;
132 default:
133 callback();
a8bf3ea4 134 }
c08717da 135}
a8bf3ea4 136
a8bf3ea4 137
772a4bb6
D
138// Websocket has disconnected, so quit all the IRC connections
139function websocketDisconnect() {
76ff1063 140 this.emit('disconnect');
e6b973da
D
141
142 this.dispose();
c08717da 143}
a8bf3ea4 144
772a4bb6
D
145
146// TODO: Should this close all the websocket connections too?
147function websocketError() {
c36ed4eb 148 this.dispose();
c3204224 149}