@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>;| Option | Type | Default | Description |
|---|---|---|---|
resolver | Resolver | Looks up DNS records. Pass Dns.create() or node:dns/promises. | |
receiver | string | 'unknown' | The checking host's name, for %{r} in explanations. |
now | any | new Date() | The time for %{t} in explanations, as a Date or a Temporal.Instant. |
signal | AbortSignal | Rejects 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;
};