4 Commits

Author SHA1 Message Date
2302632f11 1.3.2
Some checks failed
Default (tags) / security (push) Successful in 42s
Default (tags) / test (push) Failing after 2m25s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-08-16 20:37:59 +00:00
a8c36a64b7 fix(build): Bump dependencies, improve test/build scripts, expand documentation and add project metadata 2025-08-16 20:37:58 +00:00
a810338cc4 1.3.1
Some checks failed
Default (tags) / security (push) Successful in 51s
Default (tags) / test (push) Failing after 2m9s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-02-07 20:47:31 +01:00
c5049d5155 fix(core): Updated descriptions and keywords in package.json and npmextra.json. Improved README content for usage clarity. 2025-02-07 20:47:30 +01:00
14 changed files with 3451 additions and 2261 deletions

Binary file not shown.

View File

@@ -0,0 +1,35 @@
# Code Style and Conventions
## Naming Conventions
- **Interfaces**: Prefix with `I` (e.g., `IUserData`)
- **Types**: Prefix with `T` (e.g., `TResponseType`)
- **Files**: Always lowercase (e.g., `classes.clamavservice.ts`)
- **Classes**: PascalCase (e.g., `ClamAvService`)
- **Methods/Functions**: camelCase (e.g., `scanBuffer`)
- Avoid ENums when possible
## TypeScript Patterns
- TypeScript-first approach with full type safety
- ES modules (type: "module" in package.json)
- Import dependencies in `ts/plugins.ts`
- Reference with full path: `plugins.myModule.myClass()`
## File Organization
- Source code in `ts/` directory
- Tests in `test/` directory
- Distribution in `dist_ts/` directory
- Use `.js` extensions in imports for ES modules
## Testing Patterns
- Use @git.zone/tstest framework
- Import expect from @push.rocks/tapbundle
- Test files end with `export default tap.start()`
- Test naming: `*.both.ts`, `*.node.ts`, `*.browser.ts`
- EICAR test string for antivirus verification
## General Principles
- Make RAZOR SHARP changes - every modification must be goal-oriented
- Improve elegance - changes should enhance clarity and maintainability
- Preserve necessary complexity - don't oversimplify
- Keep async patterns - maintain Promises where they add value
- Remove redundancy carefully while preserving functionality

View File

@@ -0,0 +1,31 @@
# SmartAntivirus Project Overview
## Purpose
SmartAntivirus (@push.rocks/smartantivirus) is a Node.js/TypeScript library that provides enterprise-grade antivirus scanning capabilities by integrating with ClamAV. It allows developers to scan files, buffers, strings, and streams for viruses in their applications.
## Tech Stack
- TypeScript (primary language)
- Node.js (runtime)
- ClamAV (antivirus engine)
- Docker (for containerized ClamAV deployment)
- Testing: @git.zone/tstest with @push.rocks/tapbundle
- Build: @git.zone/tsbuild
## Architecture
- **ClamAvService**: High-level interface for virus scanning operations
- Scan strings, buffers, Node.js streams, and Web Streams
- Auto-manages Docker container if needed
- Connects to ClamAV daemon on port 3310
- **ClamAVManager**: Low-level Docker container management
- Handles container lifecycle (start/stop)
- Updates virus definitions
- Provides log monitoring
## Key Features
- In-memory scanning without disk I/O
- Stream processing for large files
- TypeScript-first with full type safety
- Zero-config with sensible defaults
- Auto-updating virus definitions
- Docker-based or direct daemon connection

View File

@@ -0,0 +1,31 @@
# Suggested Commands for SmartAntivirus Development
## Build & Test Commands
- `pnpm test` - Run test suite with tapbundle
- `pnpm build` - Build TypeScript to JavaScript (uses tsbuild)
- `pnpm run buildDocs` - Generate documentation (tsdoc)
## Development Tools
- `tsbuild check test/**/* --skiplibcheck` - Type-check test files
- `tsx test/test.ts` - Run individual test file directly
## Version Control
- `git mv <old> <new>` - Move/rename files preserving history
- `git status` - Check current changes
- `git diff` - View uncommitted changes
## Package Management
- `pnpm install` - Install dependencies
- `pnpm install --save-dev <package>` - Add dev dependency
- `pnpm add <package>` - Add production dependency
## File Operations
- `ls` - List directory contents
- `cat <file>` - View file contents
- `find . -name "*.ts"` - Find TypeScript files
- `rg <pattern>` - Search codebase with ripgrep
## Docker Management (if testing locally)
- `docker ps` - List running containers
- `docker logs clamav` - View ClamAV container logs
- `docker stop clamav` - Stop ClamAV container

