haraka-plugin-spamassassin 1.0.3 → 1.1.0

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 (3) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/index.js +23 -11
  3. package/package.json +9 -7
package/CHANGELOG.md CHANGED
@@ -4,6 +4,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/).
4
4
 
5
5
  ### Unreleased
6
6
 
7
+ ### [1.1.0] - 2026-05-17
8
+
9
+ - changed: dep address-rfc2821 -> @haraka/email-address
10
+ - changed: bumped all dep versions to latest
11
+
12
+ ### [1.0.4] - 2026-05-10
13
+
14
+ - fix: cleanup message pipe if spamd errors
15
+ - ci: updated configs
16
+ - deps: bumped all versions to latest
17
+
7
18
  ### [1.0.3] - 2025-02-06
8
19
 
9
20
  - results: tidying up duplicate data
@@ -27,3 +38,5 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/).
27
38
  [1.0.2]: https://github.com/haraka/haraka-plugin-spamassassin/releases/tag/v1.0.2
28
39
  [1.0.0]: https://github.com/haraka/haraka-plugin-spamassassin/releases/tag/1.0.0
29
40
  [1.0.3]: https://github.com/haraka/haraka-plugin-spamassassin/releases/tag/v1.0.3
41
+ [1.0.4]: https://github.com/haraka/haraka-plugin-spamassassin/releases/tag/v1.0.4
42
+ [1.1.0]: https://github.com/haraka/haraka-plugin-spamassassin/releases/tag/v1.1.0
package/index.js CHANGED
@@ -137,11 +137,11 @@ exports.hook_data_post = function (next, connection) {
137
137
  this.log_results(connection, spamd_response)
138
138
 
139
139
  const exceeds_err = this.score_too_high(connection, spamd_response)
140
- if (exceeds_err) return next(DENY, exceeds_err)
140
+ if (exceeds_err) return socket.nextOnce(DENY, exceeds_err)
141
141
 
142
142
  this.munge_subject(connection, spamd_response.score)
143
143
 
144
- next()
144
+ socket.nextOnce()
145
145
  })
146
146
  }
147
147
 
@@ -245,7 +245,7 @@ exports.get_spamd_username = function (conn) {
245
245
  // Enable per-user SA prefs
246
246
  if (user === 'first-recipient') {
247
247
  // special cases
248
- return conn.transaction.rcpt_to[0].address()
248
+ return conn.transaction.rcpt_to[0].address
249
249
  }
250
250
  if (user === 'all-recipients') {
251
251
  throw 'Unimplemented'
@@ -263,7 +263,7 @@ exports.get_spamd_headers = function (conn, username) {
263
263
  'HEADERS SPAMC/1.4',
264
264
  `User: ${username}`,
265
265
  '',
266
- `X-Envelope-From: ${conn.transaction.mail_from.address()}`,
266
+ `X-Envelope-From: ${conn.transaction.mail_from.address}`,
267
267
  `X-Haraka-UUID: ${conn.transaction.uuid}`,
268
268
  ]
269
269
  if (conn.relaying) {
@@ -282,6 +282,19 @@ exports.get_spamd_socket = function (next, conn, headers) {
282
282
  net_utils.add_line_processor(socket)
283
283
  const results_timeout = parseInt(plugin.cfg.main.results_timeout) || 300
284
284
 
285
+ // Idempotent terminal handler; exposed on the socket so hook_data_post's
286
+ // 'end' handler shares the guard. unpipe() before destroy() — see
287
+ // haraka/message-stream#22.
288
+ let calledNext = false
289
+ socket.nextOnce = function (code, msg) {
290
+ if (txn?.message_stream) txn.message_stream.unpipe()
291
+ if (!socket.destroyed) socket.destroy()
292
+ if (calledNext) return
293
+ calledNext = true
294
+ if (code) return next(code, msg)
295
+ return next()
296
+ }
297
+
285
298
  socket.on('connect', function () {
286
299
  // Abort if the transaction is gone
287
300
  if (!txn) {
@@ -298,24 +311,23 @@ exports.get_spamd_socket = function (next, conn, headers) {
298
311
  })
299
312
 
300
313
  socket.on('error', (err) => {
301
- socket.destroy()
302
314
  if (txn) txn.results.add(plugin, { err: `socket error: ${err.message}` })
303
- if (plugin.cfg.defer.error) return next(DENYSOFT, 'spamd scan error')
304
- return next()
315
+ if (plugin.cfg.defer.error)
316
+ return socket.nextOnce(DENYSOFT, 'spamd scan error')
317
+ return socket.nextOnce()
305
318
  })
306
319
 
307
320
  socket.on('timeout', function () {
308
- socket.destroy()
309
321
  if (!this.is_connected) {
310
322
  if (txn) txn.results.add(plugin, { err: `socket connect timeout` })
311
323
  if (plugin.cfg.defer.connect_timeout)
312
- return next(DENYSOFT, 'spamd connect timeout')
324
+ return socket.nextOnce(DENYSOFT, 'spamd connect timeout')
313
325
  } else {
314
326
  if (txn) txn.results.add(plugin, { err: `timeout waiting for results` })
315
327
  if (plugin.cfg.defer.scan_timeout)
316
- return next(DENYSOFT, 'spamd scan timeout')
328
+ return socket.nextOnce(DENYSOFT, 'spamd scan timeout')
317
329
  }
318
- return next()
330
+ return socket.nextOnce()
319
331
  })
320
332
 
321
333
  const connect_timeout = parseInt(plugin.cfg.main.connect_timeout) || 30
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "haraka-plugin-spamassassin",
3
- "version": "1.0.3",
3
+ "version": "1.1.0",
4
4
  "description": "Haraka plugin that scans messages with SpamAssassin",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -14,8 +14,10 @@
14
14
  "prettier": "npx prettier . --check",
15
15
  "prettier:fix": "npx prettier . --write --log-level=warn",
16
16
  "test": "node --test",
17
- "versions": "npx dependency-version-checker check",
18
- "versions:fix": "npx dependency-version-checker update"
17
+ "versions": "npx npm-dep-mgr check",
18
+ "versions:fix": "npx npm-dep-mgr update",
19
+ "test:coverage": "node --test --experimental-test-coverage --test-coverage-exclude=package.json --test-coverage-exclude=test/*.js",
20
+ "test:coverage:lcov": "mkdir -p coverage && node --test --experimental-test-coverage --test-reporter=lcov --test-reporter-destination=coverage/lcov.info test/*.js"
19
21
  },
20
22
  "repository": {
21
23
  "type": "git",
@@ -33,13 +35,13 @@
33
35
  },
34
36
  "homepage": "https://github.com/haraka/haraka-plugin-spamassassin#readme",
35
37
  "dependencies": {
36
- "haraka-net-utils": "^1.7.2",
38
+ "haraka-net-utils": "^1.8.2",
37
39
  "haraka-utils": "^1.1.4"
38
40
  },
39
41
  "devDependencies": {
40
- "@haraka/eslint-config": "^2.0.2",
41
- "address-rfc2821": "^2.1.3",
42
- "haraka-test-fixtures": "1.3.9"
42
+ "@haraka/eslint-config": "^2.0.4",
43
+ "@haraka/email-address": "^3.1.4",
44
+ "haraka-test-fixtures": "^1.6.0"
43
45
  },
44
46
  "prettier": {
45
47
  "singleQuote": true,