Fixed issue# 1790 - On reply of an email, the recipient will not be set if sender header contains invalid email addresses.
This commit is contained in:
parent
6f08071c3d
commit
a0c04ed190
3 changed files with 419 additions and 169 deletions
|
@ -890,6 +890,29 @@ class App.Utils
|
|||
text = text.replace(/http(s|):\/\/[-A-Za-z0-9+&@#\/%?=~_\|!:,.;]+[-A-Za-z0-9+&@#\/%=~_|]/img, placeholder)
|
||||
text.length
|
||||
|
||||
@parseAddressListLocal: (line) ->
|
||||
recipients = emailAddresses.parseAddressList(line)
|
||||
result = []
|
||||
if !_.isEmpty(recipients)
|
||||
for recipient in recipients
|
||||
if recipient && recipient.address
|
||||
result.push recipient.address
|
||||
return result
|
||||
|
||||
# workaround for email-addresses.js issue with this kind of
|
||||
# mail headers "From: invalid sender, realname <sender@example.com>"
|
||||
# email-addresses.js is returning null because it can't parse the
|
||||
# whole header
|
||||
if _.isEmpty(recipients) && line.match('@')
|
||||
recipients = line.split(',')
|
||||
re = /(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))/
|
||||
for recipient in recipients
|
||||
if recipient && recipient.match('@')
|
||||
localResult = recipient.match(re)
|
||||
if localResult && localResult[0]
|
||||
result.push localResult[0]
|
||||
result
|
||||
|
||||
@getRecipientArticle: (ticket, article, article_created_by, type, email_addresses = [], all) ->
|
||||
|
||||
# empty form
|
||||
|
@ -938,16 +961,18 @@ class App.Utils
|
|||
# check if article sender is local
|
||||
senderIsLocal = false
|
||||
if !_.isEmpty(article.from)
|
||||
senders = emailAddresses.parseAddressList(article.from)
|
||||
if senders && senders[0] && senders[0].address
|
||||
senderIsLocal = isLocalAddress(senders[0].address)
|
||||
senders = App.Utils.parseAddressListLocal(article.from)
|
||||
if senders
|
||||
for sender in senders
|
||||
if sender && sender.address && sender.address.match('@')
|
||||
senderIsLocal = isLocalAddress(sender.address)
|
||||
|
||||
# check if article recipient is local
|
||||
recipientIsLocal = false
|
||||
if !_.isEmpty(article.to)
|
||||
recipients = emailAddresses.parseAddressList(article.to)
|
||||
if recipients && recipients[0] && recipients[0].address
|
||||
recipientIsLocal = isLocalAddress(recipients[0].address)
|
||||
recipients = App.Utils.parseAddressListLocal(article.to)
|
||||
if recipients && recipients[0]
|
||||
recipientIsLocal = isLocalAddress(recipients[0])
|
||||
|
||||
# sender is local
|
||||
if senderIsLocal
|
||||
|
@ -971,14 +996,14 @@ class App.Utils
|
|||
|
||||
# filter for uniq recipients
|
||||
recipientAddresses = {}
|
||||
|
||||
addAddresses = (addressLine, line) ->
|
||||
lineNew = ''
|
||||
recipients = emailAddresses.parseAddressList(addressLine)
|
||||
recipients = App.Utils.parseAddressListLocal(addressLine)
|
||||
|
||||
if !_.isEmpty(recipients)
|
||||
for recipient in recipients
|
||||
if !_.isEmpty(recipient.address)
|
||||
localRecipientAddress = recipient.address.toString().toLowerCase()
|
||||
if !_.isEmpty(recipient)
|
||||
localRecipientAddress = recipient.toString().toLowerCase()
|
||||
|
||||
# check if address is not local
|
||||
if !isLocalAddress(localRecipientAddress)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
// email-addresses.js - RFC 5322 email address parser
|
||||
// v 2.0.1
|
||||
// v 3.0.1
|
||||
//
|
||||
// http://tools.ietf.org/html/rfc5322
|
||||
//
|
||||
|
@ -186,27 +186,7 @@ function parse5322(opts) {
|
|||
// "First Last" -> "First Last"
|
||||
// "First Last" -> "First Last"
|
||||
function collapseWhitespace(s) {
|
||||
function isWhitespace(c) {
|
||||
return c === ' ' ||
|
||||
c === '\t' ||
|
||||
c === '\r' ||
|
||||
c === '\n';
|
||||
}
|
||||
var i, str;
|
||||
str = "";
|
||||
for (i = 0; i < s.length; i += 1) {
|
||||
if (!isWhitespace(s[i]) || !isWhitespace(s[i + 1])) {
|
||||
str += s[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (isWhitespace(str[0])) {
|
||||
str = str.substring(1);
|
||||
}
|
||||
if (isWhitespace(str[str.length - 1])) {
|
||||
str = str.substring(0, str.length - 1);
|
||||
}
|
||||
return str;
|
||||
return s.replace(/([ \t]|\r\n)+/g, ' ').replace(/^\s*/, '').replace(/\s*$/, '');
|
||||
}
|
||||
|
||||
// UTF-8 pseudo-production (RFC 6532)
|
||||
|
@ -597,10 +577,14 @@ function parse5322(opts) {
|
|||
return wrap('domain', function domainCheckTLD() {
|
||||
var result = or(obsDomain, dotAtom, domainLiteral)();
|
||||
if (opts.rejectTLD) {
|
||||
if (result.semantic.indexOf('.') < 0) {
|
||||
if (result && result.semantic && result.semantic.indexOf('.') < 0) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// strip all whitespace from domains
|
||||
if (result) {
|
||||
result.semantic = result.semantic.replace(/\s+/g, '');
|
||||
}
|
||||
return result;
|
||||
}());
|
||||
}
|
||||
|
@ -612,6 +596,36 @@ function parse5322(opts) {
|
|||
)());
|
||||
}
|
||||
|
||||
// 3.6.2 Originator Fields
|
||||
// Below we only parse the field body, not the name of the field
|
||||
// like "From:", "Sender:", or "Reply-To:". Other libraries that
|
||||
// parse email headers can parse those and defer to these productions
|
||||
// for the "RFC 5322" part.
|
||||
|
||||
// RFC 6854 2.1. Replacement of RFC 5322, Section 3.6.2. Originator Fields
|
||||
// from = "From:" (mailbox-list / address-list) CRLF
|
||||
function fromSpec() {
|
||||
return wrap('from', or(
|
||||
mailboxList,
|
||||
addressList
|
||||
)());
|
||||
}
|
||||
|
||||
// RFC 6854 2.1. Replacement of RFC 5322, Section 3.6.2. Originator Fields
|
||||
// sender = "Sender:" (mailbox / address) CRLF
|
||||
function senderSpec() {
|
||||
return wrap('sender', or(
|
||||
mailbox,
|
||||
address
|
||||
)());
|
||||
}
|
||||
|
||||
// RFC 6854 2.1. Replacement of RFC 5322, Section 3.6.2. Originator Fields
|
||||
// reply-to = "Reply-To:" address-list CRLF
|
||||
function replyToSpec() {
|
||||
return wrap('reply-to', addressList());
|
||||
}
|
||||
|
||||
// 4.1. Miscellaneous Obsolete Tokens
|
||||
|
||||
// obs-NO-WS-CTL = %d1-8 / ; US-ASCII control
|
||||
|
@ -766,92 +780,186 @@ function parse5322(opts) {
|
|||
// ast analysis
|
||||
|
||||
function findNode(name, root) {
|
||||
var i, queue, node;
|
||||
var i, stack, node;
|
||||
if (root === null || root === undefined) { return null; }
|
||||
queue = [root];
|
||||
while (queue.length > 0) {
|
||||
node = queue.shift();
|
||||
stack = [root];
|
||||
while (stack.length > 0) {
|
||||
node = stack.pop();
|
||||
if (node.name === name) {
|
||||
return node;
|
||||
}
|
||||
for (i = 0; i < node.children.length; i += 1) {
|
||||
queue.push(node.children[i]);
|
||||
for (i = node.children.length - 1; i >= 0; i -= 1) {
|
||||
stack.push(node.children[i]);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function findAllNodes(name, root) {
|
||||
var i, queue, node, result;
|
||||
var i, stack, node, result;
|
||||
if (root === null || root === undefined) { return null; }
|
||||
queue = [root];
|
||||
stack = [root];
|
||||
result = [];
|
||||
while (queue.length > 0) {
|
||||
node = queue.shift();
|
||||
while (stack.length > 0) {
|
||||
node = stack.pop();
|
||||
if (node.name === name) {
|
||||
result.push(node);
|
||||
}
|
||||
for (i = 0; i < node.children.length; i += 1) {
|
||||
queue.push(node.children[i]);
|
||||
for (i = node.children.length - 1; i >= 0; i -= 1) {
|
||||
stack.push(node.children[i]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function findAllNodesNoChildren(names, root) {
|
||||
var i, stack, node, result, namesLookup;
|
||||
if (root === null || root === undefined) { return null; }
|
||||
stack = [root];
|
||||
result = [];
|
||||
namesLookup = {};
|
||||
for (i = 0; i < names.length; i += 1) {
|
||||
namesLookup[names[i]] = true;
|
||||
}
|
||||
|
||||
while (stack.length > 0) {
|
||||
node = stack.pop();
|
||||
if (node.name in namesLookup) {
|
||||
result.push(node);
|
||||
// don't look at children (hence findAllNodesNoChildren)
|
||||
} else {
|
||||
for (i = node.children.length - 1; i >= 0; i -= 1) {
|
||||
stack.push(node.children[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function giveResult(ast) {
|
||||
function grabSemantic(n) {
|
||||
return n !== null ? n.semantic : null;
|
||||
}
|
||||
var i, ret, addresses, addr, name, aspec, local, domain;
|
||||
var addresses, groupsAndMailboxes, i, groupOrMailbox, result;
|
||||
if (ast === null) {
|
||||
return null;
|
||||
}
|
||||
ret = { ast: ast };
|
||||
addresses = findAllNodes('address', ast);
|
||||
ret.addresses = [];
|
||||
for (i = 0; i < addresses.length; i += 1) {
|
||||
addr = addresses[i];
|
||||
name = findNode('display-name', addr);
|
||||
aspec = findNode('addr-spec', addr);
|
||||
local = findNode('local-part', aspec);
|
||||
domain = findNode('domain', aspec);
|
||||
ret.addresses.push({
|
||||
node: addr,
|
||||
addresses = [];
|
||||
|
||||
// An address is a 'group' (i.e. a list of mailboxes) or a 'mailbox'.
|
||||
groupsAndMailboxes = findAllNodesNoChildren(['group', 'mailbox'], ast);
|
||||
for (i = 0; i < groupsAndMailboxes.length; i += 1) {
|
||||
groupOrMailbox = groupsAndMailboxes[i];
|
||||
if (groupOrMailbox.name === 'group') {
|
||||
addresses.push(giveResultGroup(groupOrMailbox));
|
||||
} else if (groupOrMailbox.name === 'mailbox') {
|
||||
addresses.push(giveResultMailbox(groupOrMailbox));
|
||||
}
|
||||
}
|
||||
|
||||
result = {
|
||||
ast: ast,
|
||||
addresses: addresses,
|
||||
};
|
||||
if (opts.simple) {
|
||||
result = simplifyResult(result);
|
||||
}
|
||||
if (opts.oneResult) {
|
||||
return oneResult(result);
|
||||
}
|
||||
if (opts.simple) {
|
||||
return result && result.addresses;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
function giveResultGroup(group) {
|
||||
var i;
|
||||
var groupName = findNode('display-name', group);
|
||||
var groupResultMailboxes = [];
|
||||
var mailboxes = findAllNodesNoChildren(['mailbox'], group);
|
||||
for (i = 0; i < mailboxes.length; i += 1) {
|
||||
groupResultMailboxes.push(giveResultMailbox(mailboxes[i]));
|
||||
}
|
||||
return {
|
||||
node: group,
|
||||
parts: {
|
||||
name: groupName,
|
||||
},
|
||||
type: group.name, // 'group'
|
||||
name: grabSemantic(groupName),
|
||||
addresses: groupResultMailboxes,
|
||||
};
|
||||
}
|
||||
|
||||
function giveResultMailbox(mailbox) {
|
||||
var name = findNode('display-name', mailbox);
|
||||
var aspec = findNode('addr-spec', mailbox);
|
||||
var comments = findAllNodes('cfws', mailbox);
|
||||
|
||||
var local = findNode('local-part', aspec);
|
||||
var domain = findNode('domain', aspec);
|
||||
return {
|
||||
node: mailbox,
|
||||
parts: {
|
||||
name: name,
|
||||
address: aspec,
|
||||
local: local,
|
||||
domain: domain
|
||||
domain: domain,
|
||||
comments: comments
|
||||
},
|
||||
type: mailbox.name, // 'mailbox'
|
||||
name: grabSemantic(name),
|
||||
address: grabSemantic(aspec),
|
||||
local: grabSemantic(local),
|
||||
domain: grabSemantic(domain)
|
||||
});
|
||||
domain: grabSemantic(domain),
|
||||
groupName: grabSemantic(mailbox.groupName),
|
||||
};
|
||||
}
|
||||
|
||||
if (opts.simple) {
|
||||
ret = ret.addresses;
|
||||
for (i = 0; i < ret.length; i += 1) {
|
||||
delete ret[i].node;
|
||||
function grabSemantic(n) {
|
||||
return n !== null && n !== undefined ? n.semantic : null;
|
||||
}
|
||||
|
||||
function simplifyResult(result) {
|
||||
var i;
|
||||
if (result && result.addresses) {
|
||||
for (i = 0; i < result.addresses.length; i += 1) {
|
||||
delete result.addresses[i].node;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
return result;
|
||||
}
|
||||
|
||||
function oneResult(result) {
|
||||
if (!result) { return null; }
|
||||
if (!opts.partial && result.addresses.length > 1) { return null; }
|
||||
return result.addresses && result.addresses[0];
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
var parseString, pos, len, parsed;
|
||||
var parseString, pos, len, parsed, startProduction;
|
||||
|
||||
opts = handleOpts(opts, {});
|
||||
if (opts === null) { return null; }
|
||||
|
||||
parseString = opts.input;
|
||||
|
||||
startProduction = {
|
||||
'address': address,
|
||||
'address-list': addressList,
|
||||
'angle-addr': angleAddr,
|
||||
'from': fromSpec,
|
||||
'group': group,
|
||||
'mailbox': mailbox,
|
||||
'mailbox-list': mailboxList,
|
||||
'reply-to': replyToSpec,
|
||||
'sender': senderSpec,
|
||||
}[opts.startAt] || addressList;
|
||||
|
||||
if (!opts.strict) {
|
||||
initialize();
|
||||
opts.strict = true;
|
||||
parsed = addressList(parseString);
|
||||
parsed = startProduction(parseString);
|
||||
if (opts.partial || !inStr()) {
|
||||
return giveResult(parsed);
|
||||
}
|
||||
|
@ -859,46 +967,51 @@ function parse5322(opts) {
|
|||
}
|
||||
|
||||
initialize();
|
||||
parsed = addressList(parseString);
|
||||
parsed = startProduction(parseString);
|
||||
if (!opts.partial && inStr()) { return null; }
|
||||
return giveResult(parsed);
|
||||
}
|
||||
|
||||
function parseOneAddressSimple(opts) {
|
||||
var result;
|
||||
|
||||
opts = handleOpts(opts, {
|
||||
return parse5322(handleOpts(opts, {
|
||||
oneResult: true,
|
||||
rfc6532: true,
|
||||
simple: true
|
||||
});
|
||||
if (opts === null) { return null; }
|
||||
|
||||
result = parse5322(opts);
|
||||
|
||||
if ((!result) ||
|
||||
(!opts.partial &&
|
||||
(opts.simple && result.length > 1) ||
|
||||
(!opts.simple && result.addresses.length > 1))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return opts.simple ?
|
||||
result && result[0] :
|
||||
result && result.addresses && result.addresses[0];
|
||||
simple: true,
|
||||
startAt: 'address-list',
|
||||
}));
|
||||
}
|
||||
|
||||
function parseAddressListSimple(opts) {
|
||||
var result;
|
||||
|
||||
opts = handleOpts(opts, {
|
||||
return parse5322(handleOpts(opts, {
|
||||
rfc6532: true,
|
||||
simple: true
|
||||
});
|
||||
if (opts === null) { return null; }
|
||||
simple: true,
|
||||
startAt: 'address-list',
|
||||
}));
|
||||
}
|
||||
|
||||
result = parse5322(opts);
|
||||
function parseFromSimple(opts) {
|
||||
return parse5322(handleOpts(opts, {
|
||||
rfc6532: true,
|
||||
simple: true,
|
||||
startAt: 'from',
|
||||
}));
|
||||
}
|
||||
|
||||
return opts.simple ? result : result.addresses;
|
||||
function parseSenderSimple(opts) {
|
||||
return parse5322(handleOpts(opts, {
|
||||
oneResult: true,
|
||||
rfc6532: true,
|
||||
simple: true,
|
||||
startAt: 'sender',
|
||||
}));
|
||||
}
|
||||
|
||||
function parseReplyToSimple(opts) {
|
||||
return parse5322(handleOpts(opts, {
|
||||
rfc6532: true,
|
||||
simple: true,
|
||||
startAt: 'reply-to',
|
||||
}));
|
||||
}
|
||||
|
||||
function handleOpts(opts, defs) {
|
||||
|
@ -926,24 +1039,28 @@ function handleOpts(opts, defs) {
|
|||
if (!defs) { return null; }
|
||||
|
||||
defaults = {
|
||||
rfc6532: false,
|
||||
oneResult: false,
|
||||
partial: false,
|
||||
rejectTLD: false,
|
||||
rfc6532: false,
|
||||
simple: false,
|
||||
startAt: 'address-list',
|
||||
strict: false,
|
||||
rejectTLD: false
|
||||
};
|
||||
|
||||
for (o in defaults) {
|
||||
if (isNullUndef(opts[o])) {
|
||||
opts[o] = !isNullUndef(defs[o]) ? defs[o] : defaults[o];
|
||||
}
|
||||
opts[o] = !!opts[o];
|
||||
}
|
||||
return opts;
|
||||
}
|
||||
|
||||
parse5322.parseOneAddress = parseOneAddressSimple;
|
||||
parse5322.parseAddressList = parseAddressListSimple;
|
||||
parse5322.parseFrom = parseFromSimple;
|
||||
parse5322.parseSender = parseSenderSimple;
|
||||
parse5322.parseReplyTo = parseReplyToSimple;
|
||||
|
||||
// in Zammad context, go back to non CommonJS
|
||||
// if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
||||
|
|
|
@ -1982,34 +1982,106 @@ test('check getRecipientArticle format', function() {
|
|||
lastname: 'lastname',
|
||||
email: 'customer@example.com',
|
||||
}
|
||||
agent = {
|
||||
login: 'login',
|
||||
firstname: 'firstname',
|
||||
lastname: 'lastname',
|
||||
email: 'agent@example.com',
|
||||
}
|
||||
ticket = {
|
||||
customer: customer,
|
||||
}
|
||||
article = {
|
||||
message_id: 'message_id7',
|
||||
created_by: agent,
|
||||
type: {
|
||||
name: 'email',
|
||||
},
|
||||
sender: {
|
||||
name: 'Agent',
|
||||
name: 'Customer',
|
||||
},
|
||||
from: 'customer2@example.com',
|
||||
to: 'customer@example.com',
|
||||
from: 'some other invalid part, ' + customer.email,
|
||||
to: 'some group',
|
||||
created_by: {
|
||||
login: 'login',
|
||||
firstname: 'firstname',
|
||||
lastname: 'lastname',
|
||||
email: 'article_created_by@example.com',
|
||||
}
|
||||
}
|
||||
result = {
|
||||
to: 'customer2@example.com',
|
||||
to: 'customer@example.com',
|
||||
cc: '',
|
||||
body: '',
|
||||
in_reply_to: 'message_id7',
|
||||
}
|
||||
verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type)
|
||||
console.log(verify)
|
||||
deepEqual(verify, result)
|
||||
|
||||
customer = {
|
||||
login: 'login',
|
||||
firstname: 'firstname',
|
||||
lastname: 'lastname',
|
||||
email: 'customer@example.com',
|
||||
}
|
||||
ticket = {
|
||||
customer: customer,
|
||||
}
|
||||
article = {
|
||||
message_id: 'message_id7.1',
|
||||
type: {
|
||||
name: 'email',
|
||||
},
|
||||
sender: {
|
||||
name: 'Customer',
|
||||
},
|
||||
from: 'some other invalid part, Some Realname ' + customer.email,
|
||||
to: 'some group',
|
||||
created_by: {
|
||||
login: 'login',
|
||||
firstname: 'firstname',
|
||||
lastname: 'lastname',
|
||||
email: 'article_created_by@example.com',
|
||||
}
|
||||
}
|
||||
result = {
|
||||
to: 'customer@example.com',
|
||||
cc: '',
|
||||
body: '',
|
||||
in_reply_to: 'message_id7.1',
|
||||
}
|
||||
verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type)
|
||||
console.log(verify)
|
||||
deepEqual(verify, result)
|
||||
|
||||
customer = {
|
||||
login: 'login',
|
||||
firstname: 'firstname',
|
||||
lastname: 'lastname',
|
||||
email: 'customer@example.com',
|
||||
}
|
||||
ticket = {
|
||||
customer: customer,
|
||||
}
|
||||
article = {
|
||||
message_id: 'message_id7.2',
|
||||
type: {
|
||||
name: 'email',
|
||||
},
|
||||
sender: {
|
||||
name: 'Customer',
|
||||
},
|
||||
from: 'some other invalid part, Some Realname ' + customer.email + ' , abc',
|
||||
to: 'some group',
|
||||
created_by: {
|
||||
login: 'login',
|
||||
firstname: 'firstname',
|
||||
lastname: 'lastname',
|
||||
email: 'article_created_by@example.com',
|
||||
}
|
||||
}
|
||||
result = {
|
||||
to: 'customer@example.com',
|
||||
cc: '',
|
||||
body: '',
|
||||
in_reply_to: 'message_id7.2',
|
||||
}
|
||||
verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type)
|
||||
console.log(verify)
|
||||
deepEqual(verify, result)
|
||||
|
||||
customer = {
|
||||
|
@ -2036,11 +2108,11 @@ test('check getRecipientArticle format', function() {
|
|||
sender: {
|
||||
name: 'Agent',
|
||||
},
|
||||
from: 'agent@example.com',
|
||||
from: 'customer2@example.com',
|
||||
to: 'customer@example.com',
|
||||
}
|
||||
result = {
|
||||
to: 'customer@example.com',
|
||||
to: 'customer2@example.com',
|
||||
cc: '',
|
||||
body: '',
|
||||
in_reply_to: 'message_id8',
|
||||
|
@ -2072,9 +2144,8 @@ test('check getRecipientArticle format', function() {
|
|||
sender: {
|
||||
name: 'Agent',
|
||||
},
|
||||
from: 'Agent@Example.com',
|
||||
from: 'agent@example.com',
|
||||
to: 'customer@example.com',
|
||||
cc: 'zammad@example.com',
|
||||
}
|
||||
result = {
|
||||
to: 'customer@example.com',
|
||||
|
@ -2110,16 +2181,16 @@ test('check getRecipientArticle format', function() {
|
|||
name: 'Agent',
|
||||
},
|
||||
from: 'Agent@Example.com',
|
||||
to: 'customer@example.com, agent@example.com',
|
||||
to: 'customer@example.com',
|
||||
cc: 'zammad@example.com',
|
||||
}
|
||||
result = {
|
||||
to: 'customer@example.com, agent@example.com',
|
||||
cc: 'zammad@example.com',
|
||||
to: 'customer@example.com',
|
||||
cc: '',
|
||||
body: '',
|
||||
in_reply_to: 'message_id10',
|
||||
}
|
||||
verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type, [], true)
|
||||
verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type)
|
||||
deepEqual(verify, result)
|
||||
|
||||
customer = {
|
||||
|
@ -2147,8 +2218,8 @@ test('check getRecipientArticle format', function() {
|
|||
name: 'Agent',
|
||||
},
|
||||
from: 'Agent@Example.com',
|
||||
to: 'customeR@EXAMPLE.com, agent@example.com',
|
||||
cc: 'zammad@example.com, customer@example.com',
|
||||
to: 'customer@example.com, agent@example.com',
|
||||
cc: 'zammad@example.com',
|
||||
}
|
||||
result = {
|
||||
to: 'customer@example.com, agent@example.com',
|
||||
|
@ -2156,7 +2227,7 @@ test('check getRecipientArticle format', function() {
|
|||
body: '',
|
||||
in_reply_to: 'message_id11',
|
||||
}
|
||||
verify = App.Utils.getRecipientArticle(ticket, article, agent, article.type, [], true)
|
||||
verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type, [], true)
|
||||
deepEqual(verify, result)
|
||||
|
||||
customer = {
|
||||
|
@ -2184,24 +2255,16 @@ test('check getRecipientArticle format', function() {
|
|||
name: 'Agent',
|
||||
},
|
||||
from: 'Agent@Example.com',
|
||||
to: 'customeR@EXAMPLE.com, agent@example.com, zammad2@EXAMPLE.com',
|
||||
cc: 'zammad@example.com, customer2@example.com',
|
||||
to: 'customeR@EXAMPLE.com, agent@example.com',
|
||||
cc: 'zammad@example.com, customer@example.com',
|
||||
}
|
||||
result = {
|
||||
to: 'customer@example.com, agent@example.com',
|
||||
cc: 'customer2@example.com',
|
||||
cc: 'zammad@example.com',
|
||||
body: '',
|
||||
in_reply_to: 'message_id12',
|
||||
}
|
||||
email_addresses = [
|
||||
{
|
||||
email: 'zammad@example.com',
|
||||
},
|
||||
{
|
||||
email: 'zammad2@example.com',
|
||||
}
|
||||
]
|
||||
verify = App.Utils.getRecipientArticle(ticket, article, agent, article.type, email_addresses, true)
|
||||
verify = App.Utils.getRecipientArticle(ticket, article, agent, article.type, [], true)
|
||||
deepEqual(verify, result)
|
||||
|
||||
customer = {
|
||||
|
@ -2214,7 +2277,7 @@ test('check getRecipientArticle format', function() {
|
|||
login: 'login',
|
||||
firstname: 'firstname',
|
||||
lastname: 'lastname',
|
||||
email: 'AGENT@example.com',
|
||||
email: 'agent@example.com',
|
||||
}
|
||||
ticket = {
|
||||
customer: customer,
|
||||
|
@ -2253,21 +2316,27 @@ test('check getRecipientArticle format', function() {
|
|||
login: 'login',
|
||||
firstname: 'firstname',
|
||||
lastname: 'lastname',
|
||||
email: 'zammad@example.com',
|
||||
email: 'customer@example.com',
|
||||
}
|
||||
agent = {
|
||||
login: 'login',
|
||||
firstname: 'firstname',
|
||||
lastname: 'lastname',
|
||||
email: 'AGENT@example.com',
|
||||
}
|
||||
ticket = {
|
||||
customer: customer,
|
||||
}
|
||||
article = {
|
||||
message_id: 'message_id14',
|
||||
created_by: customer,
|
||||
created_by: agent,
|
||||
type: {
|
||||
name: 'email',
|
||||
},
|
||||
sender: {
|
||||
name: 'Agent',
|
||||
},
|
||||
from: 'zammad@EXAMPLE.com',
|
||||
from: 'Agent@Example.com',
|
||||
to: 'customeR@EXAMPLE.com, agent@example.com, zammad2@EXAMPLE.com',
|
||||
cc: 'zammad@example.com, customer2@example.com',
|
||||
}
|
||||
|
@ -2292,7 +2361,7 @@ test('check getRecipientArticle format', function() {
|
|||
login: 'login',
|
||||
firstname: 'firstname',
|
||||
lastname: 'lastname',
|
||||
email: 'customer@example.com',
|
||||
email: 'zammad@example.com',
|
||||
}
|
||||
ticket = {
|
||||
customer: customer,
|
||||
|
@ -2306,13 +2375,13 @@ test('check getRecipientArticle format', function() {
|
|||
sender: {
|
||||
name: 'Agent',
|
||||
},
|
||||
from: 'customer@example.com',
|
||||
to: 'customer1@example.com, customer2@example.com, zammad@example.com',
|
||||
cc: '',
|
||||
from: 'zammad@EXAMPLE.com',
|
||||
to: 'customeR@EXAMPLE.com, agent@example.com, zammad2@EXAMPLE.com',
|
||||
cc: 'zammad@example.com, customer2@example.com',
|
||||
}
|
||||
result = {
|
||||
to: 'customer1@example.com, customer2@example.com, customer@example.com',
|
||||
cc: '',
|
||||
to: 'customer@example.com, agent@example.com',
|
||||
cc: 'customer2@example.com',
|
||||
body: '',
|
||||
in_reply_to: 'message_id15',
|
||||
}
|
||||
|
@ -2346,11 +2415,11 @@ test('check getRecipientArticle format', function() {
|
|||
name: 'Agent',
|
||||
},
|
||||
from: 'customer@example.com',
|
||||
to: 'customer1@example.com, customer2@example.com, zammad@example.com, customer2+2@example.com',
|
||||
to: 'customer1@example.com, customer2@example.com, zammad@example.com',
|
||||
cc: '',
|
||||
}
|
||||
result = {
|
||||
to: 'customer1@example.com, customer2@example.com, customer2+2@example.com, customer@example.com',
|
||||
to: 'customer1@example.com, customer2@example.com, customer@example.com',
|
||||
cc: '',
|
||||
body: '',
|
||||
in_reply_to: 'message_id16',
|
||||
|
@ -2372,30 +2441,24 @@ test('check getRecipientArticle format', function() {
|
|||
lastname: 'lastname',
|
||||
email: 'customer@example.com',
|
||||
}
|
||||
agent = {
|
||||
login: 'login',
|
||||
firstname: 'firstname',
|
||||
lastname: 'lastname',
|
||||
email: 'zammad@example.com',
|
||||
}
|
||||
ticket = {
|
||||
customer: customer,
|
||||
}
|
||||
article = {
|
||||
message_id: 'message_id17',
|
||||
created_by: agent,
|
||||
created_by: customer,
|
||||
type: {
|
||||
name: 'email',
|
||||
},
|
||||
sender: {
|
||||
name: 'Agent',
|
||||
},
|
||||
from: 'zammad@example.com',
|
||||
to: 'customer@example.com',
|
||||
from: 'customer@example.com',
|
||||
to: 'customer1@example.com, customer2@example.com, zammad@example.com, customer2+2@example.com',
|
||||
cc: '',
|
||||
}
|
||||
result = {
|
||||
to: 'customer@example.com',
|
||||
to: 'customer1@example.com, customer2@example.com, customer2+2@example.com, customer@example.com',
|
||||
cc: '',
|
||||
body: '',
|
||||
in_reply_to: 'message_id17',
|
||||
|
@ -2435,6 +2498,51 @@ test('check getRecipientArticle format', function() {
|
|||
sender: {
|
||||
name: 'Agent',
|
||||
},
|
||||
from: 'zammad@example.com',
|
||||
to: 'customer@example.com',
|
||||
cc: '',
|
||||
}
|
||||
result = {
|
||||
to: 'customer@example.com',
|
||||
cc: '',
|
||||
body: '',
|
||||
in_reply_to: 'message_id18',
|
||||
}
|
||||
email_addresses = [
|
||||
{
|
||||
email: 'zammad@example.com',
|
||||
},
|
||||
{
|
||||
email: 'zammad2@example.com',
|
||||
}
|
||||
]
|
||||
verify = App.Utils.getRecipientArticle(ticket, article, agent, article.type, email_addresses, true)
|
||||
deepEqual(verify, result)
|
||||
|
||||
customer = {
|
||||
login: 'login',
|
||||
firstname: 'firstname',
|
||||
lastname: 'lastname',
|
||||
email: 'customer@example.com',
|
||||
}
|
||||
agent = {
|
||||
login: 'login',
|
||||
firstname: 'firstname',
|
||||
lastname: 'lastname',
|
||||
email: 'zammad@example.com',
|
||||
}
|
||||
ticket = {
|
||||
customer: customer,
|
||||
}
|
||||
article = {
|
||||
message_id: 'message_id19',
|
||||
created_by: agent,
|
||||
type: {
|
||||
name: 'email',
|
||||
},
|
||||
sender: {
|
||||
name: 'Agent',
|
||||
},
|
||||
from: 'Sender <zammad@example.com>',
|
||||
to: 'Customer <customer@example.com>',
|
||||
cc: '',
|
||||
|
@ -2443,7 +2551,7 @@ test('check getRecipientArticle format', function() {
|
|||
to: 'customer@example.com',
|
||||
cc: '',
|
||||
body: '',
|
||||
in_reply_to: 'message_id18',
|
||||
in_reply_to: 'message_id19',
|
||||
}
|
||||
email_addresses = [
|
||||
{
|
||||
|
@ -2466,7 +2574,7 @@ test('check getRecipientArticle format', function() {
|
|||
customer: agent,
|
||||
}
|
||||
article = {
|
||||
message_id: 'message_id19',
|
||||
message_id: 'message_id20',
|
||||
created_by: agent,
|
||||
type: {
|
||||
name: 'email',
|
||||
|
@ -2482,7 +2590,7 @@ test('check getRecipientArticle format', function() {
|
|||
to: 'agent@example.com',
|
||||
cc: '',
|
||||
body: '',
|
||||
in_reply_to: 'message_id19',
|
||||
in_reply_to: 'message_id20',
|
||||
}
|
||||
email_addresses = [
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue