Commit | Line | Data |
---|---|---|
138d8d17 D |
1 | var _ = require('lodash'); |
2 | ||
3 | module.exports = function AddCommandHandlers(command_controller) { | |
4 | _.each(handlers, function(handler, handler_command) { | |
5 | command_controller.addHandler(handler_command, handler); | |
6 | }); | |
7 | }; | |
8 | ||
9 | ||
10 | var handlers = { | |
11 | RPL_WELCOME: function (command) { | |
12 | var nick = command.params[0]; | |
138d8d17 D |
13 | this.cap_negotiation = false; |
14 | this.emit('server ' + this.irc_connection.irc_host.hostname + ' connect', { | |
15 | nick: nick | |
16 | }); | |
17 | }, | |
18 | ||
19 | ||
20 | RPL_ISUPPORT: function (command) { | |
21 | var options, i, option, matches, j; | |
22 | options = command.params; | |
23 | for (i = 1; i < options.length; i++) { | |
24 | option = options[i].split("=", 2); | |
25 | option[0] = option[0].toUpperCase(); | |
26 | this.irc_connection.options[option[0]] = (typeof option[1] !== 'undefined') ? option[1] : true; | |
27 | if (_.include(['NETWORK', 'PREFIX', 'CHANTYPES', 'CHANMODES', 'NAMESX'], option[0])) { | |
28 | if (option[0] === 'PREFIX') { | |
29 | matches = /\(([^)]*)\)(.*)/.exec(option[1]); | |
30 | if ((matches) && (matches.length === 3)) { | |
31 | this.irc_connection.options.PREFIX = []; | |
32 | for (j = 0; j < matches[2].length; j++) { | |
33 | this.irc_connection.options.PREFIX.push({symbol: matches[2].charAt(j), mode: matches[1].charAt(j)}); | |
34 | } | |
35 | } | |
36 | } else if (option[0] === 'CHANTYPES') { | |
37 | this.irc_connection.options.CHANTYPES = this.irc_connection.options.CHANTYPES.split(''); | |
38 | } else if (option[0] === 'CHANMODES') { | |
39 | this.irc_connection.options.CHANMODES = option[1].split(','); | |
40 | } else if ((option[0] === 'NAMESX') && (!_.contains(this.irc_connection.cap.enabled, 'multi-prefix'))) { | |
41 | this.irc_connection.write('PROTOCTL NAMESX'); | |
42 | } | |
43 | } | |
44 | } | |
45 | this.emit('server ' + this.irc_connection.irc_host.hostname + ' options', { | |
46 | options: this.irc_connection.options, | |
47 | cap: this.irc_connection.cap.enabled | |
48 | }); | |
49 | }, | |
50 | ||
51 | ||
52 | CAP: function (command) { | |
53 | // TODO: capability modifiers | |
54 | // i.e. - for disable, ~ for requires ACK, = for sticky | |
55 | var capabilities = command.params[command.params.length - 1].replace(/(?:^| )[\-~=]/, '').split(' '); | |
56 | var request; | |
57 | ||
58 | // Which capabilities we want to enable | |
59 | var want = ['multi-prefix', 'away-notify', 'server-time', 'znc.in/server-time-iso', 'znc.in/server-time']; | |
60 | ||
61 | if (this.irc_connection.password) { | |
62 | want.push('sasl'); | |
63 | } | |
64 | ||
65 | switch (command.params[1]) { | |
66 | case 'LS': | |
67 | // Compute which of the available capabilities we want and request them | |
68 | request = _.intersection(capabilities, want); | |
69 | if (request.length > 0) { | |
70 | this.irc_connection.cap.requested = request; | |
71 | this.irc_connection.write('CAP REQ :' + request.join(' ')); | |
72 | } else { | |
73 | this.irc_connection.write('CAP END'); | |
74 | this.irc_connection.cap_negotiation = false; | |
75 | } | |
76 | break; | |
77 | case 'ACK': | |
78 | if (capabilities.length > 0) { | |
79 | // Update list of enabled capabilities | |
80 | this.irc_connection.cap.enabled = capabilities; | |
81 | // Update list of capabilities we would like to have but that aren't enabled | |
82 | this.irc_connection.cap.requested = _.difference(this.irc_connection.cap.requested, capabilities); | |
83 | } | |
84 | if (this.irc_connection.cap.enabled.length > 0) { | |
85 | if (_.contains(this.irc_connection.cap.enabled, 'sasl')) { | |
86 | this.irc_connection.sasl = true; | |
87 | this.irc_connection.write('AUTHENTICATE PLAIN'); | |
88 | } else { | |
89 | this.irc_connection.write('CAP END'); | |
90 | this.irc_connection.cap_negotiation = false; | |
91 | } | |
92 | } | |
93 | break; | |
94 | case 'NAK': | |
95 | if (capabilities.length > 0) { | |
96 | this.irc_connection.cap.requested = _.difference(this.irc_connection.cap.requested, capabilities); | |
97 | } | |
98 | if (this.irc_connection.cap.requested.length > 0) { | |
99 | this.irc_connection.write('CAP END'); | |
100 | this.irc_connection.cap_negotiation = false; | |
101 | } | |
102 | break; | |
103 | case 'LIST': | |
104 | // should we do anything here? | |
105 | break; | |
106 | } | |
107 | }, | |
108 | ||
109 | ||
110 | AUTHENTICATE: function (command) { | |
111 | var b = new Buffer(this.irc_connection.nick + "\0" + this.irc_connection.nick + "\0" + this.irc_connection.password, 'utf8'); | |
112 | var b64 = b.toString('base64'); | |
113 | if (command.params[0] === '+') { | |
114 | while (b64.length >= 400) { | |
115 | this.irc_connection.write('AUTHENTICATE ' + b64.slice(0, 399)); | |
116 | b64 = b64.slice(399); | |
117 | } | |
118 | if (b64.length > 0) { | |
119 | this.irc_connection.write('AUTHENTICATE ' + b64); | |
120 | } else { | |
121 | this.irc_connection.write('AUTHENTICATE +'); | |
122 | } | |
123 | } else { | |
124 | this.irc_connection.write('CAP END'); | |
125 | this.irc_connection.cap_negotiation = false; | |
126 | } | |
127 | }, | |
128 | ||
129 | ||
130 | RPL_SASLAUTHENTICATED: function (command) { | |
131 | this.irc_connection.write('CAP END'); | |
132 | this.irc_connection.cap_negotiation = false; | |
133 | this.irc_connection.sasl = true; | |
134 | }, | |
135 | ||
136 | ||
137 | RPL_SASLLOGGEDIN: function (command) { | |
138 | if (this.irc_connection.cap_negotiation === true) { | |
139 | this.irc_connection.write('CAP END'); | |
140 | this.irc_connection.cap_negotiation = false; | |
141 | } | |
142 | }, | |
143 | ||
144 | ERR_SASLNOTAUTHORISED: function (command) { | |
145 | this.irc_connection.write('CAP END'); | |
146 | this.irc_connection.cap_negotiation = false; | |
147 | }, | |
148 | ||
149 | ||
150 | ERR_SASLABORTED: function (command) { | |
151 | this.irc_connection.write('CAP END'); | |
152 | this.irc_connection.cap_negotiation = false; | |
153 | }, | |
154 | ||
155 | ||
156 | ERR_SASLALREADYAUTHED: function (command) { | |
157 | // noop | |
158 | } | |
159 | }; |