Haraka 3.1.0 → 3.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.prettierignore +4 -0
- package/CONTRIBUTORS.md +5 -5
- package/Changes.md +69 -50
- package/Plugins.md +3 -1
- package/README.md +1 -1
- package/bin/haraka +475 -478
- package/config/outbound.ini +3 -0
- package/connection.js +1072 -1108
- package/docs/Connection.md +29 -30
- package/docs/CoreConfig.md +38 -39
- package/docs/CustomReturnCodes.md +0 -1
- package/docs/HAProxy.md +2 -2
- package/docs/Header.md +1 -1
- package/docs/Logging.md +29 -5
- package/docs/Outbound.md +93 -78
- package/docs/Plugins.md +103 -108
- package/docs/Transaction.md +49 -51
- package/docs/Tutorial.md +127 -143
- package/docs/deprecated/access.md +0 -1
- package/docs/deprecated/backscatterer.md +2 -3
- package/docs/deprecated/connect.rdns_access.md +18 -27
- package/docs/deprecated/data.headers.md +0 -1
- package/docs/deprecated/data.nomsgid.md +1 -2
- package/docs/deprecated/data.noreceived.md +1 -2
- package/docs/deprecated/data.rfc5322_header_checks.md +1 -2
- package/docs/deprecated/dkim_sign.md +13 -17
- package/docs/deprecated/dkim_verify.md +9 -17
- package/docs/deprecated/dnsbl.md +36 -38
- package/docs/deprecated/dnswl.md +41 -43
- package/docs/deprecated/lookup_rdns.strict.md +21 -34
- package/docs/deprecated/mail_from.access.md +17 -25
- package/docs/deprecated/mail_from.blocklist.md +9 -12
- package/docs/deprecated/mail_from.nobounces.md +1 -2
- package/docs/deprecated/rcpt_to.access.md +20 -27
- package/docs/deprecated/rcpt_to.blocklist.md +10 -13
- package/docs/deprecated/rcpt_to.routes.md +0 -1
- package/docs/deprecated/rdns.regexp.md +13 -15
- package/docs/plugins/aliases.md +89 -89
- package/docs/plugins/auth/auth_bridge.md +5 -7
- package/docs/plugins/auth/auth_ldap.md +11 -14
- package/docs/plugins/auth/auth_proxy.md +10 -12
- package/docs/plugins/auth/auth_vpopmaild.md +5 -6
- package/docs/plugins/auth/flat_file.md +4 -4
- package/docs/plugins/block_me.md +3 -3
- package/docs/plugins/data.signatures.md +1 -2
- package/docs/plugins/delay_deny.md +3 -4
- package/docs/plugins/max_unrecognized_commands.md +4 -4
- package/docs/plugins/prevent_credential_leaks.md +6 -6
- package/docs/plugins/process_title.md +18 -18
- package/docs/plugins/queue/deliver.md +2 -3
- package/docs/plugins/queue/discard.md +4 -4
- package/docs/plugins/queue/lmtp.md +1 -3
- package/docs/plugins/queue/qmail-queue.md +7 -9
- package/docs/plugins/queue/quarantine.md +16 -21
- package/docs/plugins/queue/rabbitmq.md +8 -11
- package/docs/plugins/queue/rabbitmq_amqplib.md +43 -39
- package/docs/plugins/queue/smtp_bridge.md +7 -10
- package/docs/plugins/queue/smtp_forward.md +42 -34
- package/docs/plugins/queue/smtp_proxy.md +30 -29
- package/docs/plugins/queue/test.md +1 -3
- package/docs/plugins/rcpt_to.in_host_list.md +6 -6
- package/docs/plugins/rcpt_to.max_count.md +1 -1
- package/docs/plugins/record_envelope_addresses.md +3 -3
- package/docs/plugins/reseed_rng.md +6 -6
- package/docs/plugins/status.md +9 -8
- package/docs/plugins/tarpit.md +7 -11
- package/docs/plugins/tls.md +12 -17
- package/docs/plugins/toobusy.md +4 -4
- package/docs/plugins/xclient.md +3 -3
- package/docs/tutorials/Migrating_from_v1_to_v2.md +19 -41
- package/docs/tutorials/SettingUpOutbound.md +6 -9
- package/endpoint.js +35 -38
- package/eslint.config.mjs +22 -19
- package/haraka.js +42 -47
- package/host_pool.js +75 -79
- package/http/html/404.html +45 -49
- package/http/html/index.html +39 -28
- package/http/package.json +2 -4
- package/line_socket.js +27 -28
- package/logger.js +182 -201
- package/outbound/client_pool.js +34 -27
- package/outbound/config.js +64 -59
- package/outbound/fsync_writestream.js +24 -25
- package/outbound/hmail.js +888 -835
- package/outbound/index.js +194 -187
- package/outbound/qfile.js +49 -52
- package/outbound/queue.js +197 -190
- package/outbound/timer_queue.js +41 -43
- package/outbound/tls.js +68 -61
- package/outbound/todo.js +11 -11
- package/package.json +38 -33
- package/plugins/.eslintrc.yaml +0 -1
- package/plugins/auth/auth_base.js +123 -127
- package/plugins/auth/auth_bridge.js +7 -7
- package/plugins/auth/auth_proxy.js +121 -126
- package/plugins/auth/auth_vpopmaild.js +84 -85
- package/plugins/auth/flat_file.js +18 -17
- package/plugins/block_me.js +31 -31
- package/plugins/data.signatures.js +13 -13
- package/plugins/delay_deny.js +65 -61
- package/plugins/prevent_credential_leaks.js +23 -23
- package/plugins/process_title.js +125 -128
- package/plugins/profile.js +5 -5
- package/plugins/queue/deliver.js +3 -3
- package/plugins/queue/discard.js +13 -14
- package/plugins/queue/lmtp.js +16 -17
- package/plugins/queue/qmail-queue.js +54 -55
- package/plugins/queue/quarantine.js +68 -70
- package/plugins/queue/rabbitmq.js +80 -87
- package/plugins/queue/rabbitmq_amqplib.js +75 -54
- package/plugins/queue/smtp_bridge.js +16 -16
- package/plugins/queue/smtp_forward.js +175 -179
- package/plugins/queue/smtp_proxy.js +69 -71
- package/plugins/queue/test.js +9 -9
- package/plugins/rcpt_to.host_list_base.js +30 -34
- package/plugins/rcpt_to.in_host_list.js +19 -19
- package/plugins/record_envelope_addresses.js +4 -4
- package/plugins/reseed_rng.js +4 -4
- package/plugins/status.js +90 -97
- package/plugins/tarpit.js +25 -14
- package/plugins/tls.js +68 -68
- package/plugins/toobusy.js +21 -23
- package/plugins/xclient.js +51 -53
- package/plugins.js +276 -293
- package/rfc1869.js +30 -35
- package/server.js +308 -299
- package/smtp_client.js +244 -228
- package/test/.eslintrc.yaml +0 -1
- package/test/connection.js +127 -134
- package/test/endpoint.js +53 -47
- package/test/fixtures/line_socket.js +12 -12
- package/test/fixtures/util_hmailitem.js +89 -85
- package/test/host_pool.js +90 -92
- package/test/installation/plugins/base_plugin.js +2 -2
- package/test/installation/plugins/folder_plugin/index.js +2 -3
- package/test/installation/plugins/inherits.js +3 -3
- package/test/installation/plugins/load_first.js +2 -3
- package/test/installation/plugins/plugin.js +1 -3
- package/test/installation/plugins/tls.js +2 -4
- package/test/logger.js +135 -116
- package/test/outbound/hmail.js +49 -35
- package/test/outbound/index.js +118 -101
- package/test/outbound/qfile.js +51 -53
- package/test/outbound_bounce_net_errors.js +84 -69
- package/test/outbound_bounce_rfc3464.js +235 -165
- package/test/plugins/auth/auth_base.js +420 -279
- package/test/plugins/auth/auth_vpopmaild.js +38 -39
- package/test/plugins/queue/smtp_forward.js +126 -104
- package/test/plugins/rcpt_to.host_list_base.js +85 -67
- package/test/plugins/rcpt_to.in_host_list.js +159 -112
- package/test/plugins/status.js +71 -64
- package/test/plugins/tls.js +37 -34
- package/test/plugins.js +97 -92
- package/test/rfc1869.js +19 -26
- package/test/server.js +293 -272
- package/test/smtp_client.js +180 -176
- package/test/tls_socket.js +62 -66
- package/test/transaction.js +159 -160
- package/tls_socket.js +331 -333
- package/transaction.js +129 -137
package/test/.eslintrc.yaml
CHANGED
package/test/connection.js
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
|
|
2
1
|
const assert = require('node:assert/strict')
|
|
3
2
|
|
|
4
|
-
const constants
|
|
5
|
-
const DSN
|
|
3
|
+
const constants = require('haraka-constants')
|
|
4
|
+
const DSN = require('haraka-dsn')
|
|
6
5
|
|
|
7
|
-
const connection
|
|
8
|
-
const Server
|
|
6
|
+
const connection = require('../connection')
|
|
7
|
+
const Server = require('../server')
|
|
9
8
|
|
|
10
9
|
// hack alert, but plugin tests need constants
|
|
11
|
-
constants.import(global)
|
|
10
|
+
constants.import(global)
|
|
12
11
|
|
|
13
12
|
const _set_up = (done) => {
|
|
14
|
-
this.backup = {}
|
|
13
|
+
this.backup = {}
|
|
15
14
|
const client = {
|
|
16
15
|
remotePort: null,
|
|
17
16
|
remoteAddress: null,
|
|
18
|
-
destroy: () => {
|
|
19
|
-
|
|
17
|
+
destroy: () => {
|
|
18
|
+
true
|
|
19
|
+
},
|
|
20
|
+
}
|
|
20
21
|
const server = {
|
|
21
22
|
ip_address: null,
|
|
22
|
-
address
|
|
23
|
-
return this.ip_address
|
|
24
|
-
}
|
|
23
|
+
address() {
|
|
24
|
+
return this.ip_address
|
|
25
|
+
},
|
|
25
26
|
}
|
|
26
|
-
this.connection = connection.createConnection(client, server, Server.cfg)
|
|
27
|
+
this.connection = connection.createConnection(client, server, Server.cfg)
|
|
27
28
|
done()
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
describe('connection', () => {
|
|
31
|
-
|
|
32
32
|
describe('connectionRaw', () => {
|
|
33
33
|
beforeEach(_set_up)
|
|
34
34
|
|
|
@@ -40,14 +40,14 @@ describe('connection', () => {
|
|
|
40
40
|
info: null,
|
|
41
41
|
closed: false,
|
|
42
42
|
is_private: false,
|
|
43
|
-
is_local: false
|
|
44
|
-
})
|
|
43
|
+
is_local: false,
|
|
44
|
+
})
|
|
45
45
|
})
|
|
46
46
|
|
|
47
47
|
it('has local object', () => {
|
|
48
|
-
assert.equal(this.connection.local.ip, null)
|
|
49
|
-
assert.equal(this.connection.local.port, null)
|
|
50
|
-
assert.ok(this.connection.local.host, this.connection.local.host)
|
|
48
|
+
assert.equal(this.connection.local.ip, null)
|
|
49
|
+
assert.equal(this.connection.local.port, null)
|
|
50
|
+
assert.ok(this.connection.local.host, this.connection.local.host)
|
|
51
51
|
})
|
|
52
52
|
|
|
53
53
|
it('has tls object', () => {
|
|
@@ -56,111 +56,101 @@ describe('connection', () => {
|
|
|
56
56
|
advertised: false,
|
|
57
57
|
verified: false,
|
|
58
58
|
cipher: {},
|
|
59
|
-
})
|
|
59
|
+
})
|
|
60
60
|
})
|
|
61
61
|
|
|
62
62
|
it('get_capabilities', () => {
|
|
63
|
-
assert.deepEqual([], this.connection.get_capabilities())
|
|
63
|
+
assert.deepEqual([], this.connection.get_capabilities())
|
|
64
64
|
})
|
|
65
65
|
|
|
66
66
|
it('queue_msg, defined', () => {
|
|
67
|
-
assert.equal(
|
|
68
|
-
'test message',
|
|
69
|
-
this.connection.queue_msg(1, 'test message')
|
|
70
|
-
);
|
|
67
|
+
assert.equal('test message', this.connection.queue_msg(1, 'test message'))
|
|
71
68
|
})
|
|
72
69
|
|
|
73
70
|
it('queue_msg, default deny', () => {
|
|
74
|
-
assert.equal(
|
|
75
|
-
|
|
76
|
-
this.connection.queue_msg(DENY)
|
|
77
|
-
);
|
|
78
|
-
assert.equal(
|
|
79
|
-
'Message denied',
|
|
80
|
-
this.connection.queue_msg(DENYDISCONNECT)
|
|
81
|
-
);
|
|
71
|
+
assert.equal('Message denied', this.connection.queue_msg(DENY))
|
|
72
|
+
assert.equal('Message denied', this.connection.queue_msg(DENYDISCONNECT))
|
|
82
73
|
})
|
|
83
74
|
|
|
84
75
|
it('queue_msg, default denysoft', () => {
|
|
85
|
-
assert.equal(
|
|
86
|
-
|
|
87
|
-
this.connection.queue_msg(DENYSOFT)
|
|
88
|
-
);
|
|
89
|
-
assert.equal(
|
|
90
|
-
'Message denied temporarily',
|
|
91
|
-
this.connection.queue_msg(DENYSOFTDISCONNECT)
|
|
92
|
-
);
|
|
76
|
+
assert.equal('Message denied temporarily', this.connection.queue_msg(DENYSOFT))
|
|
77
|
+
assert.equal('Message denied temporarily', this.connection.queue_msg(DENYSOFTDISCONNECT))
|
|
93
78
|
})
|
|
94
79
|
|
|
95
80
|
it('queue_msg, default else', () => {
|
|
96
|
-
assert.equal('', this.connection.queue_msg('hello'))
|
|
81
|
+
assert.equal('', this.connection.queue_msg('hello'))
|
|
97
82
|
})
|
|
98
83
|
|
|
99
84
|
it('has normalized connection properties', () => {
|
|
100
|
-
this.connection.set('remote', 'ip', '172.16.15.1')
|
|
101
|
-
this.connection.set('hello', 'verb', 'EHLO')
|
|
102
|
-
this.connection.set('tls', 'enabled', true)
|
|
103
|
-
|
|
104
|
-
assert.equal('172.16.15.1', this.connection.remote.ip)
|
|
105
|
-
assert.equal(null, this.connection.remote.port)
|
|
106
|
-
assert.equal('EHLO', this.connection.hello.verb)
|
|
107
|
-
assert.equal(null, this.connection.hello.host)
|
|
108
|
-
assert.equal(true, this.connection.tls.enabled)
|
|
85
|
+
this.connection.set('remote', 'ip', '172.16.15.1')
|
|
86
|
+
this.connection.set('hello', 'verb', 'EHLO')
|
|
87
|
+
this.connection.set('tls', 'enabled', true)
|
|
88
|
+
|
|
89
|
+
assert.equal('172.16.15.1', this.connection.remote.ip)
|
|
90
|
+
assert.equal(null, this.connection.remote.port)
|
|
91
|
+
assert.equal('EHLO', this.connection.hello.verb)
|
|
92
|
+
assert.equal(null, this.connection.hello.host)
|
|
93
|
+
assert.equal(true, this.connection.tls.enabled)
|
|
109
94
|
})
|
|
110
95
|
|
|
111
96
|
it('sets remote.is_private and remote.is_local', () => {
|
|
112
|
-
assert.equal(false, this.connection.remote.is_private)
|
|
113
|
-
assert.equal(false, this.connection.remote.is_local)
|
|
97
|
+
assert.equal(false, this.connection.remote.is_private)
|
|
98
|
+
assert.equal(false, this.connection.remote.is_local)
|
|
114
99
|
})
|
|
115
100
|
|
|
116
101
|
it('has normalized proxy properties, default', () => {
|
|
117
|
-
assert.equal(false, this.connection.proxy.allowed)
|
|
118
|
-
assert.equal(null, this.connection.proxy.ip)
|
|
119
|
-
assert.equal(null, this.connection.proxy.type)
|
|
120
|
-
assert.equal(null, this.connection.proxy.timer)
|
|
102
|
+
assert.equal(false, this.connection.proxy.allowed)
|
|
103
|
+
assert.equal(null, this.connection.proxy.ip)
|
|
104
|
+
assert.equal(null, this.connection.proxy.type)
|
|
105
|
+
assert.equal(null, this.connection.proxy.timer)
|
|
121
106
|
})
|
|
122
107
|
|
|
123
108
|
it('has normalized proxy properties, set', () => {
|
|
124
|
-
this.connection.set('proxy', 'ip', '172.16.15.1')
|
|
125
|
-
this.connection.set('proxy', 'type', 'haproxy')
|
|
126
|
-
this.connection.set(
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
109
|
+
this.connection.set('proxy', 'ip', '172.16.15.1')
|
|
110
|
+
this.connection.set('proxy', 'type', 'haproxy')
|
|
111
|
+
this.connection.set(
|
|
112
|
+
'proxy',
|
|
113
|
+
'timer',
|
|
114
|
+
setTimeout(() => {}, 1000),
|
|
115
|
+
)
|
|
116
|
+
this.connection.set('proxy', 'allowed', true)
|
|
117
|
+
|
|
118
|
+
assert.equal(true, this.connection.proxy.allowed)
|
|
119
|
+
assert.equal('172.16.15.1', this.connection.proxy.ip)
|
|
120
|
+
assert.ok(this.connection.proxy.timer)
|
|
121
|
+
assert.equal(this.connection.proxy.type, 'haproxy')
|
|
133
122
|
})
|
|
134
123
|
})
|
|
135
124
|
|
|
136
125
|
describe('connectionPrivate', () => {
|
|
137
126
|
beforeEach((done) => {
|
|
138
|
-
this.backup = {}
|
|
127
|
+
this.backup = {}
|
|
139
128
|
const client = {
|
|
140
129
|
remotePort: 2525,
|
|
141
130
|
remoteAddress: '172.16.15.1',
|
|
142
131
|
localPort: 25,
|
|
143
132
|
localAddress: '172.16.15.254',
|
|
144
|
-
destroy: () => {
|
|
145
|
-
|
|
133
|
+
destroy: () => {
|
|
134
|
+
true
|
|
135
|
+
},
|
|
136
|
+
}
|
|
146
137
|
const server = {
|
|
147
138
|
ip_address: '172.16.15.254',
|
|
148
|
-
address
|
|
149
|
-
return this.ip_address
|
|
150
|
-
}
|
|
139
|
+
address() {
|
|
140
|
+
return this.ip_address
|
|
141
|
+
},
|
|
151
142
|
}
|
|
152
|
-
this.connection = connection.createConnection(client, server, Server.cfg)
|
|
143
|
+
this.connection = connection.createConnection(client, server, Server.cfg)
|
|
153
144
|
done()
|
|
154
145
|
})
|
|
155
146
|
|
|
156
147
|
it('sets remote.is_private and remote.is_local', () => {
|
|
157
|
-
assert.equal(true, this.connection.remote.is_private)
|
|
158
|
-
assert.equal(false, this.connection.remote.is_local)
|
|
159
|
-
assert.equal(2525, this.connection.remote.port)
|
|
148
|
+
assert.equal(true, this.connection.remote.is_private)
|
|
149
|
+
assert.equal(false, this.connection.remote.is_local)
|
|
150
|
+
assert.equal(2525, this.connection.remote.port)
|
|
160
151
|
})
|
|
161
152
|
})
|
|
162
153
|
|
|
163
|
-
|
|
164
154
|
describe('connectionLocal', () => {
|
|
165
155
|
beforeEach((done) => {
|
|
166
156
|
const client = {
|
|
@@ -168,59 +158,59 @@ describe('connection', () => {
|
|
|
168
158
|
remoteAddress: '127.0.0.2',
|
|
169
159
|
localPort: 25,
|
|
170
160
|
localAddress: '172.0.0.1',
|
|
171
|
-
destroy: () => {
|
|
172
|
-
|
|
161
|
+
destroy: () => {
|
|
162
|
+
true
|
|
163
|
+
},
|
|
164
|
+
}
|
|
173
165
|
const server = {
|
|
174
166
|
ip_address: '127.0.0.1',
|
|
175
|
-
address
|
|
176
|
-
return this.ip_address
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
this.connection = connection.createConnection(client, server, Server.cfg)
|
|
180
|
-
done()
|
|
167
|
+
address() {
|
|
168
|
+
return this.ip_address
|
|
169
|
+
},
|
|
170
|
+
}
|
|
171
|
+
this.connection = connection.createConnection(client, server, Server.cfg)
|
|
172
|
+
done()
|
|
181
173
|
})
|
|
182
174
|
|
|
183
175
|
it('sets remote.is_private and remote.is_local', () => {
|
|
184
|
-
assert.equal(true, this.connection.remote.is_private)
|
|
185
|
-
assert.equal(true, this.connection.remote.is_local)
|
|
186
|
-
assert.equal(2525, this.connection.remote.port)
|
|
176
|
+
assert.equal(true, this.connection.remote.is_private)
|
|
177
|
+
assert.equal(true, this.connection.remote.is_local)
|
|
178
|
+
assert.equal(2525, this.connection.remote.port)
|
|
187
179
|
})
|
|
188
180
|
})
|
|
189
181
|
|
|
190
|
-
|
|
191
182
|
describe('get_remote', () => {
|
|
192
183
|
beforeEach(_set_up)
|
|
193
184
|
|
|
194
185
|
it('valid hostname', () => {
|
|
195
|
-
this.connection.remote.host='a.host.tld'
|
|
196
|
-
this.connection.remote.ip='172.16.199.198'
|
|
197
|
-
assert.equal(this.connection.get_remote('host'), 'a.host.tld [172.16.199.198]')
|
|
186
|
+
this.connection.remote.host = 'a.host.tld'
|
|
187
|
+
this.connection.remote.ip = '172.16.199.198'
|
|
188
|
+
assert.equal(this.connection.get_remote('host'), 'a.host.tld [172.16.199.198]')
|
|
198
189
|
})
|
|
199
190
|
|
|
200
191
|
it('no hostname', () => {
|
|
201
|
-
this.connection.remote.ip='172.16.199.198'
|
|
202
|
-
assert.equal(this.connection.get_remote('host'), '[172.16.199.198]')
|
|
192
|
+
this.connection.remote.ip = '172.16.199.198'
|
|
193
|
+
assert.equal(this.connection.get_remote('host'), '[172.16.199.198]')
|
|
203
194
|
})
|
|
204
195
|
|
|
205
196
|
it('DNSERROR', () => {
|
|
206
|
-
this.connection.remote.host='DNSERROR'
|
|
207
|
-
this.connection.remote.ip='172.16.199.198'
|
|
208
|
-
assert.equal(this.connection.get_remote('host'), '[172.16.199.198]')
|
|
197
|
+
this.connection.remote.host = 'DNSERROR'
|
|
198
|
+
this.connection.remote.ip = '172.16.199.198'
|
|
199
|
+
assert.equal(this.connection.get_remote('host'), '[172.16.199.198]')
|
|
209
200
|
})
|
|
210
201
|
|
|
211
202
|
it('NXDOMAIN', () => {
|
|
212
|
-
this.connection.remote.host='NXDOMAIN'
|
|
213
|
-
this.connection.remote.ip='172.16.199.198'
|
|
214
|
-
assert.equal(this.connection.get_remote('host'), '[172.16.199.198]')
|
|
203
|
+
this.connection.remote.host = 'NXDOMAIN'
|
|
204
|
+
this.connection.remote.ip = '172.16.199.198'
|
|
205
|
+
assert.equal(this.connection.get_remote('host'), '[172.16.199.198]')
|
|
215
206
|
})
|
|
216
|
-
|
|
217
207
|
})
|
|
218
208
|
|
|
219
209
|
describe('local.info', () => {
|
|
220
210
|
beforeEach(_set_up)
|
|
221
211
|
|
|
222
212
|
it('is Haraka/version', () => {
|
|
223
|
-
assert.ok(/Haraka\/\d.\d/.test(this.connection.local.info), this.connection.local.info)
|
|
213
|
+
assert.ok(/Haraka\/\d.\d/.test(this.connection.local.info), this.connection.local.info)
|
|
224
214
|
})
|
|
225
215
|
})
|
|
226
216
|
|
|
@@ -228,28 +218,28 @@ describe('connection', () => {
|
|
|
228
218
|
beforeEach(_set_up)
|
|
229
219
|
|
|
230
220
|
it('sets and gets', () => {
|
|
231
|
-
assert.equal(this.connection.relaying, false)
|
|
221
|
+
assert.equal(this.connection.relaying, false)
|
|
232
222
|
|
|
233
|
-
this.connection.set('relaying', 'crocodiles')
|
|
234
|
-
assert.equal(this.connection.get('relaying'), 'crocodiles')
|
|
235
|
-
assert.equal(this.connection.relaying, 'crocodiles')
|
|
236
|
-
assert.equal(this.connection._relaying, 'crocodiles')
|
|
223
|
+
this.connection.set('relaying', 'crocodiles')
|
|
224
|
+
assert.equal(this.connection.get('relaying'), 'crocodiles')
|
|
225
|
+
assert.equal(this.connection.relaying, 'crocodiles')
|
|
226
|
+
assert.equal(this.connection._relaying, 'crocodiles')
|
|
237
227
|
|
|
238
|
-
this.connection.relaying = 'alligators'
|
|
239
|
-
assert.equal(this.connection.get('relaying'), 'alligators')
|
|
240
|
-
assert.equal(this.connection.relaying, 'alligators')
|
|
241
|
-
assert.equal(this.connection._relaying, 'alligators')
|
|
228
|
+
this.connection.relaying = 'alligators'
|
|
229
|
+
assert.equal(this.connection.get('relaying'), 'alligators')
|
|
230
|
+
assert.equal(this.connection.relaying, 'alligators')
|
|
231
|
+
assert.equal(this.connection._relaying, 'alligators')
|
|
242
232
|
})
|
|
243
233
|
|
|
244
234
|
it('sets and gets in a transaction', () => {
|
|
245
|
-
assert.equal(this.connection.relaying, false)
|
|
235
|
+
assert.equal(this.connection.relaying, false)
|
|
246
236
|
|
|
247
237
|
this.connection.transaction = {}
|
|
248
|
-
this.connection.set('relaying', 'txn-only')
|
|
238
|
+
this.connection.set('relaying', 'txn-only') // sets txn.relaying
|
|
249
239
|
|
|
250
240
|
assert.equal(this.connection.get('relaying'), 'txn-only')
|
|
251
|
-
assert.equal(this.connection._relaying, false)
|
|
252
|
-
assert.equal(this.connection.transaction._relaying, 'txn-only')
|
|
241
|
+
assert.equal(this.connection._relaying, false)
|
|
242
|
+
assert.equal(this.connection.transaction._relaying, 'txn-only')
|
|
253
243
|
})
|
|
254
244
|
})
|
|
255
245
|
|
|
@@ -257,21 +247,21 @@ describe('connection', () => {
|
|
|
257
247
|
beforeEach(_set_up)
|
|
258
248
|
|
|
259
249
|
it('sets single level properties', () => {
|
|
260
|
-
this.connection.set('encoding', true)
|
|
261
|
-
assert.ok(this.connection.encoding)
|
|
262
|
-
assert.ok(this.connection.get('encoding'))
|
|
250
|
+
this.connection.set('encoding', true)
|
|
251
|
+
assert.ok(this.connection.encoding)
|
|
252
|
+
assert.ok(this.connection.get('encoding'))
|
|
263
253
|
})
|
|
264
254
|
|
|
265
255
|
it('sets two level deep properties', () => {
|
|
266
|
-
this.connection.set('local.host', 'test')
|
|
267
|
-
assert.equal(this.connection.local.host, 'test')
|
|
268
|
-
assert.equal(this.connection.get('local.host'), 'test')
|
|
256
|
+
this.connection.set('local.host', 'test')
|
|
257
|
+
assert.equal(this.connection.local.host, 'test')
|
|
258
|
+
assert.equal(this.connection.get('local.host'), 'test')
|
|
269
259
|
})
|
|
270
260
|
|
|
271
261
|
it('sets three level deep properties', () => {
|
|
272
|
-
this.connection.set('some.fine.example', true)
|
|
273
|
-
assert.ok(this.connection.some.fine.example)
|
|
274
|
-
assert.ok(this.connection.get('some.fine.example'))
|
|
262
|
+
this.connection.set('some.fine.example', true)
|
|
263
|
+
assert.ok(this.connection.some.fine.example)
|
|
264
|
+
assert.ok(this.connection.get('some.fine.example'))
|
|
275
265
|
})
|
|
276
266
|
})
|
|
277
267
|
|
|
@@ -280,34 +270,37 @@ describe('connection', () => {
|
|
|
280
270
|
|
|
281
271
|
it('disconnected returns undefined', () => {
|
|
282
272
|
this.connection.state = constants.connection.state.DISCONNECTED
|
|
283
|
-
assert.equal(this.connection.respond(200, 'your lucky day'), undefined)
|
|
284
|
-
assert.equal(this.connection.respond(550, 'you are jacked'), undefined)
|
|
273
|
+
assert.equal(this.connection.respond(200, 'your lucky day'), undefined)
|
|
274
|
+
assert.equal(this.connection.respond(550, 'you are jacked'), undefined)
|
|
285
275
|
})
|
|
286
276
|
|
|
287
277
|
it('state=command, 200', () => {
|
|
288
|
-
assert.equal(this.connection.respond(200, 'you may pass Go'), '200 you may pass Go\r\n')
|
|
278
|
+
assert.equal(this.connection.respond(200, 'you may pass Go'), '200 you may pass Go\r\n')
|
|
289
279
|
})
|
|
290
280
|
|
|
291
281
|
it('DSN 200', () => {
|
|
292
282
|
assert.equal(
|
|
293
283
|
this.connection.respond(200, DSN.create(200, 'you may pass Go')),
|
|
294
|
-
'200 2.0.0 you may pass Go\r\n'
|
|
295
|
-
)
|
|
284
|
+
'200 2.0.0 you may pass Go\r\n',
|
|
285
|
+
)
|
|
296
286
|
})
|
|
297
287
|
|
|
298
288
|
it('DSN 550 create', () => {
|
|
299
289
|
// note, the DSN code overrides the response code
|
|
300
290
|
assert.equal(
|
|
301
291
|
this.connection.respond(450, DSN.create(550, 'This domain is not in use and does not accept mail')),
|
|
302
|
-
'550 5.0.0 This domain is not in use and does not accept mail\r\n'
|
|
303
|
-
)
|
|
292
|
+
'550 5.0.0 This domain is not in use and does not accept mail\r\n',
|
|
293
|
+
)
|
|
304
294
|
})
|
|
305
295
|
|
|
306
296
|
it('DSN 550 addr_bad_dest_system', () => {
|
|
307
297
|
assert.equal(
|
|
308
|
-
this.connection.respond(
|
|
309
|
-
|
|
310
|
-
|
|
298
|
+
this.connection.respond(
|
|
299
|
+
550,
|
|
300
|
+
DSN.addr_bad_dest_system('This domain is not in use and does not accept mail', 550),
|
|
301
|
+
),
|
|
302
|
+
'550 5.1.2 This domain is not in use and does not accept mail\r\n',
|
|
303
|
+
)
|
|
311
304
|
})
|
|
312
305
|
})
|
|
313
306
|
})
|
package/test/endpoint.js
CHANGED
|
@@ -1,94 +1,100 @@
|
|
|
1
1
|
const assert = require('node:assert')
|
|
2
2
|
|
|
3
|
-
const mock = require('mock-require')
|
|
4
|
-
const endpoint = require('../endpoint')
|
|
3
|
+
const mock = require('mock-require')
|
|
4
|
+
const endpoint = require('../endpoint')
|
|
5
5
|
|
|
6
6
|
describe('endpoint', () => {
|
|
7
|
-
|
|
8
7
|
it('toString()', () => {
|
|
9
|
-
assert.equal(
|
|
10
|
-
assert.equal(
|
|
11
|
-
assert.equal(
|
|
12
|
-
assert.equal(
|
|
13
|
-
assert.equal(
|
|
8
|
+
assert.equal(endpoint(25), '[::0]:25')
|
|
9
|
+
assert.equal(endpoint('10.0.0.3', 42), '10.0.0.3:42')
|
|
10
|
+
assert.equal(endpoint('/foo/bar.sock'), '/foo/bar.sock')
|
|
11
|
+
assert.equal(endpoint('/foo/bar.sock:770'), '/foo/bar.sock:770')
|
|
12
|
+
assert.equal(endpoint({ address: '::0', port: 80 }), '[::0]:80')
|
|
14
13
|
})
|
|
15
14
|
|
|
16
15
|
describe('parse', () => {
|
|
17
16
|
it('Number as port', () => {
|
|
18
|
-
assert.deepEqual(
|
|
17
|
+
assert.deepEqual(endpoint(25), { host: '::0', port: 25 })
|
|
19
18
|
})
|
|
20
19
|
|
|
21
20
|
it('Default port if only host', () => {
|
|
22
|
-
assert.deepEqual(
|
|
21
|
+
assert.deepEqual(endpoint('10.0.0.3', 42), {
|
|
22
|
+
host: '10.0.0.3',
|
|
23
|
+
port: 42,
|
|
24
|
+
})
|
|
23
25
|
})
|
|
24
26
|
|
|
25
27
|
it('Unix socket', () => {
|
|
26
|
-
assert.deepEqual(
|
|
28
|
+
assert.deepEqual(endpoint('/foo/bar.sock'), {
|
|
29
|
+
path: '/foo/bar.sock',
|
|
30
|
+
})
|
|
27
31
|
})
|
|
28
32
|
|
|
29
33
|
it('Unix socket w/mode', () => {
|
|
30
|
-
assert.deepEqual(
|
|
34
|
+
assert.deepEqual(endpoint('/foo/bar.sock:770'), {
|
|
35
|
+
path: '/foo/bar.sock',
|
|
36
|
+
mode: '770',
|
|
37
|
+
})
|
|
31
38
|
})
|
|
32
39
|
})
|
|
33
40
|
|
|
34
41
|
describe('bind()', () => {
|
|
35
42
|
beforeEach((done) => {
|
|
36
43
|
// Mock filesystem and log server + fs method calls
|
|
37
|
-
const modes = this.modes = {}
|
|
38
|
-
const log = this.log = []
|
|
44
|
+
const modes = (this.modes = {})
|
|
45
|
+
const log = (this.log = [])
|
|
39
46
|
|
|
40
47
|
this.server = {
|
|
41
|
-
listen
|
|
42
|
-
log.push(['listen', opts])
|
|
43
|
-
if (cb) cb()
|
|
44
|
-
}
|
|
48
|
+
listen(opts, cb) {
|
|
49
|
+
log.push(['listen', opts])
|
|
50
|
+
if (cb) cb()
|
|
51
|
+
},
|
|
45
52
|
}
|
|
46
53
|
|
|
47
54
|
this.mockfs = {
|
|
48
|
-
chmod
|
|
49
|
-
log.push(['chmod', path, mode, ...args])
|
|
50
|
-
modes[path] = mode
|
|
55
|
+
chmod(path, mode, ...args) {
|
|
56
|
+
log.push(['chmod', path, mode, ...args])
|
|
57
|
+
modes[path] = mode
|
|
51
58
|
},
|
|
52
|
-
rm
|
|
53
|
-
log.push(['rm', path, ...args])
|
|
59
|
+
rm(path, ...args) {
|
|
60
|
+
log.push(['rm', path, ...args])
|
|
54
61
|
},
|
|
55
|
-
}
|
|
62
|
+
}
|
|
56
63
|
|
|
57
|
-
mock('node:fs/promises', this.mockfs)
|
|
58
|
-
this.endpoint = mock.reRequire('../endpoint')
|
|
59
|
-
done()
|
|
64
|
+
mock('node:fs/promises', this.mockfs)
|
|
65
|
+
this.endpoint = mock.reRequire('../endpoint')
|
|
66
|
+
done()
|
|
60
67
|
})
|
|
61
68
|
|
|
62
69
|
afterEach((done) => {
|
|
63
|
-
mock.stop('node:fs/promises')
|
|
64
|
-
done()
|
|
70
|
+
mock.stop('node:fs/promises')
|
|
71
|
+
done()
|
|
65
72
|
})
|
|
66
73
|
|
|
67
74
|
it('IP socket', async () => {
|
|
68
|
-
await this.endpoint('10.0.0.3:42').bind(this.server, {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
]);
|
|
75
|
+
await this.endpoint('10.0.0.3:42').bind(this.server, {
|
|
76
|
+
backlog: 19,
|
|
77
|
+
})
|
|
78
|
+
assert.deepEqual(this.log, [['listen', { host: '10.0.0.3', port: 42, backlog: 19 }]])
|
|
73
79
|
})
|
|
74
80
|
|
|
75
81
|
it('Unix socket', async () => {
|
|
76
|
-
await this.endpoint('/foo/bar.sock').bind(this.server, {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
]
|
|
82
|
+
await this.endpoint('/foo/bar.sock').bind(this.server, {
|
|
83
|
+
readableAll: true,
|
|
84
|
+
})
|
|
85
|
+
assert.deepEqual(this.log, [
|
|
86
|
+
['rm', '/foo/bar.sock', { force: true }],
|
|
87
|
+
['listen', { path: '/foo/bar.sock', readableAll: true }],
|
|
88
|
+
])
|
|
82
89
|
})
|
|
83
90
|
|
|
84
91
|
it('Unix socket w/mode', async () => {
|
|
85
|
-
await this.endpoint('/foo/bar.sock:764').bind(this.server)
|
|
86
|
-
assert.deepEqual(
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
]);
|
|
92
|
+
await this.endpoint('/foo/bar.sock:764').bind(this.server)
|
|
93
|
+
assert.deepEqual(this.log, [
|
|
94
|
+
['rm', '/foo/bar.sock', { force: true }],
|
|
95
|
+
['listen', { path: '/foo/bar.sock' }],
|
|
96
|
+
['chmod', '/foo/bar.sock', 0o764],
|
|
97
|
+
])
|
|
92
98
|
})
|
|
93
99
|
})
|
|
94
100
|
})
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
'use strict'
|
|
1
|
+
'use strict'
|
|
2
2
|
|
|
3
|
-
const events
|
|
4
|
-
const fixtures = require('haraka-test-fixtures')
|
|
5
|
-
const { stub } = fixtures.stub
|
|
3
|
+
const events = require('node:events')
|
|
4
|
+
const fixtures = require('haraka-test-fixtures')
|
|
5
|
+
const { stub } = fixtures.stub
|
|
6
6
|
|
|
7
7
|
class Socket extends events.EventEmitter {
|
|
8
|
-
constructor
|
|
9
|
-
super()
|
|
10
|
-
this.port = port
|
|
11
|
-
this.host = host
|
|
12
|
-
this.setTimeout = stub()
|
|
13
|
-
this.setKeepAlive = stub()
|
|
14
|
-
this.destroy = stub()
|
|
8
|
+
constructor(port, host) {
|
|
9
|
+
super()
|
|
10
|
+
this.port = port
|
|
11
|
+
this.host = host
|
|
12
|
+
this.setTimeout = stub()
|
|
13
|
+
this.setKeepAlive = stub()
|
|
14
|
+
this.destroy = stub()
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
exports.Socket = Socket
|
|
18
|
+
exports.Socket = Socket
|
|
19
19
|
|
|
20
20
|
exports.connect = (port, host, cb) => new Socket(port, host)
|