cloudflare / dmarc-email-worker

DMARC reports processor using Cloudflare Workers and Email Workers
https://blog.cloudflare.com/how-we-built-dmarc-management/
MIT License
84 stars 9 forks source link

Unknown extension: #12

Closed kriiv closed 5 months ago

kriiv commented 6 months ago

I've deployed this repo with the standard code, no modifications. When triggering the worker via an email route I get the following:

{
  "outcome": "exception",
  "scriptName": "dmarc-email-worker",
  "diagnosticsChannelEvents": [],
  "exceptions": [
    {
      "name": "Error",
      "message": "unknown extension: ",
      "timestamp": 1709945220800
    }
  ],
  "logs": [],
  "eventTimestamp": 1709945220127,
  "event": {
    "rawSize": 6515,
    "rcptTo": "<redacted>",
    "mailFrom": "<redacted>"
  },
  "id": 1
}

Any thoughts on how I can get this to work properly? The file is being stored into R2 but nothing happens after that. Strange as I'm using the default code and instructions form the repo.

dattaproffs commented 5 months ago

This is because outlook for example uses the mime type "application/x-gzip" and if you look in the mime-db repo there is no extension for that mime type. The same goes for other vendors like google and yahoo. they also use some x- variant of the mime type.

You could either do a PR to mime-db and add the ones you find are missing or just do a quick and dirty "fix" and look at the file extension.

const filenameParts = attachment.filename.split('.');
const fileExtension = filenameParts[filenameParts.length - 1];
if(extension === '')
    extension = fileExtension;
kriiv commented 5 months ago

Perfect! That worked. Thanks a lot.

kriiv commented 5 months ago

For reference, I edited index.ts with the following:

async function getDMARCReportXML(attachment: Attachment) {
  let xml;
  const xmlParser = new XMLParser();
  let extension = mimeDb[attachment.mimeType]?.extensions?.[0] || '';

  if (extension === '') {
    const filenameParts = attachment.filename.split('.');
    extension = filenameParts[filenameParts.length - 1];
  }

  switch (extension) {
    case 'gz':
      xml = pako.inflate(new TextEncoder().encode(attachment.content as string), { to: 'string' });
      break;

    case 'zip':
      xml = await getXMLFromZip(attachment.content);
      break;

    case 'xml':
      xml = await new Response(attachment.content).text();
      break;

    default:
      throw new Error(`unknown extension: ${extension}`);
  }

  return await xmlParser.parse(xml);
}