Haraka 3.1.1 → 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.
Files changed (160) hide show
  1. package/.prettierignore +4 -0
  2. package/CONTRIBUTORS.md +5 -5
  3. package/Changes.md +62 -50
  4. package/Plugins.md +3 -1
  5. package/README.md +1 -1
  6. package/bin/haraka +475 -479
  7. package/config/outbound.ini +3 -0
  8. package/connection.js +1072 -1108
  9. package/docs/Connection.md +29 -30
  10. package/docs/CoreConfig.md +38 -39
  11. package/docs/CustomReturnCodes.md +0 -1
  12. package/docs/HAProxy.md +2 -2
  13. package/docs/Header.md +1 -1
  14. package/docs/Logging.md +29 -5
  15. package/docs/Outbound.md +93 -78
  16. package/docs/Plugins.md +103 -108
  17. package/docs/Transaction.md +49 -51
  18. package/docs/Tutorial.md +127 -143
  19. package/docs/deprecated/access.md +0 -1
  20. package/docs/deprecated/backscatterer.md +2 -3
  21. package/docs/deprecated/connect.rdns_access.md +18 -27
  22. package/docs/deprecated/data.headers.md +0 -1
  23. package/docs/deprecated/data.nomsgid.md +1 -2
  24. package/docs/deprecated/data.noreceived.md +1 -2
  25. package/docs/deprecated/data.rfc5322_header_checks.md +1 -2
  26. package/docs/deprecated/dkim_sign.md +13 -17
  27. package/docs/deprecated/dkim_verify.md +9 -17
  28. package/docs/deprecated/dnsbl.md +36 -38
  29. package/docs/deprecated/dnswl.md +41 -43
  30. package/docs/deprecated/lookup_rdns.strict.md +21 -34
  31. package/docs/deprecated/mail_from.access.md +17 -25
  32. package/docs/deprecated/mail_from.blocklist.md +9 -12
  33. package/docs/deprecated/mail_from.nobounces.md +1 -2
  34. package/docs/deprecated/rcpt_to.access.md +20 -27
  35. package/docs/deprecated/rcpt_to.blocklist.md +10 -13
  36. package/docs/deprecated/rcpt_to.routes.md +0 -1
  37. package/docs/deprecated/rdns.regexp.md +13 -15
  38. package/docs/plugins/aliases.md +89 -89
  39. package/docs/plugins/auth/auth_bridge.md +5 -7
  40. package/docs/plugins/auth/auth_ldap.md +11 -14
  41. package/docs/plugins/auth/auth_proxy.md +10 -12
  42. package/docs/plugins/auth/auth_vpopmaild.md +5 -6
  43. package/docs/plugins/auth/flat_file.md +4 -4
  44. package/docs/plugins/block_me.md +3 -3
  45. package/docs/plugins/data.signatures.md +1 -2
  46. package/docs/plugins/delay_deny.md +3 -4
  47. package/docs/plugins/max_unrecognized_commands.md +4 -4
  48. package/docs/plugins/prevent_credential_leaks.md +6 -6
  49. package/docs/plugins/process_title.md +18 -18
  50. package/docs/plugins/queue/deliver.md +2 -3
  51. package/docs/plugins/queue/discard.md +4 -4
  52. package/docs/plugins/queue/lmtp.md +1 -3
  53. package/docs/plugins/queue/qmail-queue.md +7 -9
  54. package/docs/plugins/queue/quarantine.md +16 -21
  55. package/docs/plugins/queue/rabbitmq.md +8 -11
  56. package/docs/plugins/queue/rabbitmq_amqplib.md +43 -39
  57. package/docs/plugins/queue/smtp_bridge.md +7 -10
  58. package/docs/plugins/queue/smtp_forward.md +42 -34
  59. package/docs/plugins/queue/smtp_proxy.md +30 -29
  60. package/docs/plugins/queue/test.md +1 -3
  61. package/docs/plugins/rcpt_to.in_host_list.md +6 -6
  62. package/docs/plugins/rcpt_to.max_count.md +1 -1
  63. package/docs/plugins/record_envelope_addresses.md +3 -3
  64. package/docs/plugins/reseed_rng.md +6 -6
  65. package/docs/plugins/status.md +9 -8
  66. package/docs/plugins/tarpit.md +7 -11
  67. package/docs/plugins/tls.md +12 -17
  68. package/docs/plugins/toobusy.md +4 -4
  69. package/docs/plugins/xclient.md +3 -3
  70. package/docs/tutorials/Migrating_from_v1_to_v2.md +19 -41
  71. package/docs/tutorials/SettingUpOutbound.md +6 -9
  72. package/endpoint.js +35 -38
  73. package/eslint.config.mjs +22 -19
  74. package/haraka.js +42 -47
  75. package/host_pool.js +75 -79
  76. package/http/html/404.html +45 -49
  77. package/http/html/index.html +39 -28
  78. package/http/package.json +2 -4
  79. package/line_socket.js +27 -28
  80. package/logger.js +182 -201
  81. package/outbound/client_pool.js +33 -33
  82. package/outbound/config.js +64 -59
  83. package/outbound/fsync_writestream.js +24 -25
  84. package/outbound/hmail.js +888 -835
  85. package/outbound/index.js +194 -187
  86. package/outbound/qfile.js +49 -52
  87. package/outbound/queue.js +197 -190
  88. package/outbound/timer_queue.js +41 -43
  89. package/outbound/tls.js +68 -61
  90. package/outbound/todo.js +11 -11
  91. package/package.json +32 -32
  92. package/plugins/.eslintrc.yaml +0 -1
  93. package/plugins/auth/auth_base.js +123 -127
  94. package/plugins/auth/auth_bridge.js +7 -7
  95. package/plugins/auth/auth_proxy.js +121 -126
  96. package/plugins/auth/auth_vpopmaild.js +84 -85
  97. package/plugins/auth/flat_file.js +18 -17
  98. package/plugins/block_me.js +31 -31
  99. package/plugins/data.signatures.js +13 -13
  100. package/plugins/delay_deny.js +65 -61
  101. package/plugins/prevent_credential_leaks.js +23 -23
  102. package/plugins/process_title.js +125 -128
  103. package/plugins/profile.js +5 -5
  104. package/plugins/queue/deliver.js +3 -3
  105. package/plugins/queue/discard.js +13 -14
  106. package/plugins/queue/lmtp.js +16 -17
  107. package/plugins/queue/qmail-queue.js +54 -55
  108. package/plugins/queue/quarantine.js +68 -70
  109. package/plugins/queue/rabbitmq.js +80 -87
  110. package/plugins/queue/rabbitmq_amqplib.js +75 -54
  111. package/plugins/queue/smtp_bridge.js +16 -16
  112. package/plugins/queue/smtp_forward.js +175 -179
  113. package/plugins/queue/smtp_proxy.js +69 -71
  114. package/plugins/queue/test.js +9 -9
  115. package/plugins/rcpt_to.host_list_base.js +30 -34
  116. package/plugins/rcpt_to.in_host_list.js +19 -19
  117. package/plugins/record_envelope_addresses.js +4 -4
  118. package/plugins/reseed_rng.js +4 -4
  119. package/plugins/status.js +90 -97
  120. package/plugins/tarpit.js +25 -14
  121. package/plugins/tls.js +68 -68
  122. package/plugins/toobusy.js +21 -23
  123. package/plugins/xclient.js +51 -53
  124. package/plugins.js +276 -293
  125. package/rfc1869.js +30 -35
  126. package/server.js +308 -299
  127. package/smtp_client.js +244 -228
  128. package/test/.eslintrc.yaml +0 -1
  129. package/test/connection.js +127 -134
  130. package/test/endpoint.js +53 -47
  131. package/test/fixtures/line_socket.js +12 -12
  132. package/test/fixtures/util_hmailitem.js +89 -85
  133. package/test/host_pool.js +90 -92
  134. package/test/installation/plugins/base_plugin.js +2 -2
  135. package/test/installation/plugins/folder_plugin/index.js +2 -3
  136. package/test/installation/plugins/inherits.js +3 -3
  137. package/test/installation/plugins/load_first.js +2 -3
  138. package/test/installation/plugins/plugin.js +1 -3
  139. package/test/installation/plugins/tls.js +2 -4
  140. package/test/logger.js +135 -116
  141. package/test/outbound/hmail.js +49 -35
  142. package/test/outbound/index.js +118 -101
  143. package/test/outbound/qfile.js +51 -53
  144. package/test/outbound_bounce_net_errors.js +84 -69
  145. package/test/outbound_bounce_rfc3464.js +235 -165
  146. package/test/plugins/auth/auth_base.js +420 -279
  147. package/test/plugins/auth/auth_vpopmaild.js +38 -39
  148. package/test/plugins/queue/smtp_forward.js +126 -104
  149. package/test/plugins/rcpt_to.host_list_base.js +85 -67
  150. package/test/plugins/rcpt_to.in_host_list.js +159 -112
  151. package/test/plugins/status.js +71 -64
  152. package/test/plugins/tls.js +37 -34
  153. package/test/plugins.js +97 -92
  154. package/test/rfc1869.js +19 -26
  155. package/test/server.js +293 -272
  156. package/test/smtp_client.js +180 -176
  157. package/test/tls_socket.js +62 -66
  158. package/test/transaction.js +159 -160
  159. package/tls_socket.js +331 -333
  160. package/transaction.js +129 -137
