Haraka 3.1.3 → 3.1.5

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 (65) hide show
  1. package/.prettierignore +2 -0
  2. package/CONTRIBUTORS.md +23 -1
  3. package/Changes.md +52 -0
  4. package/Plugins.md +81 -64
  5. package/README.md +1 -1
  6. package/bin/haraka +7 -5
  7. package/connection.js +15 -19
  8. package/docs/Plugins.md +1 -1
  9. package/docs/plugins/aliases.md +0 -2
  10. package/docs/plugins/queue/qmail-queue.md +0 -1
  11. package/logger.js +2 -2
  12. package/outbound/hmail.js +76 -83
  13. package/outbound/index.js +36 -34
  14. package/outbound/queue.js +231 -176
  15. package/package.json +26 -29
  16. package/plugins/prevent_credential_leaks.js +2 -2
  17. package/plugins/process_title.js +1 -1
  18. package/plugins/queue/smtp_forward.js +5 -5
  19. package/plugins/status.js +8 -5
  20. package/plugins/tls.js +1 -1
  21. package/plugins.js +19 -14
  22. package/rfc1869.js +10 -10
  23. package/run_tests +8 -2
  24. package/server.js +15 -10
  25. package/smtp_client.js +10 -15
  26. package/test/config/tls/haraka.local.pem +47 -47
  27. package/test/connection.js +286 -147
  28. package/test/endpoint.js +5 -4
  29. package/test/fixtures/line_socket.js +1 -0
  30. package/test/fixtures/util_hmailitem.js +1 -1
  31. package/test/host_pool.js +57 -31
  32. package/test/logger.js +75 -135
  33. package/test/outbound/bounce_net_errors.js +132 -0
  34. package/test/outbound/bounce_rfc3464.js +226 -0
  35. package/test/outbound/hmail.js +140 -104
  36. package/test/outbound/index.js +61 -101
  37. package/test/outbound/qfile.js +25 -25
  38. package/test/outbound/queue.js +233 -0
  39. package/test/plugins/auth/auth_base.js +39 -44
  40. package/test/plugins/auth/auth_vpopmaild.js +8 -9
  41. package/test/plugins/queue/smtp_forward.js +953 -183
  42. package/test/plugins/rcpt_to.host_list_base.js +58 -93
  43. package/test/plugins/rcpt_to.in_host_list.js +126 -175
  44. package/test/plugins/record_envelope_addresses.js +93 -0
  45. package/test/plugins/status.js +10 -10
  46. package/test/plugins/tls.js +11 -21
  47. package/test/plugins/xclient.js +102 -0
  48. package/test/plugins.js +10 -13
  49. package/test/rfc1869.js +71 -48
  50. package/test/server.js +281 -436
  51. package/test/smtp_client.js +1194 -220
  52. package/test/tls_socket.js +74 -243
  53. package/test/transaction.js +486 -201
  54. package/tls_socket.js +19 -23
  55. package/transaction.js +33 -10
  56. package/config/rabbitmq.ini +0 -10
  57. package/config/rabbitmq_amqplib.ini +0 -19
  58. package/docs/plugins/queue/rabbitmq.md +0 -34
  59. package/docs/plugins/queue/rabbitmq_amqplib.md +0 -51
  60. package/plugins/queue/rabbitmq.js +0 -141
  61. package/plugins/queue/rabbitmq_amqplib.js +0 -96
  62. package/test/config/tls/ec.pem +0 -23
  63. package/test/config/tls/mismatched.pem +0 -49
  64. package/test/outbound_bounce_net_errors.js +0 -157
  65. package/test/outbound_bounce_rfc3464.js +0 -366
