Intial Commit
This commit is contained in:
235
nodered/rootfs/data/node_modules/mailsplit/lib/mime-node.js
generated
vendored
Normal file
235
nodered/rootfs/data/node_modules/mailsplit/lib/mime-node.js
generated
vendored
Normal file
@@ -0,0 +1,235 @@
|
||||
'use strict';
|
||||
|
||||
const Headers = require('./headers');
|
||||
const libmime = require('libmime');
|
||||
const libqp = require('libqp');
|
||||
const libbase64 = require('libbase64');
|
||||
const PassThrough = require('stream').PassThrough;
|
||||
|
||||
class MimeNode {
|
||||
constructor(parentNode, config) {
|
||||
this.type = 'node';
|
||||
this.root = !parentNode;
|
||||
this.parentNode = parentNode;
|
||||
|
||||
this._parentBoundary = this.parentNode && this.parentNode._boundary;
|
||||
this._headersLines = [];
|
||||
this._headerlen = 0;
|
||||
|
||||
this._parsedContentType = false;
|
||||
this._boundary = false;
|
||||
|
||||
this.multipart = false;
|
||||
this.encoding = false;
|
||||
this.headers = false;
|
||||
this.contentType = false;
|
||||
this.flowed = false;
|
||||
this.delSp = false;
|
||||
|
||||
this.config = config || {};
|
||||
this.libmime = new libmime.Libmime({ Iconv: this.config.Iconv });
|
||||
|
||||
this.parentPartNumber = (parentNode && this.partNr) || [];
|
||||
this.partNr = false; // resolved later
|
||||
this.childPartNumbers = 0;
|
||||
}
|
||||
|
||||
getPartNr(provided) {
|
||||
if (provided) {
|
||||
return []
|
||||
.concat(this.partNr || [])
|
||||
.filter(nr => !isNaN(nr))
|
||||
.concat(provided);
|
||||
}
|
||||
let childPartNr = ++this.childPartNumbers;
|
||||
return []
|
||||
.concat(this.partNr || [])
|
||||
.filter(nr => !isNaN(nr))
|
||||
.concat(childPartNr);
|
||||
}
|
||||
|
||||
addHeaderChunk(line) {
|
||||
if (!line) {
|
||||
return;
|
||||
}
|
||||
this._headersLines.push(line);
|
||||
this._headerlen += line.length;
|
||||
}
|
||||
|
||||
parseHeaders() {
|
||||
if (this.headers) {
|
||||
return;
|
||||
}
|
||||
this.headers = new Headers(Buffer.concat(this._headersLines, this._headerlen), this.config);
|
||||
this._parsedContentType = this.libmime.parseHeaderValue(this.headers.getFirst('Content-Type'));
|
||||
this._parsedContentDisposition = this.libmime.parseHeaderValue(this.headers.getFirst('Content-Disposition'));
|
||||
|
||||
this.encoding = this.headers
|
||||
.getFirst('Content-Transfer-Encoding')
|
||||
.replace(/\(.*\)/g, '')
|
||||
.toLowerCase()
|
||||
.trim();
|
||||
this.contentType = (this._parsedContentType.value || '').toLowerCase().trim() || false;
|
||||
this.charset = this._parsedContentType.params.charset || false;
|
||||
this.disposition = (this._parsedContentDisposition.value || '').toLowerCase().trim() || false;
|
||||
this.filename = this._parsedContentDisposition.params.filename || this._parsedContentType.params.name || false;
|
||||
|
||||
if (this._parsedContentType.params.format && this._parsedContentType.params.format.toLowerCase().trim() === 'flowed') {
|
||||
this.flowed = true;
|
||||
if (this._parsedContentType.params.delsp && this._parsedContentType.params.delsp.toLowerCase().trim() === 'yes') {
|
||||
this.delSp = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.filename) {
|
||||
try {
|
||||
this.filename = this.libmime.decodeWords(this.filename);
|
||||
} catch (E) {
|
||||
// failed to parse filename, keep as is (most probably an unknown charset is used)
|
||||
}
|
||||
}
|
||||
|
||||
this.multipart =
|
||||
(this.contentType &&
|
||||
this.contentType.substr(0, this.contentType.indexOf('/')) === 'multipart' &&
|
||||
this.contentType.substr(this.contentType.indexOf('/') + 1)) ||
|
||||
false;
|
||||
this._boundary = (this._parsedContentType.params.boundary && Buffer.from(this._parsedContentType.params.boundary)) || false;
|
||||
|
||||
this.rfc822 = this.contentType === 'message/rfc822';
|
||||
|
||||
if (!this.parentNode || this.parentNode.rfc822) {
|
||||
this.partNr = this.parentNode ? this.parentNode.getPartNr('TEXT') : ['TEXT'];
|
||||
} else {
|
||||
this.partNr = this.parentNode ? this.parentNode.getPartNr() : [];
|
||||
}
|
||||
}
|
||||
|
||||
getHeaders() {
|
||||
if (!this.headers) {
|
||||
this.parseHeaders();
|
||||
}
|
||||
return this.headers.build();
|
||||
}
|
||||
|
||||
setContentType(contentType) {
|
||||
if (!this.headers) {
|
||||
this.parseHeaders();
|
||||
}
|
||||
|
||||
contentType = (contentType || '').toLowerCase().trim();
|
||||
if (contentType) {
|
||||
this._parsedContentType.value = contentType;
|
||||
}
|
||||
|
||||
if (!this.flowed && this._parsedContentType.params.format) {
|
||||
delete this._parsedContentType.params.format;
|
||||
}
|
||||
|
||||
if (!this.delSp && this._parsedContentType.params.delsp) {
|
||||
delete this._parsedContentType.params.delsp;
|
||||
}
|
||||
|
||||
this.headers.update('Content-Type', this.libmime.buildHeaderValue(this._parsedContentType));
|
||||
}
|
||||
|
||||
setCharset(charset) {
|
||||
if (!this.headers) {
|
||||
this.parseHeaders();
|
||||
}
|
||||
|
||||
charset = (charset || '').toLowerCase().trim();
|
||||
|
||||
if (charset === 'ascii') {
|
||||
charset = '';
|
||||
}
|
||||
|
||||
if (!charset) {
|
||||
if (!this._parsedContentType.value) {
|
||||
// nothing to set or update
|
||||
return;
|
||||
}
|
||||
delete this._parsedContentType.params.charset;
|
||||
} else {
|
||||
this._parsedContentType.params.charset = charset;
|
||||
}
|
||||
|
||||
if (!this._parsedContentType.value) {
|
||||
this._parsedContentType.value = 'text/plain';
|
||||
}
|
||||
|
||||
this.headers.update('Content-Type', this.libmime.buildHeaderValue(this._parsedContentType));
|
||||
}
|
||||
|
||||
setFilename(filename) {
|
||||
if (!this.headers) {
|
||||
this.parseHeaders();
|
||||
}
|
||||
|
||||
this.filename = (filename || '').toLowerCase().trim();
|
||||
|
||||
if (this._parsedContentType.params.name) {
|
||||
delete this._parsedContentType.params.name;
|
||||
this.headers.update('Content-Type', this.libmime.buildHeaderValue(this._parsedContentType));
|
||||
}
|
||||
|
||||
if (!this.filename) {
|
||||
if (!this._parsedContentDisposition.value) {
|
||||
// nothing to set or update
|
||||
return;
|
||||
}
|
||||
delete this._parsedContentDisposition.params.filename;
|
||||
} else {
|
||||
this._parsedContentDisposition.params.filename = this.filename;
|
||||
}
|
||||
|
||||
if (!this._parsedContentDisposition.value) {
|
||||
this._parsedContentDisposition.value = 'attachment';
|
||||
}
|
||||
|
||||
this.headers.update('Content-Disposition', this.libmime.buildHeaderValue(this._parsedContentDisposition));
|
||||
}
|
||||
|
||||
getDecoder() {
|
||||
if (!this.headers) {
|
||||
this.parseHeaders();
|
||||
}
|
||||
|
||||
switch (this.encoding) {
|
||||
case 'base64':
|
||||
return new libbase64.Decoder();
|
||||
case 'quoted-printable':
|
||||
return new libqp.Decoder();
|
||||
default:
|
||||
return new PassThrough();
|
||||
}
|
||||
}
|
||||
|
||||
getEncoder(encoding) {
|
||||
if (!this.headers) {
|
||||
this.parseHeaders();
|
||||
}
|
||||
|
||||
encoding = (encoding || '')
|
||||
.toString()
|
||||
.toLowerCase()
|
||||
.trim();
|
||||
|
||||
if (encoding && encoding !== this.encoding) {
|
||||
this.headers.update('Content-Transfer-Encoding', encoding);
|
||||
} else {
|
||||
encoding = this.encoding;
|
||||
}
|
||||
|
||||
switch (encoding) {
|
||||
case 'base64':
|
||||
return new libbase64.Encoder();
|
||||
case 'quoted-printable':
|
||||
return new libqp.Encoder();
|
||||
default:
|
||||
return new PassThrough();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = MimeNode;
|
||||
Reference in New Issue
Block a user