New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

mailauth

Package Overview
Dependencies
Maintainers
1
Versions
80
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mailauth - npm Package Compare versions

Comparing version 1.0.21 to 1.0.22

27

lib/arc/index.js

@@ -55,3 +55,3 @@ 'use strict';

try {
let res = await getPublicKey('AS', queryDomain, resolver);
let res = await getPublicKey('AS', queryDomain, opts.minBitLength, resolver);
publicKey = res?.publicKey;

@@ -307,2 +307,9 @@ } catch (err) {

Object.defineProperty(result, 'chain', {
enumerable: false,
configurable: false,
writable: false,
value: data.chain
});
try {

@@ -327,2 +334,3 @@ if (data.error) {

result.authenticationResults = data?.lastEntry?.['arc-authentication-results']?.parsed;
if (result.authenticationResults) {

@@ -332,9 +340,13 @@ delete result.authenticationResults.i;

result.authenticationResults.mta = result.authenticationResults.value;
delete result.authenticationResults.value;
if (result.authenticationResults.value) {
let mta = result.authenticationResults.value;
delete result.authenticationResults.value;
result.authenticationResults = Object.assign({ mta }, result.authenticationResults);
}
['arc', 'spf', 'dmarc'].forEach(key => {
if (result.authenticationResults[key]) {
result.authenticationResults[key].result = result.authenticationResults[key].value;
let res = result.authenticationResults[key].value;
delete result.authenticationResults[key].value;
result.authenticationResults[key] = Object.assign({ result: res }, result.authenticationResults[key]);
}

@@ -344,8 +356,11 @@ });

if (result.authenticationResults.dkim && result.authenticationResults.dkim.length) {
result.authenticationResults.dkim.forEach(entry => {
entry.result = entry.value;
result.authenticationResults.dkim = result.authenticationResults.dkim.map(entry => {
let result = entry.value;
delete entry.value;
return Object.assign({ result }, entry);
});
}
}
status.result = 'pass';

@@ -352,0 +367,0 @@ } else {

@@ -17,2 +17,3 @@ 'use strict';

this.resolver = this.options.resolver;
this.minBitLength = this.options.minBitLength;

@@ -192,4 +193,3 @@ this.results = [];

b: signatureHeader.parsed?.b?.value ? `${signatureHeader.parsed?.b?.value.substr(0, 8)}` : false
},
policy: {}
}
};

@@ -210,2 +210,3 @@

`${signatureHeader.selector}._domainkey.${signatureHeader.signingDomain}`,
this.minBitLength,
this.resolver

@@ -262,2 +263,5 @@ );

status.result = 'policy';
if (!status.policy) {
status.policy = {};
}
status.policy['dkim-rules'] = `weak-key`;

@@ -292,2 +296,6 @@ break;

if (typeof result.status.comment === 'boolean') {
delete result.status.comment;
}
switch (signatureHeader.type) {

@@ -294,0 +302,0 @@ case 'ARC':

@@ -102,2 +102,7 @@ 'use strict';

response.info = formatAuthHeaderRow('dmarc', response.status);
if (typeof response.status.comment === 'boolean') {
delete response.status.comment;
}
return response;

@@ -104,0 +109,0 @@ };

@@ -11,2 +11,3 @@ 'use strict';

const os = require('os');
const { isIP } = require('net');

@@ -23,2 +24,3 @@ /**

* @param {String} [opts.mta] MTA/MX hostname (defaults to os.hostname)
* @param {Number} [opts.minBitLength=1024] Minimal allowed length of public keys. If DKIM/ARC key is smaller, then verification fails
* @param {Object} [opts.seal] ARC sealing options

@@ -41,3 +43,4 @@ * @param {String} [opts.seal.signingDomain] ARC key domain name

sender: opts.sender, // defaults to Return-Path header
seal: opts.seal
seal: opts.seal,
minBitLength: opts.minBitLength
});

@@ -64,3 +67,4 @@

if (helo && !opts.helo) {
if (helo && !opts.helo && !opts.ip) {
// if IP was provided then do not use helo even if it is missing
opts.helo = helo;

@@ -80,2 +84,11 @@ }

if (!opts.helo && opts.ip) {
opts.helo = opts.ip;
}
if (opts.helo && isIP(opts.helo)) {
// use the bracket syntax
opts.helo = `[${opts.helo}]`;
}
const spfResult = await spf(opts);

@@ -86,3 +99,4 @@

arcResult = await arc(dkimResult.arc, {
resolver: opts.resolver
resolver: opts.resolver,
minBitLength: opts.minBitLength
});

@@ -164,3 +178,2 @@ }

return {
receivedChain,
dkim: dkimResult,

@@ -171,2 +184,3 @@ spf: spfResult,

bimi: bimiResult || false,
receivedChain,
headers: headers.join('\r\n') + '\r\n'

@@ -173,0 +187,0 @@ };

@@ -134,3 +134,4 @@ 'use strict';

value: '',
comment: ''
comment: '',
hasValue: false
};

@@ -155,2 +156,3 @@ parts.push(part);

state = 'value';
curPart.hasValue = true;
break;

@@ -235,3 +237,5 @@ }

for (let key of Object.keys(parts[i])) {
parts[i][key] = parts[i][key].replace(/\s+/g, ' ').trim();
if (typeof parts[i][key] === 'string') {
parts[i][key] = parts[i][key].replace(/\s+/g, ' ').trim();
}
}

@@ -258,7 +262,9 @@

let defaultPos = headerKey === 'arc-authentication-results' ? 1 : 0;
if (parts[defaultPos].key && !parts[defaultPos].value && !/^arc-/i.test(headerKey)) {
result.value = parts[defaultPos].key;
parts.splice(defaultPos, 1);
for (let i = 0; i < parts.length; i++) {
// find the first entry with key only and use it as the default value
if (parts[i].key && !parts[i].hasValue) {
result.value = parts[i].key;
parts.splice(i, 1);
break;
}
}

@@ -265,0 +271,0 @@

@@ -150,14 +150,21 @@ 'use strict';

for (let val of values) {
if (val.comment) {
val.comment = val.comment.replace(/\s+/g, ' ').trim();
}
if (val.key) {
let key = val.key.toLowerCase();
if (key !== 'from' && !result.tls && /tls|cipher=/i.test(val.comment)) {
result.tls = { value: '', comment: val.comment };
if (key !== 'from' && !result.tls && /tls|cipher=|Google Transport Security/i.test(val.comment)) {
result.tls = { value: '', ...(val.comment && { comment: val.comment }) };
val.comment = '';
}
result[key] = { value: val.value, comment: val.comment };
} else if (!result.tls && /tls|cipher=/i.test(val.comment)) {
result.tls = { value: val.value, comment: val.comment };
result[key] = { value: val.value, ...(val.comment && { comment: val.comment }) };
} else if (!result.tls && /tls|cipher=|Google Transport Security/i.test(val.comment)) {
result.tls = { value: val.value, ...(val.comment && { comment: val.comment }) };
}
}
if (!result.tls && /SMTPS/.test(result?.with?.value)) {
result.tls = { value: '', comment: result?.with?.value };
}
if (timestamp) {

@@ -164,0 +171,0 @@ result.timestamp = timestamp;

@@ -225,2 +225,6 @@ 'use strict';

if (typeof response.status.comment === 'boolean') {
delete response.status.comment;
}
return response;

@@ -227,0 +231,0 @@ };

@@ -234,3 +234,4 @@ /* eslint no-control-regex: 0 */

const getPublicKey = async (type, name, resolver) => {
const getPublicKey = async (type, name, minBitLength, resolver) => {
minBitLength = minBitLength || 1024;
resolver = resolver || dns.resolve;

@@ -237,0 +238,0 @@

{
"name": "mailauth",
"version": "1.0.21",
"version": "1.0.22",
"description": "Email authentication library for Node.js",

@@ -5,0 +5,0 @@ "main": "lib/mailauth.js",

@@ -24,2 +24,28 @@ ![](https://github.com/andris9/mailauth/raw/master/assets/mailauth.png)

```
await authenticate(message [,options]) ->
{ dkim, spf, arc, dmarc, bimi, receivedChain, headers }
```
Where
- **message** is either a String, a Buffer or a Readable stream that represents an email message
- **options** (_object_) is an optional options object
- **sender** (_string_) is the email address from MAIL FROM command (aka Return-Path address)
- **ip** (_string_) is the IP of remote client that sent this message
- **helo** (_string_) is the hostname value from HELO/EHLO command
- **trustReceived** (_boolean_) if true then parses values for `ip` and `helo` from latest `Received` header if you have not set these values yourself
- **mta** (_string_) is the hostname of the server performing the authentication (defaults to `os.hostname()`)
- **minBitLength** (_number_) is the minimum allowed bits of RSA public keys (defaults to 1024). If a DKIM or ARC key has less bits, then validation is conisdered as failed
- **disableArc** (_boolean_) if true then skip ARC checks
- **disableDmarc** (_boolean_) if true then skip DMARC checks. This also disables checks that are dependent on DMARC (eg. BIMI)
- **disableBimi** (_boolean_) if true then skip BIMI checks
- **seal** (_object_) if set and message does not have a broken ARC chain, then seals the message using these values
- **signingDomain** (_string_) ARC key domain name
- **selector** (_string_) ARC key selector
- **privateKey** (_string_ or _buffer_) Private key for signing. Can be a RSA or an Ed25519 key
- **resolver** (_async function_) is an optional async function for DNS requests. Defaults to dns.promises.resolve](https://nodejs.org/api/dns.html#dns_dnspromises_resolve_hostname_rrtype)
**Example**
```js

@@ -26,0 +52,0 @@ const { authenticate } = require('mailauth');

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc