@bernierllc/webhook-manager-core
v1.2.2
Published
Generic webhook registration, validation, and management primitives
Downloads
120
Readme
@bernierllc/webhook-manager-core
Generic webhook registration, validation, and management primitives
Core-layer package providing atomic utilities for webhook registration, event matching, signature validation infrastructure, and replay attack prevention. Pure functions with zero dependencies on specific webhook providers.
Installation
npm install @bernierllc/webhook-manager-coreFeatures
- Webhook Endpoint Registration - Register and manage webhook endpoints with CRUD operations
- HMAC Signature Validation - Generate and validate HMAC signatures (SHA1/256/512)
- Constant-Time Comparison - Prevent timing attacks with constant-time signature comparison
- Replay Attack Prevention - Detect and prevent replay attacks with configurable windows
- Event Deduplication - Prevent duplicate event processing with time-based caching
- Event Matching & Filtering - Match events to endpoints with flexible filter operators
- JSON Path Resolution - Support for complex nested payload filtering
- Zero Provider Dependencies - Generic core primitives, no provider-specific logic
Usage
Basic Webhook Management
import { WebhookManager } from '@bernierllc/webhook-manager-core';
// Initialize manager
const manager = new WebhookManager({
replayWindowMs: 300000, // 5 minutes
enableDeduplication: true,
deduplicationWindowMs: 60000, // 1 minute
defaultAlgorithm: 'sha256',
});
// Register an endpoint
const result = manager.registerEndpoint({
id: 'endpoint-1',
name: 'Production Webhook',
url: 'https://api.example.com/webhooks',
secret: 'webhook-secret-key',
events: ['push', 'pull_request'],
active: true,
createdAt: new Date(),
updatedAt: new Date(),
});
// Get endpoint
const endpoint = manager.getEndpoint('endpoint-1');
// List all active endpoints
const activeEndpoints = manager.listEndpoints({ active: true });
// Update endpoint
manager.updateEndpoint('endpoint-1', { active: false });
// Remove endpoint
manager.unregisterEndpoint('endpoint-1');Signature Validation
// Generate HMAC signature
const payload = JSON.stringify({ event: 'push', data: {...} });
const signature = manager.generateSignature(payload, 'secret-key', 'sha256');
// Returns: 'sha256=a1b2c3d4...'
// Validate incoming signature
const validation = manager.validateSignature(
payload,
receivedSignature,
'secret-key',
'sha256'
);
if (validation.valid) {
// Process webhook
console.log('Signature valid!');
} else {
// Reject webhook
console.error('Invalid signature:', validation.error);
}
// Constant-time comparison (prevents timing attacks)
const match = manager.compareSignatures(signature1, signature2);Replay Attack Prevention
const event = {
id: 'evt-123',
type: 'push',
source: 'github',
payload: {...},
timestamp: new Date(),
};
// Check for replay attack
const replayCheck = manager.checkReplayAttack(event);
if (replayCheck.isReplay) {
throw new Error(`Replay attack detected: ${replayCheck.reason}`);
}
// Record successful delivery
manager.recordEventDelivery(event.id, new Date());
// Cleanup old events (run periodically)
const removed = manager.cleanupOldEvents(
new Date(Date.now() - 24 * 60 * 60 * 1000)
);
console.log(`Cleaned up ${removed} old events`);Event Matching & Filtering
// Register endpoint with filters
manager.registerEndpoint({
id: 'filtered-endpoint',
name: 'Main Branch Only',
url: 'https://api.example.com/webhooks/main',
secret: 'secret',
events: ['push'],
active: true,
filters: [
{
field: 'payload.branch',
operator: 'equals',
value: 'main',
},
{
field: 'payload.repository.name',
operator: 'equals',
value: 'my-app',
},
],
createdAt: new Date(),
updatedAt: new Date(),
});
// Match event to endpoints
const matchedEndpoints = manager.matchEndpoints(event);
console.log(`Matched ${matchedEndpoints.length} endpoints`);
// Apply individual filters
const passes = manager.applyFilter(event, {
field: 'payload.branch',
operator: 'equals',
value: 'main',
});
// Apply multiple filters (AND logic)
const passesAll = manager.applyFilters(event, [
{ field: 'payload.branch', operator: 'equals', value: 'main' },
{ field: 'payload.repository.name', operator: 'contains', value: 'app' },
]);Event Deduplication
// Check if event is a duplicate
if (manager.isDuplicate(event)) {
console.log('Duplicate event detected, skipping');
return;
}
// Record event for deduplication tracking
manager.recordEvent(event);
// Clear deduplication cache (run periodically)
manager.clearDuplicateCache();API Reference
WebhookManager
Main class that orchestrates all webhook operations.
Constructor
new WebhookManager(config?: WebhookManagerConfig)Configuration Options:
interface WebhookManagerConfig {
replayWindowMs?: number; // Default: 300000 (5 minutes)
maxStoredEvents?: number; // Default: 10000
enableDeduplication?: boolean; // Default: true
deduplicationWindowMs?: number; // Default: 60000 (1 minute)
defaultAlgorithm?: SignatureAlgorithm; // Default: 'sha256'
neverhubConfig?: NeverhubConfig;
loggerConfig?: LoggerConfig;
}Registration Methods
registerEndpoint(endpoint: WebhookEndpoint): WebhookRegistrationResultunregisterEndpoint(endpointId: string): booleangetEndpoint(endpointId: string): WebhookEndpoint | nulllistEndpoints(filter?: EndpointFilter): WebhookEndpoint[]updateEndpoint(endpointId: string, updates: Partial<WebhookEndpoint>): WebhookRegistrationResult
Signature Methods
generateSignature(payload: string, secret: string, algorithm: SignatureAlgorithm): stringvalidateSignature(payload: string, signature: string, secret: string, algorithm: SignatureAlgorithm): SignatureValidationResultcompareSignatures(signature1: string, signature2: string): boolean
Replay Prevention Methods
checkReplayAttack(event: WebhookEvent, windowMs?: number): ReplayCheckResultrecordEventDelivery(eventId: string, timestamp: Date): voidcleanupOldEvents(olderThan: Date): number
Deduplication Methods
isDuplicate(event: WebhookEvent): booleanrecordEvent(event: WebhookEvent): voidclearDuplicateCache(): void
Event Matching Methods
matchEndpoints(event: WebhookEvent): WebhookEndpoint[]validateEventType(eventType: string, allowedTypes: string[]): booleanapplyFilter(event: WebhookEvent, filter: WebhookFilter): booleanapplyFilters(event: WebhookEvent, filters: WebhookFilter[]): boolean
Configuration Methods
getConfig(): WebhookManagerConfigupdateConfig(updates: Partial<WebhookManagerConfig>): void
Filter Operators
Supported filter operators for event matching:
- equals - Exact match
- notEquals - Not equal to value
- contains - String or array contains value
- notContains - String or array does not contain value
- matches - Regex pattern match
- in - Value is in array
- notIn - Value is not in array
- exists - Field exists (or not exists if value is false)
- greaterThan - Numeric comparison
- lessThan - Numeric comparison
Signature Algorithms
Supported HMAC algorithms:
- sha1 - Legacy support (not recommended)
- sha256 - Default, recommended for most use cases
- sha512 - Maximum security for sensitive webhooks
Security Considerations
- Constant-Time Comparison - Always uses constant-time comparison to prevent timing attacks
- Replay Window - Keep replay window short (5-15 minutes recommended)
- Event Cache Cleanup - Run periodic cleanup to prevent memory exhaustion
- Secret Storage - Always use environment variables for secrets, never hardcode
Integration Status
- Logger: not-applicable - Core package, no logging requirements
- Docs-Suite: ready - Complete API documentation with examples
- NeverHub: not-applicable - Core package, no service discovery needed
Testing
# Run tests
npm test
# Run tests with coverage
npm run test:coverage
# Run tests once
npm run test:runDevelopment
# Build package
npm run build
# Lint code
npm run lint
# Clean build artifacts
npm run cleanLicense
Copyright (c) 2025 Bernier LLC. All rights reserved.
This file is licensed to the client under a limited-use license. The client may use and modify this code only within the scope of the project it was delivered for. Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
Related Packages
- @bernierllc/webhook-signature-validator - Provider-specific signature validation
- @bernierllc/webhook-github-service - GitHub webhook handler
- @bernierllc/webhook-routing-service - Webhook routing logic
- @bernierllc/webhook-service - Complete webhook service
See Also
For complete webhook solutions, see:
- @bernierllc/webhook-automation-suite - Complete webhook automation
- @bernierllc/content-management-suite - Content management with webhooks
