Plugin Type
A plugin is a function that receives a Fumi instance and registers middleware on it.app.use() method and can register middleware on any SMTP phase.
Creating Plugins
Basic Plugin
A simple plugin that registers middleware on one or more SMTP phases:Plugin with Options
Plugins can accept configuration options using a factory function pattern:Multi-Phase Plugin
Plugins can register middleware on multiple SMTP phases:Using Plugins
Single Plugin
Multiple Plugins
Chain multiple plugins using method chaining:Plugin Ordering
Plugins are executed in the order they are registered. Middleware from earlier plugins runs before later ones:Built-in Plugins
Fumi includes several built-in plugins for common use cases:logger
Logs SMTP phase events to stdout.denylist
Blocks connections from specific IP addresses.maxSize
Rejects messages that exceed a size limit.FumiOptions.size to the same value for size tracking to work.
View maxSize source
requireTls
Enforces TLS encryption before allowing certain commands.senderBlock
Blocks specific sender addresses or domains.rcptFilter
Filters recipient addresses based on custom logic.Plugin Patterns
Async Plugin Initialization
Plugins can perform async setup before registration:Stateful Plugins
Plugins can maintain state across requests:Composable Plugins
Create higher-order plugins that combine multiple plugins:Best Practices
- Use factory functions: Return a Plugin instead of being one directly, allowing for configuration.
-
Call
next(): Always callawait next()in middleware unless explicitly rejecting or terminating. -
Handle errors: Use
ctx.reject()for SMTP errors rather than throwing exceptions. -
Clean up resources: Use
onCloseto clean up any resources allocated during the session. - Document options: Provide clear TypeScript interfaces for plugin options.
- Keep plugins focused: Each plugin should do one thing well.
- Export types: Export TypeScript types for plugin options to improve developer experience.