andrewpietiladotcom/lib/FromMimeHeader.js

167 lines
7.1 KiB
JavaScript
Raw Permalink Normal View History

import MimeHeader from "./MimeHeader.js";
const atext = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%&'*+-/=?^_`{|}~".split('');
const dtext = "!\"#$%^&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~".split('');
const qtext = "!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~".split('');
class FromMimeHeader extends MimeHeader {
constructor(key, value) {
super(key, value);
this._fromValue = [];
}
// From: Andrew Pietila <a.pietila@protonmail.com>
get fromValue() {
// ABNF:
// from = "From:" mailbox-list CRLF
// mailbox-list = (mailbox *("," mailbox)) / obs-mbox-list
// mailbox = name-addr / addr-spec
// name-addr = [display-name] angle-addr
// display-name = phrase
// phrase = 1*word / obs-phrase
// word = atom / quoted-string
// atom = [CFWS] 1*atext [CFWS]
// addr-spec = local-part "@" domain
// local-part = dot-atom / quoted-string / obs-local-part
// domain = dot-atom / domain-literal / obs-domain
// domain-literal = [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS]
// dtext = %d33-90 / ; Printable US-ASCII
// %d94-126 / ; characters not including
// obs-dtext ; "[", "]", or "\"
// dot-atom-text = 1*atext *("." 1*atext)
// dot-atom = [CFWS] dot-atom-text [CFWS]
// quoted-string = [CFWS]
// DQUOTE *([FWS] qcontent) [FWS] DQUOTE
// [CFWS]
// qcontent = qtext / quoted-pair
// qtext = %d33 / ; Printable US-ASCII
// %d35-91 / ; characters not including
// %d93-126 / ; "\" or the quote character
// obs-qtext
// TODO: Implement utf-8 encoding and whatever other encodings we have to support.
if ( this._fromValue.length !== 0 ) {
return this._fromValue;
}
// TODO: Implement this state machine properly according to the above ABNF.
var from = [];
var state = "";
var inCRLF = false;
var commentDepth = 0;
var displayName = "";
var inDquot = false;
var idLeft = "";
var idRight = "";
var idRightDatEmittedRightSquacket = false;
for (var char of this.rawValue) {
if ( inCRLF === true && char !== "\n" ) {
return null; // Error state.
}
if (state === "") {
// CFWS
if ( char === " ") {
continue;
} else if ( char === "\t") {
continue;
} else if ( char === "(" && !inDquot ) {
commentDepth++;
} else if ( char === "\"" ) {
inDquot = !inDquot;
} else if ( char === ")" && !inDquot ) {
commentDepth--;
} else if ( char === "\r" ) {
inCRLF = true;
} else if ( char === "\n" ) {
inCRLF = false;
} else {
state = "display-name";
}
} else if ( state === "display-name") {
if ( char === " " ) {
if ( state.endsWith(" ") ) {
continue;
} else {
}
}
}
// else if ( char === "<" ) {
// state = "id-left";
// } else {
// return null; // Error state, we couldn't produce a proper message ID from the input.
// }
// } else if ( state === "id-left" ) {
// if ( atext.includes(char) ) {
// idLeft += char;
// } else if ( char === "." ) {
// if ( idLeft.endsWith(".") || idLeft.length === 0 ) {
// return null; // Error state.
// }
// idLeft += char;
// } else if ( char === "@" ) {
// if ( idLeft.endsWith(".") || idLeft.length === 0) {
// return null; // Error state.
// }
// state = "id-right";
// }
// } else if ( state === "id-right" ) {
// if ( char === "[" ) {
// if ( idRight.length !== 0 ) {
// return null; // Error state.
// }
// idRight += char;
// state = "id-right-dat";
// } else if ( char === "." ) {
// if ( idRight.endsWith(".") || idRight.length === 0 ) {
// return null; // Error state.
// }
// idRight += char;
// } else if ( char === ">" ) {
// if ( idRight.endsWith(".") || idRight.length === 0) {
// return null; // Error state.
// }
// state = "end-cfws"
// }
// } else if ( state === "id-right-dat" ) {
// if ( char === ">" && idRight.endsWith("]") ) {
// state = "end-cfws";
// continue;
// }
// if ( dtext.includes(char) ) {
// if ( idRightDatEmittedRightSquacket ) {
// return null; // Error state.
// }
// idRight += char;
// } else if ( char === "]" ) {
// if ( idRightDatEmittedRightSquacket ) {
// return null; // Error state.
// }
// idRight += char;
// idRightDatEmittedRightSquacket = true;
// }
// } else if ( state === "end-cfws" ) {
// // CFWS
// if ( char === " ") {
// continue;
// } else if ( char === "\t") {
// continue;
// } else if ( char === "(" && !inDquot ) {
// commentDepth++;
// } else if ( char === "\"" ) {
// inDquot = !inDquot;
// } else if ( char === ")" && !inDquot ) {
// commentDepth--;
// } else if ( char === "\r" ) {
// inCRLF = true;
// } else if ( char === "\n" ) {
// inCRLF = false;
// } else {
// return null; // Error state.
// }
// }
}
this._fromValue = from;
return `${idLeft}@${idRight}`;
}
}
export default FromMimeHeader;