mirror of https://github.com/eleith/emailjs.git
smtp: allow cc/bcc-only messages
This commit is contained in:
parent
2bb5832be4
commit
10a850159c
|
@ -189,19 +189,18 @@ const options = {
|
|||
## new message.Message(headers)
|
||||
|
||||
```js
|
||||
// headers is an object with the following recognized keys:
|
||||
// headers is an object with the following recognized schema:
|
||||
const headers = {
|
||||
// required
|
||||
from, // sender of the format (address or name <address> or "name" <address>)
|
||||
to, // recipients (same format as above), multiple recipients are separated by a comma
|
||||
|
||||
// optional
|
||||
text, // text of the email
|
||||
cc, // carbon copied recipients (same format as above)
|
||||
bcc, // blind carbon copied recipients (same format as above)
|
||||
text, // text of the email
|
||||
subject, // string subject of the email
|
||||
attachment, // one attachment or array of attachments
|
||||
};
|
||||
// the `from` field is required.
|
||||
// at least one `to`, `cc`, or `bcc` header is also required.
|
||||
// you can also add whatever other headers you want.
|
||||
```
|
||||
|
||||
|
|
|
@ -42,7 +42,10 @@ export class Client {
|
|||
* @param {function(err: Error, msg: Message): void} callback sss
|
||||
* @returns {void}
|
||||
*/
|
||||
public send(msg: Message, callback: (err: Error, msg: Message) => void) {
|
||||
public send(
|
||||
msg: Message,
|
||||
callback: (err: Error | null, msg: Message) => void
|
||||
) {
|
||||
const message: Message | null =
|
||||
msg instanceof Message
|
||||
? msg
|
||||
|
@ -59,7 +62,7 @@ export class Client {
|
|||
if (valid) {
|
||||
const stack = {
|
||||
message,
|
||||
to: addressparser(message.header.to),
|
||||
to: [] as ReturnType<typeof addressparser>,
|
||||
from: addressparser(message.header.from)[0].address,
|
||||
callback: (
|
||||
callback ||
|
||||
|
@ -69,7 +72,11 @@ export class Client {
|
|||
).bind(this),
|
||||
} as MessageStack;
|
||||
|
||||
if (message.header.cc) {
|
||||
if (typeof message.header.to === 'string') {
|
||||
stack.to = addressparser(message.header.to);
|
||||
}
|
||||
|
||||
if (typeof message.header.cc === 'string') {
|
||||
stack.to = stack.to.concat(
|
||||
addressparser(message.header.cc).filter(
|
||||
(x) => stack.to.some((y) => y.address === x.address) === false
|
||||
|
@ -77,7 +84,7 @@ export class Client {
|
|||
);
|
||||
}
|
||||
|
||||
if (message.header.bcc) {
|
||||
if (typeof message.header.bcc === 'string') {
|
||||
stack.to = stack.to.concat(
|
||||
addressparser(message.header.bcc).filter(
|
||||
(x) => stack.to.some((y) => y.address === x.address) === false
|
||||
|
@ -85,6 +92,10 @@ export class Client {
|
|||
);
|
||||
}
|
||||
|
||||
if (stack.to.length === 0) {
|
||||
return callback(new Error('No recipients found in message'), msg);
|
||||
}
|
||||
|
||||
if (
|
||||
message.header['return-path'] &&
|
||||
addressparser(message.header['return-path']).length
|
||||
|
|
|
@ -116,6 +116,17 @@ export class Message {
|
|||
public readonly text?: string;
|
||||
public alternative: AlternateMessageAttachment | null = null;
|
||||
|
||||
/**
|
||||
* Construct an rfc2822-compliant message object.
|
||||
*
|
||||
* Special notes:
|
||||
* - The `from` field is required.
|
||||
* - At least one `to`, `cc`, or `bcc` header is also required.
|
||||
* - You can also add whatever other headers you want.
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc2822
|
||||
* @param {Partial<MessageHeaders>} headers Message headers
|
||||
*/
|
||||
constructor(headers: Partial<MessageHeaders>) {
|
||||
for (const header in headers) {
|
||||
// allow user to override default content-type to override charset or send a single non-text message
|
||||
|
@ -143,7 +154,6 @@ export class Message {
|
|||
);
|
||||
} else {
|
||||
// allow any headers the user wants to set??
|
||||
// if(/cc|bcc|to|from|reply-to|sender|subject|date|message-id/i.test(header))
|
||||
this.header[header.toLowerCase()] = headers[header];
|
||||
}
|
||||
}
|
||||
|
@ -196,12 +206,19 @@ export class Message {
|
|||
* @returns {void}
|
||||
*/
|
||||
public valid(callback: (arg0: boolean, arg1?: string) => void) {
|
||||
if (!this.header.from) {
|
||||
callback(false, 'message does not have a valid sender');
|
||||
if (typeof this.header.from !== 'string') {
|
||||
callback(false, 'Message must have a `from` header');
|
||||
}
|
||||
|
||||
if (!(this.header.to || this.header.cc || this.header.bcc)) {
|
||||
callback(false, 'message does not have a valid recipient');
|
||||
if (
|
||||
typeof this.header.to !== 'string' &&
|
||||
typeof this.header.cc !== 'string' &&
|
||||
typeof this.header.bcc !== 'string'
|
||||
) {
|
||||
callback(
|
||||
false,
|
||||
'Message must have at least one `to`, `cc`, or `bcc` header'
|
||||
);
|
||||
} else if (this.attachments.length === 0) {
|
||||
callback(true, undefined);
|
||||
} else {
|
||||
|
|
|
@ -69,6 +69,65 @@ test.cb('authorize plain', (t) => {
|
|||
);
|
||||
});
|
||||
|
||||
test.cb(
|
||||
'Client refuses to send message without `to`, `cc`, or `bcc` header',
|
||||
(t) => {
|
||||
const msg = {
|
||||
subject: 'this is a test TEXT message from emailjs',
|
||||
from: 'piglet@gmail.com',
|
||||
text: "It is hard to be brave when you're only a Very Small Animal.",
|
||||
};
|
||||
client.send(new m.Message(msg), (err) => {
|
||||
t.true(err instanceof Error);
|
||||
t.is(
|
||||
err?.message,
|
||||
'Message must have at least one `to`, `cc`, or `bcc` header'
|
||||
);
|
||||
t.end();
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
test.cb('Client allows message with only `cc` header', (t) => {
|
||||
const msg = {
|
||||
subject: 'this is a test TEXT message from emailjs',
|
||||
from: 'piglet@gmail.com',
|
||||
cc: 'pooh@gmail.com',
|
||||
text: "It is hard to be brave when you're only a Very Small Animal.",
|
||||
};
|
||||
|
||||
send(
|
||||
new m.Message(msg),
|
||||
(mail) => {
|
||||
t.is(mail.text, msg.text + '\n\n\n');
|
||||
t.is(mail.subject, msg.subject);
|
||||
t.is(mail.from?.text, msg.from);
|
||||
t.is(mail.cc?.text, msg.cc);
|
||||
},
|
||||
t.end
|
||||
);
|
||||
});
|
||||
|
||||
test.cb('Client allows message with only `bcc` header', (t) => {
|
||||
const msg = {
|
||||
subject: 'this is a test TEXT message from emailjs',
|
||||
from: 'piglet@gmail.com',
|
||||
bcc: 'pooh@gmail.com',
|
||||
text: "It is hard to be brave when you're only a Very Small Animal.",
|
||||
};
|
||||
|
||||
send(
|
||||
new m.Message(msg),
|
||||
(mail) => {
|
||||
t.is(mail.text, msg.text + '\n\n\n');
|
||||
t.is(mail.subject, msg.subject);
|
||||
t.is(mail.from?.text, msg.from);
|
||||
t.is(mail.bcc?.text, undefined);
|
||||
},
|
||||
t.end
|
||||
);
|
||||
});
|
||||
|
||||
test('Client constructor throws if `password` supplied without `user`', (t) => {
|
||||
t.notThrows(() => new c.Client({ user: 'anything', password: 'anything' }));
|
||||
t.throws(() => new c.Client({ password: 'anything' }));
|
||||
|
|
Loading…
Reference in New Issue