npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@bernierllc/smtp-analyzer

v0.1.4

Published

Pure atomic SMTP header analysis and email authentication parsing utilities

Readme

@bernierllc/smtp-analyzer

Pure atomic SMTP header analysis and email authentication parsing utilities. Analyze SMTP delivery paths, authentication results (SPF, DKIM, DMARC, ARC), bounce messages, and routing information without any external dependencies.

Installation

npm install @bernierllc/smtp-analyzer

Features

  • SMTP Header Parsing - Parse and validate SMTP headers with support for multi-line (folded) headers
  • Delivery Path Analysis - Extract complete delivery path with hop-by-hop analysis
  • Authentication Analysis - Parse SPF, DKIM, DMARC, and ARC authentication results
  • Bounce Message Detection - Detect and parse bounce messages with DSN (Delivery Status Notification) support
  • Routing Information - Analyze mail server routing, relays, and transport security (TLS)
  • Security Analysis - Extract and analyze security-related headers
  • Evidence-Rich Output - All analysis includes original header data for verification
  • Zero Dependencies - Completely self-contained with no external dependencies
  • TypeScript First - Full type safety with comprehensive type definitions

Usage

Quick Start

import { analyzeSMTPHeadersFromRaw } from '@bernierllc/smtp-analyzer';

// Analyze complete email headers
const rawHeaders = `
Received: from mail.sender.com by mx.google.com with ESMTPS;
  Tue, 8 Oct 2024 10:30:45 -0700
Authentication-Results: mx.google.com;
  spf=pass [email protected];
  dkim=pass header.d=example.com;
  dmarc=pass
From: [email protected]
To: [email protected]
Subject: Important Message
`;

const result = analyzeSMTPHeadersFromRaw(rawHeaders);

if (result.success) {
  const analysis = result.data;

  console.log('Authentication:', analysis.authentication.spf.result); // 'pass'
  console.log('Delivery Hops:', analysis.routing.hopCount);
  console.log('Secure Transport:', analysis.routing.hasSecureTransport);
}

Analyzing Delivery Path

import { parseHeaders, parseDeliveryPath, extractRoutingInfo } from '@bernierllc/smtp-analyzer';

const headers = parseHeaders(rawHeaders);
const receivedHeaders = headers['received'];

// Parse delivery path (chronologically ordered)
const hops = parseDeliveryPath(Array.isArray(receivedHeaders) ? receivedHeaders : [receivedHeaders]);

hops.forEach((hop, index) => {
  console.log(`Hop ${index + 1}:`);
  console.log(`  Server: ${hop.server}`);
  console.log(`  From: ${hop.from}`);
  console.log(`  Protocol: ${hop.protocol}`);
  console.log(`  TLS: ${hop.tls ? 'Yes' : 'No'}`);
  console.log(`  Timestamp: ${hop.timestamp}`);
});

// Extract routing information
const routing = extractRoutingInfo(hops);
console.log('Originating IP:', routing.originatingIp);
console.log('Final Destination:', routing.finalDestination);
console.log('Total Hops:', routing.hopCount);
console.log('Has Secure Transport:', routing.hasSecureTransport);

Authentication Analysis

import { parseAuthenticationResults, isAuthenticationPassed } from '@bernierllc/smtp-analyzer';

const authHeader = 'mx.google.com; spf=pass [email protected]; dkim=pass header.d=example.com; dmarc=pass';

const auth = parseAuthenticationResults(authHeader);

console.log('SPF Result:', auth.spf.result);
console.log('SPF Mechanism:', auth.spf.mechanism);
console.log('DKIM Result:', auth.dkim.result);
console.log('DKIM Domain:', auth.dkim.domain);
console.log('DMARC Result:', auth.dmarc.result);

// Check if all authentication passed
if (isAuthenticationPassed(auth)) {
  console.log('Email is fully authenticated');
}

Bounce Message Analysis

import { parseBounceMessage, isPermanentBounce } from '@bernierllc/smtp-analyzer';

