Webhook HMAC verification with Firebase functions

Hello, I’m having trouble verifying the HMAC header within Firebase functions. Can someone spot what we’re doing wrong?

import crypto from "crypto";
import { logger } from "firebase-functions/v2";
import { Request } from "firebase-functions/v2/https";

const CLIENT_SECRET = process.env.SHOPIFY_CLIENT_SECRET!;

export function verifyShopifyHmac(req: Request) {
  if (!req.body) return false;

  const hmacHeader = req.header("X-Shopify-Hmac-Sha256");

  if (!hmacHeader) {
    return false;
  }

  const computedHmac = crypto
    .createHmac("sha256", CLIENT_SECRET)
    .update(req.body, "utf-8")
    .digest("base64");
  logger.debug({ hmacHeader });
  logger.debug({ computedHmac });
  logger.debug({ equal: hmacHeader === computedHmac });
  if (
    Buffer.from(computedHmac) !== Buffer.from(hmacHeader as string, "base64")
  ) {
    return false;
  }

  return true;
}

Hello, I had same problem.But I found solution :slightly_smiling_face:

reference:https://community.shopify.com/post/2439345

function verifyWebhook(rawBody: Buffer, hmacHeader: string): boolean {
    const calculatedHmac = crypto
      .createHmac('sha256', 'SHOPIFY_WEBHOOK_TOKEN')
      .update(rawBody)
      .digest('base64');
    console.log('calculatedHmac', calculatedHmac);
    console.log('hmacHeader', hmacHeader);
    return crypto.timingSafeEqual(Buffer.from(calculatedHmac), Buffer.from(hmacHeader));
  }

  const rawBody = req.rawBody;
  const hmacHeader = req.header('X-Shopify-Hmac-Sha256');

  // console.log('hmacHeader', hmacHeader);
  if (!hmacHeader || typeof hmacHeader !== 'string') {
    console.log('no hmac header');
    res.status(401).send('Unauthorized');
    return;
  }
  const verified = verifyWebhook(rawBody, hmacHeader);
  if (!verified) {
    console.log('verification failed');
    res.status(401).send('Unauthorized');
    return;
  }
  console.log('verification success');