Verify JWT in HTTP post hook for form notification

When a user submits a form on my site, it triggers a HTTP post hook using Netlify notifications. Then, I want to verify this post using JWT.

The post hook has JWS secret token, which is a random string, the same as process.env.JWS_SECRET in my deploy.

The post request is then handled by a Next.js API route that looks like this:

import { createHmac } from "crypto";
import jwt from "jsonwebtoken";

const secret = process.env.JWS_SECRET;

const signed = (signature, body) => {
  try {
    const decoded = jwt.verify(signature, secret, {
      algorithms: ["HS256"],
      issuer: "netlify",
    });

    const hash = createHmac("sha256", secret).update(body).digest("hex");
    return decoded.sha256 === hash;
  } catch (error) {
    return false;
  }
};

export default async function handler(req, res) {
  if (req.method === "POST") {
    const signature = req.headers.["x-webhook-signature"];

    const formData = req.body;

    if (!signed(signature, req.body)) {
      return res.status(403).json({ message: "Invalid" });
    }

    // do something here
  } else {
    // method not allowed
  }
}

I’m adapting the Ruby code provided here Deploy notifications | Netlify Docs.

But the decoded.sha256 === hash line returns false. What am I doing wrong in the verification?

Update:

I’ve tried using this instead, which I think is actually the right way to do it, but still no luck:

const hash = createHash("sha256").update(JSON.stringify(body)).digest("hex");

I’ve asked the devs to take a look.