Skip to content
LogoLogo

@portable/mail-auth

Functions

MailAuth.authenticate

Checks a received message's SPF (RFC 7208), DKIM signatures (RFC 6376), ARC chain (RFC 8617) and DMARC policy (RFC 9989) and writes the results as an Authentication-Results field (RFC 8601). With seal, it also adds an ARC set that records them, with the chain's result as cv=.

The promise rejects only for invalid options, a failing message stream or an aborted signal. DNS failures are reported as results, such as temperror.

async function authenticate(
  message: Dkim.Message,
  options: authenticate.Options,
): Promise<Result>;
OptionTypeDefaultDescription
resolveranyLooks up DNS records. Pass Dns.create() or node:dns/promises.
authservIdstringThe authserv-id of Authentication-Results (RFC 8601 section 2.5), usually this server's host name in A-label form. It must be a token, so a value such as mx; dkim=pass is rejected.
ipstringThe SMTP client's IP address.
helostringThe HELO or EHLO name.
senderstringThe MAIL FROM address. Empty or missing for a bounce, for which SPF checks the HELO name instead.
sealSealSeals the message with an ARC set that records these results.
nowanynew Date()The time to check DKIM and ARC signature expiry against and to use for %{t} in SPF explanations, as a Date or a Temporal.Instant.
minKeyBitsnumber1024RSA keys shorter than this give DKIM policy and fail the ARC chain.
hasher((hash: Dkim.Hash) => Dkim.Hasher)buffers the body for crypto.subtle.digestCreates the body hashes, as in Dkim.verify.
organizationalDomainanythe DNS tree walkFinds organizational domains from a public suffix list, as in Dmarc.check.
signalAbortSignalStops reading the message and every lookup, and rejects with signal.reason.
import * as Dns from '@portable/dns';
import * as MailAuth from '@portable/mail-auth';
 
const result = await MailAuth.authenticate(message, {
  resolver: Dns.create(),
  authservId: 'mx.example.net',
  ip: '192.0.2.1',
  helo: 'mail.example.com',
  sender: 'alice@example.com',
  signal: AbortSignal.timeout(10_000),
});
result.dmarc?.result; // 'pass'
const delivered = result.headers + message;

Types

MailAuth.Resolver

The DNS lookups SPF, DKIM, DMARC and ARC need: a Dns.Resolver from @portable/dns, node:dns/promises, or a plain object with these methods.

type Resolver = Spf.Resolver & Dmarc.Resolver & Dkim.Resolver;

MailAuth.Result

What authenticate found, and the header fields to add to the message.

type Result = {
  spf: Spf.Result;
  dkim: readonly Dkim.Result[];
  arc: Arc.Result;
  dmarc?: Dmarc.Result | undefined;
  dmarcSkipReason?: Result.DmarcSkipReason | undefined;
  authResults: string;
  headers: string;
  sealSkipReason?: string | undefined;
};