This commit is contained in:
2025-05-22 10:18:02 +00:00
parent 7c0f9b4e44
commit ac419e7b79
21 changed files with 4541 additions and 1868 deletions

View File

@ -1,224 +1,234 @@
# SMTP Server Refactoring Plan
# SMTP Client Refactoring Plan
## Problem Statement
The SMTP server implementation in `classes.smtpserver.ts` has grown to be too large and complex, with over 1300 lines of code. This makes it difficult to maintain, test, and extend. We need to refactor it into multiple smaller, focused files to improve maintainability and adhere to the single responsibility principle.
Following the successful SMTP server refactoring, the SMTP client implementation in `classes.smtp.client.ts` has grown to be too large and complex, with over 1,421 lines of code. This monolithic structure makes it difficult to maintain, test, and extend. We need to refactor it into multiple smaller, focused files to improve maintainability and achieve consistency with the server architecture.
## Refactoring Goals
1. Improve code organization by splitting the SMTPServer class into multiple focused modules
2. Enhance testability by making components more isolated and easier to mock
1. Improve code organization by splitting the SmtpClient class into multiple focused modules
2. Enhance testability by making components more isolated and easier to mock
3. Improve maintainability by reducing file sizes and complexity
4. Preserve existing functionality and behavior while improving the architecture
4. Achieve architectural consistency with the refactored SMTP server structure
5. Preserve existing functionality and behavior while improving the architecture
## Proposed File Structure
```
mail/
└── delivery/
├── smtp/
├── smtpclient/
│ ├── index.ts - Main export file
│ ├── interfaces.ts - All SMTP-related interfaces
│ ├── constants.ts - Constants and enums
│ ├── smtp-server.ts - Main server class (core functionality)
│ ├── session-manager.ts - Session creation and management
│ ├── command-handler.ts - SMTP command processing
│ ├── data-handler.ts - Email data processing
│ ├── tls-handler.ts - TLS and STARTTLS functionality
│ ├── security-handler.ts - Security checks and validations
│ ├── connection-manager.ts - Connection management and cleanup
│ ├── interfaces.ts - All SMTP client interfaces
│ ├── constants.ts - Constants and error codes
│ ├── smtp-client.ts - Main client class (core functionality)
│ ├── connection-manager.ts - Connection pooling and lifecycle
│ ├── command-handler.ts - SMTP command sending and parsing
│ ├── auth-handler.ts - Authentication mechanisms
│ ├── tls-handler.ts - TLS and STARTTLS client functionality
│ ├── error-handler.ts - Error classification and recovery
│ ├── create-client.ts - Factory function for client creation
│ └── utils/
│ ├── validation.ts - Validation utilities
│ ├── logging.ts - Logging utilities
│ └── helpers.ts - Other helper functions
├── classes.smtpserver.ts - Legacy file (will be deprecated)
│ ├── validation.ts - Input validation utilities
│ ├── logging.ts - Client-side logging utilities
│ └── helpers.ts - Protocol helper functions
├── classes.smtp.client.ts - Legacy file (will be deprecated)
└── interfaces.ts - Main delivery interfaces
```
## Module Responsibilities
### 1. smtp-server.ts (150-200 lines)
- Core server initialization and lifecycle management
- Server startup and shutdown
- Port binding and socket creation
### 1. smtp-client.ts (150-200 lines)
- Core client initialization and lifecycle management
- Client configuration and options handling
- Connection coordination and delegation
- High-level send operations
- Delegates to other modules for specific functionality
### 2. session-manager.ts (100-150 lines)
- Session creation and tracking
- Session timeout management
- Session cleanup
- Session state management
### 2. connection-manager.ts (150-200 lines)
- Connection pooling and reuse
- Socket lifecycle management
- Connection timeout handling
- Connection health monitoring
- Connection error recovery
### 3. command-handler.ts (200-250 lines)
- SMTP command parsing and routing
- Command validation
- Command implementation (EHLO, MAIL FROM, RCPT TO, etc.)
- Response formatting
- SMTP command formatting and sending
- Server response parsing and validation
- Command pipeline management
- Response code interpretation
- Protocol state tracking
### 4. data-handler.ts (150-200 lines)
- Email data collection and processing
- DATA command handling
- MIME parsing
- Email creation and forwarding
- Email storage
### 4. auth-handler.ts (150-200 lines)
- Authentication mechanism selection
- PLAIN, LOGIN, OAUTH2 implementation
- Credential management
- Authentication challenge handling
- Authentication error handling
### 5. tls-handler.ts (100-150 lines)
- TLS connection handling
- STARTTLS implementation
- Certificate management
- Secure socket creation
- TLS connection establishment
- STARTTLS client implementation
- Certificate validation
- Secure socket creation and management
- TLS error handling
### 6. security-handler.ts (100-150 lines)
- IP reputation checking
- Access control
- Rate limiting
- Security logging
- SPAM detection
### 6. error-handler.ts (150-200 lines)
- SMTP error code classification
- Error recovery strategies
- Retry logic implementation
- Error logging and reporting
- Connection failure handling
### 7. connection-manager.ts (100-150 lines)
- Connection tracking and limits
- Idle connection cleanup
- Connection error handling
- Socket event handling
### 7. create-client.ts (50-100 lines)
- Factory function for client creation
- Dependency injection setup
- Configuration validation
- Component initialization
- Default option handling
### 8. interfaces.ts (100-150 lines)
- All interface definitions
- Type aliases
- Type guards
- Enum definitions
- All client interface definitions
- Type aliases for client operations
- Error type definitions
- Configuration interfaces
- Result type definitions
## Implementation Strategy
### Phase 1: Initial Structure and Scaffolding (Days 1-2)
### Phase 1: Initial Structure and Scaffolding (Days 1-2)
1. Create the folder structure and empty files
- Create `mail/delivery/smtp` directory
- Create all module files with basic exports
- Set up barrel file (index.ts)
1. Create the folder structure and empty files
- Create `mail/delivery/smtpclient` directory
- Create all module files with basic exports
- Set up barrel file (index.ts)
2. Move interfaces to the new interfaces.ts file
- Extract all interfaces from current implementation
- Add proper documentation
- Add any missing interface properties
2. Move interfaces to the new interfaces.ts file
- Extract all interfaces from current client implementation
- Add proper documentation for client-specific interfaces
- Add any missing interface properties
3. Extract constants and enums to constants.ts
- Move all constants and enums to dedicated file
- Ensure proper typing and documentation
- Replace magic numbers with named constants
3. Extract constants and enums to constants.ts
- Move all SMTP client constants and error codes
- Ensure proper typing and documentation
- Replace magic numbers with named constants
4. Set up the basic structure for each module
- Define basic class skeletons
- Set up dependency injection structure
- Document interfaces for each module
4. Set up the basic structure for each module
- Define basic class skeletons for each handler
- Set up dependency injection structure
- Document interfaces for each module
### Phase 2: Gradual Implementation Transfer (Days 3-7)
### Phase 2: Gradual Implementation Transfer (Days 3-7)
1. Start with utility modules
- Implement validation.ts with email validation functions
- Create logging.ts with structured logging utilities
- Build helpers.ts with common helper functions
1. Start with utility modules
- Implement validation.ts with input validation functions
- Create logging.ts with client-side logging utilities
- Build helpers.ts with protocol helper functions
2. Implement session-manager.ts
- Extract session creation and management logic
- Implement timeout handling
- Add session state management functions
2. Implement error-handler.ts
- Extract error classification logic
- Implement retry strategies
- Add error logging and reporting
3. Implement connection-manager.ts
- Extract connection tracking code
- Implement connection limits
- Add socket event handling logic
3. Implement connection-manager.ts
- Extract connection pooling code
- Implement connection lifecycle management
- Add connection health monitoring
4. Implement command-handler.ts
- Extract command parsing and processing
- Split command handlers into separate methods
- Implement command validation and routing
4. Implement command-handler.ts
- Extract SMTP command formatting and sending
- Split response parsing into separate methods
- Implement command pipeline management
5. Implement data-handler.ts
- Extract email data processing logic
- Implement DATA command handling
- Add email storage and forwarding
5. Implement auth-handler.ts
- Extract authentication mechanism logic
- Implement PLAIN, LOGIN, OAUTH2 handlers
- Add credential management
6. Implement tls-handler.ts
- Extract TLS connection handling
- Implement STARTTLS functionality
- Add certificate management
6. Implement tls-handler.ts
- Extract TLS client connection handling
- Implement STARTTLS client functionality
- Add certificate validation
7. Implement security-handler.ts
- Extract IP reputation checking
- Implement security logging
- Add access control functionality
7. Implement create-client.ts
- ✅ Create factory function for client creation
- Implement dependency injection setup
- Add configuration validation
### Phase 3: Core Server Refactoring (Days 8-10)
### Phase 3: Core Client Refactoring (Days 8-10)
1. Refactor the main SMTPServer class
- Update constructor to create and initialize components
- Implement dependency injection for all modules
- Delegate functionality to appropriate modules
- Reduce core class to server lifecycle management
1. Refactor the main SmtpClient class
- Update constructor to create and initialize components
- Implement dependency injection for all modules
- Delegate functionality to appropriate modules
- Reduce core class to client lifecycle management
2. Update event handling
- Ensure proper event propagation between modules
- Implement event delegation pattern
- Add missing event handlers
2. Update method delegation
- Ensure proper method delegation to handlers
- Implement proper error propagation
- Add missing method implementations
3. Implement cross-module communication
- Define clear interfaces for module interaction
- Ensure proper data flow between components
- Avoid circular dependencies
3. Implement cross-module communication
- Define clear interfaces for module interaction
- Ensure proper data flow between components
- Avoid circular dependencies
4. Verify functionality preservation
- Ensure all methods have equivalent implementations
- Add logging to trace execution flow
- Create test cases for edge conditions
4. Verify functionality preservation
- Ensure all methods have equivalent implementations
- Add logging to trace execution flow
- Create test cases for edge conditions
### Phase 4: Legacy Compatibility (Days 11-12)
### Phase 4: Legacy Compatibility and Testing (Days 11-12)
1. Create facade in classes.smtpserver.ts
- Keep original class signature
- Delegate to new implementation internally
- Ensure backward compatibility
1. Create facade in classes.smtp.client.ts
- Keep original class signature
- Delegate to new implementation internally
- Ensure backward compatibility
2. Add deprecation notices
- Mark legacy file with deprecation comments
- Add migration guide in comments
- Document breaking changes if any
2. Add deprecation notices
- Mark legacy file with deprecation comments
- Add migration guide in comments
- Document breaking changes if any
3. Update documentation
- Create detailed documentation for new architecture
- Add examples of how to use the new modules
- Document extension points
3. Update documentation
- Create detailed documentation for new architecture
- Add examples of how to use the new modules
- Document extension points
4. Create comprehensive tests
- Ensure all modules have proper unit tests
- Add integration tests between modules
- Verify backward compatibility with existing code
4. Create comprehensive tests
- Ensure all modules have proper unit tests
- Add integration tests between modules
- Verify backward compatibility with existing code
## Testing Strategy
1. Unit Testing
- Create unit tests for each module in isolation
- Mock dependencies for pure unit testing
- Test edge cases and error handling
- Create unit tests for each client module in isolation
- Mock socket connections and server responses
- Test authentication mechanisms independently
- Test error handling and recovery scenarios
2. Integration Testing
- Test interactions between modules
- Verify correct event propagation
- Test full SMTP communication flow
- Test interactions between client modules
- Verify proper command flow and response handling
- Test full SMTP client communication flow
- Test TLS/STARTTLS integration
3. Regression Testing
- Ensure all existing tests pass
- Verify no functionality is lost
- Compare performance metrics
3. Production Testing
- Create comprehensive client production test suite (similar to server tests)
- Test against real SMTP servers with various configurations
- Test authentication with different providers
- Performance and reliability testing
4. Compatibility Testing
- Test with existing code that uses the legacy class
- Verify backward compatibility
- Test with existing code that uses the legacy SmtpClient class
- Verify backward compatibility with EmailSendJob integration
- Document any necessary migration steps
## Timeline Estimate
- Phase 1: 1-2 days
- Phase 2: 3-5 days
- Phase 2: 3-5 days
- Phase 3: 2-3 days
- Phase 4: 1-2 days
@ -231,28 +241,36 @@ Total: 7-12 days of development time
3. Each file is less than 300 lines of code
4. Improved code organization and documentation
5. Better separation of concerns between modules
6. Easier maintenance and extension of SMTP functionality
6. Easier maintenance and extension of SMTP client functionality
7. Enhanced testability with modular components
8. Comprehensive production test suite for SMTP client
## Risks and Mitigations
### Risk: Breaking existing functionality
**Mitigation**: Comprehensive test coverage and backward compatibility facade
### Risk: Breaking existing EmailSendJob integration
**Mitigation**: Comprehensive test coverage and backward compatibility facade with existing interface
### Risk: Performance degradation due to additional indirection
**Mitigation**: Performance benchmarking before and after refactoring
**Mitigation**: Performance benchmarking before and after refactoring, optimize hot paths
### Risk: Increased complexity due to distributed code
**Mitigation**: Clear documentation and proper module interfaces
### Risk: Increased complexity due to distributed client code
**Mitigation**: Clear documentation and proper module interfaces, follow server refactoring patterns
### Risk: Time overrun due to unforeseen dependencies
**Mitigation**: Incremental approach with working checkpoints after each phase
### Risk: Connection pooling complexity in modular architecture
**Mitigation**: Careful design of connection-manager interface, thorough testing of connection lifecycle
### Risk: Time overrun due to authentication complexity
**Mitigation**: Incremental approach with working checkpoints, start with simpler auth mechanisms
## Future Extensions
Once this refactoring is complete, we can more easily:
1. Add support for additional SMTP extensions
2. Implement pluggable authentication mechanisms
3. Add more sophisticated security features
4. Improve performance with targeted optimizations
5. Create specialized versions for different use cases
1. Add support for additional SMTP authentication mechanisms (OAUTH2, SCRAM-SHA, etc.)
2. Implement advanced connection pooling strategies
3. Add comprehensive production test suite matching server coverage
4. Improve performance with targeted optimizations (pipelining, concurrent connections)
5. Create specialized client versions for different use cases (bulk sending, transactional)
6. Add client-side security features (connection validation, certificate pinning)
7. Implement advanced retry and fallback strategies
8. Add comprehensive monitoring and metrics collection