Package Exports
- @bernierllc/smtp-analyzer
- @bernierllc/smtp-analyzer/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@bernierllc/smtp-analyzer) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
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-analyzerFeatures
- 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 smtp.mailfrom=sender@example.com;
dkim=pass header.d=example.com;
dmarc=pass
From: sender@example.com
To: recipient@example.com
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 smtp.mailfrom=sender@example.com; 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:
invalid@nonexistent.com
Technical details:
550-5.1.1 The email account that you tried to reach does not exist.
Final-Recipient: rfc822; invalid@nonexistent.com
Action: failed
Status: 5.1.1
`;
const bounce = parseBounceMessage(
bounceContent,
'Delivery Status Notification (Failure)',
'mailer-daemon@googlemail.com'
);
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': 'sender@example.com',
'to': 'recipient@example.com',
'message-id': '<abc123@example.com>',
'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 (useparseHeaders()to convert raw headers)
Returns: Complete SMTP analysis including:
deliveryPath- Array of SMTP hopsauthentication- SPF, DKIM, DMARC, ARC resultsrouting- Routing and relay informationdeliveryStatus- Delivery status and timingsecurityHeaders- Security-related headersbounce- 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/loggerfor 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-adapterfor 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.