package/tls_socket.js CHANGED
@@ -159,21 +159,16 @@ exports.parse_x509 = async (string) => {
159
159
  const res = {}
160
160
  if (!string) return res
161
161
 
162
- const keyRe = new RegExp('([-]+BEGIN (?:\\w+ )?PRIVATE KEY[-]+[^-]*[-]+END (?:\\w+ )?PRIVATE KEY[-]+)', 'gm')
162
+ const keyRe = /([-]+BEGIN (?:\w+ )?PRIVATE KEY[-]+[^-]*[-]+END (?:\w+ )?PRIVATE KEY[-]+)/gm
163
163
  res.keys = string.match(keyRe)
164
164
 
165
- const certRe = new RegExp('([-]+BEGIN CERTIFICATE[-]+[^-]*[-]+END CERTIFICATE[-]+)', 'gm')
165
+ const certRe = /([-]+BEGIN CERTIFICATE[-]+[^-]*[-]+END CERTIFICATE[-]+)/gm
166
166
  res.chain = string.match(certRe)
167
167
 
168
168
  if (res.chain?.length) {
169
- const opensslArgs = [res.chain[0], 'x509', '-noout']
170
- // shush openssl, https://github.com/openssl/openssl/issues/22893
171
- // if (['darwin','linux','freebsd'].includes(process.platform))
172
- // opensslArgs.push('-in', '/dev/stdin')
173
-
174
169
  // it's cleaner to call openssl with each of -enddate, -subject, etc, but it costs
175
170
  // 40-50ms per spawn with node v21 on a M1 MBP
176
- const raw = await openssl(...opensslArgs, '-enddate', '-subject', '-ext', 'subjectAltName')
171
+ const raw = await openssl(res.chain[0], 'x509', '-noout', '-enddate', '-subject', '-ext', 'subjectAltName')
177
172
  if (!raw) return res
178
173
 
179
174
  res.expire = new Date(raw.match(/notAfter=(.* [A-Z]{3})/)[1])
@@ -191,7 +186,7 @@ exports.parse_x509 = async (string) => {
191
186
  }
192
187
 
193
188
  exports.load_tls_ini = (opts) => {
194
- log.info(`loading tls.ini`) // from ${this.config.root_path}`);
189
+ log.info('loading tls.ini')
195
190
 
196
191
  const cfg = exports.config.get(
197
192
  'tls.ini',
@@ -339,7 +334,7 @@ exports.load_default_opts = () => {
339
334
  if (!Array.isArray(cfg.key)) cfg.key = [cfg.key]
340
335
  if (!Array.isArray(cfg.cert)) cfg.cert = [cfg.cert]
341
336
 
342
- if (cfg.key.length != cfg.cert.length) {
337
+ if (cfg.key.length !== cfg.cert.length) {
343
338
  log.error(`number of keys (${cfg.key.length}) not equal to certs (${cfg.cert.length}).`)
344
339
  }
345
340
 
@@ -454,19 +449,20 @@ exports.get_certs_dir = async (tlsDir) => {
454
449
  function openssl(crt, ...params) {
455
450
  return new Promise((resolve) => {
456
451
  let crtTxt = ''
452
+ let errTxt = ''
457
453
 
458
- const o = spawn('openssl', [...params], { timeout: 1000 })
454
+ const o = spawn('openssl', params, { timeout: 2000 })
459
455
  o.stdout.on('data', (data) => {
460
456
  crtTxt += data
461
457
  })
462
458
 
463
459
  o.stderr.on('data', (data) => {
464
- log.debug(`err: ${data.toString().trim()}`)
460
+ errTxt += data
465
461
  })
466
462
 
467
463
  o.on('close', (code) => {
468
464
  if (code !== 0) {
469
- if (code) console.error(code)
465
+ log.error(`openssl ${params.join(' ')} failed with code ${code}: ${errTxt.trim()}`)
470
466
  }
471
467
  resolve(crtTxt)
472
468
  })
@@ -484,8 +480,7 @@ exports.getSocketOpts = async (name) => {
484
480
  await this.get_certs_dir('tls')
485
481
  } catch (err) {
486
482
  if (err.code !== 'ENOENT') {
487
- console.error(err.messsage)
488
- log.error(err)
483
+ log.error(err.message)
489
484
  }
490
485
  }
491
486
 
@@ -519,7 +514,7 @@ exports.ensureDhparams = (done) => {
519
514
 
520
515
  log.info(`Generating a 2048 bit dhparams file at ${fpResolved}`)
521
516
 
522
- const o = spawn('openssl', ['dhparam', '-out', `${fpResolved}`, '2048'])
517
+ const o = spawn('openssl', ['dhparam', '-out', fpResolved, '2048'], { timeout: 30000 })
523
518
  o.stdout.on('data', (data) => {
524
519
  // normally empty output
525
520
  log.debug(data)
@@ -586,9 +581,9 @@ exports.shutdown = () => {
586
581
 
587
582
  function cleanOcspCache() {
588
583
  log.debug(`Cleaning ocspCache. How many keys? ${Object.keys(ocspCache.cache).length}`)
589
- Object.keys(ocspCache.cache).forEach((key) => {
584
+ for (const key of Object.keys(ocspCache.cache)) {
590
585
  clearTimeout(ocspCache.cache[key].timer)
591
- })
586
+ }
592
587
  }
593
588
 
594
589
  exports.certsByHost = certsByHost
@@ -615,7 +610,7 @@ function createServer(cb) {
615
610
 
616
611
  cryptoSocket.removeAllListeners('data')
617
612
 
618
- const options = Object.assign({}, certsByHost['*'])
613
+ const options = { ...certsByHost['*'] }
619
614
  options.server = server // TLSSocket needs server for SNI to work
620
615
 
621
616
  options.rejectUnauthorized = exports.get_rejectUnauthorized(
@@ -679,21 +674,22 @@ function connect(conn_options = {}) {
679
674
  const host = conn_options.host
680
675
  if (exports.cfg === undefined) exports.load_tls_ini()
681
676
  if (exports.cfg.mutual_auth_hosts[host]) {
682
- options = Object.assign(options, getCertFor(exports.cfg.mutual_auth_hosts[host]))
677
+ options = { ...options, ...getCertFor(exports.cfg.mutual_auth_hosts[host]) }
683
678
  } else if (exports.cfg.mutual_auth_hosts_exclude[host]) {
684
679
  // send no client cert
685
680
  } else if (exports.cfg.main.mutual_tls) {
686
- options = Object.assign(options, getCertFor(host))
681
+ options = { ...options, ...getCertFor(host) }
687
682
  }
688
683
  }
689
684
  options.socket = cryptoSocket
690
685
 
691
- const cleartext = new tls.connect(options)
686
+ const cleartext = tls.connect(options)
692
687
 
693
688
  pipe(cleartext, cryptoSocket)
694
689
 
695
690
  cleartext.on('error', (err) => {
696
- if (err.reason) log.error(`client TLS error: ${err}`)
691
+ err.source = 'tls'
692
+ socket.emit('error', err)
697
693
  })
698
694
 
699
695
  cleartext.once('secureConnect', () => {
package/transaction.js CHANGED
@@ -55,9 +55,12 @@ class Transaction {
55
55
 
56
56
  for (const o of this.body_filters) {
57
57
  this.body.add_filter((ct, enc, buf) => {
58
- const re_match = util.types.isRegExp(o.ct_match) && o.ct_match.test(ct.toLowerCase())
59
- const ct_begins = ct.toLowerCase().indexOf(String(o.ct_match).toLowerCase()) === 0
60
- if (re_match || ct_begins) return o.filter(ct, enc, buf)
58
+ if (!ct) return buf
59
+ const ct_lc = String(ct).toLowerCase().trim()
60
+ const re_match = util.types.isRegExp(o.ct_match) && o.ct_match.test(ct_lc)
61
+ const ct_begins = ct_lc.indexOf(String(o.ct_match).toLowerCase()) === 0
62
+ if (re_match || ct_begins) return o.filter(ct, enc, buf) || buf
63
+ return buf
61
64
  })
62
65
  }
63
66
  }
@@ -133,7 +136,7 @@ class Transaction {
133
136
  // is this the end of headers line?
134
137
  if (this.header_pos === 0 && (line[0] === 0x0a || (line[0] === 0x0d && line[1] === 0x0a))) {
135
138
  this.header.parse(this.header_lines)
136
- this.header_pos = this.header_lines.length
139
+ this.header_pos = this.header.header_list ? this.header.header_list.length : -1
137
140
  this.found_hb_sep = true
138
141
  if (this.parse_body) this.ensure_body()
139
142
  } else if (this.header_pos === 0) {
@@ -143,6 +146,7 @@ class Transaction {
143
146
  this.header_lines.push(line.toString(this.encoding).replace(/\r\n$/, '\n'))
144
147
  }
145
148
  } else if (this.parse_body) {
149
+ this.ensure_body()
146
150
  let new_line = line
147
151
  if (new_line[0] === 0x2e) new_line = new_line.slice(1) // Strip leading "."
148
152
 
@@ -169,13 +173,23 @@ class Transaction {
169
173
  }
170
174
  const body_lines = this.header_lines.splice(header_pos + 1)
171
175
  this.header.parse(this.header_lines)
172
- this.header_pos = header_pos
176
+ this.header_pos = this.header.header_list ? this.header.header_list.length : -1
177
+ this.found_hb_sep = true
178
+
179
+ // We MUST add an empty line to the message_stream so that it knows
180
+ // where the headers end. Otherwise it skips everything.
181
+ if (!this.discard_data) this.message_stream.add_line(Buffer.from('\r\n'))
182
+
173
183
  if (this.parse_body) {
174
184
  this.ensure_body()
175
185
  for (const bodyLine of body_lines) {
176
186
  this.body.parse_more(bodyLine)
177
187
  }
178
188
  }
189
+
190
+ for (const bodyLine of body_lines) {
191
+ if (!this.discard_data) this.message_stream.add_line(Buffer.from(`${bodyLine}\n`))
192
+ }
179
193
  }
180
194
  if (this.header_pos && this.parse_body) {
181
195
  const line = this.add_dot_stuffing_and_ensure_crlf_newlines(this.body.parse_end())
@@ -195,22 +209,21 @@ class Transaction {
195
209
 
196
210
  add_header(key, value) {
197
211
  this.header.add_end(key, value)
198
- if (this.header_pos > 0) this.reset_headers()
212
+ if (this.found_hb_sep) this.reset_headers()
199
213
  }
200
214
 
201
215
  add_leading_header(key, value) {
202
216
  this.header.add(key, value)
203
- if (this.header_pos > 0) this.reset_headers()
217
+ if (this.found_hb_sep) this.reset_headers()
204
218
  }
205
219
 
206
220
  reset_headers() {
207
- const header_lines = this.header.lines()
208
- this.header_pos = header_lines.length
221
+ this.header_pos = this.header.header_list ? this.header.header_list.length : -1
209
222
  }
210
223
 
211
224
  remove_header(key) {
212
225
  this.header.remove(key)
213
- if (this.header_pos > 0) this.reset_headers()
226
+ if (this.found_hb_sep) this.reset_headers()
214
227
  }
215
228
 
216
229
  attachment_hooks(start, data, end) {
@@ -230,6 +243,16 @@ class Transaction {
230
243
  add_body_filter(ct_match, filter) {
231
244
  this.parse_body = true
232
245
  this.body_filters.push({ ct_match, filter })
246
+ if (this.body) {
247
+ this.body.add_filter((ct, enc, buf) => {
248
+ if (!ct) return buf
249
+ const ct_lc = String(ct).toLowerCase().trim()
250
+ const re_match = util.types.isRegExp(ct_match) && ct_match.test(ct_lc)
251
+ const ct_begins = ct_lc.indexOf(String(ct_match).toLowerCase()) === 0
252
+ if (re_match || ct_begins) return filter(ct, enc, buf) || buf
253
+ return buf
254
+ })
255
+ }
233
256
  }
234
257
 
235
258
  incr_mime_count(line) {
@@ -1,10 +0,0 @@
1
- [rabbitmq]
2
- exchangeName = emailMessages
3
- server_ip = localhost
4
- server_port = 5672
5
- queueName = email
6
- deliveryMode = 2
7
- confirm = true
8
- durable = true
9
- autoDelete = false
10
- exchangeType = direct
@@ -1,19 +0,0 @@
1
- [rabbitmq]
2
- host = localhost
3
- port = 5672
4
- user = guest
5
- password = guest
6
- exchangeName = email_messages
7
- exchangeType = direct
8
- queueName = emails
9
- deliveryMode = 2
10
- confirm = true
11
- durable = true
12
- autoDelete = false
13
-
14
- ; Optional queue arguments
15
- ; [queue_args]
16
- ; x-dead-letter-exchange =
17
- ; x-dead-letter-routing-key = emails_dlq
18
- ; x-overflow = reject-publish
19
- ; x-queue-type = quorum
@@ -1,34 +0,0 @@
1
- # queue/rabbitmq
2
-
3
- This plugin delivers mails to rabbitmq queue for further processing.
4
-
5
- ## Configuration
6
-
7
- - `config/rabbitmq.ini`
8
- This config file provides server address and port of rabbitmq server to deliver with other configs of queues and exchange.
9
-
10
- Example:
11
-
12
- [rabbitmq]
13
- ; This is name of exchange.
14
- exchangeName = emailMessages
15
- ; ip and port of the server.
16
- server_ip = localhost
17
- server_port = 5672
18
- ; user and password
19
- user = guest
20
- password = guest
21
- ; name of the queue which reader will read
22
- queueName = email
23
- ; This is for making it persistant while publishing message
24
- deliveryMode = 2
25
- ; If true it will require ack for marking it complete from worker
26
- confirm = true
27
- ; Again for persistance passed while creating queue
28
- durable = true
29
- ; if true will delete queue if publisher quits
30
- autoDelete = false
31
- ; type of the exchange
32
- exchangeType = direct
33
-
34
- More information about rabbitmq can be found at https://www.rabbitmq.com/
@@ -1,51 +0,0 @@
1
- # queue/rabbitmq_amqplib
2
-
3
- This plugin delivers emails to RabbitMQ queue for further processing. Based on `queue/rabbitmq` but using `amqplib`.
4
-
5
- ## Dependency
6
-
7
- - `amqplib` - https://github.com/squaremo/amqp.node
8
-
9
- ## Configuration
10
-
11
- - `config/rabbitmq.ini` - Connection, exchange and queue settings
12
-
13
- Example:
14
-
15
- [rabbitmq]
16
- ; Connection
17
- ; Protocol. Either "amqp" or "amqps"
18
- protocol = amqp
19
- host = localhost
20
- port = 5672
21
- ;Virtual Host. Start with "/". Leave blank or not use if you don't want to use virtual hosts.
22
- vhost = /haraka
23
- ;Credentials
24
- user = guest
25
- password = guest
26
- ; Exchange
27
- exchangeName = email_messages
28
- exchangeType = direct
29
- ; Queue
30
- queueName = emails
31
- confirm = true
32
- durable = true
33
- autoDelete = false
34
- ; Message
35
- deliveryMode = 2
36
- priority = 1
37
-
38
- ; Optional exchange arguments
39
- ; More information about exchange x-arguments can be found at https://www.rabbitmq.com/docs/exchanges#optional-arguments
40
- [exchange_args]
41
- alternate-exchange =
42
-
43
- ; Optional queue arguments
44
- ; More information about queue x-arguments can be found at https://www.rabbitmq.com/queues.html#optional-arguments
45
- [queue_args]
46
- x-dead-letter-exchange =
47
- x-dead-letter-routing-key = emails_dlq
48
- x-overflow = reject-publish
49
- x-queue-type = quorum
50
-
51
- More information about RabbitMQ can be found at https://www.rabbitmq.com/
@@ -1,141 +0,0 @@
1
- const amqp = require('amqp')
2
-
3
- let rabbitqueue
4
- let exchangeName
5
- let queueName
6
- let deliveryMode
7
- let connExchange_
8
- let connQueue_
9
- let routing_
10
- exports.exchangeMapping = {}
11
-
12
- //This method registers the hook and try to initialize the connection to rabbitmq server for later use.
13
- exports.register = function () {
14
- this.logdebug('About to connect and initialize queue object')
15
- this.init_rabbitmq_server()
16
- this.logdebug(`Finished initiating : ${exports.exchangeMapping[exchangeName + queueName]}`)
17
- }
18
-
19
- //Actual magic of publishing message to rabbit when email comes happen here.
20
- exports.hook_queue = function (next, connection) {
21
- if (!connection?.transaction) return next()
22
-
23
- //Calling the get_data method and when it gets the data on callback, publish the message to queue with routing key.
24
- connection.transaction.message_stream.get_data((buffere) => {
25
- const exchangeData = exports.exchangeMapping[exchangeName + queueName]
26
- this.logdebug(`Sending the data: ${queueName} Routing : ${exchangeData} exchange :${connExchange_}`)
27
- if (connExchange_ && routing_) {
28
- //This is publish function of rabbitmq amqp library, currently direct queue is configured and routing is fixed.
29
- //Needs to be changed.
30
- connExchange_.publish(routing_, buffere, { deliveryMode }, (error) => {
31
- if (error) {
32
- //There was some error while sending the email to queue.
33
- this.logdebug('queueFailure: #{JSON.stringify(error)}')
34
- exports.init_rabbitmq_server()
35
- next()
36
- } else {
37
- //Queueing was successful, send ok as reply
38
- this.logdebug('queueSuccess')
39
- next(OK, 'Successfully Queued! in rabbitmq')
40
- }
41
- })
42
- } else {
43
- //Seems like connExchange is not defined , lets create one for next call
44
- exports.init_rabbitmq_server()
45
- next()
46
- }
47
- })
48
- }
49
-
50
- //This initializes the connection to rabbitmq server, It reads values from rabbitmq.ini file in config directory.
51
- exports.init_rabbitmq_server = function () {
52
- // this is called during init of rabbitmq
53
-
54
- //Read the config file rabbitmq
55
- const config = this.config.get('rabbitmq.ini')
56
- //Just putting the defaults
57
- const options = {}
58
- let confirm = true
59
- let durable = true
60
- let autoDelete = false
61
- let exchangeType = 'direct'
62
-
63
- //Getting the values from config file rabbitmq.ini
64
- if (config.rabbitmq) {
65
- options.host = config.rabbitmq.server_ip || '127.0.0.1'
66
- options.port = config.rabbitmq.server_port || '5672'
67
- options.login = config.rabbitmq.user || 'guest'
68
- options.password = config.rabbitmq.password || 'guest'
69
- exchangeName = config.rabbitmq.exchangeName || 'emailMessages'
70
- exchangeType = config.rabbitmq.exchangeType || 'direct'
71
- confirm = config.rabbitmq.confirm === 'true' || true
72
- durable = config.rabbitmq.durable === 'true' || true
73
- autoDelete = config.rabbitmq.autoDelete === 'true' || false
74
- deliveryMode = config.rabbitmq.deliveryMode || 2
75
- queueName = config.rabbitmq.queueName || 'emails'
76
- } else {
77
- //If config file is not available , lets get the default values
78
- queueName = 'emails'
79
- exchangeName = 'emailMessages'
80
- deliveryMode = 2
81
- durable = true
82
- }
83
-
84
- //Create connection to the rabbitmq server
85
- this.logdebug('About to Create connection with server')
86
- rabbitqueue = amqp.createConnection(options)
87
-
88
- //Declaring listerner on error on connection.
89
- rabbitqueue.on('error', (error) => {
90
- this.logerror(`There was some error on the connection : ${error}`)
91
- })
92
-
93
- //Declaring listerner on close on connection.
94
- rabbitqueue.on('close', (close) => {
95
- this.logdebug(` Connection is being closed : ${close}`)
96
- })
97
-
98
- /* Declaring the function to perform when connection is established and ready, function involves like:
99
- * 1. Creating or connecting to Exchange.
100
- * 2. Creating or connecting to Queue.
101
- * 3. Binding the Exchange and Queue.
102
- * 4. Saving some variables in global to be used while publishing message.
103
- */
104
-
105
- rabbitqueue.on('ready', () => {
106
- this.logdebug('Connection is ready, will try making exchange')
107
- // Now connection is ready will try to open exchange with config data.
108
- rabbitqueue.exchange(exchangeName, { type: exchangeType, confirm, durable }, (connExchange) => {
109
- this.logdebug(`connExchange with server ${connExchange} autoDelete : ${autoDelete}`)
110
-
111
- //Exchange is now open, will try to open queue.
112
- return rabbitqueue.queue(queueName, { autoDelete, durable }, (connQueue) => {
113
- this.logdebug(`connQueue with server ${connQueue}`)
114
-
115
- //Creating the Routing key to bind the queue and exchange.
116
- const routing = `${queueName}Routing`
117
-
118
- // Will try to bing queue and exchange which was created above.
119
- connQueue.bind(connExchange, routing)
120
- const key = exchangeName + queueName
121
-
122
- //Save the variables for publising later.
123
- if (!exports.exchangeMapping[key]) {
124
- exports.exchangeMapping[key] = []
125
- }
126
- connExchange_ = connExchange
127
- connQueue_ = connQueue
128
- routing_ = routing
129
- exports.exchangeMapping[key].push({
130
- exchange: connExchange_,
131
- queue: connQueue_,
132
- routing: routing_,
133
- queueName,
134
- })
135
- this.logdebug(
136
- `exchange: ${exchangeName}, queue: ${queueName} exchange : ${connExchange_} queue : ${connQueue_}`,
137
- )
138
- })
139
- })
140
- })
141
- }
@@ -1,96 +0,0 @@
1
- // queue/rabbitmq_amqplib
2
-
3
- const amqp = require('amqplib/callback_api')
4
-
5
- let channel
6
- let queue
7
- let deliveryMode
8
- let priority
9
-
10
- exports.register = function () {
11
- this.init_amqp_connection()
12
- }
13
-
14
- exports.rabbitmq_queue = function (next, connection) {
15
- if (!connection?.transaction) return next()
16
-
17
- connection.transaction.message_stream.get_data((str) => {
18
- const sendOptions = { deliveryMode }
19
- if (priority != null) {
20
- sendOptions.priority = priority
21
- }
22
- if (channel?.sendToQueue(queue, str, sendOptions)) {
23
- return next(OK)
24
- } else {
25
- this.logerror('Failed to queue to rabbitmq')
26
- return next()
27
- }
28
- })
29
- }
30
-
31
- exports.init_amqp_connection = function () {
32
- const cfg = this.config.get('rabbitmq.ini').rabbitmq
33
-
34
- const protocol = cfg.protocol || 'amqp'
35
- const host = cfg.host || '127.0.0.1'
36
- const port = cfg.port || '5672'
37
- const vhost = cfg.vhost || ''
38
- const user = cfg.user || 'guest'
39
- const password = cfg.password || 'guest'
40
- const exchangeName = cfg.exchangeName || 'emailMessages'
41
- const exchangeType = cfg.exchangeType || 'direct'
42
- const queueName = cfg.queueName || 'emails'
43
- const durable = cfg.durable === 'true' || true
44
- // var confirm = cfg.confirm === "true" || true;
45
- const autoDelete = cfg.autoDelete === 'true' || false
46
- deliveryMode = cfg.deliveryMode || 2
47
- priority = cfg.priority
48
-
49
- amqp.connect(
50
- `${protocol}://${encodeURIComponent(user)}:${encodeURIComponent(password)}@${host}:${port}${vhost}`,
51
- (err, conn) => {
52
- if (err) {
53
- this.logerror(`Connection to rabbitmq failed: ${err}`)
54
- return
55
- }
56
- // TODO: if !confirm conn.createChannel...
57
- conn.createConfirmChannel((err2, ch) => {
58
- if (err2) {
59
- this.logerror(`Error creating rabbitmq channel: ${err2}`)
60
- return conn.close()
61
- }
62
- ch.assertExchange(
63
- exchangeName,
64
- exchangeType,
65
- {
66
- durable,
67
- arguments: this.config.get('rabbitmq.ini').exchange_args,
68
- },
69
- (err3, ok) => {
70
- if (err3) {
71
- this.logerror(`Error asserting rabbitmq exchange: ${err3}`)
72
- return conn.close()
73
- }
74
- ch.assertQueue(
75
- queueName,
76
- {
77
- durable,
78
- autoDelete,
79
- arguments: this.config.get('rabbitmq.ini').queue_args,
80
- },
81
- (err4, ok2) => {
82
- if (err4) {
83
- this.logerror(`Error asserting rabbitmq queue: ${err4}`)
84
- return conn.close()
85
- }
86
- queue = ok2.queue
87
- channel = ch
88
- this.register_hook('queue', 'rabbitmq_queue')
89
- },
90
- )
91
- },
92
- )
93
- })
94
- },
95
- )
96
- }
@@ -1,23 +0,0 @@
1
- -----BEGIN EC PARAMETERS-----
2
- BggqhkjOPQMBBw==
3
- -----END EC PARAMETERS-----
4
- -----BEGIN EC PRIVATE KEY-----
5
- MHcCAQEEIIDhiI5q6l7txfMJ6kIEYjK12EFcHLvDIkfWIwzdZBsloAoGCCqGSM49
6
- AwEHoUQDQgAEZg2nHEFy9nquFPF3DQyQE28e/ytjXeb4nD/8U+L4KHKFtglaX3R4
7
- uZ+5JcwfcDghpL4Z8h4ouUD/xqe957e2+g==
8
- -----END EC PRIVATE KEY-----
9
- -----BEGIN CERTIFICATE-----
10
- MIICaTCCAg+gAwIBAgIUEDa9VX16wCdo97WvIk7jyEBz1wQwCgYIKoZIzj0EAwIw
11
- gYkxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdT
12
- ZWF0dGxlMRQwEgYDVQQKDAtIYXJha2EgTWFpbDEXMBUGA1UEAwwObWFpbC5oYXJh
13
- a2EuaW8xJDAiBgkqhkiG9w0BCQEWFWhhcmFrYS5tYWlsQGdtYWlsLmNvbTAeFw0y
14
- MTEwMTQwNjQxMTlaFw0yMjEwMTQwNjQxMTlaMIGJMQswCQYDVQQGEwJVUzETMBEG
15
- A1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEUMBIGA1UECgwLSGFy
16
- YWthIE1haWwxFzAVBgNVBAMMDm1haWwuaGFyYWthLmlvMSQwIgYJKoZIhvcNAQkB
17
- FhVoYXJha2EubWFpbEBnbWFpbC5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC
18
- AARmDaccQXL2eq4U8XcNDJATbx7/K2Nd5vicP/xT4vgocoW2CVpfdHi5n7klzB9w
19
- OCGkvhnyHii5QP/Gp73nt7b6o1MwUTAdBgNVHQ4EFgQU094ROMLHmLEspT4ZoCfX
20
- Rz0mR/YwHwYDVR0jBBgwFoAU094ROMLHmLEspT4ZoCfXRz0mR/YwDwYDVR0TAQH/
21
- BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiEAsmshzvMDjmYDHyGRrKdMmsnnESFd
22
- GMtfRXYIv0AZe7ICIGD2Sta9LL0zZ44ARGXhh+sPjxd78I/+0FdIPsofr2I+
23
- -----END CERTIFICATE-----
@@ -1,49 +0,0 @@
1
- -----BEGIN PRIVATE KEY-----
2
- MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDcg5h5TVO1gECK
3
- yNCXbpJduNqJvhE6hyVb9q0WRR8zKHE7DnOog9JqOcrz4mv3TmszDZ2511mGxo/v
4
- j2dAYakU7HxEuSqKX1CsjbDP3xa7IvVCaKQbcMImq7dzmenXkCdPivuglZmooZen
5
- c18QZ6YkrunDeh/OcP8WAA+9yYXp82lmKPzKNkJETfGVXff0loXWR5SSjGXYvjqm
6
- XK6IXqPcuNriUTmylLx2149O6RWJPaZ2YYxTOHTeV5OMeEHjLpAOShCfZi4VYvAe
7
- GZSFq5UdMv5QD1k6BueS1Ruf6ChCLjfqkMcCAw8DOY8oxvzovgM/sgBcx3L00/pe
8
- QeSegG+3AgMBAAECggEAW9qJEcYvH0SMHgNmOB375ARTK9s7S/jti/Aly0gBpgqr
9
- l+D+NmyqokruikZ/mKVWrA546+eTSDu/yxcd+Eh16NxVKz9CRB9N+IKQ6xXPXyZB
10
- qWbzLOb8SKVwpjuvl3ZZmZ2YER0fw4mEJWE+cRPrtg4SG7XsN88DwoNGC1U9beSL
11
- vZ3lDuOMHNBNGx5k608i5HCV8Ty3Sz8ksvL9fPFwUpKAvRuG3lYgS+GxSrijH+KO
12
- vIwXAu3E+7MIPXdbsg14HBRRHEfyQlRGV8rj3e8neDLFarB8fXDVqIsko6/D5qZZ
13
- D/jXYW7pcafOGT0PTbHxUMrUxahhAjKKfPt3Y7JVcQKBgQDzIhmN7SbQvu2dl54X
14
- XezrgKteDVd4q7VYVpiAjNEZA+kNdBcXC6k2T5WMNPesNwyFIoDLDFWUg4FMG/Mc
15
- KA1eArBocGQ0gQvLlnlUxBy519e/AAj7jTspLi7gAwLqfTo0TGdTH/Hfq+1uCXys
16
- dd3BKYnDKc4aDPTQCEkRzfPHDwKBgQDoLw7MZecGnNNrqArqsOaOO1uUKFysW6pi
17
- 2ZU7KKj1x6vKGIW88YmzNBPCj4LU8XlXbR1isaSs5TaWgc6N0aAEXwA6TN/8PXhq
18
- 6IXarR1WJIq2DEDtdBrj2AiaPoF8Y6hsebsQs+EpyLx8MCGLaucYJvqyK87ep000
19
- mXQuyfgM2QKBgHCLy2qAaeRdTV8S7TKB3wcQ88LAyEnqqjJvO37eMHi076+zmnCn
20
- jDfA1UgmyLNmdBw44YeceQ0bZsHVek8BV1a6RfDCfhAz4ELor9eGRInemVcn7ACN
21
- 2uHwJ/C4VCQ5vbSx3W6ELhHM40Z5i8XFddZRpRy7gFVcxAJ8o15jiMIPAoGAHiq3
22
- DoGS8b4AjjVILdQMMKCvtmFEITTLv4orpIMU6NInlNt4zOLJFFqI0reYtRgmvuAz
23
- eDZCgiBJ5mY5Mx3wX4EEY47Hb1uBQMqzUYU6kY2v5BVVfkSelcnk3D2Qz1uXb3il
24
- gHcOo0IskyohwZ6DJhUyb2HXwAAWvOXPPaEKNIkCgYAqWhzYCAoxZ6f7i2I3J1JO
25
- 5OaMi4+9YR3ivTDcKVYp1ZOzANe0gsQlal/gf2fTjG35b9FyK3Lo5rp0QLKxv2vh
26
- 6dR+sk+58jJhk8H1kPNIVzvA4SAd51YoE0x7edi7+5vDMwlz57yz5rwMQvN1wUOO
27
- 5Ev9F9qrVJZFF4Ei+fRW9Q==
28
- -----END PRIVATE KEY-----
29
- -----BEGIN CERTIFICATE-----
30
- MIIDXTCCAkWgAwIBAgIJAIloeq99SSuwMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
31
- BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
32
- aWRnaXRzIFB0eSBMdGQwHhcNMTcwMTMxMDQyNTIwWhcNMjMwMTMwMDQyNTIwWjBF
33
- MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
34
- ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
35
- CgKCAQEAyMYkzD7HnZ29d83Hi2cTOVRsNJX/oTwwq7SiZwm8cwt/bMj4pK2XFxHK
36
- 0UDHSTgERKLSTCZJRvvGnWyBGRfTkdYui605gxlcmUkvHY5ZJ658iLnFCyrKkTj6
37
- hZOCtD2Y4P0WUItt4LsU+5smluZoJeeNfJG3os77LHb2G7j2U8UbKyH5uYRGecmt
38
- cuFfIPUxny2Mom+3BySb1QDOcMO1JtI2IzbuRKUlWicIjhqGyYTm5ceZoGt18hSC
39
- xilH2dT59rB2XKZ2gR1oA/Zj7EXCxzUvw48JuPZgbayuhRgDIPJVh26PDR5atYkq
40
- /RUtMaeurPTL++BUrGYTObLw86h1FwIDAQABo1AwTjAdBgNVHQ4EFgQUsW4yJbIS
41
- kLw2Q3V2a2vjWkzGo3owHwYDVR0jBBgwFoAUsW4yJbISkLw2Q3V2a2vjWkzGo3ow
42
- DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAjom2PQHtX0hCpMZovIoA
43
- JHeGMffuoP2N1445SMkxvxfcawK4LP/eeTvHGsBukBsVqa206orqooYVd3UWtcSQ
44
- rKfkwM0fQ1j7vCswJfCE3HIGtPyUTrtQHLAbu0vNeIlAH2v/wJZ+rhjIc3DrN8dt
45
- u2dnErb4V/KM5f3vlyZQgLvwJisx/vzvTYD0GC0XteHwxkJ6mpnH3ORDVyLaBZA3
46
- bFkuB7iwp4frwdvdcIDYVcuFBaLcu1zoJuSdEYNXo5d4Ji6hnSTyZsXz4jkGoH7n
47
- 5OLoHzF0lY9EpyLMdINWOyodxTEXjKUWggSUKsFRWkb8cTUjp+0lfvFiJ6gs3H+a
48
- sQ==
49
- -----END CERTIFICATE-----