Skip to content

Commit 35e87c4

Browse files
whowas: return all responses from the server (#372)
whowas: return all responses from the server --------- Co-authored-by: ItsOnlyBinary <[email protected]>
1 parent 4ed9d28 commit 35e87c4

File tree

2 files changed

+48
-14
lines changed

2 files changed

+48
-14
lines changed

docs/events.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -596,19 +596,30 @@ Not all of these options will be available. Some will be missing depending on th
596596

597597
**whowas**
598598

599-
If the requested user was not found, error will contain 'no_such_nick'.
599+
The response root includes the latest data from `whowas[0]` to maintain backwards compatibility.
600+
The `whowas` array contains all RPL_WHOWASUSER responses with the newest being first.
601+
602+
If the requested user was not found, `error` will contain 'no_such_nick'.
603+
604+
> Note: The available data can vary depending on the network.
605+
600606
~~~javascript
601607
{
602608
nick: 'prawnsalad',
603609
ident: 'prawn',
604610
hostname: 'manchester.isp.net',
605611
actual_ip: 'sometimes set when using webirc, could be the same as actual_hostname',
606612
actual_hostname: 'sometimes set when using webirc',
613+
actual_username: 'prawn',
607614
real_name: 'A real prawn',
608615
server: 'irc.server.net',
609616
server_info: 'Thu Jun 14 09:15:51 2018',
610617
account: 'logged on account',
611618
error: ''
619+
whowas: [
620+
{ ... },
621+
{ ... },
622+
]
612623
}
613624
~~~
614625

src/commands/handlers/user.js

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -328,12 +328,29 @@ const handlers = {
328328

329329
RPL_WHOWASUSER: function(command, handler) {
330330
const cache_key = command.params[1].toLowerCase();
331-
const cache = handler.cache('whois.' + cache_key);
331+
let whois_cache = handler.cache('whois.' + cache_key);
332+
333+
// multiple RPL_WHOWASUSER replies are received prior to the RPL_ENDOFWHOWAS command
334+
// one for each timestamp the server is aware of, from newest to oldest.
335+
// They are optionally interleaved with various other numerics such as RPL_WHOISACTUALLY etc.
336+
// Hence if we already find something we are receiving older data and need to make sure that we
337+
// store anything already in the cache into its own entry
338+
const whowas_cache = handler.cache('whowas.' + cache_key);
339+
if (!whowas_cache.whowas) {
340+
// this will get populated by the next RPL_WHOWASUSER or RPL_ENDOFWHOWAS
341+
whowas_cache.whowas = [];
342+
} else {
343+
// push the previous event prior to modifying anything
344+
whowas_cache.whowas.push(whois_cache);
345+
// ensure we are starting with a clean cache for the next data
346+
whois_cache.destroy();
347+
whois_cache = handler.cache('whois.' + cache_key);
348+
}
332349

333-
cache.nick = command.params[1];
334-
cache.ident = command.params[2];
335-
cache.hostname = command.params[3];
336-
cache.real_name = command.params[command.params.length - 1];
350+
whois_cache.nick = command.params[1];
351+
whois_cache.ident = command.params[2];
352+
whois_cache.hostname = command.params[3];
353+
whois_cache.real_name = command.params[command.params.length - 1];
337354
},
338355

339356
RPL_ENDOFWHOWAS: function(command, handler) {
@@ -347,16 +364,22 @@ const handlers = {
347364
// server_info, actual_username
348365
// More optional fields MAY exist, depending on the type of ircd.
349366
const cache_key = command.params[1].toLowerCase();
350-
const cache = handler.cache('whois.' + cache_key);
351-
352-
// Should, in theory, never happen.
353-
if (!cache.nick) {
354-
cache.nick = command.params[1];
355-
cache.error = 'no_such_nick';
367+
const whois_cache = handler.cache('whois.' + cache_key);
368+
const whowas_cache = handler.cache('whowas.' + cache_key);
369+
370+
// after all prior RPL_WHOWASUSER pushed newer events onto the history stack
371+
// push the last one to complete the set (server returns from newest to oldest)
372+
whowas_cache.whowas = whowas_cache.whowas || [];
373+
if (!whois_cache.error) {
374+
whowas_cache.whowas.push(whois_cache);
375+
Object.assign(whowas_cache, whowas_cache.whowas[0]);
376+
} else {
377+
Object.assign(whowas_cache, whois_cache);
356378
}
357379

358-
handler.emit('whowas', cache);
359-
cache.destroy();
380+
handler.emit('whowas', whowas_cache);
381+
whois_cache.destroy();
382+
whowas_cache.destroy();
360383
},
361384

362385
ERR_WASNOSUCHNICK: function(command, handler) {

0 commit comments

Comments
 (0)