Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
1 change: 1 addition & 0 deletions changelog.d/110.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Include any certfp lines in a whois response.
4 changes: 4 additions & 0 deletions src/codes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ export const replyCodes = {
name: 'rpl_globalusers',
type: 'reply'
},
276: {
name: 'rpl_whoiscertfp',
type: 'reply',
},
300: {
name: 'rpl_none',
type: 'reply'
Expand Down
12 changes: 7 additions & 5 deletions src/irc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1052,6 +1052,8 @@ export class Client extends (EventEmitter as unknown as new () => TypedEmitter<C
return this._addWhoisData(message.args[1], 'serverinfo', message.args[3]);
case 'rpl_whoisactually':
return this._addWhoisData(message.args[1], 'realHost', message.args[2]);
case 'rpl_whoiscertfp':
return this._addWhoisData(message.args[1], 'certfp', message.args[2]);
case 'rpl_whoisoperator':
return this._addWhoisData(message.args[1], 'operator', message.args[2]);
case 'rpl_whoisaccount':
Expand Down Expand Up @@ -1452,6 +1454,7 @@ export class Client extends (EventEmitter as unknown as new () => TypedEmitter<C
* unmaps the client instance from the socket. The state will also need to be cleared up seperately.
*/
public destroy() {
util.log('Destroying connection');
(
['data', 'end', 'close', 'timeout', 'error'] as (keyof IrcConnectionEventsMap)[]
).forEach(evtType => {
Expand Down Expand Up @@ -1692,11 +1695,10 @@ export class Client extends (EventEmitter as unknown as new () => TypedEmitter<C

private _addWhoisData(nick: string, key: keyof(WhoisResponse), value: string|string[], onlyIfExists = false) {
if (onlyIfExists && !this.state.whoisData.has(nick)) {return;}
const data: WhoisResponse = {
...this.state.whoisData.get(nick),
nick,
[key]: value,
};
const data: WhoisResponse = this.state.whoisData.get(nick) || { nick };
// Note: Type unsafety, it's possible we might be trying to insert a string into a string[] or vice versa.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
data[key] = value as any;
this.state.whoisData.set(nick, data);
}

Expand Down
1 change: 1 addition & 0 deletions src/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface WhoisResponse {
account?: string;
accountinfo?: string;
realHost?: string;
certfp?: string;
}

export interface IrcSupported {
Expand Down
8 changes: 6 additions & 2 deletions src/testing/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { randomUUID } from 'crypto';
import { Client, ClientEvents, Message } from '..';
import { Client, ClientEvents, IrcClientOpts, Message } from '..';

const DEFAULT_PORT = parseInt(process.env.IRC_TEST_PORT ?? '6667', 10);
const DEFAULT_ADDRESS = process.env.IRC_TEST_ADDRESS ?? "127.0.0.1";
Expand Down Expand Up @@ -75,7 +75,10 @@ export class TestIrcServer {
}

public readonly clients: Record<string, TestClient> = {};
constructor(public readonly address = DEFAULT_ADDRESS, public readonly port = DEFAULT_PORT) { }
constructor(
public readonly address = DEFAULT_ADDRESS, public readonly port = DEFAULT_PORT,
public readonly customConfig: Partial<IrcClientOpts> = {}
) { }

async setUp(clients = ['speaker', 'listener']) {
const connections: Promise<void>[] = [];
Expand All @@ -86,6 +89,7 @@ export class TestIrcServer {
autoConnect: false,
connectionTimeout: 4000,
debug: true,
...this.customConfig,
});
this.clients[clientName] = client;
// Make sure we load isupport before reporting readyness.
Expand Down