@@ -1,200 +1,197 @@
1
1
  // process_title
2
2
 
3
- const outbound = require('./outbound');
3
+ const outbound = require('./outbound')
4
4
 
5
- function setupInterval (title, server) {
5
+ function setupInterval(title, server) {
6
6
  // Set up a timer to update title
7
7
  return setInterval(() => {
8
8
  // Connections per second
9
- const av_cps = Math.round((server.notes.pt_connections/process.uptime()*100))/100;
10
- const cps = server.notes.pt_connections - server.notes.pt_cps_diff;
11
- if (cps > server.notes.pt_cps_max) server.notes.pt_cps_max = cps;
12
- server.notes.pt_cps_diff = server.notes.pt_connections;
9
+ const av_cps = Math.round((server.notes.pt_connections / process.uptime()) * 100) / 100
10
+ const cps = server.notes.pt_connections - server.notes.pt_cps_diff
11
+ if (cps > server.notes.pt_cps_max) server.notes.pt_cps_max = cps
12
+ server.notes.pt_cps_diff = server.notes.pt_connections
13
13
  // Recipients per second
14
- const av_rps = Math.round((server.notes.pt_recipients/process.uptime()*100))/100;
15
- const rps = server.notes.pt_recipients - server.notes.pt_rps_diff;
16
- if (rps > server.notes.pt_rps_max) server.notes.pt_rps_max = rps;
17
- server.notes.pt_rps_diff = server.notes.pt_recipients;
14
+ const av_rps = Math.round((server.notes.pt_recipients / process.uptime()) * 100) / 100
15
+ const rps = server.notes.pt_recipients - server.notes.pt_rps_diff
16
+ if (rps > server.notes.pt_rps_max) server.notes.pt_rps_max = rps
17
+ server.notes.pt_rps_diff = server.notes.pt_recipients
18
18
  // Recipients per message
19
- const rpm = Math.round((server.notes.pt_recipients / server.notes.pt_messages)*100)/100 || 0;
19
+ const rpm = Math.round((server.notes.pt_recipients / server.notes.pt_messages) * 100) / 100 || 0
20
20
  // Messages per second
21
- const av_mps = Math.round((server.notes.pt_messages/process.uptime()*100))/100;
22
- const mps = server.notes.pt_messages - server.notes.pt_mps_diff;
23
- if (mps > server.notes.pt_mps_max) server.notes.pt_mps_max = mps;
24
- server.notes.pt_mps_diff = server.notes.pt_messages;
21
+ const av_mps = Math.round((server.notes.pt_messages / process.uptime()) * 100) / 100
22
+ const mps = server.notes.pt_messages - server.notes.pt_mps_diff
23
+ if (mps > server.notes.pt_mps_max) server.notes.pt_mps_max = mps
24
+ server.notes.pt_mps_diff = server.notes.pt_messages
25
25
  // Messages per connection
26
- const mpc = Math.round((server.notes.pt_messages / server.notes.pt_connections)*100)/100 || 0;
26
+ const mpc = Math.round((server.notes.pt_messages / server.notes.pt_connections) * 100) / 100 || 0
27
27
 
28
- const out = server.notes.pt_out_stats || outbound.get_stats();
28
+ const out = server.notes.pt_out_stats || outbound.get_stats()
29
29
  if (/\(worker\)/.test(title)) {
30
- process.send({event: 'process_title.outbound_stats', data: out});
30
+ process.send({ event: 'process_title.outbound_stats', data: out })
31
31
  }
32
32
  // Update title
33
- let new_title = `${title} cn=${server.notes.pt_connections} cc=${server.notes.pt_concurrent
34
- } cps=${cps}/${av_cps}/${server.notes.pt_cps_max} rcpts=${server.notes.pt_recipients}/${rpm
35
- } rps=${rps}/${av_rps}/${server.notes.pt_rps_max} msgs=${server.notes.pt_messages}/${mpc
36
- } mps=${mps}/${av_mps}/${server.notes.pt_mps_max} out=${out} `;
33
+ let new_title = `${title} cn=${server.notes.pt_connections} cc=${server.notes.pt_concurrent} cps=${cps}/${av_cps}/${server.notes.pt_cps_max} rcpts=${server.notes.pt_recipients}/${rpm} rps=${rps}/${av_rps}/${server.notes.pt_rps_max} msgs=${server.notes.pt_messages}/${mpc} mps=${mps}/${av_mps}/${server.notes.pt_mps_max} out=${out} `
37
34
  if (/\(master\)/.test(title)) {
38
- new_title += `respawn=${server.notes.pt_child_exits} `;
35
+ new_title += `respawn=${server.notes.pt_child_exits} `
39
36
  }
40
- process.title = new_title;
41
- }, 1000);
37
+ process.title = new_title
38
+ }, 1000)
42
39
  }
