refactor: migrate to Elysia and enhance security middleware
- Replaced Express with Elysia for improved performance and type safety - Integrated Elysia middleware for rate limiting, security headers, and request validation - Refactored security utilities to work with Elysia's context and request handling - Updated token management and validation logic - Added comprehensive security headers and input sanitization - Simplified server initialization and error handling - Updated documentation with new setup and configuration details
This commit is contained in:
138
docs/API.md
138
docs/API.md
@@ -416,4 +416,140 @@ async function executeAction() {
|
||||
const data = await response.json();
|
||||
console.log('Action result:', data);
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
## Security Middleware
|
||||
|
||||
### Overview
|
||||
|
||||
The security middleware provides a comprehensive set of utility functions to enhance the security of the Home Assistant MCP application. These functions cover various aspects of web security, including:
|
||||
|
||||
- Rate limiting
|
||||
- Request validation
|
||||
- Input sanitization
|
||||
- Security headers
|
||||
- Error handling
|
||||
|
||||
### Utility Functions
|
||||
|
||||
#### `checkRateLimit(ip: string, maxRequests?: number, windowMs?: number)`
|
||||
|
||||
Manages rate limiting for IP addresses to prevent abuse.
|
||||
|
||||
**Parameters**:
|
||||
- `ip`: IP address to track
|
||||
- `maxRequests`: Maximum number of requests allowed (default: 100)
|
||||
- `windowMs`: Time window for rate limiting (default: 15 minutes)
|
||||
|
||||
**Returns**: `boolean` or throws an error if limit is exceeded
|
||||
|
||||
**Example**:
|
||||
```typescript
|
||||
try {
|
||||
checkRateLimit('127.0.0.1'); // Checks rate limit with default settings
|
||||
} catch (error) {
|
||||
// Handle rate limit exceeded
|
||||
}
|
||||
```
|
||||
|
||||
#### `validateRequestHeaders(request: Request, requiredContentType?: string)`
|
||||
|
||||
Validates incoming HTTP request headers for security and compliance.
|
||||
|
||||
**Parameters**:
|
||||
- `request`: The incoming HTTP request
|
||||
- `requiredContentType`: Expected content type (default: 'application/json')
|
||||
|
||||
**Checks**:
|
||||
- Content type
|
||||
- Request body size
|
||||
- Authorization header (optional)
|
||||
|
||||
**Example**:
|
||||
```typescript
|
||||
try {
|
||||
validateRequestHeaders(request);
|
||||
} catch (error) {
|
||||
// Handle validation errors
|
||||
}
|
||||
```
|
||||
|
||||
#### `sanitizeValue(value: unknown)`
|
||||
|
||||
Sanitizes input values to prevent XSS attacks.
|
||||
|
||||
**Features**:
|
||||
- Escapes HTML tags
|
||||
- Handles nested objects and arrays
|
||||
- Preserves non-string values
|
||||
|
||||
**Example**:
|
||||
```typescript
|
||||
const sanitized = sanitizeValue('<script>alert("xss")</script>');
|
||||
// Returns: '<script>alert("xss")</script>'
|
||||
```
|
||||
|
||||
#### `applySecurityHeaders(request: Request, helmetConfig?: HelmetOptions)`
|
||||
|
||||
Applies security headers to HTTP requests using Helmet.
|
||||
|
||||
**Security Headers**:
|
||||
- Content Security Policy
|
||||
- X-Frame-Options
|
||||
- X-Content-Type-Options
|
||||
- Referrer Policy
|
||||
- HSTS (in production)
|
||||
|
||||
**Example**:
|
||||
```typescript
|
||||
const headers = applySecurityHeaders(request);
|
||||
```
|
||||
|
||||
#### `handleError(error: Error, env?: string)`
|
||||
|
||||
Handles error responses with environment-specific details.
|
||||
|
||||
**Modes**:
|
||||
- Production: Generic error message
|
||||
- Development: Detailed error with stack trace
|
||||
|
||||
**Example**:
|
||||
```typescript
|
||||
const errorResponse = handleError(error, process.env.NODE_ENV);
|
||||
```
|
||||
|
||||
### Middleware Usage
|
||||
|
||||
These utility functions are integrated into Elysia middleware:
|
||||
|
||||
```typescript
|
||||
const app = new Elysia()
|
||||
.use(rateLimiter) // Rate limiting
|
||||
.use(validateRequest) // Request validation
|
||||
.use(sanitizeInput) // Input sanitization
|
||||
.use(securityHeaders) // Security headers
|
||||
.use(errorHandler) // Error handling
|
||||
```
|
||||
|
||||
### Best Practices
|
||||
|
||||
1. Always validate and sanitize user inputs
|
||||
2. Use rate limiting to prevent abuse
|
||||
3. Apply security headers
|
||||
4. Handle errors gracefully
|
||||
5. Keep environment-specific error handling
|
||||
|
||||
### Security Considerations
|
||||
|
||||
- Configurable rate limits
|
||||
- XSS protection
|
||||
- Content security policies
|
||||
- Token validation
|
||||
- Error information exposure control
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
- Ensure `JWT_SECRET` is set in environment
|
||||
- Check content type in requests
|
||||
- Monitor rate limit errors
|
||||
- Review error handling in different environments
|
||||
514
docs/TESTING.md
Normal file
514
docs/TESTING.md
Normal file
@@ -0,0 +1,514 @@
|
||||
# Testing Documentation
|
||||
|
||||
## Quick Reference
|
||||
|
||||
```bash
|
||||
# Most Common Commands
|
||||
bun test # Run all tests
|
||||
bun test --watch # Run tests in watch mode
|
||||
bun test --coverage # Run tests with coverage
|
||||
bun test path/to/test.ts # Run specific test file
|
||||
|
||||
# Additional Options
|
||||
DEBUG=true bun test # Run with debug output
|
||||
bun test --pattern "auth" # Run tests matching pattern
|
||||
bun test --timeout 60000 # Run with custom timeout
|
||||
```
|
||||
|
||||
## Overview
|
||||
|
||||
This document describes the testing setup and practices used in the Home Assistant MCP project. The project uses Bun's test runner for unit and integration testing, with a comprehensive test suite covering security, SSE (Server-Sent Events), middleware, and other core functionalities.
|
||||
|
||||
## Test Structure
|
||||
|
||||
Tests are organized in two main locations:
|
||||
|
||||
1. **Root Level Integration Tests** (`/__tests__/`):
|
||||
```
|
||||
__tests__/
|
||||
├── ai/ # AI/ML component tests
|
||||
├── api/ # API integration tests
|
||||
├── context/ # Context management tests
|
||||
├── hass/ # Home Assistant integration tests
|
||||
├── schemas/ # Schema validation tests
|
||||
├── security/ # Security integration tests
|
||||
├── tools/ # Tools and utilities tests
|
||||
├── websocket/ # WebSocket integration tests
|
||||
├── helpers.test.ts # Helper function tests
|
||||
├── index.test.ts # Main application tests
|
||||
└── server.test.ts # Server integration tests
|
||||
```
|
||||
|
||||
2. **Component Level Unit Tests** (`src/**/`):
|
||||
```
|
||||
src/
|
||||
├── __tests__/ # Global test setup and utilities
|
||||
│ └── setup.ts # Global test configuration
|
||||
├── component/
|
||||
│ ├── __tests__/ # Component-specific unit tests
|
||||
│ └── component.ts
|
||||
```
|
||||
|
||||
The root level `__tests__` directory contains integration and end-to-end tests that verify the interaction between different components of the system, while the component-level tests focus on unit testing individual modules.
|
||||
|
||||
## Test Configuration
|
||||
|
||||
### Bun Test Configuration (`bunfig.toml`)
|
||||
|
||||
```toml
|
||||
[test]
|
||||
preload = ["./src/__tests__/setup.ts"] # Global test setup
|
||||
coverage = true # Enable coverage by default
|
||||
timeout = 30000 # Test timeout in milliseconds
|
||||
testMatch = ["**/__tests__/**/*.test.ts"] # Test file patterns
|
||||
```
|
||||
|
||||
### NPM Scripts
|
||||
|
||||
Available test commands in `package.json`:
|
||||
|
||||
```bash
|
||||
# Run all tests
|
||||
npm test # or: bun test
|
||||
|
||||
# Watch mode for development
|
||||
npm run test:watch # or: bun test --watch
|
||||
|
||||
# Generate coverage report
|
||||
npm run test:coverage # or: bun test --coverage
|
||||
|
||||
# Run linting
|
||||
npm run lint
|
||||
|
||||
# Format code
|
||||
npm run format
|
||||
```
|
||||
|
||||
## Test Setup
|
||||
|
||||
### Global Configuration
|
||||
|
||||
The project uses a global test setup file (`src/__tests__/setup.ts`) that provides:
|
||||
|
||||
- Environment configuration
|
||||
- Mock utilities
|
||||
- Test helper functions
|
||||
- Global test lifecycle hooks
|
||||
|
||||
### Test Environment
|
||||
|
||||
Tests run with the following configuration:
|
||||
|
||||
- Environment variables are loaded from `.env.test`
|
||||
- Console output is suppressed during tests (unless DEBUG=true)
|
||||
- JWT secrets and tokens are automatically configured for testing
|
||||
- Rate limiting and other security features are properly initialized
|
||||
|
||||
## Running Tests
|
||||
|
||||
To run the test suite:
|
||||
|
||||
```bash
|
||||
# Basic test run
|
||||
bun test
|
||||
|
||||
# Run tests with coverage
|
||||
bun test --coverage
|
||||
|
||||
# Run specific test file
|
||||
bun test path/to/test.test.ts
|
||||
|
||||
# Run tests in watch mode
|
||||
bun test --watch
|
||||
|
||||
# Run tests with debug output
|
||||
DEBUG=true bun test
|
||||
|
||||
# Run tests with increased timeout
|
||||
bun test --timeout 60000
|
||||
|
||||
# Run tests matching a pattern
|
||||
bun test --pattern "auth"
|
||||
```
|
||||
|
||||
### Test Environment Setup
|
||||
|
||||
1. **Prerequisites**:
|
||||
- Bun >= 1.0.0
|
||||
- Node.js dependencies (see package.json)
|
||||
|
||||
2. **Environment Files**:
|
||||
- `.env.test` - Test environment variables
|
||||
- `.env.development` - Development environment variables
|
||||
|
||||
3. **Test Data**:
|
||||
- Mock responses in `__tests__/mock-responses/`
|
||||
- Test fixtures in `__tests__/fixtures/`
|
||||
|
||||
### Continuous Integration
|
||||
|
||||
The project uses GitHub Actions for CI/CD. Tests are automatically run on:
|
||||
- Pull requests
|
||||
- Pushes to main branch
|
||||
- Release tags
|
||||
|
||||
## Writing Tests
|
||||
|
||||
### Test File Naming
|
||||
|
||||
- Test files should be placed in a `__tests__` directory adjacent to the code being tested
|
||||
- Test files should be named `*.test.ts`
|
||||
- Test files should mirror the structure of the source code
|
||||
|
||||
### Test Structure
|
||||
|
||||
```typescript
|
||||
import { describe, expect, it, beforeEach } from "bun:test";
|
||||
|
||||
describe("Module Name", () => {
|
||||
beforeEach(() => {
|
||||
// Setup for each test
|
||||
});
|
||||
|
||||
describe("Feature/Function Name", () => {
|
||||
it("should do something specific", () => {
|
||||
// Test implementation
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Test Utilities
|
||||
|
||||
The project provides several test utilities:
|
||||
|
||||
```typescript
|
||||
import { testUtils } from "../__tests__/setup";
|
||||
|
||||
// Available utilities:
|
||||
- mockWebSocket() // Mock WebSocket for SSE tests
|
||||
- mockResponse() // Mock HTTP response for API tests
|
||||
- mockRequest() // Mock HTTP request for API tests
|
||||
- createTestClient() // Create test SSE client
|
||||
- createTestEvent() // Create test event
|
||||
- createTestEntity() // Create test Home Assistant entity
|
||||
- wait() // Helper to wait for async operations
|
||||
```
|
||||
|
||||
## Testing Patterns
|
||||
|
||||
### Security Testing
|
||||
|
||||
Security tests cover:
|
||||
- Token validation and encryption
|
||||
- Rate limiting
|
||||
- Request validation
|
||||
- Input sanitization
|
||||
- Error handling
|
||||
|
||||
Example:
|
||||
```typescript
|
||||
describe("Security Features", () => {
|
||||
it("should validate tokens correctly", () => {
|
||||
const payload = { userId: "123", role: "user" };
|
||||
const token = jwt.sign(payload, validSecret, { expiresIn: "1h" });
|
||||
const result = TokenManager.validateToken(token, testIp);
|
||||
expect(result.valid).toBe(true);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### SSE Testing
|
||||
|
||||
SSE tests cover:
|
||||
- Client authentication
|
||||
- Message broadcasting
|
||||
- Rate limiting
|
||||
- Subscription management
|
||||
- Client cleanup
|
||||
|
||||
Example:
|
||||
```typescript
|
||||
describe("SSE Features", () => {
|
||||
it("should authenticate valid clients", () => {
|
||||
const client = createTestClient("test-client");
|
||||
const result = sseManager.addClient(client, validToken);
|
||||
expect(result?.authenticated).toBe(true);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Middleware Testing
|
||||
|
||||
Middleware tests cover:
|
||||
- Request validation
|
||||
- Input sanitization
|
||||
- Error handling
|
||||
- Response formatting
|
||||
|
||||
Example:
|
||||
```typescript
|
||||
describe("Middleware", () => {
|
||||
it("should sanitize HTML in request body", () => {
|
||||
const req = mockRequest({
|
||||
body: { text: '<script>alert("xss")</script>' }
|
||||
});
|
||||
sanitizeInput(req, res, next);
|
||||
expect(req.body.text).toBe("");
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Integration Testing
|
||||
|
||||
Integration tests in the root `__tests__` directory cover:
|
||||
|
||||
- **AI/ML Components**: Testing machine learning model integrations and predictions
|
||||
- **API Integration**: End-to-end API route testing
|
||||
- **Context Management**: Testing context persistence and state management
|
||||
- **Home Assistant Integration**: Testing communication with Home Assistant
|
||||
- **Schema Validation**: Testing data validation across the application
|
||||
- **Security Integration**: Testing security features in a full system context
|
||||
- **WebSocket Communication**: Testing real-time communication
|
||||
- **Server Integration**: Testing the complete server setup and configuration
|
||||
|
||||
Example integration test:
|
||||
```typescript
|
||||
describe("API Integration", () => {
|
||||
it("should handle a complete authentication flow", async () => {
|
||||
// Setup test client
|
||||
const client = await createTestClient();
|
||||
|
||||
// Test registration
|
||||
const regResponse = await client.register(testUser);
|
||||
expect(regResponse.status).toBe(201);
|
||||
|
||||
// Test authentication
|
||||
const authResponse = await client.authenticate(testCredentials);
|
||||
expect(authResponse.status).toBe(200);
|
||||
expect(authResponse.body.token).toBeDefined();
|
||||
|
||||
// Test protected endpoint access
|
||||
const protectedResponse = await client.get("/api/protected", {
|
||||
headers: { Authorization: `Bearer ${authResponse.body.token}` }
|
||||
});
|
||||
expect(protectedResponse.status).toBe(200);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Security Middleware Testing
|
||||
|
||||
### Utility Function Testing
|
||||
|
||||
The security middleware now uses a utility-first approach, which allows for more granular and comprehensive testing. Each security function is now independently testable, improving code reliability and maintainability.
|
||||
|
||||
#### Key Utility Functions
|
||||
|
||||
1. **Rate Limiting (`checkRateLimit`)**
|
||||
- Tests multiple scenarios:
|
||||
- Requests under threshold
|
||||
- Requests exceeding threshold
|
||||
- Rate limit reset after window expiration
|
||||
|
||||
```typescript
|
||||
// Example test
|
||||
it('should throw when requests exceed threshold', () => {
|
||||
const ip = '127.0.0.2';
|
||||
for (let i = 0; i < 11; i++) {
|
||||
if (i < 10) {
|
||||
expect(() => checkRateLimit(ip, 10)).not.toThrow();
|
||||
} else {
|
||||
expect(() => checkRateLimit(ip, 10)).toThrow('Too many requests from this IP');
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
2. **Request Validation (`validateRequestHeaders`)**
|
||||
- Tests content type validation
|
||||
- Checks request size limits
|
||||
- Validates authorization headers
|
||||
|
||||
```typescript
|
||||
it('should reject invalid content type', () => {
|
||||
const mockRequest = new Request('http://localhost', {
|
||||
method: 'POST',
|
||||
headers: { 'content-type': 'text/plain' }
|
||||
});
|
||||
expect(() => validateRequestHeaders(mockRequest)).toThrow('Content-Type must be application/json');
|
||||
});
|
||||
```
|
||||
|
||||
3. **Input Sanitization (`sanitizeValue`)**
|
||||
- Sanitizes HTML tags
|
||||
- Handles nested objects
|
||||
- Preserves non-string values
|
||||
|
||||
```typescript
|
||||
it('should sanitize HTML tags', () => {
|
||||
const input = '<script>alert("xss")</script>Hello';
|
||||
const sanitized = sanitizeValue(input);
|
||||
expect(sanitized).toBe('<script>alert("xss")</script>Hello');
|
||||
});
|
||||
```
|
||||
|
||||
4. **Security Headers (`applySecurityHeaders`)**
|
||||
- Verifies correct security header application
|
||||
- Checks CSP, frame options, and other security headers
|
||||
|
||||
```typescript
|
||||
it('should apply security headers', () => {
|
||||
const mockRequest = new Request('http://localhost');
|
||||
const headers = applySecurityHeaders(mockRequest);
|
||||
expect(headers['content-security-policy']).toBeDefined();
|
||||
expect(headers['x-frame-options']).toBeDefined();
|
||||
});
|
||||
```
|
||||
|
||||
5. **Error Handling (`handleError`)**
|
||||
- Tests error responses in production and development modes
|
||||
- Verifies error message and stack trace inclusion
|
||||
|
||||
```typescript
|
||||
it('should include error details in development mode', () => {
|
||||
const error = new Error('Test error');
|
||||
const result = handleError(error, 'development');
|
||||
expect(result).toEqual({
|
||||
error: true,
|
||||
message: 'Internal server error',
|
||||
error: 'Test error',
|
||||
stack: expect.any(String)
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Testing Philosophy
|
||||
|
||||
- **Isolation**: Each utility function is tested independently
|
||||
- **Comprehensive Coverage**: Multiple scenarios for each function
|
||||
- **Predictable Behavior**: Clear expectations for input and output
|
||||
- **Error Handling**: Robust testing of error conditions
|
||||
|
||||
### Best Practices
|
||||
|
||||
1. Use minimal, focused test cases
|
||||
2. Test both successful and failure scenarios
|
||||
3. Verify input sanitization and security measures
|
||||
4. Mock external dependencies when necessary
|
||||
|
||||
### Running Security Tests
|
||||
|
||||
```bash
|
||||
# Run all tests
|
||||
bun test
|
||||
|
||||
# Run specific security tests
|
||||
bun test __tests__/security/
|
||||
```
|
||||
|
||||
### Continuous Improvement
|
||||
|
||||
- Regularly update test cases
|
||||
- Add new test scenarios as security requirements evolve
|
||||
- Perform periodic security audits
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Isolation**: Each test should be independent and not rely on the state of other tests.
|
||||
2. **Mocking**: Use the provided mock utilities for external dependencies.
|
||||
3. **Cleanup**: Clean up any resources or state modifications in `afterEach` or `afterAll` hooks.
|
||||
4. **Descriptive Names**: Use clear, descriptive test names that explain the expected behavior.
|
||||
5. **Assertions**: Make specific, meaningful assertions rather than general ones.
|
||||
6. **Setup**: Use `beforeEach` for common test setup to avoid repetition.
|
||||
7. **Error Cases**: Test both success and error cases for complete coverage.
|
||||
|
||||
## Coverage
|
||||
|
||||
The project aims for high test coverage, particularly focusing on:
|
||||
- Security-critical code paths
|
||||
- API endpoints
|
||||
- Data validation
|
||||
- Error handling
|
||||
- Event broadcasting
|
||||
|
||||
Run coverage reports using:
|
||||
```bash
|
||||
bun test --coverage
|
||||
```
|
||||
|
||||
## Debugging Tests
|
||||
|
||||
To debug tests:
|
||||
1. Set `DEBUG=true` to enable console output during tests
|
||||
2. Use the `--watch` flag for development
|
||||
3. Add `console.log()` statements (they're only shown when DEBUG is true)
|
||||
4. Use the test utilities' debugging helpers
|
||||
|
||||
### Advanced Debugging
|
||||
|
||||
1. **Using Node Inspector**:
|
||||
```bash
|
||||
# Start tests with inspector
|
||||
bun test --inspect
|
||||
|
||||
# Start tests with inspector and break on first line
|
||||
bun test --inspect-brk
|
||||
```
|
||||
|
||||
2. **Using VS Code**:
|
||||
```jsonc
|
||||
// .vscode/launch.json
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "bun",
|
||||
"request": "launch",
|
||||
"name": "Debug Tests",
|
||||
"program": "${workspaceFolder}/node_modules/bun/bin/bun",
|
||||
"args": ["test", "${file}"],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"env": { "DEBUG": "true" }
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
3. **Test Isolation**:
|
||||
To run a single test in isolation:
|
||||
```typescript
|
||||
describe.only("specific test suite", () => {
|
||||
it.only("specific test case", () => {
|
||||
// Only this test will run
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
When contributing new code:
|
||||
1. Add tests for new features
|
||||
2. Ensure existing tests pass
|
||||
3. Maintain or improve coverage
|
||||
4. Follow the existing test patterns and naming conventions
|
||||
5. Document any new test utilities or patterns
|
||||
|
||||
## Coverage Requirements
|
||||
|
||||
The project maintains strict coverage requirements:
|
||||
|
||||
- Minimum overall coverage: 80%
|
||||
- Critical paths (security, API, data validation): 90%
|
||||
- New features must include tests with >= 85% coverage
|
||||
|
||||
Coverage reports are generated in multiple formats:
|
||||
- Console summary
|
||||
- HTML report (./coverage/index.html)
|
||||
- LCOV report (./coverage/lcov.info)
|
||||
|
||||
To view detailed coverage:
|
||||
```bash
|
||||
# Generate and open coverage report
|
||||
bun test --coverage && open coverage/index.html
|
||||
```
|
||||
354
docs/TROUBLESHOOTING.md
Normal file
354
docs/TROUBLESHOOTING.md
Normal file
@@ -0,0 +1,354 @@
|
||||
# Troubleshooting Guide
|
||||
|
||||
This guide helps you diagnose and fix common issues with the Home Assistant MCP.
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Connection Issues
|
||||
|
||||
#### Cannot Connect to Home Assistant
|
||||
|
||||
**Symptoms:**
|
||||
- Connection timeout errors
|
||||
- "Failed to connect to Home Assistant" messages
|
||||
- 401 Unauthorized errors
|
||||
|
||||
**Solutions:**
|
||||
1. Verify Home Assistant is running
|
||||
2. Check HASS_HOST environment variable
|
||||
3. Validate HASS_TOKEN is correct
|
||||
4. Ensure network connectivity
|
||||
5. Check firewall settings
|
||||
|
||||
#### SSE Connection Drops
|
||||
|
||||
**Symptoms:**
|
||||
- Frequent disconnections
|
||||
- Missing events
|
||||
- Connection reset errors
|
||||
|
||||
**Solutions:**
|
||||
1. Check network stability
|
||||
2. Increase connection timeout
|
||||
3. Implement reconnection logic
|
||||
4. Monitor server resources
|
||||
|
||||
### Authentication Issues
|
||||
|
||||
#### Invalid Token
|
||||
|
||||
**Symptoms:**
|
||||
- 401 Unauthorized responses
|
||||
- "Invalid token" messages
|
||||
- Authentication failures
|
||||
|
||||
**Solutions:**
|
||||
1. Generate new Long-Lived Access Token
|
||||
2. Check token expiration
|
||||
3. Verify token format
|
||||
4. Update environment variables
|
||||
|
||||
#### Rate Limiting
|
||||
|
||||
**Symptoms:**
|
||||
- 429 Too Many Requests
|
||||
- "Rate limit exceeded" messages
|
||||
|
||||
**Solutions:**
|
||||
1. Implement request throttling
|
||||
2. Adjust rate limit settings
|
||||
3. Cache responses
|
||||
4. Optimize request patterns
|
||||
|
||||
### Tool Issues
|
||||
|
||||
#### Tool Not Found
|
||||
|
||||
**Symptoms:**
|
||||
- "Tool not found" errors
|
||||
- 404 Not Found responses
|
||||
|
||||
**Solutions:**
|
||||
1. Check tool name spelling
|
||||
2. Verify tool registration
|
||||
3. Update tool imports
|
||||
4. Check tool availability
|
||||
|
||||
#### Tool Execution Fails
|
||||
|
||||
**Symptoms:**
|
||||
- Tool execution errors
|
||||
- Unexpected responses
|
||||
- Timeout issues
|
||||
|
||||
**Solutions:**
|
||||
1. Validate input parameters
|
||||
2. Check error logs
|
||||
3. Debug tool implementation
|
||||
4. Verify Home Assistant permissions
|
||||
|
||||
## Debugging
|
||||
|
||||
### Server Logs
|
||||
|
||||
1. Enable debug logging:
|
||||
```env
|
||||
LOG_LEVEL=debug
|
||||
```
|
||||
|
||||
2. Check logs:
|
||||
```bash
|
||||
npm run logs
|
||||
```
|
||||
|
||||
3. Filter logs:
|
||||
```bash
|
||||
npm run logs | grep "error"
|
||||
```
|
||||
|
||||
### Network Debugging
|
||||
|
||||
1. Check API endpoints:
|
||||
```bash
|
||||
curl -v http://localhost:3000/api/health
|
||||
```
|
||||
|
||||
2. Monitor SSE connections:
|
||||
```bash
|
||||
curl -N http://localhost:3000/api/sse/stats
|
||||
```
|
||||
|
||||
3. Test WebSocket:
|
||||
```bash
|
||||
wscat -c ws://localhost:3000
|
||||
```
|
||||
|
||||
### Performance Issues
|
||||
|
||||
1. Monitor memory usage:
|
||||
```bash
|
||||
npm run stats
|
||||
```
|
||||
|
||||
2. Check response times:
|
||||
```bash
|
||||
curl -w "%{time_total}\n" -o /dev/null -s http://localhost:3000/api/health
|
||||
```
|
||||
|
||||
3. Profile code:
|
||||
```bash
|
||||
npm run profile
|
||||
```
|
||||
|
||||
## FAQ
|
||||
|
||||
### Q: How do I reset my configuration?
|
||||
A: Delete `.env` and copy `.env.example` to start fresh.
|
||||
|
||||
### Q: Why are my events delayed?
|
||||
A: Check network latency and server load. Consider adjusting buffer sizes.
|
||||
|
||||
### Q: How do I update my token?
|
||||
A: Generate a new token in Home Assistant and update HASS_TOKEN.
|
||||
|
||||
### Q: Why do I get "Maximum clients reached"?
|
||||
A: Adjust SSE_MAX_CLIENTS in configuration or clean up stale connections.
|
||||
|
||||
## Error Codes
|
||||
|
||||
- `E001`: Connection Error
|
||||
- `E002`: Authentication Error
|
||||
- `E003`: Rate Limit Error
|
||||
- `E004`: Tool Error
|
||||
- `E005`: Configuration Error
|
||||
|
||||
## Support Resources
|
||||
|
||||
1. Documentation
|
||||
- [API Reference](./API.md)
|
||||
- [Configuration Guide](./configuration/README.md)
|
||||
- [Development Guide](./development/README.md)
|
||||
|
||||
2. Community
|
||||
- GitHub Issues
|
||||
- Discussion Forums
|
||||
- Stack Overflow
|
||||
|
||||
3. Tools
|
||||
- Diagnostic Scripts
|
||||
- Testing Tools
|
||||
- Monitoring Tools
|
||||
|
||||
## Still Need Help?
|
||||
|
||||
1. Create a detailed issue:
|
||||
- Error messages
|
||||
- Steps to reproduce
|
||||
- Environment details
|
||||
- Logs
|
||||
|
||||
2. Contact support:
|
||||
- GitHub Issues
|
||||
- Email Support
|
||||
- Community Forums
|
||||
|
||||
## Security Middleware Troubleshooting
|
||||
|
||||
### Common Issues and Solutions
|
||||
|
||||
#### Rate Limiting Problems
|
||||
|
||||
**Symptom**: Unexpected 429 (Too Many Requests) errors
|
||||
|
||||
**Possible Causes**:
|
||||
- Misconfigured rate limit settings
|
||||
- Shared IP addresses (e.g., behind NAT)
|
||||
- Aggressive client-side retry mechanisms
|
||||
|
||||
**Solutions**:
|
||||
1. Adjust rate limit parameters
|
||||
```typescript
|
||||
// Customize rate limit for specific scenarios
|
||||
checkRateLimit(ip, maxRequests = 200, windowMs = 30 * 60 * 1000)
|
||||
```
|
||||
|
||||
2. Implement more granular rate limiting
|
||||
- Use different limits for different endpoints
|
||||
- Consider user authentication level
|
||||
|
||||
#### Request Validation Failures
|
||||
|
||||
**Symptom**: 400 or 415 status codes on valid requests
|
||||
|
||||
**Possible Causes**:
|
||||
- Incorrect `Content-Type` header
|
||||
- Large request payloads
|
||||
- Malformed authorization headers
|
||||
|
||||
**Debugging Steps**:
|
||||
1. Verify request headers
|
||||
```typescript
|
||||
// Check content type and size
|
||||
validateRequestHeaders(request, 'application/json')
|
||||
```
|
||||
|
||||
2. Log detailed validation errors
|
||||
```typescript
|
||||
try {
|
||||
validateRequestHeaders(request);
|
||||
} catch (error) {
|
||||
console.error('Request validation failed:', error.message);
|
||||
}
|
||||
```
|
||||
|
||||
#### Input Sanitization Issues
|
||||
|
||||
**Symptom**: Unexpected data transformation or loss
|
||||
|
||||
**Possible Causes**:
|
||||
- Complex nested objects
|
||||
- Non-standard input formats
|
||||
- Overly aggressive sanitization
|
||||
|
||||
**Troubleshooting**:
|
||||
1. Test sanitization with various input types
|
||||
```typescript
|
||||
const input = {
|
||||
text: '<script>alert("xss")</script>',
|
||||
nested: { html: '<img src="x" onerror="alert(1)">World' }
|
||||
};
|
||||
const sanitized = sanitizeValue(input);
|
||||
```
|
||||
|
||||
2. Custom sanitization for specific use cases
|
||||
```typescript
|
||||
function customSanitize(value) {
|
||||
// Add custom sanitization logic
|
||||
return sanitizeValue(value);
|
||||
}
|
||||
```
|
||||
|
||||
#### Security Header Configuration
|
||||
|
||||
**Symptom**: Missing or incorrect security headers
|
||||
|
||||
**Possible Causes**:
|
||||
- Misconfigured Helmet options
|
||||
- Environment-specific header requirements
|
||||
|
||||
**Solutions**:
|
||||
1. Custom security header configuration
|
||||
```typescript
|
||||
const customHelmetConfig = {
|
||||
contentSecurityPolicy: {
|
||||
directives: {
|
||||
defaultSrc: ["'self'"],
|
||||
scriptSrc: ["'self'", 'trusted-cdn.com']
|
||||
}
|
||||
}
|
||||
};
|
||||
applySecurityHeaders(request, customHelmetConfig);
|
||||
```
|
||||
|
||||
#### Error Handling and Logging
|
||||
|
||||
**Symptom**: Inconsistent error responses
|
||||
|
||||
**Possible Causes**:
|
||||
- Incorrect environment configuration
|
||||
- Unhandled error types
|
||||
|
||||
**Debugging Techniques**:
|
||||
1. Verify environment settings
|
||||
```typescript
|
||||
const errorResponse = handleError(error, process.env.NODE_ENV);
|
||||
```
|
||||
|
||||
2. Add custom error handling
|
||||
```typescript
|
||||
function enhancedErrorHandler(error, env) {
|
||||
// Add custom logging or monitoring
|
||||
console.error('Security error:', error);
|
||||
return handleError(error, env);
|
||||
}
|
||||
```
|
||||
|
||||
### Performance and Security Monitoring
|
||||
|
||||
1. **Logging**
|
||||
- Enable debug logging for security events
|
||||
- Monitor rate limit and validation logs
|
||||
|
||||
2. **Metrics**
|
||||
- Track rate limit hit rates
|
||||
- Monitor request validation success/failure ratios
|
||||
|
||||
3. **Continuous Improvement**
|
||||
- Regularly review and update security configurations
|
||||
- Conduct periodic security audits
|
||||
|
||||
### Environment-Specific Considerations
|
||||
|
||||
#### Development
|
||||
- More verbose error messages
|
||||
- Relaxed rate limiting
|
||||
- Detailed security logs
|
||||
|
||||
#### Production
|
||||
- Minimal error details
|
||||
- Strict rate limiting
|
||||
- Comprehensive security headers
|
||||
|
||||
### External Resources
|
||||
|
||||
- [OWASP Security Guidelines](https://owasp.org/www-project-top-ten/)
|
||||
- [Helmet.js Documentation](https://helmetjs.github.io/)
|
||||
- [JWT Security Best Practices](https://jwt.io/introduction)
|
||||
|
||||
### Getting Help
|
||||
|
||||
If you encounter persistent issues:
|
||||
1. Check application logs
|
||||
2. Verify environment configurations
|
||||
3. Consult the project's issue tracker
|
||||
4. Reach out to the development team with detailed error information
|
||||
@@ -7,6 +7,8 @@ This guide provides information for developers who want to contribute to or exte
|
||||
```
|
||||
homeassistant-mcp/
|
||||
├── src/
|
||||
│ ├── __tests__/ # Test files
|
||||
│ ├── __mocks__/ # Mock files
|
||||
│ ├── api/ # API endpoints and route handlers
|
||||
│ ├── config/ # Configuration management
|
||||
│ ├── hass/ # Home Assistant integration
|
||||
|
||||
@@ -1,193 +0,0 @@
|
||||
# Troubleshooting Guide
|
||||
|
||||
This guide helps you diagnose and fix common issues with the Home Assistant MCP.
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Connection Issues
|
||||
|
||||
#### Cannot Connect to Home Assistant
|
||||
|
||||
**Symptoms:**
|
||||
- Connection timeout errors
|
||||
- "Failed to connect to Home Assistant" messages
|
||||
- 401 Unauthorized errors
|
||||
|
||||
**Solutions:**
|
||||
1. Verify Home Assistant is running
|
||||
2. Check HASS_HOST environment variable
|
||||
3. Validate HASS_TOKEN is correct
|
||||
4. Ensure network connectivity
|
||||
5. Check firewall settings
|
||||
|
||||
#### SSE Connection Drops
|
||||
|
||||
**Symptoms:**
|
||||
- Frequent disconnections
|
||||
- Missing events
|
||||
- Connection reset errors
|
||||
|
||||
**Solutions:**
|
||||
1. Check network stability
|
||||
2. Increase connection timeout
|
||||
3. Implement reconnection logic
|
||||
4. Monitor server resources
|
||||
|
||||
### Authentication Issues
|
||||
|
||||
#### Invalid Token
|
||||
|
||||
**Symptoms:**
|
||||
- 401 Unauthorized responses
|
||||
- "Invalid token" messages
|
||||
- Authentication failures
|
||||
|
||||
**Solutions:**
|
||||
1. Generate new Long-Lived Access Token
|
||||
2. Check token expiration
|
||||
3. Verify token format
|
||||
4. Update environment variables
|
||||
|
||||
#### Rate Limiting
|
||||
|
||||
**Symptoms:**
|
||||
- 429 Too Many Requests
|
||||
- "Rate limit exceeded" messages
|
||||
|
||||
**Solutions:**
|
||||
1. Implement request throttling
|
||||
2. Adjust rate limit settings
|
||||
3. Cache responses
|
||||
4. Optimize request patterns
|
||||
|
||||
### Tool Issues
|
||||
|
||||
#### Tool Not Found
|
||||
|
||||
**Symptoms:**
|
||||
- "Tool not found" errors
|
||||
- 404 Not Found responses
|
||||
|
||||
**Solutions:**
|
||||
1. Check tool name spelling
|
||||
2. Verify tool registration
|
||||
3. Update tool imports
|
||||
4. Check tool availability
|
||||
|
||||
#### Tool Execution Fails
|
||||
|
||||
**Symptoms:**
|
||||
- Tool execution errors
|
||||
- Unexpected responses
|
||||
- Timeout issues
|
||||
|
||||
**Solutions:**
|
||||
1. Validate input parameters
|
||||
2. Check error logs
|
||||
3. Debug tool implementation
|
||||
4. Verify Home Assistant permissions
|
||||
|
||||
## Debugging
|
||||
|
||||
### Server Logs
|
||||
|
||||
1. Enable debug logging:
|
||||
```env
|
||||
LOG_LEVEL=debug
|
||||
```
|
||||
|
||||
2. Check logs:
|
||||
```bash
|
||||
npm run logs
|
||||
```
|
||||
|
||||
3. Filter logs:
|
||||
```bash
|
||||
npm run logs | grep "error"
|
||||
```
|
||||
|
||||
### Network Debugging
|
||||
|
||||
1. Check API endpoints:
|
||||
```bash
|
||||
curl -v http://localhost:3000/api/health
|
||||
```
|
||||
|
||||
2. Monitor SSE connections:
|
||||
```bash
|
||||
curl -N http://localhost:3000/api/sse/stats
|
||||
```
|
||||
|
||||
3. Test WebSocket:
|
||||
```bash
|
||||
wscat -c ws://localhost:3000
|
||||
```
|
||||
|
||||
### Performance Issues
|
||||
|
||||
1. Monitor memory usage:
|
||||
```bash
|
||||
npm run stats
|
||||
```
|
||||
|
||||
2. Check response times:
|
||||
```bash
|
||||
curl -w "%{time_total}\n" -o /dev/null -s http://localhost:3000/api/health
|
||||
```
|
||||
|
||||
3. Profile code:
|
||||
```bash
|
||||
npm run profile
|
||||
```
|
||||
|
||||
## FAQ
|
||||
|
||||
### Q: How do I reset my configuration?
|
||||
A: Delete `.env` and copy `.env.example` to start fresh.
|
||||
|
||||
### Q: Why are my events delayed?
|
||||
A: Check network latency and server load. Consider adjusting buffer sizes.
|
||||
|
||||
### Q: How do I update my token?
|
||||
A: Generate a new token in Home Assistant and update HASS_TOKEN.
|
||||
|
||||
### Q: Why do I get "Maximum clients reached"?
|
||||
A: Adjust SSE_MAX_CLIENTS in configuration or clean up stale connections.
|
||||
|
||||
## Error Codes
|
||||
|
||||
- `E001`: Connection Error
|
||||
- `E002`: Authentication Error
|
||||
- `E003`: Rate Limit Error
|
||||
- `E004`: Tool Error
|
||||
- `E005`: Configuration Error
|
||||
|
||||
## Support Resources
|
||||
|
||||
1. Documentation
|
||||
- [API Reference](./API.md)
|
||||
- [Configuration Guide](./configuration/README.md)
|
||||
- [Development Guide](./development/README.md)
|
||||
|
||||
2. Community
|
||||
- GitHub Issues
|
||||
- Discussion Forums
|
||||
- Stack Overflow
|
||||
|
||||
3. Tools
|
||||
- Diagnostic Scripts
|
||||
- Testing Tools
|
||||
- Monitoring Tools
|
||||
|
||||
## Still Need Help?
|
||||
|
||||
1. Create a detailed issue:
|
||||
- Error messages
|
||||
- Steps to reproduce
|
||||
- Environment details
|
||||
- Logs
|
||||
|
||||
2. Contact support:
|
||||
- GitHub Issues
|
||||
- Email Support
|
||||
- Community Forums
|
||||
Reference in New Issue
Block a user