Data4Autos-Shopify-Backend/routes/privacyLawWebhooks.js
2026-04-13 05:23:25 +00:00

72 lines
2.1 KiB
JavaScript
Executable File

// routes/privacyLawWebhooks.js
require('dotenv').config();
const express = require('express');
const crypto = require('crypto');
const router = express.Router();
// Use raw body ONLY for this router so HMAC works
router.use(express.raw({ type: '*/*' }));
const SHOPIFY_API_SECRET = process.env.SHOPIFY_API_SECRET;
// ---- helpers ----
function verifyHmac(rawBody, hmacHeader) {
if (!SHOPIFY_API_SECRET || !hmacHeader || !rawBody) return false;
const digest = crypto
.createHmac('sha256', SHOPIFY_API_SECRET)
.update(rawBody) // raw Buffer
.digest('base64');
const generated = Buffer.from(digest, 'utf8');
const received = Buffer.from(hmacHeader, 'utf8');
if (generated.length !== received.length) return false;
return crypto.timingSafeEqual(generated, received);
}
function parseJsonSafe(buf) {
try { return JSON.parse(buf.toString('utf8')); }
catch { return null; }
}
function handleWebhook(req, res, topicName) {
const hmacHeader = req.header('x-shopify-hmac-sha256');
const shop = req.header('x-shopify-shop-domain');
const topic = req.header('x-shopify-topic') || topicName;
const isValid = verifyHmac(req.body, hmacHeader);
if (!isValid) {
// You asked for 500 on invalid HMAC. (Best practice is 401.)
console.error(`[WEBHOOK:${topic}] INVALID HMAC from shop=${shop}`);
return res.status(401).send('Invalid HMAC');
}
const payload = parseJsonSafe(req.body) || {};
// Log minimally; avoid logging full PII in real apps
console.log(`[WEBHOOK:${topic}] shop=${shop}`, payload);
// Echo back for your debugging
return res.status(200).json({ status: 'ok', topic, shop, received: payload });
}
// ---- endpoints ----
// 1) customers/data_request
router.post('/customers/data_request', (req, res) =>
handleWebhook(req, res, 'customers/data_request')
);
// 2) customers/redact
router.post('/customers/redact', (req, res) =>
handleWebhook(req, res, 'customers/redact')
);
// 3) shop/redact
router.post('/shop/redact', (req, res) =>
handleWebhook(req, res, 'shop/redact')
);
module.exports = router;