Haraka 2.8.28 → 3.0.1
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/.eslintrc.yaml +2 -10
- package/Changes.md +84 -2
- package/Dockerfile +1 -1
- package/Plugins.md +9 -4
- package/README.md +2 -6
- package/bin/haraka +5 -4
- package/config/outbound.ini +0 -7
- package/config/plugins +1 -1
- package/config/smtp.ini +1 -1
- package/config/smtp_forward.ini +2 -8
- package/config/smtp_proxy.ini +0 -6
- package/connection.js +178 -204
- package/coverage/lcov.info +13863 -0
- package/coverage/tmp/coverage-42958-1658373250585-0.json +1 -0
- package/coverage/tmp/coverage-42961-1658373250529-0.json +1 -0
- package/dkim.js +66 -73
- package/docs/Body.md +1 -22
- package/docs/CoreConfig.md +2 -2
- package/docs/Header.md +1 -47
- package/docs/Outbound.md +8 -36
- package/endpoint.js +1 -1
- package/haraka.js +1 -1
- package/host_pool.js +8 -12
- package/logger.js +25 -32
- package/outbound/client_pool.js +11 -153
- package/outbound/config.js +5 -11
- package/outbound/hmail.js +109 -143
- package/outbound/index.js +13 -25
- package/outbound/mx_lookup.js +10 -7
- package/outbound/queue.js +8 -12
- package/outbound/timer_queue.js +2 -4
- package/outbound/tls.js +17 -18
- package/outbound/todo.js +1 -0
- package/package.json +57 -55
- package/plugins/auth/auth_base.js +39 -63
- package/plugins/auth/auth_bridge.js +3 -4
- package/plugins/auth/auth_proxy.js +16 -16
- package/plugins/auth/auth_vpopmaild.js +30 -37
- package/plugins/auth/flat_file.js +9 -13
- package/plugins/avg.js +9 -11
- package/plugins/backscatterer.js +1 -1
- package/plugins/block_me.js +2 -6
- package/plugins/bounce.js +106 -124
- package/plugins/clamd.js +59 -63
- package/plugins/data.signatures.js +6 -6
- package/plugins/data.uribl.js +1 -415
- package/plugins/delay_deny.js +19 -20
- package/plugins/dkim_sign.js +56 -62
- package/plugins/dkim_verify.js +9 -8
- package/plugins/dns_list_base.js +43 -42
- package/plugins/dnsbl.js +41 -46
- package/plugins/dnswl.js +23 -26
- package/plugins/early_talker.js +24 -28
- package/plugins/esets.js +8 -11
- package/plugins/greylist.js +161 -190
- package/plugins/helo.checks.js +175 -197
- package/plugins/mail_from.is_resolvable.js +38 -38
- package/plugins/messagesniffer.js +33 -40
- package/plugins/prevent_credential_leaks.js +7 -5
- package/plugins/process_title.js +16 -17
- package/plugins/queue/deliver.js +2 -2
- package/plugins/queue/lmtp.js +5 -6
- package/plugins/queue/qmail-queue.js +11 -13
- package/plugins/queue/quarantine.js +25 -34
- package/plugins/queue/rabbitmq.js +3 -2
- package/plugins/queue/rabbitmq_amqplib.js +9 -9
- package/plugins/queue/smtp_bridge.js +5 -4
- package/plugins/queue/smtp_forward.js +81 -89
- package/plugins/queue/smtp_proxy.js +21 -22
- package/plugins/queue/test.js +2 -1
- package/plugins/rcpt_to.host_list_base.js +20 -30
- package/plugins/rcpt_to.in_host_list.js +12 -14
- package/plugins/rcpt_to.max_count.js +7 -5
- package/plugins/record_envelope_addresses.js +4 -6
- package/plugins/relay.js +64 -74
- package/plugins/reseed_rng.js +1 -2
- package/plugins/spamassassin.js +56 -68
- package/plugins/status.js +2 -3
- package/plugins/tarpit.js +8 -11
- package/plugins/tls.js +14 -17
- package/plugins/toobusy.js +6 -8
- package/plugins/xclient.js +14 -25
- package/plugins.js +24 -29
- package/rfc1869.js +2 -2
- package/server.js +3 -13
- package/smtp_client.js +138 -215
- package/tests/config/smtp_forward.ini +0 -6
- package/tests/fixtures/line_socket.js +1 -1
- package/tests/fixtures/util_hmailitem.js +5 -7
- package/tests/fixtures/vm_harness.js +2 -2
- package/tests/host_pool.js +13 -14
- package/tests/installation/plugins/inherits.js +1 -2
- package/tests/logger.js +2 -2
- package/tests/plugins/bounce.js +6 -8
- package/tests/plugins/dkim_signer.js +7 -7
- package/tests/plugins/dns_list_base.js +7 -7
- package/tests/plugins/helo.checks.js +1 -1
- package/tests/plugins/mail_from.is_resolvable.js +10 -54
- package/tests/plugins/queue/smtp_forward.js +11 -11
- package/tests/plugins/rcpt_to.host_list_base.js +1 -1
- package/tests/plugins/rcpt_to.in_host_list.js +1 -1
- package/tests/plugins/spamassassin.js +1 -1
- package/tests/queue/multibyte +0 -0
- package/tests/queue/plain +0 -0
- package/tests/rfc1869.js +4 -1
- package/tests/server.js +15 -9
- package/tests/smtp_client/auth.js +4 -14
- package/tests/smtp_client/basic.js +5 -15
- package/tests/smtp_client.js +7 -3
- package/tests/transaction.js +72 -19
- package/tls_socket.js +75 -85
- package/transaction.js +7 -9
- package/attachment_stream.js +0 -118
- package/bin/spf +0 -48
- package/chunkemitter.js +0 -75
- package/config/data.uribl.excludes +0 -202
- package/config/data.uribl.ini +0 -37
- package/config/spf.ini +0 -1
- package/docs/plugins/attachment.md +0 -92
- package/docs/plugins/data.uribl.md +0 -120
- package/docs/plugins/spf.md +0 -142
- package/mailbody.js +0 -502
- package/mailheader.js +0 -304
- package/messagestream.js +0 -441
- package/plugins/aliases.js +0 -120
- package/plugins/attachment.js +0 -503
- package/plugins/connect.p0f.js +0 -5
- package/plugins/spf.js +0 -327
- package/spf.js +0 -689
- package/tests/mailbody.js +0 -348
- package/tests/mailheader.js +0 -138
- package/tests/messagestream.js +0 -34
- package/tests/plugins/aliases.js +0 -376
- package/tests/plugins/spf.js +0 -251
- package/tests/spf.js +0 -96
package/plugins/spf.js
DELETED
|
@@ -1,327 +0,0 @@
|
|
|
1
|
-
// spf
|
|
2
|
-
|
|
3
|
-
const SPF = require('./spf').SPF;
|
|
4
|
-
const net_utils = require('haraka-net-utils');
|
|
5
|
-
const DSN = require('haraka-dsn');
|
|
6
|
-
|
|
7
|
-
exports.register = function () {
|
|
8
|
-
const plugin = this;
|
|
9
|
-
|
|
10
|
-
// Override logging in SPF module
|
|
11
|
-
SPF.prototype.log_debug = str => plugin.logdebug(str);
|
|
12
|
-
|
|
13
|
-
plugin.load_spf_ini();
|
|
14
|
-
|
|
15
|
-
plugin.register_hook('helo', 'helo_spf');
|
|
16
|
-
plugin.register_hook('ehlo', 'helo_spf');
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
exports.load_spf_ini = function () {
|
|
20
|
-
const plugin = this;
|
|
21
|
-
plugin.nu = net_utils; // so tests can set public_ip
|
|
22
|
-
plugin.SPF = SPF;
|
|
23
|
-
|
|
24
|
-
plugin.cfg = plugin.config.get('spf.ini', {
|
|
25
|
-
booleans: [
|
|
26
|
-
'-defer.helo_temperror',
|
|
27
|
-
'-defer.mfrom_temperror',
|
|
28
|
-
|
|
29
|
-
'-defer_relay.helo_temperror',
|
|
30
|
-
'-defer_relay.mfrom_temperror',
|
|
31
|
-
|
|
32
|
-
'-deny.helo_none',
|
|
33
|
-
'-deny.helo_softfail',
|
|
34
|
-
'-deny.helo_fail',
|
|
35
|
-
'-deny.helo_permerror',
|
|
36
|
-
'-deny.openspf_text',
|
|
37
|
-
|
|
38
|
-
'-deny.mfrom_none',
|
|
39
|
-
'-deny.mfrom_softfail',
|
|
40
|
-
'-deny.mfrom_fail',
|
|
41
|
-
'-deny.mfrom_permerror',
|
|
42
|
-
|
|
43
|
-
'-deny_relay.helo_none',
|
|
44
|
-
'-deny_relay.helo_softfail',
|
|
45
|
-
'-deny_relay.helo_fail',
|
|
46
|
-
'-deny_relay.helo_permerror',
|
|
47
|
-
|
|
48
|
-
'-deny_relay.mfrom_none',
|
|
49
|
-
'-deny_relay.mfrom_softfail',
|
|
50
|
-
'-deny_relay.mfrom_fail',
|
|
51
|
-
'-deny_relay.mfrom_permerror',
|
|
52
|
-
'-deny_relay.openspf_text',
|
|
53
|
-
|
|
54
|
-
'-skip.relaying',
|
|
55
|
-
'-skip.auth',
|
|
56
|
-
]
|
|
57
|
-
},
|
|
58
|
-
() => { plugin.load_spf_ini(); }
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
// when set, preserve legacy config settings
|
|
62
|
-
['helo','mail'].forEach(phase => {
|
|
63
|
-
if (plugin.cfg.main[`${phase}_softfail_reject`]) {
|
|
64
|
-
plugin.cfg.deny[`${phase}_softfail`] = true;
|
|
65
|
-
}
|
|
66
|
-
if (plugin.cfg.main[`${phase}_fail_reject`]) {
|
|
67
|
-
plugin.cfg.deny[`${phase}_fail`] = true;
|
|
68
|
-
}
|
|
69
|
-
if (plugin.cfg.main[`${phase}_temperror_defer`]) {
|
|
70
|
-
plugin.cfg.defer[`${phase}_temperror`] = true;
|
|
71
|
-
}
|
|
72
|
-
if (plugin.cfg.main[`${phase}_permerror_reject`]) {
|
|
73
|
-
plugin.cfg.deny[`${phase}_permerror`] = true;
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
if (!plugin.cfg.relay) {
|
|
78
|
-
plugin.cfg.relay = { context: 'sender' }; // default/legacy
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
plugin.cfg.lookup_timeout = plugin.cfg.main.lookup_timeout || plugin.timeout - 1;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
exports.helo_spf = function (next, connection, helo) {
|
|
85
|
-
const plugin = this;
|
|
86
|
-
|
|
87
|
-
// bypass auth'ed or relay'ing hosts if told to
|
|
88
|
-
const skip_reason = exports.skip_hosts(connection);
|
|
89
|
-
if (skip_reason) {
|
|
90
|
-
connection.results.add(plugin, {skip: `helo(${skip_reason})`});
|
|
91
|
-
return next();
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Bypass private IPs
|
|
95
|
-
if (connection.remote.is_private) {
|
|
96
|
-
connection.results.add(plugin, {skip: 'helo(private_ip)'});
|
|
97
|
-
return next();
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// RFC 4408, 2.1: "SPF clients must be prepared for the "HELO"
|
|
101
|
-
// identity to be malformed or an IP address literal.
|
|
102
|
-
if (net_utils.is_ip_literal(helo)) {
|
|
103
|
-
connection.results.add(plugin, {skip: 'helo(ip_literal)'});
|
|
104
|
-
return next();
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// avoid 2nd EHLO evaluation if EHLO host is identical
|
|
108
|
-
const results = connection.results.get(plugin);
|
|
109
|
-
if (results && results.domain === helo) return next();
|
|
110
|
-
|
|
111
|
-
let timeout = false;
|
|
112
|
-
const spf = new SPF();
|
|
113
|
-
const timer = setTimeout(() => {
|
|
114
|
-
timeout = true;
|
|
115
|
-
connection.loginfo(plugin, 'timeout');
|
|
116
|
-
return next();
|
|
117
|
-
}, plugin.cfg.lookup_timeout * 1000);
|
|
118
|
-
|
|
119
|
-
spf.check_host(connection.remote.ip, helo, null, (err, result) => {
|
|
120
|
-
if (timer) clearTimeout(timer);
|
|
121
|
-
if (timeout) return;
|
|
122
|
-
if (err) {
|
|
123
|
-
connection.logerror(plugin, err);
|
|
124
|
-
return next();
|
|
125
|
-
}
|
|
126
|
-
const host = connection.hello.host;
|
|
127
|
-
plugin.log_result(connection, 'helo', host, `postmaster@${host}`, spf.result(result));
|
|
128
|
-
|
|
129
|
-
connection.notes.spf_helo = result; // used between hooks
|
|
130
|
-
connection.results.add(plugin, {
|
|
131
|
-
scope: 'helo',
|
|
132
|
-
result: spf.result(result),
|
|
133
|
-
domain: host,
|
|
134
|
-
emit: true,
|
|
135
|
-
});
|
|
136
|
-
if (spf.result(result) === 'Pass') connection.results.add(plugin, { pass: host });
|
|
137
|
-
next();
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
exports.hook_mail = function (next, connection, params) {
|
|
142
|
-
const plugin = this;
|
|
143
|
-
|
|
144
|
-
const txn = connection.transaction;
|
|
145
|
-
if (!txn) return next();
|
|
146
|
-
|
|
147
|
-
// bypass auth'ed or relay'ing hosts if told to
|
|
148
|
-
const skip_reason = exports.skip_hosts(connection);
|
|
149
|
-
if (skip_reason) {
|
|
150
|
-
txn.results.add(plugin, {skip: `host(${skip_reason})`});
|
|
151
|
-
return next(CONT, `skipped because host(${skip_reason})`);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// For messages from private IP space...
|
|
155
|
-
if (connection.remote.is_private) {
|
|
156
|
-
if (!connection.relaying) return next();
|
|
157
|
-
if (connection.relaying && plugin.cfg.relay.context !== 'myself') {
|
|
158
|
-
txn.results.add(plugin, {skip: 'host(private_ip)'});
|
|
159
|
-
return next(CONT, 'envelope from private IP space');
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
const mfrom = params[0].address();
|
|
164
|
-
const host = params[0].host;
|
|
165
|
-
let spf = new SPF();
|
|
166
|
-
let auth_result;
|
|
167
|
-
|
|
168
|
-
if (connection.notes.spf_helo) {
|
|
169
|
-
const h_result = connection.notes.spf_helo;
|
|
170
|
-
const h_host = connection.hello.host;
|
|
171
|
-
plugin.save_to_header(connection, spf, h_result, mfrom, h_host, 'helo');
|
|
172
|
-
if (!host) { // Use results from HELO if the return-path is null
|
|
173
|
-
auth_result = spf.result(h_result).toLowerCase();
|
|
174
|
-
connection.auth_results(`spf=${auth_result} smtp.helo=${h_host}`);
|
|
175
|
-
|
|
176
|
-
const sender = `<> via ${h_host}`;
|
|
177
|
-
return plugin.return_results(next, connection, spf, 'helo', h_result, sender);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
if (!host) return next(); // null-sender
|
|
182
|
-
|
|
183
|
-
let timeout = false;
|
|
184
|
-
const timer = setTimeout(() => {
|
|
185
|
-
timeout = true;
|
|
186
|
-
connection.loginfo(plugin, 'timeout');
|
|
187
|
-
next();
|
|
188
|
-
}, plugin.cfg.lookup_timeout * 1000);
|
|
189
|
-
|
|
190
|
-
spf.helo = connection.hello.host;
|
|
191
|
-
|
|
192
|
-
function ch_cb (err, result, ip) {
|
|
193
|
-
if (timer) clearTimeout(timer);
|
|
194
|
-
if (timeout) return;
|
|
195
|
-
if (err) {
|
|
196
|
-
connection.logerror(plugin, err);
|
|
197
|
-
return next();
|
|
198
|
-
}
|
|
199
|
-
plugin.log_result(connection, 'mfrom', host, mfrom, spf.result(result), (ip ? ip : connection.remote.ip));
|
|
200
|
-
plugin.save_to_header(connection, spf, result, mfrom, host, 'mailfrom', (ip ? ip : connection.remote.ip));
|
|
201
|
-
|
|
202
|
-
auth_result = spf.result(result).toLowerCase();
|
|
203
|
-
connection.auth_results(`spf=${auth_result} smtp.mailfrom=${host}`);
|
|
204
|
-
|
|
205
|
-
txn.notes.spf_mail_result = spf.result(result);
|
|
206
|
-
txn.notes.spf_mail_record = spf.spf_record;
|
|
207
|
-
txn.results.add(plugin, {
|
|
208
|
-
scope: 'mfrom',
|
|
209
|
-
result: spf.result(result),
|
|
210
|
-
domain: host,
|
|
211
|
-
emit: true,
|
|
212
|
-
});
|
|
213
|
-
if (spf.result(result) === 'Pass') connection.results.add(plugin, { pass: host });
|
|
214
|
-
plugin.return_results(next, connection, spf, 'mfrom', result, mfrom);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// typical inbound (!relay)
|
|
218
|
-
if (!connection.relaying) {
|
|
219
|
-
return spf.check_host(connection.remote.ip, host, mfrom, ch_cb);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
// outbound (relaying), context=sender
|
|
223
|
-
if (plugin.cfg.relay.context === 'sender') {
|
|
224
|
-
return spf.check_host(connection.remote.ip, host, mfrom, ch_cb);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
// outbound (relaying), context=myself
|
|
228
|
-
net_utils.get_public_ip((e, my_public_ip) => {
|
|
229
|
-
// We always check the client IP first, because a relay
|
|
230
|
-
// could be sending inbound mail from a non-local domain
|
|
231
|
-
// which could case an incorrect SPF Fail result if we
|
|
232
|
-
// check the public IP first, so we only check the public
|
|
233
|
-
// IP if the client IP returns a result other than 'Pass'.
|
|
234
|
-
spf.check_host(connection.remote.ip, host, mfrom, (err, result) => {
|
|
235
|
-
let spf_result;
|
|
236
|
-
if (result) {
|
|
237
|
-
spf_result = spf.result(result).toLowerCase();
|
|
238
|
-
}
|
|
239
|
-
if (err || (spf_result && spf_result !== 'pass')) {
|
|
240
|
-
if (e) return ch_cb(e); // Error looking up public IP
|
|
241
|
-
|
|
242
|
-
if (!my_public_ip) {
|
|
243
|
-
return ch_cb(new Error(`failed to discover public IP`));
|
|
244
|
-
}
|
|
245
|
-
spf = new SPF();
|
|
246
|
-
spf.check_host(my_public_ip, host, mfrom, (er, r) => {
|
|
247
|
-
ch_cb(er, r, my_public_ip);
|
|
248
|
-
});
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
ch_cb(err, result, connection.remote.ip);
|
|
252
|
-
});
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
exports.log_result = function (connection, scope, host, mfrom, result, ip) {
|
|
257
|
-
const show_ip=ip ? ip : connection.remote.ip;
|
|
258
|
-
connection.loginfo(this, `identity=${scope} ip=${show_ip} domain="${host}" mfrom=<${mfrom}> result=${result}`);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
exports.return_results = function (next, connection, spf, scope, result, sender) {
|
|
262
|
-
const plugin = this;
|
|
263
|
-
const msgpre = (scope === 'helo') ? `sender ${sender}` : `sender <${sender}>`;
|
|
264
|
-
const deny = connection.relaying ? 'deny_relay' : 'deny';
|
|
265
|
-
const defer = connection.relaying ? 'defer_relay' : 'defer';
|
|
266
|
-
const sender_id = (scope === 'helo') ? connection.hello_host : sender;
|
|
267
|
-
let text = DSN.sec_unauthorized(`http://www.openspf.org/Why?s=${scope}&id=${sender_id}&ip=${connection.remote.ip}`);
|
|
268
|
-
|
|
269
|
-
switch (result) {
|
|
270
|
-
case spf.SPF_NONE:
|
|
271
|
-
if (plugin.cfg[deny][`${scope}_none`]) {
|
|
272
|
-
text = plugin.cfg[deny].openspf_text ? text : `${msgpre} SPF record not found`;
|
|
273
|
-
return next(DENY, text);
|
|
274
|
-
}
|
|
275
|
-
return next();
|
|
276
|
-
case spf.SPF_NEUTRAL:
|
|
277
|
-
case spf.SPF_PASS:
|
|
278
|
-
return next();
|
|
279
|
-
case spf.SPF_SOFTFAIL:
|
|
280
|
-
if (plugin.cfg[deny][`${scope}_softfail`]) {
|
|
281
|
-
text = plugin.cfg[deny].openspf_text ? text : `${msgpre} SPF SoftFail`;
|
|
282
|
-
return next(DENY, text);
|
|
283
|
-
}
|
|
284
|
-
return next();
|
|
285
|
-
case spf.SPF_FAIL:
|
|
286
|
-
if (plugin.cfg[deny][`${scope}_fail`]) {
|
|
287
|
-
text = plugin.cfg[deny].openspf_text ? text : `${msgpre} SPF Fail`;
|
|
288
|
-
return next(DENY, text);
|
|
289
|
-
}
|
|
290
|
-
return next();
|
|
291
|
-
case spf.SPF_TEMPERROR:
|
|
292
|
-
if (plugin.cfg[defer][`${scope}_temperror`]) {
|
|
293
|
-
return next(DENYSOFT, `${msgpre} SPF Temporary Error`);
|
|
294
|
-
}
|
|
295
|
-
return next();
|
|
296
|
-
case spf.SPF_PERMERROR:
|
|
297
|
-
if (plugin.cfg[deny][`${scope}_permerror`]) {
|
|
298
|
-
return next(DENY, `${msgpre} SPF Permanent Error`);
|
|
299
|
-
}
|
|
300
|
-
return next();
|
|
301
|
-
default:
|
|
302
|
-
// Unknown result
|
|
303
|
-
connection.logerror(plugin, `unknown result code=${result}`);
|
|
304
|
-
return next();
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
exports.save_to_header = (connection, spf, result, mfrom, host, id, ip) => {
|
|
309
|
-
// Add a trace header
|
|
310
|
-
if (!connection) return;
|
|
311
|
-
if (!connection.transaction) return;
|
|
312
|
-
const des = result === spf.SPF_PASS ? 'designates' : 'does not designate';
|
|
313
|
-
const identity = `identity=${id}; client-ip=${ip ? ip : connection.remote.ip}`;
|
|
314
|
-
connection.transaction.add_leading_header('Received-SPF',
|
|
315
|
-
`${spf.result(result)} (${connection.local.host}: domain of ${host} ${des} ${connection.remote.ip} as permitted sender) receiver=${connection.local.host}; ${identity} helo=${connection.hello.host}; envelope-from=<${mfrom}>`
|
|
316
|
-
);
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
exports.skip_hosts = function (connection) {
|
|
320
|
-
const plugin = this;
|
|
321
|
-
|
|
322
|
-
const skip = plugin.cfg.skip;
|
|
323
|
-
if (skip) {
|
|
324
|
-
if (skip.relaying && connection.relaying) return 'relay';
|
|
325
|
-
if (skip.auth && connection.notes.auth_user) return 'auth';
|
|
326
|
-
}
|
|
327
|
-
}
|