const bounceContent = `
Delivery to the following recipient failed permanently:
     [email protected]

Technical details:
550-5.1.1 The email account that you tried to reach does not exist.

Final-Recipient: rfc822; [email protected]
Action: failed
Status: 5.1.1
`;

const bounce = parseBounceMessage(
  bounceContent,
  'Delivery Status Notification (Failure)',
  '[email protected]'
);

if (bounce.isBounce) {
  console.log('Bounce Type:', bounce.bounceType); // 'hard'
  console.log('Original Recipient:', bounce.originalRecipient);
  console.log('Reason:', bounce.reason);

  if (bounce.dsn) {
    console.log('DSN Action:', bounce.dsn.action);
    console.log('DSN Status Code:', bounce.dsn.statusCode);
    console.log('Diagnostic Code:', bounce.dsn.diagnosticCode);
  }

  // Check if permanent bounce
  if (isPermanentBounce(bounce)) {
    console.log('This is a permanent bounce - remove recipient');
  }
}

Complete Analysis

import { analyzeSMTPHeaders, getSummary, isEmailAuthenticated } from '@bernierllc/smtp-analyzer';

const analysis = analyzeSMTPHeaders({
  'received': [
    'from mail.sender.com by mx.google.com with ESMTPS; Tue, 8 Oct 2024 10:30:45 -0700',
    'from localhost by mail.sender.com with SMTP; Tue, 8 Oct 2024 13:30:40 -0400',
  ],
  'authentication-results': 'mx.google.com; spf=pass; dkim=pass; dmarc=pass',
  'from': '[email protected]',
  'to': '[email protected]',
  'message-id': '<[email protected]>',
  'date': 'Tue, 8 Oct 2024 13:30:40 -0400',
});

// Get human-readable summary
console.log(getSummary(analysis));
// Output:
// Delivery Path: 2 hops
// SPF: pass
// DKIM: pass
// DMARC: pass
// Secure Transport: Yes
// Delivery Time: 5s

// Check authentication
if (isEmailAuthenticated(analysis)) {
  console.log('Email is authenticated');
}

// Check for bounce
if (analysis.bounce?.isBounce) {
  console.log('This is a bounce message');
}

Security Analysis

import { detectSuspiciousPatterns, identifyRelays } from '@bernierllc/smtp-analyzer';

const hops = parseDeliveryPath(receivedHeaders);

// Detect suspicious patterns
const issues = detectSuspiciousPatterns(hops);
if (issues.length > 0) {
  console.log('Security concerns detected:');
  issues.forEach(issue => console.log(`  - ${issue}`));
}

// Identify relay servers
const relays = identifyRelays(hops);
console.log('Relay servers:', relays);

API Reference

Main Analyzer

analyzeSMTPHeaders(headers: ParsedHeaders): SMTPAnalysis

Analyze SMTP headers and extract all relevant information.

Parameters:

  • headers - Parsed headers object (use parseHeaders() to convert raw headers)

Returns: Complete SMTP analysis including:

  • deliveryPath - Array of SMTP hops
  • authentication - SPF, DKIM, DMARC, ARC results
  • routing - Routing and relay information
  • deliveryStatus - Delivery status and timing
  • securityHeaders - Security-related headers
  • bounce - Bounce information (if applicable)

analyzeSMTPHeadersFromRaw(rawHeaders: string): AnalysisResult<SMTPAnalysis>

Convenience wrapper that parses headers and performs analysis.

Parameters:

  • rawHeaders - Raw email headers as string

Returns: Result wrapper with success flag and data or error

Header Parsing

parseHeaders(rawHeaders: string): ParsedHeaders

Parse email headers from raw header string. Handles multi-line (folded) headers per RFC 5322.

getHeader(headers: ParsedHeaders, name: string): string | string[] | undefined

Get header value(s). Returns array if multiple values exist.

getHeaderArray(headers: ParsedHeaders, name: string): string[]

Get all values for a header as array (even if single value).

getHeaderFirst(headers: ParsedHeaders, name: string): string | undefined

Get first value for a header (useful for headers that should be unique).

extractEmailAddress(headerValue: string): string | null

Extract email address from header value (handles various formats).

parseHeaderDate(dateString: string): Date | null