43
40
 
44
41
  exports.hook_init_master = function (next, server) {
45
- server.notes.pt_connections = 0;
46
- server.notes.pt_concurrent = 0;
47
- server.notes.pt_cps_diff = 0;
48
- server.notes.pt_cps_max = 0;
49
- server.notes.pt_recipients = 0;
50
- server.notes.pt_rps_diff = 0;
51
- server.notes.pt_rps_max = 0;
52
- server.notes.pt_messages = 0;
53
- server.notes.pt_mps_diff = 0;
54
- server.notes.pt_mps_max = 0;
55
- server.notes.pt_child_exits = 0;
56
- let title = 'Haraka';
42
+ server.notes.pt_connections = 0
43
+ server.notes.pt_concurrent = 0
44
+ server.notes.pt_cps_diff = 0
45
+ server.notes.pt_cps_max = 0
46
+ server.notes.pt_recipients = 0
47
+ server.notes.pt_rps_diff = 0
48
+ server.notes.pt_rps_max = 0
49
+ server.notes.pt_messages = 0
50
+ server.notes.pt_mps_diff = 0
51
+ server.notes.pt_mps_max = 0
52
+ server.notes.pt_child_exits = 0
53
+ let title = 'Haraka'
57
54
  if (server.cluster) {
58
- title = 'Haraka (master)';
59
- process.title = title;
60
- server.notes.pt_concurrent_cluster = {};
61
- server.notes.pt_new_out_stats = [0,0,0,0];
62
- const { cluster } = server;
63
- const recvMsg = msg => {
64
- let count;
55
+ title = 'Haraka (master)'
56
+ process.title = title
57
+ server.notes.pt_concurrent_cluster = {}
58
+ server.notes.pt_new_out_stats = [0, 0, 0, 0]
59
+ const { cluster } = server
60
+ const recvMsg = (msg) => {
61
+ let count
65
62
  switch (msg.event) {
66
63
  case 'process_title.connect':
67
- server.notes.pt_connections++;
68
- server.notes.pt_concurrent_cluster[msg.wid]++;
69
- count = 0;
70
- Object.keys(server.notes.pt_concurrent_cluster).forEach(id => {
71
- count += server.notes.pt_concurrent_cluster[id];
72
- });
73
- server.notes.pt_concurrent = count;
74
- break;
64
+ server.notes.pt_connections++
65
+ server.notes.pt_concurrent_cluster[msg.wid]++
66
+ count = 0
67
+ Object.keys(server.notes.pt_concurrent_cluster).forEach((id) => {
68
+ count += server.notes.pt_concurrent_cluster[id]
69
+ })
70
+ server.notes.pt_concurrent = count
71
+ break
75
72
  case 'process_title.disconnect':
76
- server.notes.pt_concurrent_cluster[msg.wid]--;
77
- count = 0;
78
- Object.keys(server.notes.pt_concurrent_cluster).forEach(id => {
79
- count += server.notes.pt_concurrent_cluster[id];
80
- });
81
- server.notes.pt_concurrent = count;
82
- break;
73
+ server.notes.pt_concurrent_cluster[msg.wid]--
74
+ count = 0
75
+ Object.keys(server.notes.pt_concurrent_cluster).forEach((id) => {
76
+ count += server.notes.pt_concurrent_cluster[id]
77
+ })
78
+ server.notes.pt_concurrent = count
79
+ break
83
80
  case 'process_title.recipient':
84
- server.notes.pt_recipients++;
85
- break;
81
+ server.notes.pt_recipients++
82
+ break
86
83
  case 'process_title.message':
87
- server.notes.pt_messages++;
88
- break;
84
+ server.notes.pt_messages++
85
+ break
89
86
  case 'process_title.outbound_stats': {
90
- const out_stats = msg.data.split('/');
91
- for (let i=0; i<out_stats.length; i++) {
92
- server.notes.pt_new_out_stats[i] += parseInt(out_stats[i], 10);
87
+ const out_stats = msg.data.split('/')
88
+ for (let i = 0; i < out_stats.length; i++) {
89
+ server.notes.pt_new_out_stats[i] += parseInt(out_stats[i], 10)
93
90
  }
94
- server.notes.pt_new_out_stats[3]++;
91
+ server.notes.pt_new_out_stats[3]++
95
92
  // Check if we got all results back yet
96
93
  if (server.notes.pt_new_out_stats[3] === Object.keys(cluster.workers).length) {
97
- server.notes.pt_out_stats = server.notes.pt_new_out_stats.slice(0,3).join('/');
98
- server.notes.pt_new_out_stats = [0,0,0,0];
94
+ server.notes.pt_out_stats = server.notes.pt_new_out_stats.slice(0, 3).join('/')
95
+ server.notes.pt_new_out_stats = [0, 0, 0, 0]
99
96
  }
100
97
  }
101
98
  // fall through
102
99
  default:
103
- // Unknown message
100
+ // Unknown message
104
101
  }
105
- };
102
+ }
106
103
  // Register any new workers
107
- cluster.on('fork', worker => {
108
- server.notes.pt_concurrent_cluster[worker.id] = 0;
109
- cluster.workers[worker.id].on('message', recvMsg);
110
- });
111
- cluster.on('exit', worker => {
112
- delete server.notes.pt_concurrent_cluster[worker.id];
104
+ cluster.on('fork', (worker) => {
105
+ server.notes.pt_concurrent_cluster[worker.id] = 0
106
+ cluster.workers[worker.id].on('message', recvMsg)
107
+ })
108
+ cluster.on('exit', (worker) => {
109
+ delete server.notes.pt_concurrent_cluster[worker.id]
113
110
  // Update concurrency
114
- let count = 0;
115
- Object.keys(server.notes.pt_concurrent_cluster).forEach(id => {
116
- count += server.notes.pt_concurrent_cluster[id];
117
- });
118
- server.notes.pt_concurrent = count;
119
- server.notes.pt_child_exits++;
120
- });
111
+ let count = 0
112
+ Object.keys(server.notes.pt_concurrent_cluster).forEach((id) => {
113
+ count += server.notes.pt_concurrent_cluster[id]
114
+ })
115
+ server.notes.pt_concurrent = count
116
+ server.notes.pt_child_exits++
117
+ })
121
118
  }
122
- this._interval = setupInterval(title, server);
123
- next();
119
+ this._interval = setupInterval(title, server)
120
+ next()
124
121
  }
125
122
 
126
123
  exports.hook_init_child = function (next, server) {
127
- server.notes.pt_connections = 0;
128
- server.notes.pt_concurrent = 0;
129
- server.notes.pt_cps_diff = 0;
130
- server.notes.pt_cps_max = 0;
131
- server.notes.pt_recipients = 0;
132
- server.notes.pt_rps_diff = 0;
133
- server.notes.pt_rps_max = 0;
134
- server.notes.pt_messages = 0;
135
- server.notes.pt_mps_diff = 0;
136
- server.notes.pt_mps_max = 0;
137
- process.title = 'Haraka (worker)';
138
- this._interval = setupInterval(process.title, server);
139
- next();
124
+ server.notes.pt_connections = 0
125
+ server.notes.pt_concurrent = 0
126
+ server.notes.pt_cps_diff = 0
127
+ server.notes.pt_cps_max = 0
128
+ server.notes.pt_recipients = 0
129
+ server.notes.pt_rps_diff = 0
130
+ server.notes.pt_rps_max = 0
131
+ server.notes.pt_messages = 0
132
+ server.notes.pt_mps_diff = 0
133
+ server.notes.pt_mps_max = 0
134
+ process.title = 'Haraka (worker)'
135
+ this._interval = setupInterval(process.title, server)
136
+ next()
140
137
  }
141
138
 
142
139
  exports.shutdown = function () {
143
- this.logdebug(`Shutting down interval: ${this._interval}`);
144
- clearInterval(this._interval);
140
+ this.logdebug(`Shutting down interval: ${this._interval}`)
141
+ clearInterval(this._interval)
145
142
  }
146
143
 
147
144
  exports.hook_connect_init = (next, connection) => {
148
- const { server } = connection;
149
- connection.notes.pt_connect_run = true;
145
+ const { server } = connection
146
+ connection.notes.pt_connect_run = true
150
147
  if (server.cluster) {
151
- const { worker } = server.cluster;
152
- worker.send({event: 'process_title.connect', wid: worker.id});
148
+ const { worker } = server.cluster
149
+ worker.send({ event: 'process_title.connect', wid: worker.id })
153
150
  }
154
- server.notes.pt_connections++;
155
- server.notes.pt_concurrent++;
156
- next();
151
+ server.notes.pt_connections++
152
+ server.notes.pt_concurrent++
153
+ next()
157
154
  }
158
155
 
159
156
  exports.hook_disconnect = (next, connection) => {
160
- const { server } = connection;
157
+ const { server } = connection
161
158
  // Check that the hook above ran
162
159
  // It might not if the disconnection is immediate
163
160
  // echo "QUIT" | nc localhost 25
164
161
  // will exhibit this behaviour.
165
- let worker;
162
+ let worker
166
163
  if (!connection.notes.pt_connect_run) {
167
164
  if (server.cluster) {
168
- worker = server.cluster.worker;
169
- worker.send({event: 'process_title.connect', wid: worker.id});
165
+ worker = server.cluster.worker
166
+ worker.send({ event: 'process_title.connect', wid: worker.id })
170
167
  }
171
- server.notes.pt_connections++;
172
- server.notes.pt_concurrent++;
168
+ server.notes.pt_connections++
169
+ server.notes.pt_concurrent++
173
170
  }
174
171
  if (server.cluster) {
175
- worker = server.cluster.worker;
176
- worker.send({event: 'process_title.disconnect', wid: worker.id});
172
+ worker = server.cluster.worker
173
+ worker.send({ event: 'process_title.disconnect', wid: worker.id })
177
174
  }
178
- server.notes.pt_concurrent--;
179
- next();
175
+ server.notes.pt_concurrent--
176
+ next()
180
177
  }
181
178
 
182
179
  exports.hook_rcpt = (next, connection) => {
183
- const { server } = connection;
180
+ const { server } = connection
184
181
  if (server.cluster) {
185
- const { worker } = server.cluster;
186
- worker.send({event: 'process_title.recipient'});
182
+ const { worker } = server.cluster
183
+ worker.send({ event: 'process_title.recipient' })
187
184
  }
188
- server.notes.pt_recipients++;
189
- next();
185
+ server.notes.pt_recipients++
186
+ next()
190
187
  }
191
188
 
192
189
  exports.hook_data = (next, connection) => {
193
- const { server } = connection;
190
+ const { server } = connection
194
191
  if (server.cluster) {
195
- const { worker } = server.cluster;
196
- worker.send({event: 'process_title.message'});
192
+ const { worker } = server.cluster
193
+ worker.send({ event: 'process_title.message' })
197
194
  }
198
- server.notes.pt_messages++;
199
- next();
195
+ server.notes.pt_messages++
196
+ next()
200
197
  }
@@ -1,11 +1,11 @@
1
- const prof = require('v8-profiler');
1
+ const prof = require('v8-profiler')
2
2
 
3
3
  exports.hook_connect_init = (next, conn) => {
4
- prof.startProfiling(`Connection from: ${conn.remote.ip}`);
5
- next();
4
+ prof.startProfiling(`Connection from: ${conn.remote.ip}`)
5
+ next()
6
6
  }
7
7
 
8
8
  exports.hook_disconnect = (next, conn) => {
9
- prof.stopProfiling(`Connection from: ${conn.remote.ip}`);
10
- next();
9
+ prof.stopProfiling(`Connection from: ${conn.remote.ip}`)
10
+ next()
11
11
  }
@@ -2,11 +2,11 @@
2
2
  // automatically just like this. It is kept here for backwards compatibility
3
3
  // purposes only.
4
4
 
5
- const outbound = require('./outbound');
5
+ const outbound = require('./outbound')
6
6
 
7
7
  exports.hook_queue_outbound = (next, connection) => {
8
8
  // if not relaying, don't deliver outbound
9
- if (!connection?.relaying) return next();
9
+ if (!connection?.relaying) return next()
10
10
 
11
- outbound.send_trans_email(connection?.transaction, next);
11
+ outbound.send_trans_email(connection?.transaction, next)
12
12
  }
@@ -1,28 +1,27 @@
1
1
  // discard
2
2
 
3
3
  exports.register = function () {
4
- this.register_hook('queue', 'discard');
5
- this.register_hook('queue_outbound', 'discard');
4
+ this.register_hook('queue', 'discard')
5
+ this.register_hook('queue_outbound', 'discard')
6
6
  }
7
7
 
8
8
  exports.discard = (next, connection) => {
9
+ const txn = connection.transaction
9
10
 
10
- const txn = connection.transaction;
11
+ const q_wants = txn.notes.get('queue.wants')
12
+ if (q_wants && q_wants !== 'discard') return next()
11
13
 
12
- const q_wants = txn.notes.get('queue.wants');
13
- if (q_wants && q_wants !== 'discard') return next();
14
-
15
- function discard () {
16
- connection.loginfo('discarding message');
14
+ function discard() {
15
+ connection.loginfo('discarding message')
17
16
  // Pretend we delivered the message
18
- return next(OK);
17
+ return next(OK)
19
18
  }
20
19
 
21
- if (connection.notes.discard) return discard();
22
- if (txn.notes.discard) return discard();
23
- if (q_wants === 'discard') return discard();
24
- if (process.env.YES_REALLY_DO_DISCARD) return discard();
20
+ if (connection.notes.discard) return discard()
21
+ if (txn.notes.discard) return discard()
22
+ if (q_wants === 'discard') return discard()
23
+ if (process.env.YES_REALLY_DO_DISCARD) return discard()
25
24
 
26
25
  // Allow other queue plugins to deliver
27
- next();
26
+ next()
28
27
  }
@@ -1,46 +1,45 @@
1
1
  //queue/lmtp
2
2
 
3
- 'use strict';
3
+ 'use strict'
4
4
 
5
- let outbound;
5
+ let outbound
6
6
 
7
7
  exports.register = function () {
8
- this.load_lmtp_ini();
9
- outbound = this.haraka_require('outbound');
8
+ this.load_lmtp_ini()
9
+ outbound = this.haraka_require('outbound')
10
10
  }
11
11
 
12
12
  exports.load_lmtp_ini = function () {
13
13
  this.cfg = this.config.get('lmtp.ini', () => {
14
- this.load_lmtp_ini();
14
+ this.load_lmtp_ini()
15
15
  })
16
16
  }
17
17
 
18
18
  exports.hook_get_mx = function (next, hmail, domain) {
19
+ if (!hmail.todo.notes.using_lmtp) return next()
19
20
 
20
- if (!hmail.todo.notes.using_lmtp) return next();
21
-
22
- const section = this.cfg[domain] || this.cfg.main;
21
+ const section = this.cfg[domain] || this.cfg.main
23
22
 
24
23
  const mx = {
25
24
  using_lmtp: true,
26
25
  priority: 0,
27
26
  exchange: section.host ?? '127.0.0.1',
28
27
  port: section.port ?? 24,
29
- };
28
+ }
30
29
 
31
- if (section.path) mx.path = section.path;
30
+ if (section.path) mx.path = section.path
32
31
 
33
- next(OK, mx);
32
+ next(OK, mx)
34
33
  }
35
34
 
36
35
  exports.hook_queue = (next, connection) => {
37
- const txn = connection?.transaction;
38
- if (!txn) return next();
36
+ const txn = connection?.transaction
37
+ if (!txn) return next()
39
38
 
40
- const q_wants = txn.notes.get('queue.wants');
39
+ const q_wants = txn.notes.get('queue.wants')
41
40
 
42
- if (q_wants && q_wants !== 'lmtp') return next();
41
+ if (q_wants && q_wants !== 'lmtp') return next()
43
42
 
44
- txn.notes.using_lmtp = true;
45
- outbound.send_trans_email(txn, next);
43
+ txn.notes.using_lmtp = true
44
+ outbound.send_trans_email(txn, next)
46
45
  }
@@ -1,98 +1,97 @@
1
1
  // Queue to qmail-queue
2
2
 
3
- const childproc = require('node:child_process');
4
- const fs = require('node:fs');
3
+ const childproc = require('node:child_process')
4
+ const fs = require('node:fs')
5
5
 
6
6
  exports.register = function () {
7
-
8
- this.queue_exec = this.config.get('qmail-queue.path') || '/var/qmail/bin/qmail-queue';
7
+ this.queue_exec = this.config.get('qmail-queue.path') || '/var/qmail/bin/qmail-queue'
9
8
  if (!fs.existsSync(this.queue_exec)) {
10
- throw new Error(`Cannot find qmail-queue binary (${this.queue_exec})`);
9
+ throw new Error(`Cannot find qmail-queue binary (${this.queue_exec})`)
11
10
  }
12
11
 
13
- this.load_qmail_queue_ini();
12
+ this.load_qmail_queue_ini()
14
13
 
15
14
  if (this.cfg.main.enable_outbound) {
16
- this.register_hook('queue_outbound', 'hook_queue');
15
+ this.register_hook('queue_outbound', 'hook_queue')
17
16
  }
18
17
  }
19
18
 
20
19
  exports.load_qmail_queue_ini = function () {
21
-
22
- this.cfg = this.config.get('qmail-queue.ini', {
23
- booleans: [
24
- '+main.enable_outbound',
25
- ],
26
- },
27
- () => {
28
- this.load_qmail_queue_ini();
29
- });
20
+ this.cfg = this.config.get(
21
+ 'qmail-queue.ini',
22
+ {
23
+ booleans: ['+main.enable_outbound'],
24
+ },
25
+ () => {
26
+ this.load_qmail_queue_ini()
27
+ },
28
+ )
30
29
  }
31
30
 
32
31
  exports.hook_queue = function (next, connection) {
33
- const plugin = this;
32
+ const plugin = this
34
33
 
35
- const txn = connection?.transaction;
36
- if (!txn) return next();
34
+ const txn = connection?.transaction
35
+ if (!txn) return next()
37
36
 
38
- const q_wants = txn.notes.get('queue.wants');
39
- if (q_wants && q_wants !== 'qmail-queue') return next();
37
+ const q_wants = txn.notes.get('queue.wants')
38
+ if (q_wants && q_wants !== 'qmail-queue') return next()
40
39
 
41
40
  const qmail_queue = childproc.spawn(
42
41
  this.queue_exec, // process name
43
- [], // arguments
44
- { stdio: ['pipe', 'pipe', process.stderr] }
45
- );
42
+ [], // arguments
43
+ { stdio: ['pipe', 'pipe', process.stderr] },
44
+ )
46
45
 
47
- qmail_queue.on('exit', function finished (code) {
46
+ qmail_queue.on('exit', function finished(code) {
48
47
  if (code !== 0) {
49
- connection.logerror(plugin, `Unable to queue message to qmail-queue: ${code}`);
50
- next();
48
+ connection.logerror(plugin, `Unable to queue message to qmail-queue: ${code}`)
49
+ next()
50
+ } else {
51
+ next(OK, 'Queued!')
51
52
  }
52
- else {
53
- next(OK, "Queued!");
54
- }
55
- });
53
+ })
56
54
 
57
- connection.transaction.message_stream.pipe(qmail_queue.stdin, { line_endings: '\n' });
55
+ connection.transaction.message_stream.pipe(qmail_queue.stdin, {
56
+ line_endings: '\n',
57
+ })
58
58
 
59
59
  qmail_queue.stdin.on('close', () => {
60
60
  if (!connection?.transaction) {
61
- plugin.logerror("Transaction went away while delivering mail to qmail-queue");
61
+ plugin.logerror('Transaction went away while delivering mail to qmail-queue')
62
62
  try {
63
- qmail_queue.stdout.end();
64
- }
65
- catch (err) {
63
+ qmail_queue.stdout.end()
64
+ } catch (err) {
66
65
  if (err.code !== 'ENOTCONN') {
67
66
  // Ignore ENOTCONN and re throw anything else
68
67
  throw err
69
68
  }
70
69
  }
71
70
 
72
- connection.results.add(plugin, { err: 'dead sender' });
73
- return;
71
+ connection.results.add(plugin, { err: 'dead sender' })
72
+ return
74
73
  }
75
- plugin.loginfo("Message Stream sent to qmail. Now sending envelope");
74
+ plugin.loginfo('Message Stream sent to qmail. Now sending envelope')
76
75
  // now send envelope
77
76
  // Hope this will be big enough...
78
- const buf = Buffer.alloc(4096);
79
- let p = 0;
80
- buf[p++] = 70;
81
- const mail_from = connection.transaction.mail_from.address();
77
+ const buf = Buffer.alloc(4096)
78
+ let p = 0
79
+ buf[p++] = 70
80
+ const mail_from = connection.transaction.mail_from.address()
82
81
  for (let i = 0; i < mail_from.length; i++) {
83
- buf[p++] = mail_from.charCodeAt(i);
82
+ buf[p++] = mail_from.charCodeAt(i)
84
83
  }
85
- buf[p++] = 0;
86
- connection.transaction.rcpt_to.forEach(rcpt => {
87
- buf[p++] = 84;
88
- const rcpt_to = rcpt.address();
84
+ buf[p++] = 0
85
+ connection.transaction.rcpt_to.forEach((rcpt) => {
86
+ buf[p++] = 84
87
+ const rcpt_to = rcpt.address()
89
88
  for (let j = 0; j < rcpt_to.length; j++) {
90
- buf[p++] = rcpt_to.charCodeAt(j);
89
+ buf[p++] = rcpt_to.charCodeAt(j)
91
90
  }
92
- buf[p++] = 0;
93
- });
94
- buf[p++] = 0;
95
- qmail_queue.stdout.on('error', err => {}); // stdout throws an error on close
96
- qmail_queue.stdout.end(buf);
97
- });
91
+ buf[p++] = 0
92
+ })
93
+ buf[p++] = 0
94
+ qmail_queue.stdout.on('error', (err) => {}) // stdout throws an error on close
95
+ qmail_queue.stdout.end(buf)
96
+ })
98
97
  }