View File

@@ -0,0 +1,44 @@
# Task Completion Workflow
## Required Steps After Making Code Changes
1. **Build the Project**
```bash
pnpm build
```
Ensures TypeScript compiles without errors
2. **Run Tests**
```bash
pnpm test
```
Verifies functionality with test suite
3. **Type Check Test Files** (if tests were modified)
```bash
tsbuild check test/**/* --skiplibcheck
```
## Quality Checks
- Verify no TypeScript compilation errors
- Ensure all tests pass
- Check that new code follows existing patterns
- Verify imports use `.js` extensions for ES modules
- Confirm no hardcoded values that should be configurable
## Documentation Updates
- Update readme.md if API changes
- Add JSDoc comments for new public methods
- Update changelog.md for version changes
## Before Committing
- NEVER commit without explicit user approval
- Use `git status` to review changes
- Use `git diff` to verify modifications
- Create focused commits with clear messages
- Never commit secrets or API keys
## Important Notes
- The project uses pnpm exclusively (not npm or yarn)
- Always read documentation before using unfamiliar APIs
- Check existing code patterns before implementing new features

68
.serena/project.yml Normal file
View File

@@ -0,0 +1,68 @@
# language of the project (csharp, python, rust, java, typescript, go, cpp, or ruby)
# * For C, use cpp
# * For JavaScript, use typescript
# Special requirements:
# * csharp: Requires the presence of a .sln file in the project folder.
language: typescript
# whether to use the project's gitignore file to ignore files
# Added on 2025-04-07
ignore_all_files_in_gitignore: true
# list of additional paths to ignore
# same syntax as gitignore, so you can use * and **
# Was previously called `ignored_dirs`, please update your config if you are using that.
# Added (renamed) on 2025-04-07
ignored_paths: []
# whether the project is in read-only mode
# If set to true, all editing tools will be disabled and attempts to use them will result in an error
# Added on 2025-04-18
read_only: false
# list of tool names to exclude. We recommend not excluding any tools, see the readme for more details.
# Below is the complete list of tools for convenience.
# To make sure you have the latest list of tools, and to view their descriptions,
# execute `uv run scripts/print_tool_overview.py`.
#
# * `activate_project`: Activates a project by name.
# * `check_onboarding_performed`: Checks whether project onboarding was already performed.
# * `create_text_file`: Creates/overwrites a file in the project directory.
# * `delete_lines`: Deletes a range of lines within a file.
# * `delete_memory`: Deletes a memory from Serena's project-specific memory store.
# * `execute_shell_command`: Executes a shell command.
# * `find_referencing_code_snippets`: Finds code snippets in which the symbol at the given location is referenced.
# * `find_referencing_symbols`: Finds symbols that reference the symbol at the given location (optionally filtered by type).
# * `find_symbol`: Performs a global (or local) search for symbols with/containing a given name/substring (optionally filtered by type).
# * `get_current_config`: Prints the current configuration of the agent, including the active and available projects, tools, contexts, and modes.
# * `get_symbols_overview`: Gets an overview of the top-level symbols defined in a given file.
# * `initial_instructions`: Gets the initial instructions for the current project.
# Should only be used in settings where the system prompt cannot be set,
# e.g. in clients you have no control over, like Claude Desktop.
# * `insert_after_symbol`: Inserts content after the end of the definition of a given symbol.
# * `insert_at_line`: Inserts content at a given line in a file.
# * `insert_before_symbol`: Inserts content before the beginning of the definition of a given symbol.
# * `list_dir`: Lists files and directories in the given directory (optionally with recursion).
# * `list_memories`: Lists memories in Serena's project-specific memory store.
# * `onboarding`: Performs onboarding (identifying the project structure and essential tasks, e.g. for testing or building).
# * `prepare_for_new_conversation`: Provides instructions for preparing for a new conversation (in order to continue with the necessary context).
# * `read_file`: Reads a file within the project directory.
# * `read_memory`: Reads the memory with the given name from Serena's project-specific memory store.
# * `remove_project`: Removes a project from the Serena configuration.
# * `replace_lines`: Replaces a range of lines within a file with new content.
# * `replace_symbol_body`: Replaces the full definition of a symbol.
# * `restart_language_server`: Restarts the language server, may be necessary when edits not through Serena happen.
# * `search_for_pattern`: Performs a search for a pattern in the project.
# * `summarize_changes`: Provides instructions for summarizing the changes made to the codebase.
# * `switch_modes`: Activates modes by providing a list of their names
# * `think_about_collected_information`: Thinking tool for pondering the completeness of collected information.
# * `think_about_task_adherence`: Thinking tool for determining whether the agent is still on track with the current task.
# * `think_about_whether_you_are_done`: Thinking tool for determining whether the task is truly completed.
# * `write_memory`: Writes a named memory (for future reference) to Serena's project-specific memory store.
excluded_tools: []
# initial prompt for the project. It will always be given to the LLM upon activating the project
# (contrary to the memories, which are loaded on demand).
initial_prompt: ""
project_name: "smartantivirus"

