feat: add IP address logging to webhooks for whitelisting

Implements comprehensive IP logging for webhook requests to enable
IP whitelisting and security monitoring.

Features:
- Capture source IP from webhook requests (x-forwarded-for, x-real-ip)
- Capture user agent for identification
- Store in webhook_logs table
- New API endpoint: GET /api/webhooks/ips
- View unique IPs with request counts and statistics
- Identify Autotask IPs for whitelisting

Database Changes:
- Added source_ip column (VARCHAR 45) to webhook_logs
- Added user_agent column (TEXT) to webhook_logs
- Added index on source_ip for efficient queries
- Migration 005 for existing installations

API Endpoints:
- GET /api/webhooks/ips?hours=168&entityType=Tickets
  Returns unique IPs with:
  * Request counts (total, successful, failed)
  * First/last seen timestamps
  * Entity types accessed
  * User agent strings

Use Cases:
1. Identify Autotask webhook IPs
2. Configure IP whitelist in nginx/Pangolin/Cloudflare
3. Monitor for unauthorized webhook attempts
4. Audit webhook sources
5. Detect IP changes from Autotask

Security Benefits:
- Enable IP whitelisting for webhook endpoint
- Block unauthorized webhook attempts
- Monitor for suspicious activity
- Audit trail of webhook sources

Documentation:
- Complete IP whitelisting guide (WEBHOOK_IP_WHITELISTING.md)
- Configuration examples for nginx, Pangolin, Cloudflare
- Monitoring queries and best practices
- Troubleshooting guide

Files Modified:
- migrations/004_webhook_support.sql - Added IP columns
- migrations/005_add_webhook_ip_logging.sql - Migration for existing installs
- lib/types/webhook.ts - Added IP fields to WebhookLog
- lib/services/webhook-service.ts - Capture and log IPs
- app/api/webhooks/autotask/route.ts - Extract IP from headers
- app/api/webhooks/ips/route.ts - New IP viewing endpoint
- docs/WEBHOOK_IP_WHITELISTING.md - Complete guide

Next Steps:
1. Run migration (004 for new, 005 for existing)
2. Deploy updated code
3. Receive webhooks from Autotask
4. View IPs via /api/webhooks/ips
5. Configure IP whitelist in proxy/tunnel
This commit is contained in:
root 2026-01-24 17:28:56 -05:00
parent 8e83347138
commit a093f8787c
7 changed files with 672 additions and 7 deletions

View file

@ -13,12 +13,12 @@ export class WebhookService {
/**
* Process an incoming webhook from Autotask
*/
async processWebhook(payload: AutotaskWebhookPayload): Promise<WebhookProcessingResult> {
async processWebhook(payload: AutotaskWebhookPayload, sourceIp?: string, userAgent?: string): Promise<WebhookProcessingResult> {
const startTime = Date.now();
try {
// Log the webhook event
await this.logWebhookEvent(payload, 'pending');
await this.logWebhookEvent(payload, 'pending', sourceIp, userAgent);
console.log(`[WEBHOOK] Processing ${payload.eventType} event for ${payload.entityType} #${payload.entityId}`);
@ -169,10 +169,10 @@ export class WebhookService {
/**
* Log webhook event to database
*/
private async logWebhookEvent(payload: AutotaskWebhookPayload, status: 'pending' | 'processed' | 'failed'): Promise<void> {
private async logWebhookEvent(payload: AutotaskWebhookPayload, status: 'pending' | 'processed' | 'failed', sourceIp?: string, userAgent?: string): Promise<void> {
const query = `
INSERT INTO webhook_logs (event_id, entity_type, entity_id, event_type, status, payload)
VALUES ($1, $2, $3, $4, $5, $6)
INSERT INTO webhook_logs (event_id, entity_type, entity_id, event_type, status, source_ip, user_agent, payload)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
ON CONFLICT (event_id) DO NOTHING
`;
@ -182,6 +182,8 @@ export class WebhookService {
payload.entityId,
payload.eventType,
status,
sourceIp || null,
userAgent || null,
JSON.stringify(payload),
]);
}

View file

@ -90,6 +90,8 @@ export interface WebhookLog {
event_type: WebhookEventType;
status: 'pending' | 'processed' | 'failed';
error_message?: string;
source_ip?: string;
user_agent?: string;
received_at: Date;
processed_at?: Date;
processing_time_ms?: number;