Parse date from header value (RFC 5322 format).

Delivery Path Analysis

parseDeliveryPath(receivedHeaders: string[]): SMTPHop[]

Parse delivery path from Received headers. Returns hops in chronological order (oldest first).

extractRoutingInfo(hops: SMTPHop[]): RoutingInfo

Extract routing information from delivery path.

calculateDeliveryTime(hops: SMTPHop[]): number | null

Calculate delivery time from first to last hop. Returns time in milliseconds.

identifyRelays(hops: SMTPHop[]): string[]

Identify relay servers in the delivery path.

detectSuspiciousPatterns(hops: SMTPHop[]): string[]

Detect suspicious patterns in delivery path. Returns array of detected issues.

Authentication Parsing

parseAuthenticationResults(authHeader: string): AuthenticationResults

Parse Authentication-Results header.

parseReceivedSPF(receivedSpfHeader: string): SPFDetails

Parse Received-SPF header.

parseDKIMSignature(dkimSignature: string): DKIMDetails

Parse DKIM-Signature header.

isAuthenticationPassed(results: AuthenticationResults): boolean

Check if authentication passed all checks.

getAuthenticationSummary(results: AuthenticationResults): string

Get authentication status summary.

Bounce Message Parsing

detectBounce(subject: string, from: string, contentType?: string): boolean

Detect if email is a bounce message.

parseBounceMessage(emailContent: string, subject?: string, from?: string): BounceInfo

Parse bounce message to extract details.

parseDSN(content: string): DSNDetails | null

Parse DSN (Delivery Status Notification) from email content.

isPermanentBounce(bounceInfo: BounceInfo): boolean

Check if bounce is permanent (hard bounce).

isTemporaryBounce(bounceInfo: BounceInfo): boolean

Check if bounce is temporary (soft bounce).

Types

Core Types

interface SMTPAnalysis {
  deliveryPath: SMTPHop[];
  authentication: AuthenticationResults;
  routing: RoutingInfo;
  deliveryStatus: DeliveryInfo;
  securityHeaders: SecurityHeaders;
  bounce?: BounceInfo;
}

interface SMTPHop {
  server: string;
  timestamp: Date | null;
  protocol: string;
  from: string;
  for: string;
  id?: string;
  with?: string;
  tls?: boolean;
  raw: string;
}

interface AuthenticationResults {
  spf: SPFDetails;
  dkim: DKIMDetails;
  dmarc: DMARCDetails;
  arc: ARCDetails;
  rawHeader?: string;
}

interface RoutingInfo {
  originatingIp?: string;
  originatingServer?: string;
  finalDestination?: string;
  hopCount: number;
  totalHops: SMTPHop[];
  hasSecureTransport: boolean;
}

interface BounceInfo {
  isBounce: boolean;
  bounceType?: 'hard' | 'soft' | 'general' | 'unknown';
  dsn?: DSNDetails;
  originalRecipient?: string;
  reason?: string;
  diagnosticCode?: string;
}

Production Use Cases

  • Email Security Monitoring - Analyze authentication failures and detect spoofing
  • Deliverability Analytics - Track delivery path performance and identify issues
  • Compliance Auditing - Verify authentication compliance (SPF, DKIM, DMARC)
  • Spam Detection - Analyze sender reputation signals and delivery patterns
  • Email Forensics - Investigate email origin and routing for security analysis
  • Bounce Management - Parse and categorize bounce messages for list hygiene
  • Transport Security - Monitor TLS usage across delivery paths

Integration Status

  • Logger Integration: Not applicable - This is a pure utility package with no internal logging needs. Applications using this package can optionally integrate @bernierllc/logger for logging analysis results or errors at the application level.
  • Docs-Suite: Ready - Complete TypeDoc documentation with examples
  • NeverHub Integration: Not applicable - This is a core utility package with no orchestration needs. The package works independently and does not require @bernierllc/neverhub-adapter for service discovery or event communication.

License

Copyright (c) 2025 Bernier LLC. All rights reserved.

This package is licensed to the client under a limited-use license. The client may use and modify this code only within the scope of the project it was delivered for. Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.