Skip to content

Commit

Permalink
whowas: return all responses from the server
Browse files Browse the repository at this point in the history
Whowas results are a list of all known RPL_WHOWASUSER replies.
Return the most recent event as the top level and add the
rest to a `historical` field as an array.

Example:

```
:inspircd.server.example 314 val someone ident3 127.0.0.1 * :Realname
:inspircd.server.example 312 val someone My.Little.Server :Sun Mar 20 2022 10:59:26
:inspircd.server.example 314 val someone ident2 127.0.0.1 * :Realname
:inspircd.server.example 312 val someone My.Little.Server :Sun Mar 20 2022 10:59:16
:inspircd.server.example 314 val someone ident1 127.0.0.1 * :Realname
:inspircd.server.example 312 val someone My.Little.Server :Sun Mar 19 2022 9:23:06
:inspircd.server.example 369 val someone :End of WHOWAS

whowas {
  nick: 'someone',
  ident: 'ident3',
  hostname: '127.0.0.1',
  real_name: 'Realname',
  server: 'My.Little.Server',
  server_info: 'Sun Mar 20 2022 10:59:26',
  historical: [
    {
      nick: 'someone',
      ident: 'ident2',
      hostname: '127.0.0.1',
      real_name: 'Realname',
      server: 'My.Little.Server',
      server_info: 'Sun Mar 20 2022 10:59:16'
    },
    {
      nick: 'someone',
      ident: 'ident1',
      hostname: '127.0.0.1',
      real_name: 'Realname',
      server: 'My.Little.Server',
      server_info: 'Sun Mar 19 2022 9:23:06'
    }
  ]
}
```

Fixes: #371
  • Loading branch information
brunnre8 committed Dec 28, 2023
1 parent f2989ca commit 55720c1
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 11 deletions.
8 changes: 8 additions & 0 deletions docs/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,10 @@ Not all of these options will be available. Some will be missing depending on th

**whowas**

The response includes the latest known data.
If more than one RPL_WHOWASUSER is returned by the server, older ones
are stored in the same format in the 'historical' array from newest to oldest.

If the requested user was not found, error will contain 'no_such_nick'.
~~~javascript
{
Expand All @@ -609,6 +613,10 @@ If the requested user was not found, error will contain 'no_such_nick'.
server_info: 'Thu Jun 14 09:15:51 2018',
account: 'logged on account',
error: ''
historical: [
{ ... },
{ ... },
]
}
~~~

Expand Down
50 changes: 39 additions & 11 deletions src/commands/handlers/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const _ = {
each: require('lodash/each'),
map: require('lodash/map'),
cloneDeep: require('lodash/cloneDeep'),
};
const Helpers = require('../../helpers');

Expand Down Expand Up @@ -325,12 +326,26 @@ const handlers = {

RPL_WHOWASUSER: function(command, handler) {
const cache_key = command.params[1].toLowerCase();
const cache = handler.cache('whois.' + cache_key);
const whois_cache = handler.cache('whois.' + cache_key);

// multiple RPL_WHOWASUSER replies are received prior to the RPL_ENDOFWHOWAS command
// one for each timestamp the server is aware of, from newest to oldest.
// They are optionally interleaved with various other numerics such as RPL_WHOISACTUALLY etc.
// Hence if we already find something we are receiving older data and need to make sure that we
// store anything already in the cache into its own entry
const whowas_cache = handler.cache('whowas.' + cache_key);
if (!whowas_cache.historical) {
// this will get populated by the next RPL_WHOWASUSER or RPL_ENDOFWHOWAS
whowas_cache.historical = [];
} else {
// push the previous event prior to modifying anything
whowas_cache.historical.push(_.cloneDeep(whois_cache));
}

cache.nick = command.params[1];
cache.ident = command.params[2];
cache.hostname = command.params[3];
cache.real_name = command.params[command.params.length - 1];
whois_cache.nick = command.params[1];
whois_cache.ident = command.params[2];
whois_cache.hostname = command.params[3];
whois_cache.real_name = command.params[command.params.length - 1];
},

RPL_ENDOFWHOWAS: function(command, handler) {
Expand All @@ -344,16 +359,29 @@ const handlers = {
// server_info, actual_username
// More optional fields MAY exist, depending on the type of ircd.
const cache_key = command.params[1].toLowerCase();
const cache = handler.cache('whois.' + cache_key);
const whois_cache = handler.cache('whois.' + cache_key);
const whowas_cache = handler.cache('whowas.' + cache_key);

// after all prior RPL_WHOWASUSER pushed newer events onto the history stack
// push the last one to complete the set (server returns from newest to oldest)
if (!whowas_cache.historical) {
whowas_cache.historical = [];
}
whowas_cache.historical.push(_.cloneDeep(whois_cache));

// now pull the newest response to the top level and add the rest as an array
const event = whowas_cache.historical[0];
event.historical = whowas_cache.historical.slice(1);

// Should, in theory, never happen.
if (!cache.nick) {
cache.nick = command.params[1];
cache.error = 'no_such_nick';
if (!event.nick) {
event.nick = command.params[1];
event.error = 'no_such_nick';
}

handler.emit('whowas', cache);
cache.destroy();
handler.emit('whowas', event);
whois_cache.destroy();
whowas_cache.destroy();
},

ERR_WASNOSUCHNICK: function(command, handler) {
Expand Down

0 comments on commit 55720c1

Please sign in to comment.