@bernierllc/sender-identity-verification
v1.4.0
Published
Individual sender email address verification service for email production compliance
Readme
@bernierllc/sender-identity-verification
Individual sender email address verification service for email production compliance. Manages sender identity creation, email address verification workflows, provider compliance validation, and administrative interfaces.
📋 Overview
This package enables production email sending by verifying individual sender identities and ensuring provider compliance for email addresses. Works in conjunction with @bernierllc/email-domain-verification to ensure complete email sending compliance.
Version: 1.0.0 Category: service Priority: critical
🚀 Installation
npm install @bernierllc/sender-identity-verification📦 Dependencies
This package requires the following dependencies:
@bernierllc/email-sender- For sending verification emails@bernierllc/logger- For audit logging@bernierllc/neverhub-adapter- For service mesh integration@bernierllc/crypto-utils- For secure token generation@bernierllc/retry-policy- For retry logic@bernierllc/validators-email- For email validation
Note: @bernierllc/email-domain-verification is required but not yet published. Domain verification features will be available when this dependency is released.
🎯 Quick Start
import { SenderIdentityVerification, EmailProvider } from '@bernierllc/sender-identity-verification';
// Initialize the service
const service = new SenderIdentityVerification({
verificationBaseUrl: 'https://app.example.com',
verificationFromEmail: '[email protected]',
verificationFromName: 'Example Verification',
sendgridApiKey: process.env.SENDGRID_API_KEY,
emailSenderConfig: {},
domainVerificationConfig: {}
});
await service.initialize();
// Create a sender
const result = await service.createSender({
email: '[email protected]',
name: 'Hello Team',
replyToEmail: '[email protected]',
provider: EmailProvider.SENDGRID,
isDefault: true
});
console.log('Sender created:', result.data);
// Verification email automatically sent to [email protected]📚 API Reference
SenderIdentityVerification
Main service class for managing sender identities.
Constructor
new SenderIdentityVerification(config: SenderIdentityConfig)Configuration Options:
interface SenderIdentityConfig {
// Verification settings
verificationBaseUrl: string; // Base URL for verification links
verificationFromEmail: string; // From email for verification emails
verificationFromName: string; // From name for verification emails
// Provider API keys
sendgridApiKey?: string; // SendGrid API key
mailgunApiKey?: string; // Mailgun API key
sesAccessKey?: string; // AWS SES access key
sesSecretKey?: string; // AWS SES secret key
sesRegion?: string; // AWS SES region (default: 'us-east-1')
// Email sender configuration
emailSenderConfig: object;
// Domain verification configuration
domainVerificationConfig: object;
// Retry configuration
retryConfig?: object;
// Database configuration
databaseUrl?: string;
}Methods
createSender(input: CreateSenderInput): Promise<SenderIdentityResult<SenderIdentity>>
Create a new sender identity.
const result = await service.createSender({
email: '[email protected]',
name: 'Hello Team',
replyToEmail: '[email protected]',
replyToName: 'Support Team',
provider: EmailProvider.SENDGRID,
isDefault: true,
skipVerification: false // Set to true for testing
});verifySender(token: string): Promise<VerificationResult>
Verify a sender using the verification token from the email.
const result = await service.verifySender('abc123token');
if (result.success) {
console.log('Sender verified:', result.senderId);
}getSender(senderId: string): Promise<SenderIdentityResult<SenderIdentity>>
Get sender by ID.
const result = await service.getSender('sender-id-123');
console.log('Sender:', result.data);listSenders(options?: ListSendersOptions): Promise<SenderIdentityResult<SenderIdentity[]>>
List senders with optional filtering.
const result = await service.listSenders({
provider: EmailProvider.SENDGRID,
status: SenderStatus.VERIFIED,
isActive: true,
limit: 50,
offset: 0
});updateSender(senderId: string, input: UpdateSenderInput): Promise<SenderIdentityResult<SenderIdentity>>
Update sender details.
const result = await service.updateSender('sender-id-123', {
name: 'Updated Name',
replyToEmail: '[email protected]',
isDefault: true
});deleteSender(senderId: string): Promise<SenderIdentityResult<void>>
Soft delete a sender.
const result = await service.deleteSender('sender-id-123');checkCompliance(senderId: string): Promise<SenderIdentityResult<ComplianceCheckResult>>
Check provider compliance for a sender.
const result = await service.checkCompliance('sender-id-123');
if (result.success) {
console.log('Compliance status:', result.data?.isCompliant);
console.log('Domain verified:', result.data?.checks.domainVerified);
console.log('SPF valid:', result.data?.checks.spfValid);
console.log('DKIM valid:', result.data?.checks.dkimValid);
}getDefaultSender(provider: EmailProvider): Promise<SenderIdentityResult<SenderIdentity>>
Get the default sender for a provider.
const result = await service.getDefaultSender(EmailProvider.SENDGRID);
console.log('Default sender:', result.data?.email);resendVerification(senderId: string): Promise<SenderIdentityResult<void>>
Resend verification email.
const result = await service.resendVerification('sender-id-123');🔌 Integration Status
- Logger: integrated - Critical for audit trail of sender verification events
- Docs-Suite: ready - Complete API documentation with TypeScript interfaces
- NeverHub: required - Service mesh integration for event publishing
🔒 Security Considerations
Verification Token Security
- Tokens are cryptographically secure (32 bytes, URL-safe)
- Single-use tokens (cleared after successful verification)
- Time-limited (24 hour expiration)
- Stored securely in database
Rate Limiting
- Max 3 verification emails per hour per sender
- Prevents abuse and spam
- Locks sender after too many failed attempts
Provider API Key Storage
- API keys stored in environment variables (never in code)
- API keys never logged or exposed in responses
- Encrypted at rest in database (if persisting config)
📊 Monitoring & Observability
Key Metrics to Track
sender.created- Senders createdsender.verified- Senders verifiedsender.failed- Verification failuressender.locked- Senders lockedverification.email_sent- Verification emails sentverification.token_validated- Token validationscompliance.checked- Compliance checkscompliance.passed- Compliance passes
Critical Events to Log
logger.info('sender.created', { senderId, email, provider });
logger.info('sender.verified', { senderId, email, verifiedAt });
logger.warn('sender.verification_failed', { senderId, reason });
logger.error('sender.locked', { senderId, attempts });
logger.audit('sender.deleted', { senderId, email, deletedBy });🔗 Related Packages
Dependencies
- @bernierllc/email-sender - Email sending functionality
- @bernierllc/logger - Logging infrastructure
- @bernierllc/neverhub-adapter - Service mesh integration
- @bernierllc/crypto-utils - Cryptographic utilities
- @bernierllc/retry-policy - Retry logic
- @bernierllc/validators-email - Email validation
Dependent Packages
- @bernierllc/email-manager - Email management suite
- @bernierllc/email-admin-ui - Email administration UI
- @bernierllc/email-webhook-events - Email event tracking
📝 Examples
Basic Sender Creation
import { SenderIdentityVerification, EmailProvider } from '@bernierllc/sender-identity-verification';
const service = new SenderIdentityVerification({
verificationBaseUrl: 'https://app.example.com',
verificationFromEmail: '[email protected]',
verificationFromName: 'Example Verification',
sendgridApiKey: process.env.SENDGRID_API_KEY,
emailSenderConfig: {},
domainVerificationConfig: {}
});
await service.initialize();
// Create sender
const result = await service.createSender({
email: '[email protected]',
name: 'Hello Team',
replyToEmail: '[email protected]',
provider: EmailProvider.SENDGRID,
isDefault: true
});
console.log('Sender created:', result.data);Verify Sender Email
// User clicks verification link in email
// Link contains token: https://app.example.com/verify-sender?token=abc123
const verifyResult = await service.verifySender('abc123');
if (verifyResult.success) {
console.log('Sender verified:', verifyResult.senderId);
console.log('Verified at:', verifyResult.verifiedAt);
} else {
console.error('Verification failed:', verifyResult.message);
}List Verified Senders
// List all verified senders for SendGrid
const sendersResult = await service.listSenders({
provider: EmailProvider.SENDGRID,
status: SenderStatus.VERIFIED,
isActive: true
});
console.log('Verified SendGrid senders:', sendersResult.data);Check Compliance
// Check compliance for a sender
const complianceResult = await service.checkCompliance('sender-id-123');
if (complianceResult.success) {
const compliance = complianceResult.data!;
console.log('Compliance Status:', compliance.isCompliant ? 'PASS' : 'FAIL');
console.log('Domain Verified:', compliance.checks.domainVerified);
console.log('SPF Valid:', compliance.checks.spfValid);
console.log('DKIM Valid:', compliance.checks.dkimValid);
if (!compliance.isCompliant) {
console.log('Errors:', compliance.errors);
}
}🐛 Troubleshooting
Common Issues
Issue: Domain not verified error
Solution: Ensure the domain is verified using @bernierllc/email-domain-verification before creating senders
Issue: Sender already exists
Solution: Check for existing senders with listSenders() before creating new ones
Issue: Verification token expired
Solution: Use resendVerification() to send a new verification email
Issue: Too many verification emails Solution: Rate limiting prevents more than 3 emails per hour - wait before retrying
📜 License
Copyright (c) 2025 Bernier LLC
This file 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.
🤝 Support
For issues, questions, or contributions, please contact Bernier LLC.
