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.22 to 1.0.23

3

lib/arc/index.js

@@ -489,5 +489,6 @@ 'use strict';

let hashKey = `${bodyCanon}:${hashAlgo}`;
let hashKey = `${bodyCanon}:${hashAlgo}:`;
bodyHash = dkimSigner.bodyHashes.get(hashKey)?.hash;
arc = arc || dkimSigner.arc;

@@ -494,0 +495,0 @@ seal.i = arc.instance;

@@ -50,2 +50,4 @@ 'use strict';

update(chunk) {
this.byteLength += chunk.length;
let bodyStr;

@@ -52,0 +54,0 @@

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

}
return this.bodyHash.digest(encoding);

@@ -93,0 +94,0 @@ }

@@ -73,6 +73,9 @@ 'use strict';

signatureData.maxBodyLength =
typeof signatureData.maxBodyLength === 'number' && signatureData.maxBodyLength >= 0 ? signatureData.maxBodyLength : '';
let { hashAlgo } = this.getAlgorithm(signatureData);
let { bodyCanon } = this.getCanonicalization(signatureData);
let hashKey = `${bodyCanon}:${hashAlgo}`;
let hashKey = `${bodyCanon}:${hashAlgo}:${signatureData.maxBodyLength}`;

@@ -121,4 +124,4 @@ if (!this.bodyHashes.has(hashKey)) {

for (let hashKey of this.bodyHashes.keys()) {
let [bodyCanon, hashAlgo] = hashKey.split(':');
this.bodyHashes.get(hashKey).hasher = dkimBody(bodyCanon, hashAlgo);
let [bodyCanon, hashAlgo, maxBodyLength] = hashKey.split(':');
this.bodyHashes.get(hashKey).hasher = dkimBody(bodyCanon, hashAlgo, maxBodyLength ? Number(maxBodyLength) : false);
}

@@ -188,3 +191,3 @@ }

let hashKey = `${bodyCanon}:${hashAlgo}`;
let hashKey = `${bodyCanon}:${hashAlgo}:${signatureData.maxBodyLength}`;

@@ -237,9 +240,20 @@ try {

signingHeaderLines,
Object.assign({}, signatureData, {
instance: this.arc?.instance, // ARC only
algorithm,
canonicalization: this.getCanonicalization(signatureData).canonicalization,
signTime: this.signTime,
bodyHash: this.bodyHashes.has(hashKey) ? this.bodyHashes.get(hashKey).hash : null
})
Object.assign(
{},
signatureData,
{
instance: this.arc?.instance, // ARC only
algorithm,
canonicalization: this.getCanonicalization(signatureData).canonicalization,
signTime: this.signTime,
bodyHash: this.bodyHashes.has(hashKey) ? this.bodyHashes.get(hashKey).hash : null
},
// value for the l= tag (if needed)
typeof signatureData.maxBodyLength === 'number'
? {
bodyHashedBytes: this.bodyHashes.get(hashKey).hasher.bodyHashedBytes
}
: {}
)
);

@@ -246,0 +260,0 @@

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

let hashAlgo = 'sha256';
this.sealBodyHashKey = [bodyCanon, hashAlgo].join(':');
this.sealBodyHashKey = `${bodyCanon}:${hashAlgo}:`;
this.bodyHashes.set(this.sealBodyHashKey, dkimBody(bodyCanon, hashAlgo, false));

@@ -118,2 +118,5 @@ }

signatureHeader.maxBodyLength =
signatureHeader.parsed?.l?.value && !isNaN(signatureHeader.parsed?.l?.value) ? signatureHeader.parsed?.l?.value : '';
const validSignAlgo = ['rsa', 'ed25519'];

@@ -136,11 +139,5 @@ const validHeaderAlgo = signatureHeader.type === 'DKIM' ? ['sha256', 'sha1'] : ['sha256'];

signatureHeader.bodyHashKey = [signatureHeader.bodyCanon, signatureHeader.hashAlgo].join(':');
signatureHeader.bodyHashKey = [signatureHeader.bodyCanon, signatureHeader.hashAlgo, signatureHeader.maxBodyLength].join(':');
if (!this.bodyHashes.has(signatureHeader.bodyHashKey)) {
let maxLength = false;
if (signatureHeader.parsed?.l?.value) {
maxLength = signatureHeader.parsed?.l?.value;
}
this.bodyHashes.set(signatureHeader.bodyHashKey, dkimBody(signatureHeader.bodyCanon, signatureHeader.hashAlgo, maxLength));
this.bodyHashes.set(signatureHeader.bodyHashKey, dkimBody(signatureHeader.bodyCanon, signatureHeader.hashAlgo, signatureHeader.maxBodyLength));
}

@@ -164,3 +161,3 @@ }

for (let [key, bodyHash] of this.bodyHashes.entries()) {
this.bodyHashes.set(key, bodyHash.digest('base64'));
this.bodyHashes.get(key).hash = bodyHash.digest('base64');
}

@@ -203,3 +200,3 @@

