0

In a nodejs server, using DOMPurify+JSDOM, I need to download an image inside the Hook afterSanitizeElements.

For example, using the code below, I manage to get the image, but too late, and the image cannot be leveraged to be used in the code that calls purify.sanitize.

I need the code to run in sequence in time, for console.log(clean) to show, for example, the base64 string and not the 'src' like a url.


purify.addHook('afterSanitizeElements', async (node) => {
  // Do something with the current node and return it
  // You can also mutate hookEvent (i.e. set hookEvent.forceKeepAttr = true)
  if (node.tagName) {
    if (node.tagName.toLowerCase() == 'img') {
      if (node.hasAttribute('src')) {
        if (regUrlWeb.test(node.src)) {
          const base64 = await getImageBase64(node.src);
          node.setAttribute('src', base64);
        }
      }
    }
  }
  return node;
});

const getImageBase64 = async (url: string) => {
  const image = await axios.get(url, { responseType: 'arraybuffer' });
  return Buffer.from(image.data).toString('base64');;
};

const clean = await purify.sanitize(dirty);

console.log(clean);
Moisés Bites
  • 95
  • 1
  • 1
  • 4
  • Try to ```log``` immediately after you set ```src``` to ```base64``` – Amit Kumar Sep 17 '22 at 02:04
  • Thanks @amit-kumar. But I need to use the image in `base64` format outside the hooks functions, *after the sanitization* has completed its process. For example, the above `console.log(clean)` is executed before `getImageBase64` finishes executing. Oh, it's too late. That's the problem. – Moisés Bites Sep 17 '22 at 14:28
  • I asked you to try logging to see if you are getting the expected result. Callback function in the hook is asynchronous, so you need a way to detect when callback has complete execution. – Amit Kumar Sep 17 '22 at 15:14
  • Yes, the result was ok... `getImageBase64` is working correctly and returns the expected image, but in a untimely way... So, how can i make `purify.sanitize(dirty)` run synchronously to wait for all hooks to complete effectively for `console.log(clean)`to run only after the `node.setAttribute('src', base64);` is done ? – Moisés Bites Sep 17 '22 at 16:50
  • 1
    I could think of one approach but that is lengthy. Get all the image url by parsing your dirty html. Then convert them to ```base64``` and store in object/map. When all of this is done, then sanitize and use the object/map inside hook. – Amit Kumar Sep 18 '22 at 05:49
  • Thank you @AMITKUMAR. I also imagined something like this. I was hoping to find something easier to sync than this. But, I will implement it, at least for now. – Moisés Bites Sep 18 '22 at 13:29

0 Answers0