2025-08-22 17:02:49 +09:00
|
|
|
import {
|
|
|
|
|
Controller,
|
|
|
|
|
Post,
|
|
|
|
|
Body,
|
|
|
|
|
Headers,
|
|
|
|
|
UseGuards,
|
|
|
|
|
HttpCode,
|
|
|
|
|
HttpStatus,
|
|
|
|
|
BadRequestException,
|
|
|
|
|
} from "@nestjs/common";
|
2025-08-21 15:24:40 +09:00
|
|
|
import { WebhooksService } from "./webhooks.service";
|
2025-08-22 17:02:49 +09:00
|
|
|
import { ApiTags, ApiOperation, ApiResponse, ApiHeader } from "@nestjs/swagger";
|
|
|
|
|
import { ThrottlerGuard } from "@nestjs/throttler";
|
2025-09-04 14:17:54 +09:00
|
|
|
import { EnhancedWebhookSignatureGuard } from "./guards/enhanced-webhook-signature.guard";
|
2025-08-28 16:57:57 +09:00
|
|
|
import { Public } from "../auth/decorators/public.decorator";
|
2025-08-20 18:02:50 +09:00
|
|
|
|
2025-08-21 15:24:40 +09:00
|
|
|
@ApiTags("webhooks")
|
|
|
|
|
@Controller("webhooks")
|
2025-08-28 16:57:57 +09:00
|
|
|
@Public() // Webhooks use signature-based authentication, not JWT
|
2025-08-22 17:02:49 +09:00
|
|
|
@UseGuards(ThrottlerGuard) // Rate limit webhook endpoints
|
2025-08-20 18:02:50 +09:00
|
|
|
export class WebhooksController {
|
|
|
|
|
constructor(private webhooksService: WebhooksService) {}
|
|
|
|
|
|
2025-08-22 17:02:49 +09:00
|
|
|
@Post("whmcs")
|
|
|
|
|
@HttpCode(HttpStatus.OK)
|
2025-09-04 14:17:54 +09:00
|
|
|
@UseGuards(EnhancedWebhookSignatureGuard)
|
2025-08-22 17:02:49 +09:00
|
|
|
@ApiOperation({ summary: "WHMCS webhook endpoint" })
|
|
|
|
|
@ApiResponse({ status: 200, description: "Webhook processed successfully" })
|
|
|
|
|
@ApiResponse({ status: 400, description: "Invalid webhook data" })
|
|
|
|
|
@ApiResponse({ status: 401, description: "Invalid signature" })
|
|
|
|
|
@ApiHeader({ name: "X-WHMCS-Signature", description: "WHMCS webhook signature" })
|
2025-08-23 17:24:37 +09:00
|
|
|
handleWhmcsWebhook(@Body() payload: unknown, @Headers("x-whmcs-signature") signature: string) {
|
2025-08-22 17:02:49 +09:00
|
|
|
try {
|
2025-08-23 17:24:37 +09:00
|
|
|
this.webhooksService.processWhmcsWebhook(payload, signature);
|
2025-08-22 17:02:49 +09:00
|
|
|
return { success: true, message: "Webhook processed successfully" };
|
|
|
|
|
} catch {
|
|
|
|
|
throw new BadRequestException("Failed to process webhook");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Post("salesforce")
|
|
|
|
|
@HttpCode(HttpStatus.OK)
|
2025-09-04 14:17:54 +09:00
|
|
|
@UseGuards(EnhancedWebhookSignatureGuard)
|
2025-08-22 17:02:49 +09:00
|
|
|
@ApiOperation({ summary: "Salesforce webhook endpoint" })
|
|
|
|
|
@ApiResponse({ status: 200, description: "Webhook processed successfully" })
|
|
|
|
|
@ApiResponse({ status: 400, description: "Invalid webhook data" })
|
|
|
|
|
@ApiResponse({ status: 401, description: "Invalid signature" })
|
|
|
|
|
@ApiHeader({ name: "X-SF-Signature", description: "Salesforce webhook signature" })
|
2025-08-23 17:24:37 +09:00
|
|
|
handleSalesforceWebhook(@Body() payload: unknown, @Headers("x-sf-signature") signature: string) {
|
2025-08-22 17:02:49 +09:00
|
|
|
try {
|
2025-08-23 17:24:37 +09:00
|
|
|
this.webhooksService.processSalesforceWebhook(payload, signature);
|
2025-08-22 17:02:49 +09:00
|
|
|
return { success: true, message: "Webhook processed successfully" };
|
|
|
|
|
} catch {
|
|
|
|
|
throw new BadRequestException("Failed to process webhook");
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-08-20 18:02:50 +09:00
|
|
|
}
|