eml-parse-js icon indicating copy to clipboard operation
eml-parse-js copied to clipboard

Displaying inline attachments

Open pmweeks98 opened this issue 2 years ago • 2 comments

How to display inline attachments using readEml? Currently displaying as a broken image with the image and the inline attachment in the attachment array

pmweeks98 avatar Aug 29 '22 19:08 pmweeks98

As part of my sanitisation code using the xss library, my definition of IFilterXSSOptions (second argument to xss function) includes a safeAttrValue override, in which I replace href and src values starting with the string cid: with the corresponding base64 URL of the attachment.

c-harding avatar Oct 11 '22 09:10 c-harding

As part of my sanitisation code using the xss library, my definition of IFilterXSSOptions (second argument to xss function) includes a safeAttrValue override, in which I replace href and src values starting with the string cid: with the corresponding base64 URL of the attachment.

I had a similar requirement and followed the above comment to come to my solution:

import xss from 'xss'
import { readEml } from 'eml-parse-js'
...
async fetchAndParseEmail () {
  try {
    this.loading = true
    const { data: eml } = await this.$axios.get('/case/get-email?id=1234')

    // read eml data and output json
    readEml(eml, (err, json) => {
      this.parsedEml = json
    })

    // find all <img> tags in the html with regex
    const images = this.parsedEml.html?.match(/<img [^>]*src="[^"]*"[^>]*>/gm)

    // for each image, replace src cid data with base64 data taken from attachments
    images?.forEach(img => {
      const base64img = new xss.FilterXSS({
        onTagAttr: (tag, name, value) => {
          if (/^cid:/ig.test(value)) {
            const attachment = this.parsedEml.attachments?.find(x => x.id.includes(value.substr(4)))
            return attachment ? `${name}="data:image/png;base64, ${attachment.data64}"` : ''
          }
        }
      }).process(img)

      // replace the img tags in the html
      this.parsedEml.html = this.parsedEml.html.replace(img, base64img)
    })
  } catch (error) {
    console.error(error)
  } finally {
    this.loading = false
  }
}

jimklonowski avatar Dec 09 '22 20:12 jimklonowski