Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

whowas: return all responses from the server #372

Merged
merged 6 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion docs/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -596,19 +596,30 @@ Not all of these options will be available. Some will be missing depending on th

**whowas**

If the requested user was not found, error will contain 'no_such_nick'.
The response root includes the latest data from `whowas[0]` to maintain backwards compatibility.
The `whowas` array contains all RPL_WHOWASUSER responses with the newest being first.

If the requested user was not found, `error` will contain 'no_such_nick'.

> Note: The available data can vary depending on the network.

~~~javascript
{
nick: 'prawnsalad',
ident: 'prawn',
hostname: 'manchester.isp.net',
actual_ip: 'sometimes set when using webirc, could be the same as actual_hostname',
actual_hostname: 'sometimes set when using webirc',
actual_username: 'prawn',
real_name: 'A real prawn',
server: 'irc.server.net',
server_info: 'Thu Jun 14 09:15:51 2018',
account: 'logged on account',
error: ''
whowas: [
{ ... },
{ ... },
]
}
~~~

Expand Down
49 changes: 36 additions & 13 deletions src/commands/handlers/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -325,12 +325,29 @@ const handlers = {

RPL_WHOWASUSER: function(command, handler) {
const cache_key = command.params[1].toLowerCase();
const cache = handler.cache('whois.' + cache_key);
let 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.whowas) {
// this will get populated by the next RPL_WHOWASUSER or RPL_ENDOFWHOWAS
whowas_cache.whowas = [];
} else {
// push the previous event prior to modifying anything
whowas_cache.whowas.push(whois_cache);
// ensure we are starting with a clean cache for the next data
whois_cache.destroy();
whois_cache = handler.cache('whois.' + cache_key);
}

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 +361,22 @@ 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);

// Should, in theory, never happen.
if (!cache.nick) {
cache.nick = command.params[1];
cache.error = 'no_such_nick';
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)
whowas_cache.whowas = whowas_cache.whowas || [];
if (!whois_cache.error) {
whowas_cache.whowas.push(whois_cache);
Object.assign(whowas_cache, whowas_cache.whowas[0]);
} else {
Object.assign(whowas_cache, whois_cache);
}

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

ERR_WASNOSUCHNICK: function(command, handler) {
Expand Down
Loading