new plan
This commit is contained in:
parent
09fc71f051
commit
552f4c246b
938
readme.plan.md
938
readme.plan.md
@ -1,255 +1,775 @@
|
||||
# SmartProxy Interface & Type Naming Standardization Plan
|
||||
# SmartProxy Fully Unified Configuration Plan
|
||||
|
||||
## Project Goal
|
||||
Standardize interface and type naming throughout the SmartProxy codebase to improve maintainability, readability, and developer experience by:
|
||||
1. Ensuring all interfaces are prefixed with "I"
|
||||
2. Ensuring all type aliases are prefixed with "T"
|
||||
3. Maintaining backward compatibility through type aliases
|
||||
4. Updating documentation to reflect naming conventions
|
||||
Redesign SmartProxy's configuration for a more elegant, unified, and comprehensible approach by:
|
||||
1. Creating a single, unified configuration model that covers both "where to listen" and "how to forward"
|
||||
2. Eliminating the confusion between domain configs and port forwarding
|
||||
3. Providing a clear, declarative API that makes the intent obvious
|
||||
4. Enhancing maintainability and extensibility for future features
|
||||
|
||||
## Phase 2: Core Module Standardization
|
||||
## Current Issues
|
||||
|
||||
- [ ] Update core module interfaces and types
|
||||
- [ ] Rename interfaces in `ts/core/models/common-types.ts`
|
||||
- [ ] `AcmeOptions` → `IAcmeOptions`
|
||||
- [ ] `DomainOptions` → `IDomainOptions`
|
||||
- [ ] Other common interfaces
|
||||
- [ ] Add backward compatibility aliases
|
||||
- [ ] Update imports throughout core module
|
||||
The current approach has several issues:
|
||||
|
||||
- [ ] Update core utility type definitions
|
||||
- [ ] Update `ts/core/utils/validation-utils.ts`
|
||||
- [ ] Update `ts/core/utils/ip-utils.ts`
|
||||
- [ ] Standardize event type definitions
|
||||
1. **Dual Configuration Systems**:
|
||||
- Port configuration (`fromPort`, `toPort`, `globalPortRanges`) for "where to listen"
|
||||
- Domain configuration (`domainConfigs`) for "how to forward"
|
||||
- Unclear relationship between these two systems
|
||||
|
||||
- [ ] Test core module changes
|
||||
- [ ] Run unit tests for core modules
|
||||
- [ ] Verify type compatibility
|
||||
- [ ] Ensure backward compatibility
|
||||
2. **Mixed Concerns**:
|
||||
- Port management is mixed with forwarding logic
|
||||
- Domain routing is separated from port listening
|
||||
- Security settings defined in multiple places
|
||||
|
||||
## Phase 3: Certificate Module Standardization
|
||||
3. **Complex Logic**:
|
||||
- PortRangeManager must coordinate with domain configuration
|
||||
- Implicit rules for handling connections based on port and domain
|
||||
|
||||
- [ ] Update certificate interfaces
|
||||
- [ ] Rename interfaces in `ts/certificate/models/certificate-types.ts`
|
||||
- [ ] `CertificateData` → `ICertificateData`
|
||||
- [ ] `Certificates` → `ICertificates`
|
||||
- [ ] `CertificateFailure` → `ICertificateFailure`
|
||||
- [ ] `CertificateExpiring` → `ICertificateExpiring`
|
||||
- [ ] `ForwardConfig` → `IForwardConfig`
|
||||
- [ ] `DomainForwardConfig` → `IDomainForwardConfig`
|
||||
- [ ] Update ACME challenge interfaces
|
||||
- [ ] Standardize storage provider interfaces
|
||||
4. **Difficult to Understand and Configure**:
|
||||
- Two separate configuration hierarchies that must work together
|
||||
- Unclear which settings take precedence
|
||||
|
||||
- [ ] Ensure certificate provider compatibility
|
||||
- [ ] Update provider implementations
|
||||
- [ ] Rename internal interfaces
|
||||
- [ ] Maintain public API compatibility
|
||||
## Proposed Solution: Fully Unified Routing Configuration
|
||||
|
||||
- [ ] Test certificate module
|
||||
- [ ] Verify ACME functionality
|
||||
- [ ] Test certificate provisioning
|
||||
- [ ] Validate challenge handling
|
||||
Replace both port and domain configuration with a single, unified configuration:
|
||||
|
||||
## Phase 4: Forwarding System Standardization
|
||||
```typescript
|
||||
// The core unified configuration interface
|
||||
interface IRouteConfig {
|
||||
// What to match
|
||||
match: {
|
||||
// Listen on these ports (required)
|
||||
ports: number | number[] | Array<{ from: number, to: number }>;
|
||||
|
||||
// Optional domain patterns to match (default: all domains)
|
||||
domains?: string | string[];
|
||||
|
||||
// Advanced matching criteria
|
||||
path?: string; // Match specific paths
|
||||
clientIp?: string[]; // Match specific client IPs
|
||||
tlsVersion?: string[]; // Match specific TLS versions
|
||||
};
|
||||
|
||||
// What to do with matched traffic
|
||||
action: {
|
||||
// Basic routing
|
||||
type: 'forward' | 'redirect' | 'block';
|
||||
|
||||
// Target for forwarding
|
||||
target?: {
|
||||
host: string | string[]; // Support single host or round-robin
|
||||
port: number;
|
||||
preservePort?: boolean; // Use incoming port as target port
|
||||
};
|
||||
|
||||
// TLS handling
|
||||
tls?: {
|
||||
mode: 'passthrough' | 'terminate' | 'terminate-and-reencrypt';
|
||||
certificate?: 'auto' | { // Auto = use ACME
|
||||
key: string;
|
||||
cert: string;
|
||||
};
|
||||
};
|
||||
|
||||
// For redirects
|
||||
redirect?: {
|
||||
to: string; // URL or template with {domain}, {port}, etc.
|
||||
status: 301 | 302 | 307 | 308;
|
||||
};
|
||||
|
||||
// Security options
|
||||
security?: {
|
||||
allowedIps?: string[];
|
||||
blockedIps?: string[];
|
||||
maxConnections?: number;
|
||||
authentication?: {
|
||||
type: 'basic' | 'digest' | 'oauth';
|
||||
// Auth-specific options
|
||||
};
|
||||
};
|
||||
|
||||
// Advanced options
|
||||
advanced?: {
|
||||
timeout?: number;
|
||||
headers?: Record<string, string>;
|
||||
keepAlive?: boolean;
|
||||
// etc.
|
||||
};
|
||||
};
|
||||
|
||||
// Optional metadata
|
||||
name?: string; // Human-readable name for this route
|
||||
description?: string; // Description of the route's purpose
|
||||
priority?: number; // Controls matching order (higher = matched first)
|
||||
tags?: string[]; // Arbitrary tags for categorization
|
||||
}
|
||||
|
||||
- [ ] Update forwarding configuration interfaces
|
||||
- [ ] Rename interfaces in `ts/forwarding/config/forwarding-types.ts`
|
||||
- [ ] `TargetConfig` → `ITargetConfig`
|
||||
- [ ] `HttpOptions` → `IHttpOptions`
|
||||
- [ ] `HttpsOptions` → `IHttpsOptions`
|
||||
- [ ] `AcmeForwardingOptions` → `IAcmeForwardingOptions`
|
||||
- [ ] `SecurityOptions` → `ISecurityOptions`
|
||||
- [ ] `AdvancedOptions` → `IAdvancedOptions`
|
||||
- [ ] `ForwardConfig` → `IForwardConfig`
|
||||
- [ ] Rename type definitions
|
||||
- [ ] `ForwardingType` → `TForwardingType`
|
||||
- [ ] Update domain configuration interfaces
|
||||
// Main SmartProxy options
|
||||
interface ISmartProxyOptions {
|
||||
// The unified configuration array (required)
|
||||
routes: IRouteConfig[];
|
||||
|
||||
// Global/default settings
|
||||
defaults?: {
|
||||
target?: {
|
||||
host: string;
|
||||
port: number;
|
||||
};
|
||||
security?: {
|
||||
// Global security defaults
|
||||
};
|
||||
tls?: {
|
||||
// Global TLS defaults
|
||||
};
|
||||
// ...other defaults
|
||||
};
|
||||
|
||||
// Other global settings remain (acme, etc.)
|
||||
acme?: IAcmeOptions;
|
||||
|
||||
// Advanced settings remain as well
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] Standardize handler interfaces
|
||||
- [ ] Update base handler interfaces
|
||||
- [ ] Rename handler-specific interfaces
|
||||
- [ ] Update factory interfaces
|
||||
### Example Configuration
|
||||
|
||||
- [ ] Verify forwarding system functionality
|
||||
- [ ] Test all forwarding types
|
||||
- [ ] Verify configuration parsing
|
||||
- [ ] Ensure backward compatibility
|
||||
```typescript
|
||||
const proxy = new SmartProxy({
|
||||
// All routing is configured in a single array
|
||||
routes: [
|
||||
// Basic HTTPS server with automatic certificates
|
||||
{
|
||||
match: {
|
||||
ports: 443,
|
||||
domains: ['example.com', '*.example.com']
|
||||
},
|
||||
action: {
|
||||
type: 'forward',
|
||||
target: {
|
||||
host: 'localhost',
|
||||
port: 8080
|
||||
},
|
||||
tls: {
|
||||
mode: 'terminate',
|
||||
certificate: 'auto' // Use ACME
|
||||
}
|
||||
},
|
||||
name: 'Main HTTPS Server'
|
||||
},
|
||||
|
||||
// HTTP to HTTPS redirect
|
||||
{
|
||||
match: {
|
||||
ports: 80,
|
||||
domains: ['example.com', '*.example.com']
|
||||
},
|
||||
action: {
|
||||
type: 'redirect',
|
||||
redirect: {
|
||||
to: 'https://{domain}{path}',
|
||||
status: 301
|
||||
}
|
||||
},
|
||||
name: 'HTTP to HTTPS Redirect'
|
||||
},
|
||||
|
||||
// Admin portal with IP restriction
|
||||
{
|
||||
match: {
|
||||
ports: 8443,
|
||||
domains: 'admin.example.com'
|
||||
},
|
||||
action: {
|
||||
type: 'forward',
|
||||
target: {
|
||||
host: 'admin-backend',
|
||||
port: 3000
|
||||
},
|
||||
tls: {
|
||||
mode: 'terminate',
|
||||
certificate: 'auto'
|
||||
},
|
||||
security: {
|
||||
allowedIps: ['192.168.1.*', '10.0.0.*'],
|
||||
maxConnections: 10
|
||||
}
|
||||
},
|
||||
priority: 100, // Higher priority than default rules
|
||||
name: 'Admin Portal'
|
||||
},
|
||||
|
||||
// Port range for direct forwarding
|
||||
{
|
||||
match: {
|
||||
ports: [{ from: 10000, to: 10010 }],
|
||||
// No domains = all domains or direct IP
|
||||
},
|
||||
action: {
|
||||
type: 'forward',
|
||||
target: {
|
||||
host: 'backend-server',
|
||||
port: 10000,
|
||||
preservePort: true // Use same port number as incoming
|
||||
},
|
||||
tls: {
|
||||
mode: 'passthrough' // Direct TCP forwarding
|
||||
}
|
||||
},
|
||||
name: 'Dynamic Port Range'
|
||||
},
|
||||
|
||||
// Path-based routing
|
||||
{
|
||||
match: {
|
||||
ports: 443,
|
||||
domains: 'api.example.com',
|
||||
path: '/v1/*'
|
||||
},
|
||||
action: {
|
||||
type: 'forward',
|
||||
target: {
|
||||
host: 'api-v1-service',
|
||||
port: 8001
|
||||
},
|
||||
tls: {
|
||||
mode: 'terminate'
|
||||
}
|
||||
},
|
||||
name: 'API v1 Endpoints'
|
||||
},
|
||||
|
||||
// Load balanced backend
|
||||
{
|
||||
match: {
|
||||
ports: 443,
|
||||
domains: 'app.example.com'
|
||||
},
|
||||
action: {
|
||||
type: 'forward',
|
||||
target: {
|
||||
// Round-robin load balancing
|
||||
host: [
|
||||
'app-server-1',
|
||||
'app-server-2',
|
||||
'app-server-3'
|
||||
],
|
||||
port: 8080
|
||||
},
|
||||
tls: {
|
||||
mode: 'terminate'
|
||||
},
|
||||
advanced: {
|
||||
headers: {
|
||||
'X-Served-By': '{server}',
|
||||
'X-Client-IP': '{clientIp}'
|
||||
}
|
||||
}
|
||||
},
|
||||
name: 'Load Balanced App Servers'
|
||||
}
|
||||
],
|
||||
|
||||
// Global defaults
|
||||
defaults: {
|
||||
target: {
|
||||
host: 'localhost',
|
||||
port: 8080
|
||||
},
|
||||
security: {
|
||||
maxConnections: 1000,
|
||||
// Global security defaults
|
||||
}
|
||||
},
|
||||
|
||||
// ACME configuration for auto certificates
|
||||
acme: {
|
||||
enabled: true,
|
||||
email: 'admin@example.com',
|
||||
production: true,
|
||||
renewThresholdDays: 30
|
||||
},
|
||||
|
||||
// Other global settings
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
## Phase 5: Proxy Implementation Standardization
|
||||
## Implementation Plan
|
||||
|
||||
- [ ] Update SmartProxy interfaces
|
||||
- [ ] Rename interfaces in `ts/proxies/smart-proxy/models/interfaces.ts`
|
||||
- [ ] Update domain configuration interfaces
|
||||
- [ ] Standardize manager interfaces
|
||||
### Phase 1: Core Design & Interface Definition
|
||||
|
||||
- [ ] Update NetworkProxy interfaces
|
||||
- [ ] Rename in `ts/proxies/network-proxy/models/types.ts`
|
||||
- [ ] `NetworkProxyOptions` → `INetworkProxyOptions`
|
||||
- [ ] `CertificateEntry` → `ICertificateEntry`
|
||||
- [ ] `ReverseProxyConfig` → `IReverseProxyConfig`
|
||||
- [ ] `ConnectionEntry` → `IConnectionEntry`
|
||||
- [ ] `WebSocketWithHeartbeat` → `IWebSocketWithHeartbeat`
|
||||
- [ ] `Logger` → `ILogger`
|
||||
- [ ] Update request handler interfaces
|
||||
- [ ] Standardize connection interfaces
|
||||
1. **Define New Core Interfaces**:
|
||||
- Create `IRouteConfig` interface with `match` and `action` branches
|
||||
- Define all sub-interfaces for matching and actions
|
||||
- Update `ISmartProxyOptions` to use `routes` array
|
||||
- Define template variable system for dynamic values
|
||||
|
||||
- [ ] Update NfTablesProxy interfaces
|
||||
- [ ] Rename interfaces in `ts/proxies/nftables-proxy/models/interfaces.ts`
|
||||
- [ ] Update configuration interfaces
|
||||
- [ ] Standardize firewall rule interfaces
|
||||
2. **Create Helper Functions**:
|
||||
- `createRoute()` - Basic route creation with reasonable defaults
|
||||
- `createHttpRoute()`, `createHttpsRoute()`, `createRedirect()` - Common scenarios
|
||||
- `createLoadBalancer()` - For multi-target setups
|
||||
- `mergeSecurity()`, `mergeDefaults()` - For combining configs
|
||||
|
||||
- [ ] Test proxy implementations
|
||||
- [ ] Verify SmartProxy functionality
|
||||
- [ ] Test NetworkProxy with renamed interfaces
|
||||
- [ ] Validate NfTablesProxy operations
|
||||
3. **Design Router**:
|
||||
- Decision tree for route matching algorithm
|
||||
- Priority system for route ordering
|
||||
- Optimized lookup strategy for fast routing
|
||||
|
||||
## Phase 6: HTTP & TLS Module Standardization
|
||||
### Phase 2: Core Implementation
|
||||
|
||||
- [ ] Update HTTP interfaces
|
||||
- [ ] Rename in `ts/http/port80/acme-interfaces.ts`
|
||||
- [ ] `SmartAcmeCert` → `ISmartAcmeCert`
|
||||
- [ ] `SmartAcmeOptions` → `ISmartAcmeOptions`
|
||||
- [ ] `Http01Challenge` → `IHttp01Challenge`
|
||||
- [ ] `SmartAcme` → `ISmartAcme`
|
||||
- [ ] Standardize router interfaces
|
||||
- [ ] Update port80 handler interfaces
|
||||
- [ ] Update redirect interfaces
|
||||
1. **Create RouteManager**:
|
||||
- Replaces both PortRangeManager and DomainConfigManager
|
||||
- Handles all routing decisions in one place
|
||||
- Provides fast lookup from port+domain+path to action
|
||||
- Manages server instances for different ports
|
||||
|
||||
- [ ] Update TLS/SNI interfaces
|
||||
- [ ] Standardize SNI handler interfaces
|
||||
- [ ] Update client hello parser types
|
||||
- [ ] Rename TLS alert interfaces
|
||||
2. **Update ConnectionHandler**:
|
||||
- Simplify to work with the unified route system
|
||||
- Implement templating system for dynamic values
|
||||
- Support more sophisticated routing rules
|
||||
|
||||
- [ ] Test HTTP & TLS functionality
|
||||
- [ ] Verify router operation
|
||||
- [ ] Test SNI extraction
|
||||
- [ ] Validate redirect functionality
|
||||
3. **Implement New SmartProxy Core**:
|
||||
- Rewrite initialization to use route-based configuration
|
||||
- Create network servers based on port specifications
|
||||
- Manage TLS contexts and certificates
|
||||
|
||||
## Phase 7: Backward Compatibility Layer
|
||||
### Phase 3: Feature Implementation
|
||||
|
||||
- [ ] Implement comprehensive type aliases
|
||||
- [ ] Create aliases for all renamed interfaces
|
||||
- [ ] Add deprecation notices via JSDoc
|
||||
- [ ] Ensure all exports include both named versions
|
||||
1. **Path-Based Routing**:
|
||||
- Implement HTTP path matching
|
||||
- Add wildcard and regex support for paths
|
||||
- Create route differentiation based on HTTP method
|
||||
|
||||
- [ ] Update main entry point
|
||||
- [ ] Update `ts/index.ts` with all exports
|
||||
- [ ] Include both prefixed and non-prefixed names
|
||||
- [ ] Organize exports by module
|
||||
2. **Enhanced Security**:
|
||||
- Implement per-route security rules
|
||||
- Add authentication methods (basic, digest, etc.)
|
||||
- Support for IP-based access control
|
||||
|
||||
- [ ] Add compatibility documentation
|
||||
- [ ] Document renaming strategy
|
||||
- [ ] Provide migration examples
|
||||
- [ ] Create deprecation timeline
|
||||
3. **TLS Management**:
|
||||
- Support multiple certificate types (auto, manual, wildcard)
|
||||
- Implement certificate selection based on SNI
|
||||
- Support different TLS modes per route
|
||||
|
||||
## Phase 8: Documentation & Examples
|
||||
4. **Metrics & Monitoring**:
|
||||
- Per-route statistics
|
||||
- Named route tracking for better visibility
|
||||
- Tag-based grouping of metrics
|
||||
|
||||
- [ ] Update README and API documentation
|
||||
- [ ] Update interface references in README.md
|
||||
- [ ] Document naming convention in README.md
|
||||
- [ ] Update API reference documentation
|
||||
### Phase 4: Backward Compatibility
|
||||
|
||||
- [ ] Update examples
|
||||
- [ ] Modify example code to use new interface names
|
||||
- [ ] Add compatibility notes
|
||||
- [ ] Create migration examples
|
||||
1. **Legacy Adapter Layer**:
|
||||
- Convert old configuration format to route-based format
|
||||
- Map fromPort/toPort/domainConfigs to unified routes
|
||||
- Preserve all functionality during migration
|
||||
|
||||
- [ ] Add contributor guidelines
|
||||
- [ ] Document naming conventions
|
||||
- [ ] Add interface/type style guide
|
||||
- [ ] Update PR templates
|
||||
2. **API Compatibility**:
|
||||
- Support both old and new configuration methods
|
||||
- Add deprecation warnings when using legacy properties
|
||||
- Provide migration utilities
|
||||
|
||||
## Phase 9: Testing & Validation
|
||||
3. **Documentation**:
|
||||
- Clear migration guide for existing users
|
||||
- Examples mapping old config to new config
|
||||
- Timeline for deprecation
|
||||
|
||||
- [ ] Run comprehensive test suite
|
||||
- [ ] Run all unit tests
|
||||
- [ ] Execute integration tests
|
||||
- [ ] Verify example code
|
||||
### Phase 5: Documentation & Examples
|
||||
|
||||
- [ ] Build type declarations
|
||||
- [ ] Generate TypeScript declaration files
|
||||
- [ ] Verify exported types
|
||||
- [ ] Validate documentation generation
|
||||
1. **Update Core Documentation**:
|
||||
- Rewrite README.md with a focus on route-based configuration
|
||||
- Create interface reference documentation
|
||||
- Document all template variables
|
||||
|
||||
- [ ] Final compatibility check
|
||||
- [ ] Verify import compatibility
|
||||
- [ ] Test with existing dependent projects
|
||||
- [ ] Validate backward compatibility claims
|
||||
2. **Create Example Library**:
|
||||
- Common configuration patterns
|
||||
- Complex use cases for advanced features
|
||||
- Infrastructure-as-code examples
|
||||
|
||||
3. **Add Validation Tooling**:
|
||||
- Configuration validator to check for issues
|
||||
- Schema definitions for IDE autocomplete
|
||||
- Runtime validation helpers
|
||||
|
||||
### Phase 6: Testing
|
||||
|
||||
1. **Unit Tests**:
|
||||
- Test route matching logic
|
||||
- Validate priority handling
|
||||
- Test template processing
|
||||
|
||||
2. **Integration Tests**:
|
||||
- Verify full proxy flows
|
||||
- Test complex routing scenarios
|
||||
- Check backward compatibility
|
||||
|
||||
3. **Performance Testing**:
|
||||
- Benchmark routing performance
|
||||
- Evaluate memory usage
|
||||
- Test with large numbers of routes
|
||||
|
||||
## Benefits of the New Approach
|
||||
|
||||
1. **Truly Unified Configuration**:
|
||||
- One "source of truth" for all routing
|
||||
- Entire routing flow visible in a single configuration
|
||||
- No overlapping or conflicting configuration systems
|
||||
|
||||
2. **Declarative Intent**:
|
||||
- Configuration clearly states what to match and what action to take
|
||||
- Metadata provides context and documentation inline
|
||||
- Easy to understand the purpose of each route
|
||||
|
||||
3. **Advanced Routing Capabilities**:
|
||||
- Path-based routing with pattern matching
|
||||
- Client IP-based conditional routing
|
||||
- Fine-grained security controls
|
||||
|
||||
4. **Composable and Extensible**:
|
||||
- Each route is a self-contained unit of configuration
|
||||
- Routes can be grouped by tags or priority
|
||||
- New match criteria or actions can be added without breaking changes
|
||||
|
||||
5. **Better Developer Experience**:
|
||||
- Clear, consistent configuration pattern
|
||||
- Helper functions for common scenarios
|
||||
- Better error messages and validation
|
||||
|
||||
## Example Use Cases
|
||||
|
||||
### 1. Complete Reverse Proxy with Auto SSL
|
||||
|
||||
```typescript
|
||||
const proxy = new SmartProxy({
|
||||
routes: [
|
||||
// HTTPS server for all domains
|
||||
{
|
||||
match: { ports: 443 },
|
||||
action: {
|
||||
type: 'forward',
|
||||
target: { host: 'localhost', port: 8080 },
|
||||
tls: { mode: 'terminate', certificate: 'auto' }
|
||||
}
|
||||
},
|
||||
// HTTP to HTTPS redirect
|
||||
{
|
||||
match: { ports: 80 },
|
||||
action: {
|
||||
type: 'redirect',
|
||||
redirect: { to: 'https://{domain}{path}', status: 301 }
|
||||
}
|
||||
}
|
||||
],
|
||||
acme: {
|
||||
enabled: true,
|
||||
email: 'admin@example.com',
|
||||
production: true
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### 2. Microservices API Gateway
|
||||
|
||||
```typescript
|
||||
const apiGateway = new SmartProxy({
|
||||
routes: [
|
||||
// Users API
|
||||
{
|
||||
match: {
|
||||
ports: 443,
|
||||
domains: 'api.example.com',
|
||||
path: '/users/*'
|
||||
},
|
||||
action: {
|
||||
type: 'forward',
|
||||
target: { host: 'users-service', port: 8001 },
|
||||
tls: { mode: 'terminate', certificate: 'auto' }
|
||||
},
|
||||
name: 'Users Service'
|
||||
},
|
||||
// Products API
|
||||
{
|
||||
match: {
|
||||
ports: 443,
|
||||
domains: 'api.example.com',
|
||||
path: '/products/*'
|
||||
},
|
||||
action: {
|
||||
type: 'forward',
|
||||
target: { host: 'products-service', port: 8002 },
|
||||
tls: { mode: 'terminate', certificate: 'auto' }
|
||||
},
|
||||
name: 'Products Service'
|
||||
},
|
||||
// Orders API with authentication
|
||||
{
|
||||
match: {
|
||||
ports: 443,
|
||||
domains: 'api.example.com',
|
||||
path: '/orders/*'
|
||||
},
|
||||
action: {
|
||||
type: 'forward',
|
||||
target: { host: 'orders-service', port: 8003 },
|
||||
tls: { mode: 'terminate', certificate: 'auto' },
|
||||
security: {
|
||||
authentication: {
|
||||
type: 'basic',
|
||||
users: { 'admin': 'password' }
|
||||
}
|
||||
}
|
||||
},
|
||||
name: 'Orders Service (Protected)'
|
||||
}
|
||||
],
|
||||
acme: {
|
||||
enabled: true,
|
||||
email: 'admin@example.com'
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### 3. Multi-Environment Setup
|
||||
|
||||
```typescript
|
||||
const environments = {
|
||||
production: {
|
||||
target: { host: 'prod-backend', port: 8080 },
|
||||
security: { maxConnections: 1000 }
|
||||
},
|
||||
staging: {
|
||||
target: { host: 'staging-backend', port: 8080 },
|
||||
security: {
|
||||
allowedIps: ['10.0.0.*', '192.168.1.*'],
|
||||
maxConnections: 100
|
||||
}
|
||||
},
|
||||
development: {
|
||||
target: { host: 'localhost', port: 3000 },
|
||||
security: {
|
||||
allowedIps: ['127.0.0.1'],
|
||||
maxConnections: 10
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Select environment based on hostname
|
||||
const proxy = new SmartProxy({
|
||||
routes: [
|
||||
// Production environment
|
||||
{
|
||||
match: {
|
||||
ports: [80, 443],
|
||||
domains: ['app.example.com', 'www.example.com']
|
||||
},
|
||||
action: {
|
||||
type: 'forward',
|
||||
target: environments.production.target,
|
||||
tls: { mode: 'terminate', certificate: 'auto' },
|
||||
security: environments.production.security
|
||||
},
|
||||
name: 'Production Environment'
|
||||
},
|
||||
// Staging environment
|
||||
{
|
||||
match: {
|
||||
ports: [80, 443],
|
||||
domains: 'staging.example.com'
|
||||
},
|
||||
action: {
|
||||
type: 'forward',
|
||||
target: environments.staging.target,
|
||||
tls: { mode: 'terminate', certificate: 'auto' },
|
||||
security: environments.staging.security
|
||||
},
|
||||
name: 'Staging Environment'
|
||||
},
|
||||
// Development environment
|
||||
{
|
||||
match: {
|
||||
ports: [80, 443],
|
||||
domains: 'dev.example.com'
|
||||
},
|
||||
action: {
|
||||
type: 'forward',
|
||||
target: environments.development.target,
|
||||
tls: { mode: 'terminate', certificate: 'auto' },
|
||||
security: environments.development.security
|
||||
},
|
||||
name: 'Development Environment'
|
||||
}
|
||||
],
|
||||
acme: { enabled: true, email: 'admin@example.com' }
|
||||
});
|
||||
```
|
||||
|
||||
## Implementation Strategy
|
||||
|
||||
### Naming Pattern Rules
|
||||
### Code Organization
|
||||
|
||||
1. **Interfaces**:
|
||||
- All interfaces should be prefixed with "I"
|
||||
- Example: `DomainConfig` → `IDomainConfig`
|
||||
1. **New Files**:
|
||||
- `route-manager.ts` (core routing engine)
|
||||
- `route-types.ts` (interface definitions)
|
||||
- `route-helpers.ts` (helper functions)
|
||||
- `route-matcher.ts` (matching logic)
|
||||
- `template-engine.ts` (for variable substitution)
|
||||
|
||||
2. **Type Aliases**:
|
||||
- All type aliases should be prefixed with "T"
|
||||
- Example: `ForwardingType` → `TForwardingType`
|
||||
2. **Modified Files**:
|
||||
- `smart-proxy.ts` (update to use route-based configuration)
|
||||
- `connection-handler.ts` (simplify using route-based approach)
|
||||
- Replace `port-range-manager.ts` and `domain-config-manager.ts`
|
||||
|
||||
3. **Enums**:
|
||||
- Enums should be named in PascalCase without prefix
|
||||
- Example: `CertificateSource`
|
||||
### Backward Compatibility
|
||||
|
||||
4. **Backward Compatibility**:
|
||||
- No Backward compatibility. Remove old names.
|
||||
The backward compatibility layer will convert the legacy configuration to the new format:
|
||||
|
||||
### Module Implementation Order
|
||||
|
||||
1. Core module
|
||||
2. Certificate module
|
||||
3. Forwarding module
|
||||
4. Proxy implementations
|
||||
5. HTTP & TLS modules
|
||||
6. Main exports and entry points
|
||||
|
||||
### Testing Strategy
|
||||
|
||||
For each module:
|
||||
1. Rename interfaces and types
|
||||
2. Add backward compatibility aliases
|
||||
3. Update imports throughout the module
|
||||
4. Run tests to verify functionality
|
||||
5. Commit changes module by module
|
||||
|
||||
## File-Specific Changes
|
||||
|
||||
### Core Module Files
|
||||
- `ts/core/models/common-types.ts` - Primary interfaces
|
||||
- `ts/core/utils/validation-utils.ts` - Validation type definitions
|
||||
- `ts/core/utils/ip-utils.ts` - IP utility type definitions
|
||||
- `ts/core/utils/event-utils.ts` - Event type definitions
|
||||
|
||||
### Certificate Module Files
|
||||
- `ts/certificate/models/certificate-types.ts` - Certificate interfaces
|
||||
- `ts/certificate/acme/acme-factory.ts` - ACME factory types
|
||||
- `ts/certificate/providers/cert-provisioner.ts` - Provider interfaces
|
||||
- `ts/certificate/storage/file-storage.ts` - Storage interfaces
|
||||
|
||||
### Forwarding Module Files
|
||||
- `ts/forwarding/config/forwarding-types.ts` - Forwarding interfaces and types
|
||||
- `ts/forwarding/config/domain-config.ts` - Domain configuration
|
||||
- `ts/forwarding/factory/forwarding-factory.ts` - Factory interfaces
|
||||
- `ts/forwarding/handlers/*.ts` - Handler interfaces
|
||||
|
||||
### Proxy Module Files
|
||||
- `ts/proxies/network-proxy/models/types.ts` - NetworkProxy interfaces
|
||||
- `ts/proxies/smart-proxy/models/interfaces.ts` - SmartProxy interfaces
|
||||
- `ts/proxies/nftables-proxy/models/interfaces.ts` - NfTables interfaces
|
||||
- `ts/proxies/smart-proxy/connection-manager.ts` - Connection types
|
||||
|
||||
### HTTP/TLS Module Files
|
||||
- `ts/http/models/http-types.ts` - HTTP module interfaces
|
||||
- `ts/http/port80/acme-interfaces.ts` - ACME interfaces
|
||||
- `ts/tls/sni/client-hello-parser.ts` - TLS parser types
|
||||
- `ts/tls/alerts/tls-alert.ts` - TLS alert interfaces
|
||||
```typescript
|
||||
function convertLegacyConfig(legacy: ILegacySmartProxyOptions): ISmartProxyOptions {
|
||||
const routes: IRouteConfig[] = [];
|
||||
|
||||
// Convert main port configuration
|
||||
if (legacy.fromPort) {
|
||||
// Add main listener for fromPort
|
||||
routes.push({
|
||||
match: { ports: legacy.fromPort },
|
||||
action: {
|
||||
type: 'forward',
|
||||
target: { host: legacy.targetIP || 'localhost', port: legacy.toPort },
|
||||
tls: { mode: legacy.sniEnabled ? 'passthrough' : 'terminate' }
|
||||
},
|
||||
name: 'Main Listener (Legacy)'
|
||||
});
|
||||
|
||||
// If ACME is enabled, add HTTP listener for challenges
|
||||
if (legacy.acme?.enabled) {
|
||||
routes.push({
|
||||
match: { ports: 80 },
|
||||
action: {
|
||||
type: 'forward',
|
||||
target: { host: 'localhost', port: 80 },
|
||||
// Special flag for ACME handler
|
||||
acmeEnabled: true
|
||||
},
|
||||
name: 'ACME Challenge Handler (Legacy)'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Convert domain configs
|
||||
if (legacy.domainConfigs) {
|
||||
for (const domainConfig of legacy.domainConfigs) {
|
||||
const { domains, forwarding } = domainConfig;
|
||||
|
||||
// Determine action based on forwarding type
|
||||
let action: Partial<IRouteAction> = {
|
||||
type: 'forward',
|
||||
target: {
|
||||
host: forwarding.target.host,
|
||||
port: forwarding.target.port
|
||||
}
|
||||
};
|
||||
|
||||
// Set TLS mode based on forwarding type
|
||||
switch (forwarding.type) {
|
||||
case 'http-only':
|
||||
// No TLS
|
||||
break;
|
||||
case 'https-passthrough':
|
||||
action.tls = { mode: 'passthrough' };
|
||||
break;
|
||||
case 'https-terminate-to-http':
|
||||
action.tls = {
|
||||
mode: 'terminate',
|
||||
certificate: forwarding.https?.customCert || 'auto'
|
||||
};
|
||||
break;
|
||||
case 'https-terminate-to-https':
|
||||
action.tls = {
|
||||
mode: 'terminate-and-reencrypt',
|
||||
certificate: forwarding.https?.customCert || 'auto'
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
// Security settings
|
||||
if (forwarding.security) {
|
||||
action.security = forwarding.security;
|
||||
}
|
||||
|
||||
// Add HTTP redirect if needed
|
||||
if (forwarding.http?.redirectToHttps) {
|
||||
routes.push({
|
||||
match: { ports: 80, domains },
|
||||
action: {
|
||||
type: 'redirect',
|
||||
redirect: { to: 'https://{domain}{path}', status: 301 }
|
||||
},
|
||||
name: `HTTP Redirect for ${domains.join(', ')} (Legacy)`
|
||||
});
|
||||
}
|
||||
|
||||
// Add main route
|
||||
routes.push({
|
||||
match: {
|
||||
ports: forwarding.type.startsWith('https') ? 443 : 80,
|
||||
domains
|
||||
},
|
||||
action: action as IRouteAction,
|
||||
name: `Route for ${domains.join(', ')} (Legacy)`
|
||||
});
|
||||
|
||||
// Add port ranges if specified
|
||||
if (forwarding.advanced?.portRanges) {
|
||||
for (const range of forwarding.advanced.portRanges) {
|
||||
routes.push({
|
||||
match: {
|
||||
ports: { from: range.from, to: range.to },
|
||||
domains
|
||||
},
|
||||
action: action as IRouteAction,
|
||||
name: `Port Range ${range.from}-${range.to} for ${domains.join(', ')} (Legacy)`
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Global port ranges
|
||||
if (legacy.globalPortRanges) {
|
||||
for (const range of legacy.globalPortRanges) {
|
||||
routes.push({
|
||||
match: { ports: { from: range.from, to: range.to } },
|
||||
action: {
|
||||
type: 'forward',
|
||||
target: {
|
||||
host: legacy.targetIP || 'localhost',
|
||||
port: legacy.forwardAllGlobalRanges ? 0 : legacy.toPort,
|
||||
preservePort: !!legacy.forwardAllGlobalRanges
|
||||
},
|
||||
tls: { mode: 'passthrough' }
|
||||
},
|
||||
name: `Global Port Range ${range.from}-${range.to} (Legacy)`
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
routes,
|
||||
defaults: {
|
||||
target: {
|
||||
host: legacy.targetIP || 'localhost',
|
||||
port: legacy.toPort
|
||||
}
|
||||
},
|
||||
acme: legacy.acme
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Success Criteria
|
||||
|
||||
- All interfaces are prefixed with "I"
|
||||
- All type aliases are prefixed with "T"
|
||||
- All tests pass with new naming conventions
|
||||
- Documentation is updated with new naming conventions
|
||||
- Backward compatibility is maintained through type aliases
|
||||
- Declaration files correctly export both naming conventions
|
||||
- All existing functionality works with the new route-based configuration
|
||||
- Performance is equal or better than the current implementation
|
||||
- Configuration is more intuitive and easier to understand
|
||||
- New features can be added without breaking existing code
|
||||
- Code is more maintainable with clear separation of concerns
|
||||
- Migration from old configuration to new is straightforward
|
Loading…
x
Reference in New Issue
Block a user