let bodyHash = this.bodyHashes.get(signatureHeader.bodyHashKey);
let bodyHash = this.bodyHashes.get(signatureHeader.bodyHashKey)?.hash;
if (signatureHeader.parsed?.bh?.value !== bodyHash) {

@@ -278,2 +275,9 @@ status.result = 'neutral';

signatureHeader.bodyHashedBytes = this.bodyHashes.get(signatureHeader.bodyHashKey)?.bodyHashedBytes;
if (typeof signatureHeader.maxBodyLength === 'number' && signatureHeader.maxBodyLength !== signatureHeader.bodyHashedBytes) {
status.result = 'fail';
status.comment = `invalid body length ${signatureHeader.bodyHashedBytes}`;
}
let result = {

@@ -290,2 +294,10 @@ signingDomain: signatureHeader.signingDomain,

if (typeof signatureHeader.bodyHashedBytes === 'number') {
result.canonBodyLength = signatureHeader.bodyHashedBytes;
}
if (typeof signatureHeader.maxBodyLength === 'number') {
result.bodyLengthCount = signatureHeader.maxBodyLength;
}
if (publicKey) {

@@ -330,4 +342,4 @@ result.publicKey = publicKey.toString();

if (this.seal && this.bodyHashes.has(this.sealBodyHashKey) && typeof this.bodyHashes.get(this.sealBodyHashKey) === 'string') {
this.seal.bodyHash = this.bodyHashes.get(this.sealBodyHashKey);
if (this.seal && this.bodyHashes.has(this.sealBodyHashKey) && typeof this.bodyHashes.get(this.sealBodyHashKey)?.hash === 'string') {
this.seal.bodyHash = this.bodyHashes.get(this.sealBodyHashKey).hash;
}

@@ -334,0 +346,0 @@ }

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

const relaxedHeaders = (type, signingHeaderLines, options) => {
let { signatureHeaderLine, signingDomain, selector, algorithm, canonicalization, bodyHash, signTime, signature, instance } = options || {};
let { signatureHeaderLine, signingDomain, selector, algorithm, canonicalization, bodyHash, signTime, signature, instance, bodyHashedBytes } = options || {};
let chunks = [];

@@ -27,2 +27,6 @@

if (typeof bodyHashedBytes === 'number') {
opts.l = bodyHashedBytes;
}
if (instance) {

@@ -29,0 +33,0 @@ // ARC only

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

const simpleHeaders = (type, signingHeaderLines, options) => {
let { signatureHeaderLine, signingDomain, selector, algorithm, canonicalization, bodyHash, signTime, signature, instance } = options || {};
let { signatureHeaderLine, signingDomain, selector, algorithm, canonicalization, bodyHash, signTime, signature, instance, bodyHashedBytes } = options || {};
let chunks = [];

@@ -31,2 +31,6 @@

if (typeof bodyHashedBytes === 'number') {
opts.l = bodyHashedBytes;
}
if (instance) {

@@ -33,0 +37,0 @@ // ARC only (should never happen thoug as simple algo is not allowed)

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

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

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

- [x] SPF verification
- [x] DKIM signing
- [x] DKIM verification
- [x] DMARC verification
- [x] ARC verification
- [x] ARC sealing
- [x] Sealing on authentication
- [x] Sealing after modifications
- [x] BIMI resolving
- [x] MTA-STS helpers
- **SPF** verification
- **DKIM** signing
- DKIM verification
- **DMARC** verification
- **ARC** verification
- ARC sealing
- Sealing on authentication
- Sealing after modifications
- **BIMI** resolving
- **MTA-STS** helpers

@@ -25,3 +25,3 @@ Pure JavaScript implementation, no external applications or compilation needed. Runs on any server/device that has Node 14+ installed.

```
```js
await authenticate(message [,options]) ->

@@ -35,8 +35,8 @@ { dkim, spf, arc, dmarc, bimi, receivedChain, headers }

- **options** (_object_) is an optional options object
- **sender** (_string_) is the email address from MAIL FROM command (aka Return-Path address)
- **sender** (_string_) is the email address from MAIL FROM command. If not set then it is parsed from the `Return-Path` header
- **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
- **trustReceived** (_boolean_) if true then parses values for `ip` and `helo` from latest `Received` header if you have not set these values yourself. Defaults to `false`
- **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
- **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 considered as failed
- **disableArc** (_boolean_) if true then skip ARC checks

@@ -49,3 +49,3 @@ - **disableDmarc** (_boolean_) if true then skip DMARC checks. This also disables checks that are dependent on DMARC (eg. BIMI)

- **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)
- **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)

@@ -64,3 +64,3 @@ **Example**

// If you do not want to provide ip/helo/sender manually but parse from the message
// Uncomment if you do not want to provide ip/helo/sender manually but parse from the message
//trustReceived: true,

@@ -134,2 +134,6 @@

canonicalization: 'relaxed/relaxed' // c=
// Maximum number of canonicalizated body bytes to sign (eg. the "l=" tag).
// Do not use though. This is available only for compatibility testing.
// maxBodyLength: 12345
}

@@ -210,8 +214,3 @@ ]

{
// SMTP transmission options must be provided as
// these are not parsed from the message
ip: '217.146.67.33', // SMTP client IP
helo: 'uvn-67-33.tll01.zonevs.eu', // EHLO/HELO hostname
mta: 'mx.ethereal.email', // server processing this message, defaults to os.hostname()
sender: 'andris@ekiri.ee' // MAIL FROM address
trustReceived: true
}

@@ -246,10 +245,5 @@ );

{
// SMTP transmission options must be provided as
// these are not parsed from the message
ip: '217.146.67.33', // SMTP client IP
helo: 'uvn-67-33.tll01.zonevs.eu', // EHLO/HELO hostname
mta: 'mx.ethereal.email', // server processing this message, defaults to os.hostname()
sender: 'andris@ekiri.ee', // MAIL FROM address
trustReceived: true,
// Optional ARC seal settings. If this is set then resulting headers include
// ARC seal settings. If this is set then resulting headers include
// a complete ARC header set (unless the message has a failing ARC chain)

@@ -256,0 +250,0 @@ seal: {

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