1
import EventEmitter from 'node:events';
2
import { type Agent } from 'node:http';
3
import { afterEach, beforeEach, expect, test, vi, type Mock } from 'vitest';
4
import { agentWithIpValidation, type _Agent } from './agent-with-ip-validation.js';
5
import { isDeniedIp } from './is-denied-ip.js';
7
vi.mock('./is-denied-ip.js');
9
let mockSocket: EventEmitter & { destroy?: Mock };
13
mockSocket = new EventEmitter();
14
mockSocket.destroy = vi.fn();
16
const httpAgent = { createConnection: vi.fn().mockReturnValue(mockSocket) } as unknown as Agent;
18
mockAgent = agentWithIpValidation(httpAgent) as _Agent;
25
test('Blocks request if host is missing', () => {
28
expect(() => mockAgent.createConnection(options, () => {})).toThrowError(
29
`Request cannot be verified due to missing host`,
33
test('Does not call IP check on createConnection if host is not an IP', () => {
34
const options = { host: 'directus.io' };
36
mockAgent.createConnection(options, () => {});
38
expect(isDeniedIp).not.toHaveBeenCalled();
41
test('Calls IP check on createConnection if host is IP', async () => {
42
const options = { host: '127.0.0.1' };
44
mockAgent.createConnection(options, () => {});
46
expect(isDeniedIp).toHaveBeenCalled();
49
test('Blocks on createConnection if IP is denied', async () => {
50
vi.mocked(isDeniedIp).mockReturnValue(true);
52
const options = { host: '127.0.0.1' };
54
expect(() => mockAgent.createConnection(options, () => {})).toThrowError(
55
`Requested domain "${options.host}" resolves to a denied IP address`,
59
test('Blocks on resolve if IP is denied', async () => {
60
vi.mocked(isDeniedIp).mockReturnValue(true);
62
const options = { host: 'baddomain' };
64
mockAgent.createConnection(options, () => {});
66
mockSocket.emit('lookup', null, '127.0.0.1');
68
expect(mockSocket.destroy).toHaveBeenCalledWith(
69
new Error(`Requested domain "${options.host}" resolves to a denied IP address`),
73
test('Does not block on resolve if IP is allowed', async () => {
74
vi.mocked(isDeniedIp).mockReturnValue(false);
76
const options = { host: 'directus.io' };
78
mockAgent.createConnection(options, () => {});
80
mockSocket.emit('lookup', null, '127.0.0.1');
82
expect(mockSocket.destroy).not.toHaveBeenCalled();
85
test('Checks each resolved IP', async () => {
86
vi.mocked(isDeniedIp).mockReturnValueOnce(false);
87
vi.mocked(isDeniedIp).mockReturnValueOnce(true);
89
const options = { host: 'baddomain' };
91
mockAgent.createConnection(options, () => {});
93
mockSocket.emit('lookup', null, '192.158.1.38');
94
mockSocket.emit('lookup', null, '127.0.0.1');
96
expect(mockSocket.destroy).toHaveBeenCalledWith(
97
new Error(`Requested domain "${options.host}" resolves to a denied IP address`),