Skip to content
LogoLogo

@portable/spf

Functions

Spf.check

Checks whether an SMTP client may send mail for a domain, as RFC 7208's check_host() does. It reads the SPF record of the MAIL FROM domain, or of the HELO name when the sender is empty, and evaluates it against the client's IP address, with the RFC's limits of 10 DNS-querying terms and 2 void lookups. DNS failures give temperror, and broken records give permerror. The promise rejects only for an ip that isn't an IP address or a resolver without the Resolver methods, or with signal.reason when signal aborts.

async function check(
  input: check.Input,
  options: check.Options,
): Promise<Result>;
OptionTypeDefaultDescription
resolverResolverLooks up DNS records. Pass Dns.create() or node:dns/promises.
receiverstring'unknown'The checking host's name, for %{r} in explanations.
nowanynew Date()The time for %{t} in explanations, as a Date or a Temporal.Instant.
signalAbortSignalRejects with signal.reason and cancels the pending lookups when aborted.
import * as Dns from '@portable/dns';
import * as Spf from '@portable/spf';
 
const spf = await Spf.check(
  {
    ip: '192.0.2.10',
    sender: 'alice@example.com',
    helo: 'mail.example.com',
  },
  { resolver: Dns.create(), signal: AbortSignal.timeout(20_000) },
);
spf.result; // 'pass', 'fail', 'softfail', 'neutral', 'none', 'temperror' or 'permerror'

Types

Spf.Resolver

The DNS lookups SPF needs: a Dns.Resolver from @portable/dns, node:dns/promises, or a plain object with these methods. check treats a rejection with code ENOTFOUND, ENODATA or EBADNAME (an invalid name) as an empty answer, and any other rejection as a temporary DNS error.

type Resolver = Pick<Dns.Resolver,  |  |  |  | >;

Spf.Result

The outcome of an SPF check.

type Result = {
    result: Result.Code;
    domain: string;
    identity:  | ;
    mechanism?: string | undefined;
    record?: string | undefined;
    explanation?: string | undefined;
    reason?: string | undefined;
    cause?: unknown;
    lookups: number;
    voidLookups: number;
};