refactor: update AbacatePay webhook auth to use query param secret
- Replaced signature-based verification with secret validation using webhookSecret query parameter for improved compatibility - Added CORS headers in next.config.ts for webhook API routes to handle external requests from varying IPs - Updated abacatepay.ts verifyWebhookSignature method for backward compatibility, now delegating validation to route handler
This commit is contained in:
1 parent
9e86b187e1
commit
634a5bc40b
3 files changed
+34
-9
No files matched your search
@@ -4,15 +4,20 @@ import { abacatePay } from "@/lib/abacatepay";
|
|||||||
export async function POST(request: NextRequest) {
|
export async function POST(request: NextRequest) {
|
||||||
try {
|
try {
|
||||||
const payload = await request.text();
|
const payload = await request.text();
|
||||||
const signature = request.headers.get("x-abacatepay-signature");
|
|
||||||
|
|
||||||
if (!signature || !abacatePay.verifyWebhookSignature(payload, signature)) {
|
// AbacatePay envia webhookSecret como query param
|
||||||
return NextResponse.json(
|
const { searchParams } = new URL(request.url);
|
||||||
{ error: "Assinatura inválida" },
|
const webhookSecret = searchParams.get("webhookSecret");
|
||||||
{ status: 401 }
|
const expectedSecret = process.env.ABACATEPAY_WEBHOOK_SECRET;
|
||||||
);
|
|
||||||
|
// Validar secret
|
||||||
|
if (!webhookSecret || !expectedSecret || webhookSecret !== expectedSecret) {
|
||||||
|
console.error("🔒 Webhook rejeitado: secret inválido ou ausente");
|
||||||
|
return NextResponse.json({ error: "Secret inválido" }, { status: 401 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log("✅ Webhook autenticado com sucesso");
|
||||||
|
|
||||||
const event = JSON.parse(payload);
|
const event = JSON.parse(payload);
|
||||||
|
|
||||||
console.log("🔔 Webhook recebido:", JSON.stringify(event, null, 2));
|
console.log("🔔 Webhook recebido:", JSON.stringify(event, null, 2));
|
||||||
|
|||||||
+1
-3
@@ -166,9 +166,7 @@ class AbacatePayClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
verifyWebhookSignature(payload: string, signature: string): boolean {
|
verifyWebhookSignature(payload: string, signature: string): boolean {
|
||||||
// Implementar verificação de assinatura conforme documentação do AbacatePay
|
// Método mantido para compatibilidade, mas validação agora é feita via query param
|
||||||
// Por enquanto, retorna true para desenvolvimento
|
|
||||||
// Em produção, implementar a verificação real
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,28 @@ const withNextIntl = createNextIntlPlugin("./i18n/request.ts");
|
|||||||
|
|
||||||
const nextConfig: NextConfig = {
|
const nextConfig: NextConfig = {
|
||||||
/* config options here */
|
/* config options here */
|
||||||
|
async headers() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
// Aplicar CORS apenas para rotas de API
|
||||||
|
source: "/api/webhooks/:path*",
|
||||||
|
headers: [
|
||||||
|
{
|
||||||
|
key: "Access-Control-Allow-Origin",
|
||||||
|
value: "*", // AbacatePay envia de IPs variados
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "Access-Control-Allow-Methods",
|
||||||
|
value: "POST, GET, OPTIONS",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "Access-Control-Allow-Headers",
|
||||||
|
value: "Content-Type, Authorization",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withNextIntl(nextConfig);
|
export default withNextIntl(nextConfig);
|
||||||
Reference in new issue
Block a user