View File

@@ -1,5 +1,23 @@
# Changelog # Changelog
## 2025-08-16 - 1.3.2 - fix(build)
Bump dependencies, improve test/build scripts, expand documentation and add project metadata
- Updated devDependencies: bumped @git.zone/tsbuild, @git.zone/tsbundle, @git.zone/tstest, @push.rocks/tapbundle, @types/node and typescript to newer versions.
- Updated runtime dependencies: bumped @push.rocks/smartfile, @push.rocks/smartpath and axios; tar version updated.
- Adjusted npm scripts: test now runs with '(tstest test/ --web --verbose --logfile --timeout 120)'; build and docs scripts unchanged in behavior.
- Added packageManager entry (pnpm) and a pnpm-workspace.yaml with onlyBuiltDependencies configured.
- Expanded and rewrote README with detailed quick start, examples, API reference and troubleshooting guidance.
- Added local assistant/IDE metadata and memories (.claude/settings.local.json and .serena/*) to aid development tooling and project onboarding.
## 2025-02-07 - 1.3.1 - fix(core)
Updated descriptions and keywords in package.json and npmextra.json. Improved README content for usage clarity.
- Revised package.json description and keywords to better represent the project's features.
- Enhanced npmextra.json with updated module attributes.
- Improved README with clearer instructions and examples for using ClamAVManager and ClamAvService.
- Fixed incorrect import path in test.clamav.manager.ts.
## 2025-02-05 - 1.3.0 - feat(ClamAvService) ## 2025-02-05 - 1.3.0 - feat(ClamAvService)
Add support for enhanced streaming methods in ClamAvService Add support for enhanced streaming methods in ClamAvService

View File

@@ -5,21 +5,23 @@
"githost": "code.foss.global", "githost": "code.foss.global",
"gitscope": "push.rocks", "gitscope": "push.rocks",
"gitrepo": "smartantivirus", "gitrepo": "smartantivirus",
"description": "A Node.js package for integrating antivirus scanning capabilities using ClamAV, allowing in-memory file and data scanning.", "description": "A Node.js package providing integration with ClamAV for anti-virus scanning, facilitating both Docker containerized management and direct connection to a ClamAV daemon.",
"npmPackagename": "@push.rocks/smartantivirus", "npmPackagename": "@push.rocks/smartantivirus",
"license": "MIT", "license": "MIT",
"projectDomain": "push.rocks", "projectDomain": "push.rocks",
"keywords": [ "keywords": [
"antivirus", "antivirus",
"ClamAV",
"Node.js", "Node.js",
"ClamAV",
"virus scanning", "virus scanning",
"security", "security",
"buffer scanning", "Docker",
"in-memory scanning",
"file scanning",
"stream scanning",
"data protection", "data protection",
"HTTP requests", "network security",
"file handling", "buffer scanning",
"network communication",
"software testing" "software testing"
] ]
} }

View File

@@ -1,32 +1,32 @@
{ {
"name": "@push.rocks/smartantivirus", "name": "@push.rocks/smartantivirus",
"version": "1.3.0", "version": "1.3.2",
"private": false, "private": false,
"description": "A Node.js package for integrating antivirus scanning capabilities using ClamAV, allowing in-memory file and data scanning.", "description": "A Node.js package providing integration with ClamAV for anti-virus scanning, facilitating both Docker containerized management and direct connection to a ClamAV daemon.",
"main": "dist_ts/index.js", "main": "dist_ts/index.js",
"typings": "dist_ts/index.d.ts", "typings": "dist_ts/index.d.ts",
"type": "module", "type": "module",
"author": "Task Venture Capital GmbH", "author": "Task Venture Capital GmbH",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
"test": "(tstest test/ --web)", "test": "(tstest test/ --web --verbose --logfile --timeout 120)",
"build": "(tsbuild --web --allowimplicitany)", "build": "(tsbuild --web --allowimplicitany)",
"buildDocs": "(tsdoc)" "buildDocs": "(tsdoc)"
}, },
"devDependencies": { "devDependencies": {
"@git.zone/tsbuild": "^2.1.25", "@git.zone/tsbuild": "^2.6.4",
"@git.zone/tsbundle": "^2.0.5", "@git.zone/tsbundle": "^2.5.1",
"@git.zone/tsrun": "^1.2.46", "@git.zone/tsrun": "^1.2.46",
"@git.zone/tstest": "^1.0.44", "@git.zone/tstest": "^2.3.4",
"@push.rocks/tapbundle": "^5.0.15", "@push.rocks/tapbundle": "^6.0.3",
"@types/node": "^20.8.7", "@types/node": "^24.3.0",
"typescript": "^5.7.3" "typescript": "^5.9.2"
}, },
"dependencies": { "dependencies": {
"@push.rocks/smartfile": "^11.1.5", "@push.rocks/smartfile": "^11.2.5",
"@push.rocks/smartpath": "^5.0.18", "@push.rocks/smartpath": "^6.0.0",
"@push.rocks/smartstream": "^3.2.5", "@push.rocks/smartstream": "^3.2.5",
"axios": "^1.7.9", "axios": "^1.11.0",
"tar": "^7.4.3" "tar": "^7.4.3"
}, },
"repository": { "repository": {
@@ -51,15 +51,18 @@
], ],
"keywords": [ "keywords": [
"antivirus", "antivirus",
"ClamAV",
"Node.js", "Node.js",
"ClamAV",
"virus scanning", "virus scanning",
"security", "security",
"buffer scanning", "Docker",
"in-memory scanning",
"file scanning",
"stream scanning",
"data protection", "data protection",
"HTTP requests", "network security",
"file handling", "buffer scanning",
"network communication",
"software testing" "software testing"
] ],
"packageManager": "pnpm@10.14.0+sha512.ad27a79641b49c3e481a16a805baa71817a04bbe06a38d17e60e2eaee83f6a146c6a688125f5792e48dd5ba30e7da52a5cda4c3992b9ccf333f9ce223af84748"
} }

4997
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

4
pnpm-workspace.yaml Normal file
View File

@@ -0,0 +1,4 @@
onlyBuiltDependencies:
- esbuild
- mongodb-memory-server
- puppeteer

425
readme.md
View File

@@ -1,263 +1,306 @@
# @push.rocks/smartantivirus # @push.rocks/smartantivirus 🛡️
A package for performing antivirus testing with ClamAV, featuring both direct daemon communication and Docker container management. **Enterprise-grade antivirus scanning for Node.js applications** - Seamlessly integrate ClamAV's powerful virus detection into your TypeScript/JavaScript projects with zero hassle.
## Features ## Why SmartAntivirus? 🚀
- **Docker Integration**: Automatically manages ClamAV containers for easy setup and testing In today's digital landscape, security is paramount. Whether you're building a file-sharing platform, processing user uploads, or handling sensitive data streams, you need reliable virus protection that just works. SmartAntivirus gives you:
- **Real-time Logging**: Captures and processes ClamAV logs with type-safe event handling
- **Database Management**: Supports automatic database updates and version tracking - **🐳 Docker-based or Direct Connection** - Choose your deployment style
- **Flexible Scanning**: Scan strings, buffers, and files for malware - **⚡ In-memory Scanning** - Lightning-fast scanning without disk I/O
- **Health Monitoring**: Built-in service readiness checks and connection verification - **🌊 Stream Processing** - Scan data on-the-fly as it flows through your app
- **🎯 TypeScript First** - Full type safety and IntelliSense support
- **📦 Zero Config** - Works out of the box with sensible defaults
- **🔄 Auto-updating** - Virus definitions stay current automatically
## Install ## Install
Installing `@push.rocks/smartantivirus` is straightforward. You'll need Node.js and npm installed on your machine:
```bash ```bash
npm install @push.rocks/smartantivirus npm install @push.rocks/smartantivirus
``` ```
### Prerequisites Or if you're using pnpm (recommended):
- Node.js and npm ```bash
- Docker (for container-based usage) pnpm add @push.rocks/smartantivirus
- ClamAV daemon (for direct daemon usage)
## Usage
The package provides two main ways to use ClamAV:
1. **Docker-based Usage** (Recommended): Uses `ClamAVManager` to automatically handle container lifecycle
2. **Direct Daemon Usage**: Uses `ClamAvService` to communicate with an existing ClamAV daemon
Below is a comprehensive guide on how to use both approaches.
### Docker-based Usage with ClamAVManager
The `ClamAVManager` class provides a high-level interface for managing ClamAV in Docker containers:
```typescript
import { ClamAVManager } from '@push.rocks/smartantivirus';
async function main() {
// Create a new manager instance
const manager = new ClamAVManager();
// Start the ClamAV container
await manager.startContainer();
// Listen for log events
manager.on('log', (event) => {
console.log(`[ClamAV ${event.type}] ${event.message}`);
});
// Get database information
const dbInfo = await manager.getDatabaseInfo();
console.log('Database Info:', dbInfo);
// Update virus definitions
await manager.updateDatabase();
// When done, stop the container
await manager.stopContainer();
}
main().catch(console.error);
``` ```
### Direct Daemon Usage with ClamAvService ## Quick Start 🏃‍♂️
The primary interface provided by the package is the `ClamAvService` class. It allows you to scan data in memory or verify the connection to the ClamAV daemon. ### The 5-Minute Setup
```typescript ```typescript
import { ClamAvService } from '@push.rocks/smartantivirus'; import { ClamAvService } from '@push.rocks/smartantivirus';
async function main() { // That's it! The service automatically manages a Docker container
const clamService = new ClamAvService('127.0.0.1', 3310); // Replace with your ClamAV host and port const scanner = new ClamAvService();
// Verify connection to ClamAV // Scan a suspicious string
const isConnected = await clamService.verifyConnection(); const result = await scanner.scanString('Is this text safe?');
console.log(`Connection to ClamAV: ${isConnected ? 'successful' : 'failed'}`); console.log(result.isInfected ? '⚠️ Threat detected!' : '✅ All clear!');
if (!isConnected) { // Scan a buffer
console.error('Could not connect to ClamAV daemon. Please check your configuration.'); const fileBuffer = await fs.readFile('./upload.pdf');
return; const scanResult = await scanner.scanBuffer(fileBuffer);
}
// Scan a text string
const testString = 'X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*';
const scanResult = await clamService.scanString(testString);
console.log('Scan Result:', scanResult);
}
main().catch(console.error);
``` ```
### Streaming Scanning ## Core Concepts 💡
The `ClamAvService` supports scanning both NodeJS streams and Web API streams using three specialized methods: SmartAntivirus provides two main classes:
- `scanStream(stream: NodeJS.ReadableStream)`: Scans any NodeJS readable stream (files, network, etc.) ### 🎯 ClamAvService
- `scanWebStream(webstream: ReadableStream)`: Scans a Web API ReadableStream The high-level interface for virus scanning. It handles all the complexity behind a simple, intuitive API.
- `scanFileFromWebAsStream(url: string)`: Fetches and scans a file from a URL using NodeJS http/https
#### Example Usage ### 🐳 ClamAVManager
Low-level Docker container management for advanced use cases. Most users won't need to interact with this directly.
## Real-World Examples 🌍
### Protecting File Uploads
```typescript
import { ClamAvService } from '@push.rocks/smartantivirus';
import express from 'express';
import multer from 'multer';
const app = express();
const scanner = new ClamAvService();
const upload = multer({ storage: multer.memoryStorage() });
app.post('/upload', upload.single('file'), async (req, res) => {
try {
// Scan the uploaded file buffer
const result = await scanner.scanBuffer(req.file.buffer);
if (result.isInfected) {
return res.status(400).json({
error: 'File rejected',
threat: result.reason
});
}
// File is safe, proceed with storage
await saveFile(req.file);
res.json({ message: 'File uploaded successfully' });
} catch (error) {
res.status(500).json({ error: 'Scan failed' });
}
});
```
### Streaming Large Files
Never load huge files into memory! Stream them instead:
```typescript ```typescript
import { ClamAvService } from '@push.rocks/smartantivirus'; import { ClamAvService } from '@push.rocks/smartantivirus';
import { createReadStream } from 'fs'; import { createReadStream } from 'fs';
async function main() { const scanner = new ClamAvService();
const clamService = new ClamAvService('127.0.0.1', 3310);
// Example 1: Scanning a local file stream (NodeJS) async function scanLargeFile(filePath: string) {
const fileStream = createReadStream('path/to/local/file'); const stream = createReadStream(filePath);
const streamResult = await clamService.scanStream(fileStream); const result = await scanner.scanStream(stream);
console.log('Stream Scan Result:', streamResult);
if (result.isInfected) {
// Example 2: Scanning a web resource using NodeJS http/https console.log(`🚨 Threat found: ${result.reason}`);
const webResult = await clamService.scanFileFromWebAsStream('http://example.com/file'); // Quarantine or delete the file
console.log('Web Stream Scan Result:', webResult); } else {
console.log('✅ File is clean');
// Example 3: Scanning a Web API ReadableStream
const response = await fetch('http://example.com/file');
if (response.body) {
const webStreamResult = await clamService.scanWebStream(response.body);
console.log('Web Stream API Scan Result:', webStreamResult);
} }
} }
main().catch(console.error);
``` ```
**Breaking Down the Example:** ### Scanning Remote Content
1. **Initialization**: We start by creating an instance of the `ClamAvService` class. It takes two optional parameters: the host and port where your ClamAV daemon is running. By default, it assumes `127.0.0.1` and `3310`. Perfect for proxies, CDNs, or content moderation:
2. **Verify Connection**: The `verifyConnection` method is called to ensure that our application can communicate with the ClamAV daemon. It returns a promise that resolves to `true` if the connection is successful, and `false` otherwise. ```typescript
const scanner = new ClamAvService();
3. **Scan Strings**: We utilize the `scanString` method to scan a text string (in this example, the EICAR test virus string is used). This method converts the string to a buffer and sends it to the ClamAV daemon for scanning. // Scan a file from a URL
const result = await scanner.scanFileFromWebAsStream('https://example.com/document.pdf');
### Handling Buffers // For browser environments using Web Streams API
async function scanInBrowser(url: string) {
const response = await fetch(url);
const webStream = response.body as ReadableStream<Uint8Array>;
if (webStream) {
const result = await scanner.scanWebStream(webStream);
return result;
}
}
```
Below is an example demonstrating scanning raw binary data in the form of buffers: ### Advanced Container Management
For production environments requiring fine-grained control:
```typescript
import { ClamAVManager } from '@push.rocks/smartantivirus';
class AntivirusService {
private manager: ClamAVManager;
async initialize() {
this.manager = new ClamAVManager();
// Start the container
await this.manager.startContainer();
// Set up log monitoring
this.manager.on('log', (event) => {
if (event.type === 'error') {
console.error(`ClamAV Error: ${event.message}`);
// Send to your logging service
}
});
// Update virus definitions
await this.manager.updateDatabase();
// Get database info
const dbInfo = await this.manager.getDatabaseInfo();
console.log(`Virus DB Version: ${dbInfo}`);
}
async shutdown() {
await this.manager.stopContainer();
}
}
```
## Testing 🧪
We use the industry-standard EICAR test string for verification:
```typescript ```typescript
import { ClamAvService } from '@push.rocks/smartantivirus'; import { ClamAvService } from '@push.rocks/smartantivirus';
async function scanBufferExample() { const scanner = new ClamAvService();
const clamService = new ClamAvService();
// This buffer should represent the binary data you want to scan. // This is the EICAR test string - it's harmless but triggers antivirus
const buffer = Buffer.from('Sample buffer contents', 'utf8'); const EICAR = 'X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*';
try { const result = await scanner.scanString(EICAR);
const scanResult = await clamService.scanBuffer(buffer); console.log(result.isInfected); // true
console.log('Buffer Scan Result:', scanResult); console.log(result.reason); // 'Eicar-Test-Signature'
} catch (error) {
console.error('Error scanning buffer:', error);
}
}
scanBufferExample();
``` ```
**Explanation:** Run the test suite:
- We create an instance of `ClamAvService`.
- A buffer is created and passed to the `scanBuffer` method, which scans the in-memory data for potential viruses.
### Error Handling and Debugging
Both `ClamAVManager` and `ClamAvService` provide comprehensive error handling:
```typescript
try {
// Using ClamAVManager
const manager = new ClamAVManager();
await manager.startContainer();
// Listen for errors in logs
manager.on('log', (event) => {
if (event.type === 'error') {
console.error(`ClamAV Error: ${event.message}`);
}
});
// Using ClamAvService
const service = new ClamAvService();
const scanResult = await service.scanString('Some suspicious string...');
console.log(`Infection Status: ${scanResult.isInfected ? 'Infected' : 'Clean'}`);
if (scanResult.isInfected) {
console.log(`Reason: ${scanResult.reason}`);
}
} catch (error) {
console.error('An error occurred during the scanning process:', error);
}
```
### Testing your setup
A preconfigured test script is provided, which demonstrates how to use the package with the Tap bundle testing framework. You can find the test script in `test/test.ts`. This is configured to run with the default `@push.rocks/tapbundle` setup:
```bash ```bash
npm run test npm test
``` ```
The tests include creating and utilizing a `ClamAvService` instance and attempts to scan the well-known EICAR test string. They ensure that the basic functionality of the package is working as intended. ## API Reference 📚
### Advanced Usage and Integration ### ClamAvService
#### Container Configuration
The `ClamAVManager` supports customizing the Docker container:
#### Constructor
```typescript ```typescript
const manager = new ClamAVManager(); new ClamAvService(host?: string, port?: number)
// Container properties are configurable
console.log(manager.containerName); // 'clamav-daemon'
console.log(manager.port); // 3310
``` ```
- `host` - ClamAV daemon host (default: '127.0.0.1')
- `port` - ClamAV daemon port (default: 3310)
#### Log Management #### Methods
Access and process ClamAV logs: ##### `scanString(text: string): Promise<ScanResult>`
Scan a text string for threats.
##### `scanBuffer(buffer: Buffer): Promise<ScanResult>`
Scan binary data in a Buffer.
##### `scanStream(stream: NodeJS.ReadableStream): Promise<ScanResult>`
Scan a Node.js readable stream.
##### `scanWebStream(stream: ReadableStream<Uint8Array>): Promise<ScanResult>`
Scan a Web Streams API stream (browser-compatible).
##### `scanFileFromWebAsStream(url: string): Promise<ScanResult>`
Download and scan a file from a URL.
##### `verifyConnection(): Promise<boolean>`
Test the connection to ClamAV daemon.
#### ScanResult Type
```typescript ```typescript
const manager = new ClamAVManager(); interface ScanResult {
isInfected: boolean;
// Get all logs reason?: string; // Threat name if infected
const logs = manager.getLogs(); }
// Filter logs by type
const errorLogs = logs.filter(log => log.type === 'error');
const updateLogs = logs.filter(log => log.type === 'update');
``` ```
#### Health Checks ### ClamAVManager
Monitor ClamAV service health: Advanced container management for production deployments:
```typescript - `startContainer()` - Launch ClamAV in Docker
const manager = new ClamAVManager(); - `stopContainer()` - Gracefully shutdown
- `updateDatabase()` - Update virus definitions
- `getDatabaseInfo()` - Get current DB version
- `getLogs()` - Retrieve container logs
- Event: `'log'` - Real-time log streaming
// Service automatically checks readiness during initialization ## Production Considerations 🏭
await manager.startContainer(); // Includes readiness checks
// Get database status ### Performance Tips
const dbInfo = await manager.getDatabaseInfo();
console.log('Database Version:', dbInfo); 1. **Reuse connections** - Create one `ClamAvService` instance and reuse it
2. **Stream large files** - Don't load them into memory
3. **Implement timeouts** - Protect against hanging scans
4. **Monitor logs** - Watch for database update failures
### Security Best Practices
- Run ClamAV container with limited resources
- Implement rate limiting on scan endpoints
- Log all detected threats for audit trails
- Regularly update virus definitions
- Use separate containers for different environments
### Deployment Options
#### Docker Compose
```yaml
services:
clamav:
image: clamav/clamav:latest
ports:
- "3310:3310"
volumes:
- clamav-db:/var/lib/clamav
``` ```
You can build upon these functionalities to implement advanced use cases such as: #### Kubernetes
- Automated virus scanning in CI/CD pipelines The service automatically manages containers, but you can also deploy ClamAV separately and connect directly to the daemon.
- Real-time file monitoring in web applications
- Cloud-based malware detection services
- Integration with security information and event management (SIEM) systems
With the help of Node.js worker threads or external task queues like RabbitMQ, you can distribute scanning tasks efficiently within high-traffic environments. ## Troubleshooting 🔧
### Common Issues
**Container won't start**
- Ensure Docker is running
- Check port 3310 isn't already in use
- Verify sufficient disk space for virus definitions
**Scans timing out**
- Large files may take time - implement appropriate timeouts
- Check container resources (CPU/Memory)
- Ensure virus database is not updating
**False positives**
- Some packers/obfuscators trigger detection
- Whitelist known-safe patterns if needed
- Keep virus definitions updated
## Contributing & Support 🤝
- 🐛 [Report Issues](https://code.foss.global/push.rocks/smartantivirus/issues)
- 📖 [Documentation](https://code.foss.global/push.rocks/smartantivirus)
- 💬 [Discussions](https://code.foss.global/push.rocks/smartantivirus/issues)
## License and Legal Information ## License and Legal Information

View File

@@ -1,4 +1,4 @@
import { expect, tap } from '../ts/plugins.js'; import { expect, tap } from '@push.rocks/tapbundle';
import type { ClamAVLogEvent } from '../ts/classes.clamav.manager.js'; import type { ClamAVLogEvent } from '../ts/classes.clamav.manager.js';
import { setupClamAV, cleanupClamAV, getManager } from './helpers/clamav.helper.js'; import { setupClamAV, cleanupClamAV, getManager } from './helpers/clamav.helper.js';

View File

@@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@push.rocks/smartantivirus', name: '@push.rocks/smartantivirus',
version: '1.3.0', version: '1.3.2',
description: 'A Node.js package for integrating antivirus scanning capabilities using ClamAV, allowing in-memory file and data scanning.' description: 'A Node.js package providing integration with ClamAV for anti-virus scanning, facilitating both Docker containerized management and direct connection to a ClamAV daemon.'
} }