Bugfix: addressparser() didn't handle groups properly

This commit is contained in:
the-djmaze 2023-02-13 19:47:24 +01:00
parent ebf429215b
commit a696d6c0a1
4 changed files with 27 additions and 25 deletions

View file

@ -5,15 +5,15 @@ const contentType = 'snappymail/emailaddress',
getAddressKey = li => li?.emailaddress?.key, getAddressKey = li => li?.emailaddress?.key,
parseEmailLine = line => addressparser(line).map(item => parseEmailLine = line => addressparser(line).map(item =>
(item.name || item.address) (item.name || item.email)
? new EmailModel(item.address, item.name) : null ? new EmailModel(item.email, item.name) : null
).filter(v => v), ).filter(v => v),
splitEmailLine = line => { splitEmailLine = line => {
const result = []; const result = [];
let exists = false; let exists = false;
addressparser(line).forEach(item => { addressparser(line).forEach(item => {
const address = (item.name || item.address) const address = (item.name || item.email)
? new EmailModel(item.address, item.name) ? new EmailModel(item.email, item.name)
: null; : null;
if (address?.email) { if (address?.email) {

View file

@ -77,7 +77,7 @@ export function addressparser(str) {
} else { } else {
endOperator = endOperator ? '' : OPERATORS[chr]; endOperator = endOperator ? '' : OPERATORS[chr];
if ('<' === chr) { if ('<' === chr) {
node.type = 'address'; node.type = 'email';
} else if ('(' === chr) { } else if ('(' === chr) {
node.type = 'comment'; node.type = 'comment';
} else if (':' === chr) { } else if (':' === chr) {
@ -94,7 +94,7 @@ export function addressparser(str) {
pushAddress(); pushAddress();
return addresses; return addresses;
// return addresses.map(item => (item.name || item.address) ? new EmailModel(item.address, item.name) : null).filter(v => v); // return addresses.map(item => (item.name || item.email) ? new EmailModel(item.email, item.name) : null).filter(v => v);
} }
/** /**
@ -109,13 +109,12 @@ function _handleAddress(tokens) {
address = {}, address = {},
addresses = [], addresses = [],
data = { data = {
address: [], email: [],
comment: [], comment: [],
group: [], group: [],
text: [] text: []
}; };
// Filter out <addresses>, (comments) and regular text
tokens.forEach(token => { tokens.forEach(token => {
isGroup = isGroup || 'group' === token.type; isGroup = isGroup || 'group' === token.type;
data[token.type].push(token.value); data[token.type].push(token.value);
@ -129,68 +128,71 @@ function _handleAddress(tokens) {
if (isGroup) { if (isGroup) {
// http://tools.ietf.org/html/rfc2822#appendix-A.1.3 // http://tools.ietf.org/html/rfc2822#appendix-A.1.3
/*
addresses.push({ addresses.push({
address: '', email: '',
name: data.text.join(' ').trim(), name: data.text.join(' ').trim(),
group: addressparser(data.group.join(',')) group: addressparser(data.group.join(','))
// ,comment: data.comment.join(' ').trim() // ,comment: data.comment.join(' ').trim()
}); });
*/
addresses = addresses.concat(addressparser(data.group.join(',')));
} else { } else {
// If no address was found, try to detect one from regular text // If no address was found, try to detect one from regular text
if (!data.address.length && data.text.length) { if (!data.email.length && data.text.length) {
var i = data.text.length; var i = data.text.length;
while (i--) { while (i--) {
if (data.text[i].match(/^[^@\s]+@[^@\s]+$/)) { if (data.text[i].match(/^[^@\s]+@[^@\s]+$/)) {
data.address = data.text.splice(i, 1); data.email = data.text.splice(i, 1);
break; break;
} }
} }
// still no address // still no address
if (!data.address.length) { if (!data.email.length) {
i = data.text.length; i = data.text.length;
while (i--) { while (i--) {
data.text[i] = data.text[i].replace(/\s*\b[^@\s]+@[^@\s]+\b\s*/, address => { data.text[i] = data.text[i].replace(/\s*\b[^@\s]+@[^@\s]+\b\s*/, address => {
if (!data.address.length) { if (!data.email.length) {
data.address = [address.trim()]; data.email = [address.trim()];
return ''; return '';
} }
return address.trim(); return address.trim();
}); });
if (data.address.length) { if (data.email.length) {
break; break;
} }
} }
} }
} }
// If there's still is no text but a comment exists, replace the two // If there's still no text but a comment exists, replace the two
if (!data.text.length && data.comment.length) { if (!data.text.length && data.comment.length) {
data.text = data.comment; data.text = data.comment;
data.comment = []; data.comment = [];
} }
// Keep only the first address occurence, push others to regular text // Keep only the first address occurence, push others to regular text
if (data.address.length > 1) { if (data.email.length > 1) {
data.text = data.text.concat(data.address.splice(1)); data.text = data.text.concat(data.email.splice(1));
} }
address = { address = {
// Join values with spaces // Join values with spaces
address: data.address.join(' ').trim(), email: data.email.join(' ').trim(),
name: data.text.join(' ').trim() name: data.text.join(' ').trim()
// ,comment: data.comment.join(' ').trim() // ,comment: data.comment.join(' ').trim()
}; };
if (address.address === address.name) { if (address.email === address.name) {
if (address.address.includes('@')) { if (address.email.includes('@')) {
address.name = ''; address.name = '';
} else { } else {
address.address = ''; address.email = '';
} }
} }
// address.address = address.address.replace(/^[<]+(.*)[>]+$/g, '$1'); // address.email = address.email.replace(/^[<]+(.*)[>]+$/g, '$1');
addresses.push(address); addresses.push(address);
} }

View file

@ -40,7 +40,7 @@ export class EmailCollectionModel extends AbstractCollectionModel
if (str) { if (str) {
let items = {}, key; let items = {}, key;
addressparser(str).forEach(item => { addressparser(str).forEach(item => {
item = new EmailModel(item.address, item.name); item = new EmailModel(item.email, item.name);
// Make them unique // Make them unique
key = item.email || item.name; key = item.email || item.name;
if (key && (item.name || !items[key])) { if (key && (item.name || !items[key])) {

View file

@ -59,7 +59,7 @@ const
base64_encode = text => btoa(unescape(encodeURIComponent(text))).match(/.{1,76}/g).join('\r\n'), base64_encode = text => btoa(unescape(encodeURIComponent(text))).match(/.{1,76}/g).join('\r\n'),
getEmail = value => addressparser(value)[0]?.address || false, getEmail = value => addressparser(value)[0]?.email || false,
/** /**
* @param {Array} aList * @param {Array} aList