haraka-plugin-karma 1.0.13 → 1.0.14
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/.github/ISSUE_TEMPLATE/bug_report.md +29 -0
- package/.github/ISSUE_TEMPLATE/custom.md +10 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- package/.github/workflows/ci-test-win.yml +38 -0
- package/.github/workflows/ci-test.yml +41 -0
- package/.github/workflows/lint.yml +33 -0
- package/.travis.yml +1 -2
- package/Changes.md +3 -0
- package/index.js +37 -45
- package/package.json +3 -3
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Create a report to help us improve
|
|
4
|
+
title: ''
|
|
5
|
+
labels: ''
|
|
6
|
+
assignees: ''
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
**System Info:**
|
|
11
|
+
|
|
12
|
+
Please report your OS, Node version, and Haraka version by running this shell script on your Haraka server and replacing this section with the output.
|
|
13
|
+
|
|
14
|
+
echo "Haraka | $(haraka -v)"; echo " --- | :--- "; echo "Node | $(node -v)"; echo "OS | $(uname -a)"; echo "openssl | $(openssl version)"
|
|
15
|
+
|
|
16
|
+
**Describe the bug**
|
|
17
|
+
A clear and concise description of what the bug is.
|
|
18
|
+
|
|
19
|
+
**Expected behavior**
|
|
20
|
+
A clear and concise description of what you expected to happen.
|
|
21
|
+
|
|
22
|
+
**Observed behavior**
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
**Steps To Reproduce**
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
**Additional context**
|
|
29
|
+
Add any other context about the problem here.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature request
|
|
3
|
+
about: Suggest an idea for this project
|
|
4
|
+
title: ''
|
|
5
|
+
labels: ''
|
|
6
|
+
assignees: ''
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
**Is your feature request related to a problem? Please describe.**
|
|
11
|
+
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
|
12
|
+
|
|
13
|
+
**Describe the solution you'd like**
|
|
14
|
+
A clear and concise description of what you want to happen.
|
|
15
|
+
|
|
16
|
+
**Describe alternatives you've considered**
|
|
17
|
+
A clear and concise description of any alternative solutions or features you've considered.
|
|
18
|
+
|
|
19
|
+
**Additional context**
|
|
20
|
+
Add any other context or screenshots about the feature request here.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: Tests - Windows
|
|
2
|
+
|
|
3
|
+
on: [ push, pull_request ]
|
|
4
|
+
|
|
5
|
+
# no docker/images support on Windows (currently), so run w/o Redis
|
|
6
|
+
# also, stack run commands so test doesn't begin before install completes
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
|
|
10
|
+
ci-test-win:
|
|
11
|
+
|
|
12
|
+
runs-on: ${{ matrix.os }}
|
|
13
|
+
|
|
14
|
+
strategy:
|
|
15
|
+
matrix:
|
|
16
|
+
os: [ windows-latest ]
|
|
17
|
+
node-version: [ 14.x, 16.x ]
|
|
18
|
+
fail-fast: false
|
|
19
|
+
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v2
|
|
22
|
+
name: Checkout
|
|
23
|
+
with:
|
|
24
|
+
fetch-depth: 1
|
|
25
|
+
|
|
26
|
+
- uses: actions/setup-node@v2
|
|
27
|
+
name: Use Node.js ${{ matrix.node-version }}
|
|
28
|
+
with:
|
|
29
|
+
node-version: ${{ matrix.node-version }}
|
|
30
|
+
|
|
31
|
+
- name: Install
|
|
32
|
+
run: npm install
|
|
33
|
+
|
|
34
|
+
- name: Test
|
|
35
|
+
run: npm run test
|
|
36
|
+
|
|
37
|
+
env:
|
|
38
|
+
CI: true
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on: [ push, pull_request ]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
|
|
7
|
+
ci-test:
|
|
8
|
+
|
|
9
|
+
runs-on: ${{ matrix.os }}
|
|
10
|
+
|
|
11
|
+
strategy:
|
|
12
|
+
matrix:
|
|
13
|
+
os: [ ubuntu-latest ]
|
|
14
|
+
node-version: [ 14.x, 16.x ]
|
|
15
|
+
fail-fast: false
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v2
|
|
19
|
+
name: Checkout
|
|
20
|
+
with:
|
|
21
|
+
fetch-depth: 1
|
|
22
|
+
|
|
23
|
+
- uses: actions/setup-node@v2
|
|
24
|
+
name: Use Node.js ${{ matrix.node-version }}
|
|
25
|
+
with:
|
|
26
|
+
node-version: ${{ matrix.node-version }}
|
|
27
|
+
|
|
28
|
+
- name: Install
|
|
29
|
+
run: npm install
|
|
30
|
+
|
|
31
|
+
- name: Test
|
|
32
|
+
run: npm run test
|
|
33
|
+
|
|
34
|
+
env:
|
|
35
|
+
CI: true
|
|
36
|
+
|
|
37
|
+
services:
|
|
38
|
+
redis:
|
|
39
|
+
image: redis
|
|
40
|
+
ports:
|
|
41
|
+
- 6379/tcp
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: Haraka Lint
|
|
2
|
+
|
|
3
|
+
on: [ push, pull_request ]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
|
|
7
|
+
lint:
|
|
8
|
+
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
|
|
11
|
+
strategy:
|
|
12
|
+
matrix:
|
|
13
|
+
node-version: [ 14.x ]
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v2
|
|
17
|
+
name: Checkout
|
|
18
|
+
with:
|
|
19
|
+
fetch-depth: 1
|
|
20
|
+
|
|
21
|
+
- uses: actions/setup-node@v2
|
|
22
|
+
name: Use Node.js ${{ matrix.node-version }}
|
|
23
|
+
with:
|
|
24
|
+
node-version: ${{ matrix.node-version }}
|
|
25
|
+
|
|
26
|
+
- name: Install
|
|
27
|
+
run: npm install
|
|
28
|
+
|
|
29
|
+
- name: Lint
|
|
30
|
+
run: npm run lint
|
|
31
|
+
|
|
32
|
+
env:
|
|
33
|
+
CI: true
|
package/.travis.yml
CHANGED
package/Changes.md
CHANGED
package/index.js
CHANGED
|
@@ -15,9 +15,9 @@ exports.register = function () {
|
|
|
15
15
|
|
|
16
16
|
// set up defaults
|
|
17
17
|
plugin.deny_hooks = utils.to_object(
|
|
18
|
-
['unrecognized_command','helo','data','data_post','queue']
|
|
18
|
+
['unrecognized_command','helo','data','data_post','queue','queue_outbound']
|
|
19
19
|
);
|
|
20
|
-
plugin.deny_exclude_hooks = utils.to_object('rcpt_to
|
|
20
|
+
plugin.deny_exclude_hooks = utils.to_object('rcpt_to queue queue_outbound');
|
|
21
21
|
plugin.deny_exclude_plugins = utils.to_object([
|
|
22
22
|
'access', 'helo.checks', 'data.headers', 'spamassassin',
|
|
23
23
|
'mail_from.is_resolvable', 'clamd', 'tls'
|
|
@@ -210,7 +210,7 @@ exports.result_as_array = function (result) {
|
|
|
210
210
|
});
|
|
211
211
|
return array;
|
|
212
212
|
}
|
|
213
|
-
this.loginfo(
|
|
213
|
+
this.loginfo(`what format is result: ${result}`);
|
|
214
214
|
return result;
|
|
215
215
|
}
|
|
216
216
|
|
|
@@ -286,10 +286,7 @@ exports.check_result_length = function (thisResult, thisAward, conn) {
|
|
|
286
286
|
const plugin = this;
|
|
287
287
|
|
|
288
288
|
for (let j=0; j < thisResult.length; j++) {
|
|
289
|
-
|
|
290
|
-
const matches = thisAward.value.split(/\s+/);
|
|
291
|
-
const operator = matches[0];
|
|
292
|
-
const qty = matches[1];
|
|
289
|
+
const [operator, qty] = thisAward.value.split(/\s+/); // requires node 6+
|
|
293
290
|
|
|
294
291
|
switch (operator) {
|
|
295
292
|
case 'eq':
|
|
@@ -304,12 +301,12 @@ exports.check_result_length = function (thisResult, thisAward, conn) {
|
|
|
304
301
|
if (parseInt(thisResult[j], 10) >= parseInt(qty, 10)) continue;
|
|
305
302
|
break;
|
|
306
303
|
default:
|
|
307
|
-
conn.results.add(plugin, { err:
|
|
304
|
+
conn.results.add(plugin, { err: `invalid operator: ${operator}` });
|
|
308
305
|
continue;
|
|
309
306
|
}
|
|
310
307
|
|
|
311
|
-
conn.results.incr(plugin, {score:
|
|
312
|
-
conn.results.push(plugin, {awards: thisAward.id});
|
|
308
|
+
conn.results.incr(plugin, {score: thisAward.award});
|
|
309
|
+
conn.results.push(plugin, {awards: thisAward.id });
|
|
313
310
|
}
|
|
314
311
|
}
|
|
315
312
|
|
|
@@ -351,9 +348,9 @@ exports.apply_tarpit = function (connection, hook, score, next) {
|
|
|
351
348
|
const delay = plugin.tarpit_delay(score, connection, hook, k);
|
|
352
349
|
if (!delay) return next();
|
|
353
350
|
|
|
354
|
-
connection.logdebug(plugin,
|
|
351
|
+
connection.logdebug(plugin, `tarpitting ${hook} for ${delay}s`);
|
|
355
352
|
setTimeout(() => {
|
|
356
|
-
connection.logdebug(plugin,
|
|
353
|
+
connection.logdebug(plugin, `tarpit ${hook} end`);
|
|
357
354
|
next();
|
|
358
355
|
}, delay * 1000);
|
|
359
356
|
}
|
|
@@ -376,7 +373,7 @@ exports.tarpit_delay = function (score, connection, hook, k) {
|
|
|
376
373
|
|
|
377
374
|
const max = plugin.cfg.tarpit.max || 5;
|
|
378
375
|
if (delay > max) {
|
|
379
|
-
connection.logdebug(plugin,
|
|
376
|
+
connection.logdebug(plugin, `tarpit capped to: ${max}`);
|
|
380
377
|
return max;
|
|
381
378
|
}
|
|
382
379
|
|
|
@@ -393,20 +390,20 @@ exports.tarpit_delay_msa = function (connection, delay, k) {
|
|
|
393
390
|
const history = ((k.good || 0) - (k.bad || 0));
|
|
394
391
|
if (history > 0) {
|
|
395
392
|
delay = delay - 2;
|
|
396
|
-
connection.logdebug(plugin, trg
|
|
393
|
+
connection.logdebug(plugin, `${trg} history: ${delay}`);
|
|
397
394
|
}
|
|
398
395
|
|
|
399
396
|
// Reduce delay for good ASN history
|
|
400
397
|
let asn = connection.results.get('asn');
|
|
401
398
|
if (!asn) { asn = connection.results.get('geoip'); }
|
|
402
399
|
if (asn && asn.asn && k.neighbors > 0) {
|
|
403
|
-
connection.logdebug(plugin, trg
|
|
400
|
+
connection.logdebug(plugin, `${trg} neighbors: ${delay}`);
|
|
404
401
|
delay = delay - 2;
|
|
405
402
|
}
|
|
406
403
|
|
|
407
404
|
const max = plugin.cfg.tarpit.max_msa || 2;
|
|
408
405
|
if (delay > max) {
|
|
409
|
-
connection.logdebug(plugin,
|
|
406
|
+
connection.logdebug(plugin, `tarpit capped at: ${delay}`);
|
|
410
407
|
delay = max;
|
|
411
408
|
}
|
|
412
409
|
|
|
@@ -423,7 +420,7 @@ exports.should_we_deny = function (next, connection, hook) {
|
|
|
423
420
|
const plugin = this;
|
|
424
421
|
|
|
425
422
|
const r = connection.results.get('karma');
|
|
426
|
-
if (!r)
|
|
423
|
+
if (!r) return next();
|
|
427
424
|
|
|
428
425
|
plugin.check_awards(connection); // update awards first
|
|
429
426
|
|
|
@@ -487,7 +484,7 @@ exports.hook_deny = function (next, connection, params) {
|
|
|
487
484
|
}
|
|
488
485
|
|
|
489
486
|
// intercept any other denials
|
|
490
|
-
connection.results.add(plugin, { msg:
|
|
487
|
+
connection.results.add(plugin, { msg: `deny: ${pi_name}` });
|
|
491
488
|
connection.results.incr(plugin, { score: -2 });
|
|
492
489
|
|
|
493
490
|
next(constants.OK); // resume the connection
|
|
@@ -585,7 +582,7 @@ exports.ip_history_from_redis = function (next, connection) {
|
|
|
585
582
|
if (plugin.should_we_skip(connection)) return next();
|
|
586
583
|
|
|
587
584
|
const expire = (plugin.cfg.redis.expire_days || 60) * 86400; // to days
|
|
588
|
-
const dbkey =
|
|
585
|
+
const dbkey = `karma|${connection.remote.ip}`;
|
|
589
586
|
|
|
590
587
|
// redis plugin is emitting errors, no need to here
|
|
591
588
|
if (!plugin.db) return next();
|
|
@@ -641,7 +638,7 @@ exports.hook_mail = function (next, connection, params) {
|
|
|
641
638
|
// look for invalid (RFC 5321,(2)821) space in envelope from
|
|
642
639
|
const full_from = connection.current_line;
|
|
643
640
|
if (full_from.toUpperCase().substring(0,11) !== 'MAIL FROM:<') {
|
|
644
|
-
connection.loginfo(plugin,
|
|
641
|
+
connection.loginfo(plugin, `RFC ignorant env addr format: ${full_from}`);
|
|
645
642
|
connection.results.add(plugin, {fail: 'rfc5321.MailFrom'});
|
|
646
643
|
}
|
|
647
644
|
|
|
@@ -706,7 +703,7 @@ exports.hook_data_post = function (next, connection) {
|
|
|
706
703
|
plugin.check_awards(connection); // update awards
|
|
707
704
|
|
|
708
705
|
const results = connection.results.collate(plugin);
|
|
709
|
-
connection.logdebug(plugin,
|
|
706
|
+
connection.logdebug(plugin, `adding header: ${results}`);
|
|
710
707
|
connection.transaction.remove_header('X-Haraka-Karma');
|
|
711
708
|
connection.transaction.add_header('X-Haraka-Karma', results);
|
|
712
709
|
|
|
@@ -717,7 +714,7 @@ exports.increment = function (connection, key, val) {
|
|
|
717
714
|
const plugin = this;
|
|
718
715
|
if (!plugin.db) return;
|
|
719
716
|
|
|
720
|
-
plugin.db.hincrby(
|
|
717
|
+
plugin.db.hincrby(`karma|${connection.remote.ip}`, key, 1);
|
|
721
718
|
|
|
722
719
|
const asnkey = plugin.get_asn_key(connection);
|
|
723
720
|
if (asnkey) plugin.db.hincrby(asnkey, key, 1);
|
|
@@ -726,10 +723,10 @@ exports.increment = function (connection, key, val) {
|
|
|
726
723
|
exports.hook_disconnect = function (next, connection) {
|
|
727
724
|
const plugin = this;
|
|
728
725
|
|
|
729
|
-
if (plugin.should_we_skip(connection)) return next();
|
|
730
|
-
|
|
731
726
|
plugin.redis_unsubscribe(connection);
|
|
732
727
|
|
|
728
|
+
if (plugin.should_we_skip(connection)) return next();
|
|
729
|
+
|
|
733
730
|
const k = connection.results.get('karma');
|
|
734
731
|
if (!k || k.score === undefined) {
|
|
735
732
|
connection.results.add(plugin, {err: 'karma results missing'});
|
|
@@ -761,11 +758,11 @@ exports.get_award_loc_from_note = function (connection, award) {
|
|
|
761
758
|
if (obj) { return obj; }
|
|
762
759
|
}
|
|
763
760
|
|
|
764
|
-
// connection.logdebug(plugin,
|
|
761
|
+
// connection.logdebug(plugin, `no txn note: ${award}`);
|
|
765
762
|
const obj = plugin.assemble_note_obj(connection, award);
|
|
766
763
|
if (obj) return obj;
|
|
767
764
|
|
|
768
|
-
// connection.logdebug(plugin,
|
|
765
|
+
// connection.logdebug(plugin, `no conn note: ${award}`);
|
|
769
766
|
return;
|
|
770
767
|
}
|
|
771
768
|
|
|
@@ -775,7 +772,7 @@ exports.get_award_loc_from_results = function (connection, loc_bits) {
|
|
|
775
772
|
let notekey = loc_bits[2];
|
|
776
773
|
|
|
777
774
|
if (phase_prefixes[pi_name]) {
|
|
778
|
-
pi_name = loc_bits[1]
|
|
775
|
+
pi_name = `${loc_bits[1]}.${loc_bits[2]}`;
|
|
779
776
|
notekey = loc_bits[3];
|
|
780
777
|
}
|
|
781
778
|
|
|
@@ -784,17 +781,16 @@ exports.get_award_loc_from_results = function (connection, loc_bits) {
|
|
|
784
781
|
obj = connection.transaction.results.get(pi_name);
|
|
785
782
|
}
|
|
786
783
|
if (!obj) {
|
|
787
|
-
// connection.logdebug(plugin,
|
|
784
|
+
// connection.logdebug(plugin, `no txn results: ${pi_name}`);
|
|
788
785
|
obj = connection.results.get(pi_name);
|
|
789
786
|
}
|
|
790
787
|
if (!obj) {
|
|
791
|
-
// connection.logdebug(plugin,
|
|
788
|
+
// connection.logdebug(plugin, `no conn results: ${pi_name}`);
|
|
792
789
|
return;
|
|
793
790
|
}
|
|
794
791
|
|
|
795
|
-
// connection.logdebug(plugin,
|
|
796
|
-
|
|
797
|
-
if (notekey) { return obj[notekey]; }
|
|
792
|
+
// connection.logdebug(plugin, `found results for ${pi_name}, ${notekey}`);
|
|
793
|
+
if (notekey) return obj[notekey];
|
|
798
794
|
return obj;
|
|
799
795
|
}
|
|
800
796
|
|
|
@@ -823,7 +819,7 @@ exports.get_award_location = function (connection, award_key) {
|
|
|
823
819
|
return plugin.get_award_loc_from_results(connection.transaction, loc_bits);
|
|
824
820
|
}
|
|
825
821
|
|
|
826
|
-
connection.logdebug(plugin,
|
|
822
|
+
connection.logdebug(plugin, `unknown location for ${award_key}`);
|
|
827
823
|
}
|
|
828
824
|
|
|
829
825
|
exports.get_award_condition = function (note_key, note_val) {
|
|
@@ -871,8 +867,7 @@ exports.check_awards = function (connection) {
|
|
|
871
867
|
if (note !== wants) { continue; } // didn't match
|
|
872
868
|
}
|
|
873
869
|
|
|
874
|
-
// connection.loginfo(plugin,
|
|
875
|
-
// wants);
|
|
870
|
+
// connection.loginfo(plugin, `check_awards, case matching for: ${wants}`
|
|
876
871
|
|
|
877
872
|
// the matching logic here is inverted, weeding out misses (continue)
|
|
878
873
|
// Matches fall through (break) to the apply_award below.
|
|
@@ -908,8 +903,7 @@ exports.check_awards = function (connection) {
|
|
|
908
903
|
if (note.length !== parseFloat(wants)) { continue; }
|
|
909
904
|
break;
|
|
910
905
|
default:
|
|
911
|
-
connection.logerror(plugin,
|
|
912
|
-
operator + '" not supported.');
|
|
906
|
+
connection.logerror(plugin, `length operator "${operator}" not supported.`);
|
|
913
907
|
continue;
|
|
914
908
|
}
|
|
915
909
|
break;
|
|
@@ -933,15 +927,14 @@ exports.apply_award = function (connection, nl, award) {
|
|
|
933
927
|
const plugin = this;
|
|
934
928
|
if (!award) { return; }
|
|
935
929
|
if (isNaN(award)) { // garbage in config
|
|
936
|
-
connection.logerror(plugin,
|
|
937
|
-
award);
|
|
930
|
+
connection.logerror(plugin, `non-numeric award from: ${nl}:${award}`);
|
|
938
931
|
return;
|
|
939
932
|
}
|
|
940
933
|
|
|
941
934
|
const bits = nl.split('@'); nl = bits[0]; // strip off @... if present
|
|
942
935
|
|
|
943
936
|
connection.results.incr(plugin, {score: award});
|
|
944
|
-
connection.logdebug(plugin,
|
|
937
|
+
connection.logdebug(plugin, `applied ${nl}:${award}`);
|
|
945
938
|
|
|
946
939
|
let trimmed = nl.substring(0, 5) === 'notes' ? nl.substring(6) :
|
|
947
940
|
nl.substring(0, 7) === 'results' ? nl.substring(8) :
|
|
@@ -963,7 +956,7 @@ exports.check_spammy_tld = function (mail_from, connection) {
|
|
|
963
956
|
if (mail_from.isNull()) return; // null sender (bounce)
|
|
964
957
|
|
|
965
958
|
const from_tld = mail_from.host.split('.').pop();
|
|
966
|
-
// connection.logdebug(plugin,
|
|
959
|
+
// connection.logdebug(plugin, `from_tld: ${from_tld}`);
|
|
967
960
|
|
|
968
961
|
const tld_penalty = parseFloat(plugin.cfg.spammy_tlds[from_tld] || 0);
|
|
969
962
|
if (tld_penalty === 0) return;
|
|
@@ -979,8 +972,7 @@ exports.check_syntax_RcptTo = function (connection) {
|
|
|
979
972
|
const full_rcpt = connection.current_line;
|
|
980
973
|
if (full_rcpt.toUpperCase().substring(0,9) === 'RCPT TO:<') { return; }
|
|
981
974
|
|
|
982
|
-
connection.loginfo(plugin,
|
|
983
|
-
full_rcpt );
|
|
975
|
+
connection.loginfo(plugin, `illegal envelope address format: ${full_rcpt}`);
|
|
984
976
|
connection.results.add(plugin, {fail: 'rfc5321.RcptTo'});
|
|
985
977
|
}
|
|
986
978
|
|
|
@@ -990,7 +982,7 @@ exports.assemble_note_obj = function (prefix, key) {
|
|
|
990
982
|
while (parts.length > 0) {
|
|
991
983
|
let next = parts.shift();
|
|
992
984
|
if (phase_prefixes[next]) {
|
|
993
|
-
next = next
|
|
985
|
+
next = `${next}.${parts.shift()}`;
|
|
994
986
|
}
|
|
995
987
|
note = note[next];
|
|
996
988
|
if (note === null || note === undefined) { break; }
|
|
@@ -1067,7 +1059,7 @@ exports.get_asn_key = function (connection) {
|
|
|
1067
1059
|
asn = connection.results.get('geoip');
|
|
1068
1060
|
}
|
|
1069
1061
|
if (!asn || !asn.asn || isNaN(asn.asn)) { return; }
|
|
1070
|
-
return
|
|
1062
|
+
return `as${asn.asn}`;
|
|
1071
1063
|
}
|
|
1072
1064
|
|
|
1073
1065
|
exports.init_asn = function (asnkey, expire) {
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "haraka-plugin-karma",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.14",
|
|
4
4
|
"description": "A heuristics scoring and reputation engine for SMTP connections",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "npx mocha",
|
|
8
|
-
"lint": "npx eslint
|
|
9
|
-
"lintfix": "npx eslint --fix
|
|
8
|
+
"lint": "npx eslint index.js test/*.js",
|
|
9
|
+
"lintfix": "npx eslint --fix index.js test/*.js",
|
|
10
10
|
"cover": "npx istanbul cover npx mocha"
|
|
11
11
|
},
|
|
12
12
|
"repository": {
|