A robust Node.js Express API that provides antivirus scanning capabilities using ClamAV antivirus engine. This API allows you to upload files and scan them for viruses through a RESTful interface with comprehensive documentation.
- File Upload & Scanning - Upload files and scan them for viruses using ClamAV
- RESTful API - Clean, intuitive REST endpoints
- Interactive Documentation - Swagger/OpenAPI 3.0 documentation
- Comprehensive Testing - Full test suite with 95%+ coverage
- Error Handling - Robust error handling and validation
- File Cleanup - Automatic cleanup of uploaded files after scanning
- Cross-Platform - Works on Windows, macOS, and Linux
- Production Ready - Includes logging, validation, and security measures
- Open Source - Uses ClamAV, a free and open-source antivirus engine
- Docker Support - Complete Docker and Docker Compose setup
- Docker (version 20.10 or higher)
- Docker Compose (version 2.0 or higher)
# Clone the repository
git clone https://github.com/nicholasadamou/avscan-api.git
cd avscan-api
# Build and start the application
docker-compose up -d
# Access the API
curl http://localhost:3000/
# Start development environment with hot reloading
docker-compose -f docker-compose.dev.yml up -d
# View logs
docker-compose -f docker-compose.dev.yml logs -f
π For detailed Docker instructions, see DOCKER.md
- Node.js (v14.0.0 or higher)
- ClamAV antivirus engine installed on your system
- npm or yarn package manager
The API requires ClamAV to be installed. Here's how to install it on different platforms:
# Using Homebrew
brew install clamav
# Update virus definitions
freshclam
# Install ClamAV
sudo apt-get update
sudo apt-get install clamav clamav-daemon
# Update virus definitions
sudo freshclam
- Download ClamAV from https://www.clamav.net/downloads
- Install to
C:\Program Files\ClamAV\
- Update virus definitions using the GUI or command line
# Install ClamAV
sudo yum install clamav clamav-update
# Update virus definitions
sudo freshclam
-
Clone the repository
git clone https://github.com/nicholasadamou/avscan-api.git cd avscan-api
-
Install dependencies
pnpm install
-
Create uploads directory
mkdir uploads
-
Start the server
pnpm start
The API will be available at http://localhost:3000
Visit http://localhost:3000/api-docs
for interactive Swagger documentation where you can:
- View all available endpoints
- Test the API directly from your browser
- See request/response schemas
- Understand the API structure
Returns basic information about the API.
Response:
{
"name": "AV Scan API",
"version": "1.0.0",
"description": "A Node.js Express server that provides antivirus scanning capabilities using ClamAV",
"endpoints": {
"scan": "POST /scan - Scan uploaded file for viruses",
"docs": "GET /api-docs - API documentation"
},
"scanner": {
"name": "ClamAV",
"type": "Open Source Antivirus Engine"
}
}
Upload and scan a file for viruses using ClamAV.
Request:
- Content-Type:
multipart/form-data
- Body: File upload with field name
file
Response (Clean File):
{
"clean": true,
"rawOutput": "File is clean - no threats detected"
}
Response (Infected File):
{
"clean": false,
"rawOutput": "test.exe: Win.Trojan.Generic-12345 FOUND"
}
Error Response:
{
"error": "Scan failed",
"details": "ClamAV scanner not found or failed to execute"
}
const FormData = require('form-data');
const fs = require('fs');
const fetch = require('node-fetch');
async function scanFile(filePath) {
const form = new FormData();
form.append('file', fs.createReadStream(filePath));
const response = await fetch('http://localhost:3000/scan', {
method: 'POST',
body: form
});
const result = await response.json();
if (result.clean) {
console.log('β
File is clean!');
} else {
console.log('β File is infected!');
console.log('Threat detected:', result.rawOutput);
}
return result;
}
// Usage
scanFile('./suspicious-file.exe');
# Scan a file
curl -X POST \
-F "file=@/path/to/your/file.txt" \
http://localhost:3000/scan
# Get API information
curl http://localhost:3000/
import requests
def scan_file(file_path):
with open(file_path, 'rb') as file:
files = {'file': file}
response = requests.post('http://localhost:3000/scan', files=files)
result = response.json()
if result['clean']:
print("β
File is clean!")
else:
print("β File is infected!")
print(f"Threat: {result['rawOutput']}")
return result
# Usage
scan_file('./suspicious-file.exe')
The project includes a comprehensive test suite with 95%+ coverage.
# Run all tests
pnpm test
# Run tests with coverage
pnpm run test:coverage
# Run tests in watch mode
pnpm run test:watch
The test suite covers:
- β Route handlers and validation
- β File upload and scanning with ClamAV
- β Error handling and edge cases
- β Server configuration
- β Swagger documentation
- β Integration workflows
- β Performance and reliability
- β ClamAV-specific scenarios
avscan-api/
βββ server.js # Main server file
βββ routes.js # Route handlers with ClamAV integration
βββ config/
β βββ swagger.js # Swagger configuration
βββ tests/ # Test suite
β βββ setup.js # Test configuration
β βββ routes.test.js # Route tests
β βββ server.test.js # Server tests
β βββ swagger.test.js # Swagger tests
β βββ integration.test.js # Integration tests
β βββ README.md # Test documentation
βββ uploads/ # Temporary file uploads
βββ nginx/ # Nginx configuration
β βββ nginx.conf # Reverse proxy config
βββ package.json # Dependencies and scripts
βββ Dockerfile # Production Docker image
βββ Dockerfile.dev # Development Docker image
βββ docker-compose.yml # Production orchestration
βββ docker-compose.dev.yml # Development orchestration
βββ DOCKER.md # Docker documentation
βββ README.md # This file
You can configure the API using environment variables:
# Port (default: 3000)
PORT=3000
# ClamAV scanner path (auto-detected by default)
CLAMAV_PATH=/usr/local/bin/clamscan
# Upload directory (default: ./uploads)
UPLOAD_DIR=./uploads
The API automatically detects ClamAV installation paths, but you can customize it:
// In routes.js, modify the getScannerPath() function
function getScannerPath() {
// Custom path for your ClamAV installation
return '/custom/path/to/clamscan';
}
The API uses the following ClamAV options:
--no-summary
: Don't print summary--infected
: Only print infected files--suppress-ok-results
: Don't print OK results
You can modify these options in routes.js
if needed.
-
Set environment variables
export NODE_ENV=production export PORT=3000
-
Install dependencies
pnpm install --production
-
Start the server
pnpm start
# Production deployment
docker-compose up -d
# Development deployment
docker-compose -f docker-compose.dev.yml up -d
# With Nginx reverse proxy
docker-compose --profile production up -d
# Install PM2
npm install -g pm2
# Start the application
pm2 start server.js --name "avscan-api"
# Monitor the application
pm2 monit
- File Upload Limits: Configure appropriate file size limits
- File Type Validation: Consider adding file type validation
- Rate Limiting: Implement rate limiting for production use
- Authentication: Add authentication for production deployments
- HTTPS: Use HTTPS in production environments
- Input Validation: Validate all inputs and sanitize file names
- ClamAV Updates: Keep ClamAV virus definitions updated regularly
We welcome contributions! Please follow these steps:
- Fork the repository
- Create a feature branch
git checkout -b feature/amazing-feature
- Make your changes
- Add tests for new functionality
- Run the test suite
pnpm test
- Commit your changes
git commit -m 'Add amazing feature'
- Push to the branch
git push origin feature/amazing-feature
- Open a Pull Request
# Install development dependencies
pnpm install
# Start development server with auto-reload
pnpm run dev
# Run tests in watch mode
pnpm run test:watch
This project is licensed under the MIT License - see the LICENSE file for details.