"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var PaystackWebhookGuard_1; Object.defineProperty(exports, "__esModule", { value: true }); exports.PaystackWebhookGuard = void 0; const common_1 = require("@nestjs/common"); const config_1 = require("@nestjs/config"); const crypto_1 = require("crypto"); let PaystackWebhookGuard = PaystackWebhookGuard_1 = class PaystackWebhookGuard { configService; logger = new common_1.Logger(PaystackWebhookGuard_1.name); secretKey; isProduction; constructor(configService) { this.configService = configService; this.secretKey = this.configService.get("PAYSTACK_SECRET_KEY") || ""; this.isProduction = this.configService.get("NODE_ENV") === "production"; } canActivate(context) { if (!this.secretKey) { if (this.isProduction) { this.logger.error("PAYSTACK_SECRET_KEY is not configured in production — rejecting webhook."); throw new common_1.UnauthorizedException("Paystack is not configured"); } this.logger.warn("PAYSTACK_SECRET_KEY is not configured — webhook signature verification skipped (dev only)."); return true; } const request = context.switchToHttp().getRequest(); const signatureHeader = request.headers["x-paystack-signature"] || undefined; if (!signatureHeader) { throw new common_1.UnauthorizedException("Missing Paystack signature header"); } const rawBody = this.extractRawBody(request); if (!rawBody) { throw new common_1.UnauthorizedException("Unable to read raw request body"); } const expected = (0, crypto_1.createHmac)("sha512", this.secretKey) .update(rawBody) .digest("hex"); if (expected.length !== signatureHeader.length) { throw new common_1.UnauthorizedException("Invalid Paystack signature"); } let mismatch = 0; for (let i = 0; i < expected.length; i++) { mismatch |= expected.charCodeAt(i) ^ signatureHeader.charCodeAt(i); } if (mismatch !== 0) { throw new common_1.UnauthorizedException("Invalid Paystack signature"); } return true; } extractRawBody(request) { if (typeof request.rawBody === "string") return request.rawBody; if (Buffer.isBuffer(request.rawBody)) return request.rawBody.toString("utf8"); if (request.body && typeof request.body === "object") { try { return JSON.stringify(request.body); } catch { return undefined; } } return undefined; } }; exports.PaystackWebhookGuard = PaystackWebhookGuard; exports.PaystackWebhookGuard = PaystackWebhookGuard = PaystackWebhookGuard_1 = __decorate([ (0, common_1.Injectable)(), __metadata("design:paramtypes", [config_1.ConfigService]) ], PaystackWebhookGuard); //# sourceMappingURL=paystack-webhook.guard.js.map