mirror of
https://github.com/dawidd6/action-send-mail.git
synced 2025-11-02 07:55:51 +07:00
node_modules: upgrade
This commit is contained in:
6
node_modules/nodemailer/.gitattributes
generated
vendored
Normal file
6
node_modules/nodemailer/.gitattributes
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
*.js text eol=lf
|
||||
*.txt text eol=lf
|
||||
*.html text eol=lf
|
||||
*.htm text eol=lf
|
||||
*.ics -text
|
||||
*.bin -text
|
||||
58
node_modules/nodemailer/CHANGELOG.md
generated
vendored
58
node_modules/nodemailer/CHANGELOG.md
generated
vendored
@ -1,5 +1,61 @@
|
||||
# CHANGELOG
|
||||
|
||||
## 6.8.0 2022-09-28
|
||||
|
||||
- Add DNS timeout (huksley)
|
||||
- add dns.REFUSED (lucagianfelici)
|
||||
|
||||
## 6.7.8 2022-08-11
|
||||
|
||||
- Allow to use multiple Reply-To addresses
|
||||
|
||||
## 6.7.7 2022-07-06
|
||||
|
||||
- Resolver fixes
|
||||
|
||||
## 6.7.5 2022-05-04
|
||||
|
||||
- No changes, pushing a new README to npmjs.org
|
||||
|
||||
## 6.7.4 2022-04-29
|
||||
|
||||
- Ensure compatibility with Node 18
|
||||
- Replaced Travis with Github Actions
|
||||
|
||||
## 6.7.3 2022-03-21
|
||||
|
||||
- Typo fixes
|
||||
- Added stale issue automation fir Github
|
||||
- Add Infomaniak config to well known service (popod)
|
||||
- Update Outlook/Hotmail host in well known services (popod)
|
||||
- fix: DSN recipient gets ignored (KornKalle)
|
||||
|
||||
## 6.7.2 2021-11-26
|
||||
|
||||
- Fix proxies for account verification
|
||||
|
||||
## 6.7.1 2021-11-15
|
||||
|
||||
- fix verify on ses-transport (stanofsky)
|
||||
|
||||
## 6.7.0 2021-10-11
|
||||
|
||||
- Updated DNS resolving logic. If there are multiple responses for a A/AAAA record, then loop these randomly instead of only caching the first one
|
||||
|
||||
## 6.6.5 2021-09-23
|
||||
|
||||
- Replaced Object.values() and Array.flat() with polyfills to allow using Nodemailer in Node v6+
|
||||
|
||||
## 6.6.4 2021-09-22
|
||||
|
||||
- Better compatibility with IPv6-only SMTP hosts (oxzi)
|
||||
- Fix ses verify for sdk v3 (hannesvdvreken)
|
||||
- Added SECURITY.txt for contact info
|
||||
|
||||
## 6.6.3 2021-07-14
|
||||
|
||||
- Do not show passwords in SMTP transaction logs. All passwords used in logging are replaced by `"/* secret */"`
|
||||
|
||||
## 6.6.1 2021-05-23
|
||||
|
||||
- Fixed address formatting issue where newlines in an email address, if provided via address object, were not properly removed. Reported by tmazeika (#1289)
|
||||
@ -55,7 +111,7 @@
|
||||
## 6.4.7 2020-05-28
|
||||
|
||||
- Always set charset=utf-8 for Content-Type headers
|
||||
- Catch error whn using invalid crypto.sign input
|
||||
- Catch error when using invalid crypto.sign input
|
||||
|
||||
## 6.4.6 2020-03-20
|
||||
|
||||
|
||||
61
node_modules/nodemailer/README.md
generated
vendored
61
node_modules/nodemailer/README.md
generated
vendored
@ -2,12 +2,24 @@
|
||||
|
||||
[](https://nodemailer.com/about/)
|
||||
|
||||
Send e-mails from Node.js – easy as cake! 🍰✉️
|
||||
Send emails from Node.js – easy as cake! 🍰✉️
|
||||
|
||||
[](https://nodemailer.com/about/)
|
||||
|
||||
See [nodemailer.com](https://nodemailer.com/) for documentation and terms.
|
||||
|
||||
---
|
||||
|
||||
> Check out **[EmailEngine](https://emailengine.app/?utm_source=github-nodemailer&utm_campaign=nodemailer&utm_medium=readme-link)** – a self-hosted email gateway that allows making **REST requests against IMAP and SMTP servers**. EmailEngine also sends webhooks whenever something changes on the registered accounts.\
|
||||
> \
|
||||
> Using the email accounts registered with EmailEngine, you can receive and [send emails](https://emailengine.app/sending-emails?utm_source=github-nodemailer&utm_campaign=nodemailer&utm_medium=readme-link). EmailEngine supports OAuth2, delayed sends, opens and clicks tracking, bounce detection, etc. All on top of regular email accounts without an external MTA service.
|
||||
|
||||
---
|
||||
|
||||
This project is supported by [Forward Email](https://forwardemail.net) – the 100% open-source and privacy-focused email service.
|
||||
|
||||
---
|
||||
|
||||
## Having an issue?
|
||||
|
||||
#### First review the docs
|
||||
@ -16,20 +28,57 @@ Documentation for Nodemailer can be found at [nodemailer.com](https://nodemailer
|
||||
|
||||
#### Nodemailer throws a SyntaxError for "..."
|
||||
|
||||
You are using older Node.js version than v6.0. Upgrade Node.js to get support for the spread operator.
|
||||
You are using an older Node.js version than v6.0. Upgrade Node.js to get support for the spread operator. Nodemailer supports all Node.js versions starting from Node.js@v6.0.0.
|
||||
|
||||
#### I'm having issues with Gmail
|
||||
|
||||
Gmail either works well or it does not work at all. It is probably easier to switch to an alternative service instead of fixing issues with Gmail. If Gmail does not work for you then don't use it. Read more about it [here](https://nodemailer.com/usage/using-gmail/).
|
||||
Gmail either works well, or it does not work at all. It is probably easier to switch to an alternative service instead of fixing issues with Gmail. If Gmail does not work for you, then don't use it. Read more about it [here](https://nodemailer.com/usage/using-gmail/).
|
||||
|
||||
#### I get ETIMEDOUT errors
|
||||
|
||||
Check your firewall settings. Timeout usually occurs when you try to open a connection to a port that is firewalled either on the server or on your machine.
|
||||
Check your firewall settings. Timeout usually occurs when you try to open a connection to a firewalled port either on the server or on your machine. Some ISPs also block email ports to prevent spamming.
|
||||
|
||||
#### Nodemailer works on one machine but not in another
|
||||
|
||||
It's either a firewall issue, or your SMTP server blocks authentication attempts from some servers.
|
||||
|
||||
#### I get TLS errors
|
||||
|
||||
- If you are running the code in your own machine, then check your antivirus settings. Antiviruses often mess around with email ports usage. Node.js might not recognize the MITM cert your antivirus is using.
|
||||
- Latest Node versions allow only TLS versions 1.2 and higher, some servers might still use TLS 1.1 or lower. Check Node.js docs how to get correct TLS support for your app.
|
||||
- If you are running the code on your machine, check your antivirus settings. Antiviruses often mess around with email ports usage. Node.js might not recognize the MITM cert your antivirus is using.
|
||||
- Latest Node versions allow only TLS versions 1.2 and higher. Some servers might still use TLS 1.1 or lower. Check Node.js docs on how to get correct TLS support for your app. You can change this with [tls.minVersion](https://nodejs.org/dist/latest-v16.x/docs/api/tls.html#tls_tls_createsecurecontext_options) option
|
||||
- You might have the wrong value for the `secure` option. This should be set to `true` only for port 465. For every other port, it should be `false`. Setting it to `false` does not mean that Nodemailer would not use TLS. Nodemailer would still try to upgrade the connection to use TLS if the server supports it.
|
||||
- Older Node versions do not fully support the certificate chain of the newest Let's Encrypt certificates. Either set [tls.rejectUnauthorized](https://nodejs.org/dist/latest-v16.x/docs/api/tls.html#tlsconnectoptions-callback) to `false` to skip chain verification or upgrade your Node version
|
||||
|
||||
```
|
||||
let configOptions = {
|
||||
host: "smtp.example.com",
|
||||
port: 587,
|
||||
tls: {
|
||||
rejectUnauthorized: true,
|
||||
minVersion: "TLSv1.2"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### I have issues with DNS / hosts file
|
||||
|
||||
Node.js uses [c-ares](https://nodejs.org/en/docs/meta/topics/dependencies/#c-ares) to resolve domain names, not the DNS library provided by the system, so if you have some custom DNS routing set up, it might be ignored. Nodemailer runs [dns.resolve4()](https://nodejs.org/dist/latest-v16.x/docs/api/dns.html#dnsresolve4hostname-options-callback) and [dns.resolve6()](https://nodejs.org/dist/latest-v16.x/docs/api/dns.html#dnsresolve6hostname-options-callback) to resolve hostname into an IP address. If both calls fail, then Nodemailer will fall back to [dns.lookup()](https://nodejs.org/dist/latest-v16.x/docs/api/dns.html#dnslookuphostname-options-callback). If this does not work for you, you can hard code the IP address into the configuration like shown below. In that case, Nodemailer would not perform any DNS lookups.
|
||||
|
||||
```
|
||||
let configOptions = {
|
||||
host: "1.2.3.4",
|
||||
port: 465,
|
||||
secure: true,
|
||||
tls: {
|
||||
// must provide server name, otherwise TLS certificate check will fail
|
||||
servername: "example.com"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### I have an issue with TypeScript types
|
||||
|
||||
Nodemailer has official support for Node.js only. For anything related to TypeScript, you need to directly contact the authors of the [type definitions](https://www.npmjs.com/package/@types/nodemailer).
|
||||
|
||||
#### I have a different problem
|
||||
|
||||
|
||||
22
node_modules/nodemailer/SECURITY.txt
generated
vendored
Normal file
22
node_modules/nodemailer/SECURITY.txt
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
Hash: SHA256
|
||||
|
||||
Contact: mailto:andris@reinman.eu
|
||||
Encryption: https://keys.openpgp.org/vks/v1/by-fingerprint/5D952A46E1D8C931F6364E01DC6C83F4D584D364
|
||||
Preferred-Languages: en, et
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQIzBAEBCAAdFiEEXZUqRuHYyTH2Nk4B3GyD9NWE02QFAmFDnUgACgkQ3GyD9NWE
|
||||
02RqUA/+MM3afmRYq874C7wp+uN6dTMCvUX5g5zqBZ2yKpFr46L+PYvM7o8TMm5h
|
||||
hmLT2I1zZmi+xezOL3zHFizaw0tKkZIz9cWl3Jrgs0FLp0zOsSz1xucp9Q2tYM/Q
|
||||
vbiP6ys0gbim4tkDGRmZOEiO23s0BuRnmHt7vZg210O+D105Yd8/Ohzbj6PSLBO5
|
||||
W1tA7Xw5t0FQ14NNH5+MKyDIKoCX12n0FmrC6qLTXeojf291UgKhCUPda3LIGTmx
|
||||
mTXz0y68149Mw+JikRCYP8HfGRY9eA4XZrYXF7Bl2T9OJpKD3JAH+69P3xBw19Gn
|
||||
Csaw3twu8P1bxoVGjY4KRrBOp68W8TwZYjWVWbqY6oV8hb/JfrMxa+kaSxRuloFs
|
||||
oL6+phrDSPTWdOj2LlEDBJbPOMeDFzIlsBBcJ/JHCEHTvlHl7LoWr3YuWce9PUwl
|
||||
4r3JUovvaeuJxLgC0vu3WCB3Jeocsl3SreqNkrVc1IjvkSomn3YGm5nCNAd/2F0V
|
||||
exCGRk/8wbkSjAY38GwQ8K/VuFsefWN3L9sVwIMAMu88KFCAN+GzVFiwvyIXehF5
|
||||
eogP9mIXzdQ5YReQjUjApOzGz54XnDyv9RJ3sdvMHosLP+IOg+0q5t9agWv6aqSR
|
||||
2HzCpiQnH/gmM5NS0AU4Koq/L7IBeLu1B8+61/+BiHgZJJmPdgU=
|
||||
=BUZr
|
||||
-----END PGP SIGNATURE-----
|
||||
2
node_modules/nodemailer/lib/base64/index.js
generated
vendored
2
node_modules/nodemailer/lib/base64/index.js
generated
vendored
@ -51,7 +51,7 @@ function wrap(str, lineLength) {
|
||||
*
|
||||
* @constructor
|
||||
* @param {Object} options Stream options
|
||||
* @param {Number} [options.lineLength=76] Maximum lenght for lines, set to false to disable wrapping
|
||||
* @param {Number} [options.lineLength=76] Maximum length for lines, set to false to disable wrapping
|
||||
*/
|
||||
class Encoder extends Transform {
|
||||
constructor(options) {
|
||||
|
||||
8
node_modules/nodemailer/lib/dkim/index.js
generated
vendored
8
node_modules/nodemailer/lib/dkim/index.js
generated
vendored
@ -54,10 +54,10 @@ class DKIMSigner {
|
||||
this.output = output;
|
||||
this.output.usingCache = false;
|
||||
|
||||
this.errored = false;
|
||||
this.hasErrored = false;
|
||||
|
||||
this.input.on('error', err => {
|
||||
this.errored = true;
|
||||
this.hasErrored = true;
|
||||
this.cleanup();
|
||||
output.emit('error', err);
|
||||
});
|
||||
@ -84,7 +84,7 @@ class DKIMSigner {
|
||||
}
|
||||
|
||||
sendNextChunk() {
|
||||
if (this.errored) {
|
||||
if (this.hasErrored) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -145,7 +145,7 @@ class DKIMSigner {
|
||||
// do nothing
|
||||
}
|
||||
});
|
||||
this.errored = true;
|
||||
this.hasErrored = true;
|
||||
// emit error
|
||||
this.output.emit('error', err);
|
||||
});
|
||||
|
||||
6
node_modules/nodemailer/lib/fetch/index.js
generated
vendored
6
node_modules/nodemailer/lib/fetch/index.js
generated
vendored
@ -11,12 +11,12 @@ const packageData = require('../../package.json');
|
||||
const MAX_REDIRECTS = 5;
|
||||
|
||||
module.exports = function (url, options) {
|
||||
return fetch(url, options);
|
||||
return nmfetch(url, options);
|
||||
};
|
||||
|
||||
module.exports.Cookies = Cookies;
|
||||
|
||||
function fetch(url, options) {
|
||||
function nmfetch(url, options) {
|
||||
options = options || {};
|
||||
|
||||
options.fetchRes = options.fetchRes || new PassThrough();
|
||||
@ -202,7 +202,7 @@ function fetch(url, options) {
|
||||
// redirect does not include POST body
|
||||
options.method = 'GET';
|
||||
options.body = false;
|
||||
return fetch(urllib.resolve(url, res.headers.location), options);
|
||||
return nmfetch(urllib.resolve(url, res.headers.location), options);
|
||||
}
|
||||
|
||||
fetchRes.statusCode = res.statusCode;
|
||||
|
||||
4
node_modules/nodemailer/lib/mailer/index.js
generated
vendored
4
node_modules/nodemailer/lib/mailer/index.js
generated
vendored
@ -95,6 +95,10 @@ class Mail extends EventEmitter {
|
||||
['close', 'isIdle', 'verify'].forEach(method => {
|
||||
this[method] = (...args) => {
|
||||
if (typeof this.transporter[method] === 'function') {
|
||||
if (method === 'verify' && typeof this.getSocket === 'function') {
|
||||
this.transporter.getSocket = this.getSocket;
|
||||
this.getSocket = false;
|
||||
}
|
||||
return this.transporter[method](...args);
|
||||
} else {
|
||||
this.logger.warn(
|
||||
|
||||
2
node_modules/nodemailer/lib/mailer/mail-message.js
generated
vendored
2
node_modules/nodemailer/lib/mailer/mail-message.js
generated
vendored
@ -96,7 +96,7 @@ class MailMessage {
|
||||
}
|
||||
});
|
||||
|
||||
let singleKeys = ['from', 'sender', 'replyTo'];
|
||||
let singleKeys = ['from', 'sender'];
|
||||
singleKeys.forEach(address => {
|
||||
if (this.data[address]) {
|
||||
this.data[address] = this.data[address].shift();
|
||||
|
||||
4
node_modules/nodemailer/lib/mime-funcs/mime-types.js
generated
vendored
4
node_modules/nodemailer/lib/mime-funcs/mime-types.js
generated
vendored
@ -532,7 +532,7 @@ const mimeTypes = new Map([
|
||||
['application/x-bittorrent', 'torrent'],
|
||||
['application/x-bsh', ['bsh', 'sh', 'shar']],
|
||||
['application/x-bytecode.elisp', 'elc'],
|
||||
['applicaiton/x-bytecode.python', 'pyc'],
|
||||
['application/x-bytecode.python', 'pyc'],
|
||||
['application/x-bzip', 'bz'],
|
||||
['application/x-bzip2', ['boz', 'bz2']],
|
||||
['application/x-cdf', 'cdf'],
|
||||
@ -1688,7 +1688,7 @@ const extensions = new Map([
|
||||
['pwz', 'application/vnd.ms-powerpoint'],
|
||||
['py', 'text/x-script.phyton'],
|
||||
['pya', 'audio/vnd.ms-playready.media.pya'],
|
||||
['pyc', 'applicaiton/x-bytecode.python'],
|
||||
['pyc', 'application/x-bytecode.python'],
|
||||
['pyv', 'video/vnd.ms-playready.media.pyv'],
|
||||
['qam', 'application/vnd.epson.quickanime'],
|
||||
['qbo', 'application/vnd.intu.qbo'],
|
||||
|
||||
7
node_modules/nodemailer/lib/mime-node/index.js
generated
vendored
7
node_modules/nodemailer/lib/mime-node/index.js
generated
vendored
@ -3,7 +3,6 @@
|
||||
'use strict';
|
||||
|
||||
const crypto = require('crypto');
|
||||
const os = require('os');
|
||||
const fs = require('fs');
|
||||
const punycode = require('punycode');
|
||||
const PassThrough = require('stream').PassThrough;
|
||||
@ -13,7 +12,7 @@ const mimeFuncs = require('../mime-funcs');
|
||||
const qp = require('../qp');
|
||||
const base64 = require('../base64');
|
||||
const addressparser = require('../addressparser');
|
||||
const fetch = require('../fetch');
|
||||
const nmfetch = require('../fetch');
|
||||
const LastNewline = require('./last-newline');
|
||||
|
||||
const LeWindows = require('./le-windows');
|
||||
@ -971,7 +970,7 @@ class MimeNode {
|
||||
return contentStream;
|
||||
}
|
||||
// fetch URL
|
||||
return fetch(content.href, { headers: content.httpHeaders });
|
||||
return nmfetch(content.href, { headers: content.httpHeaders });
|
||||
} else {
|
||||
// pass string or buffer content as a stream
|
||||
contentStream = new PassThrough();
|
||||
@ -1282,7 +1281,7 @@ class MimeNode {
|
||||
) +
|
||||
'@' +
|
||||
// try to use the domain of the FROM address or fallback to server hostname
|
||||
(this.getEnvelope().from || this.hostname || os.hostname() || 'localhost').split('@').pop() +
|
||||
(this.getEnvelope().from || this.hostname || 'localhost').split('@').pop() +
|
||||
'>'
|
||||
);
|
||||
}
|
||||
|
||||
4
node_modules/nodemailer/lib/nodemailer.js
generated
vendored
4
node_modules/nodemailer/lib/nodemailer.js
generated
vendored
@ -8,7 +8,7 @@ const SendmailTransport = require('./sendmail-transport');
|
||||
const StreamTransport = require('./stream-transport');
|
||||
const JSONTransport = require('./json-transport');
|
||||
const SESTransport = require('./ses-transport');
|
||||
const fetch = require('./fetch');
|
||||
const nmfetch = require('./fetch');
|
||||
const packageData = require('../package.json');
|
||||
|
||||
const ETHEREAL_API = (process.env.ETHEREAL_API || 'https://api.nodemailer.com').replace(/\/+$/, '');
|
||||
@ -79,7 +79,7 @@ module.exports.createTestAccount = function (apiUrl, callback) {
|
||||
let chunks = [];
|
||||
let chunklen = 0;
|
||||
|
||||
let req = fetch(apiUrl + '/user', {
|
||||
let req = nmfetch(apiUrl + '/user', {
|
||||
contentType: 'application/json',
|
||||
method: 'POST',
|
||||
body: Buffer.from(
|
||||
|
||||
2
node_modules/nodemailer/lib/qp/index.js
generated
vendored
2
node_modules/nodemailer/lib/qp/index.js
generated
vendored
@ -149,7 +149,7 @@ function checkRanges(nr, ranges) {
|
||||
*
|
||||
* @constructor
|
||||
* @param {Object} options Stream options
|
||||
* @param {Number} [options.lineLength=76] Maximum lenght for lines, set to false to disable wrapping
|
||||
* @param {Number} [options.lineLength=76] Maximum length for lines, set to false to disable wrapping
|
||||
*/
|
||||
class Encoder extends Transform {
|
||||
constructor(options) {
|
||||
|
||||
15
node_modules/nodemailer/lib/ses-transport/index.js
generated
vendored
15
node_modules/nodemailer/lib/ses-transport/index.js
generated
vendored
@ -320,25 +320,26 @@ class SESTransport extends EventEmitter {
|
||||
Source: 'invalid@invalid',
|
||||
Destinations: ['invalid@invalid']
|
||||
};
|
||||
const cb = err => {
|
||||
if (err && err.code !== 'InvalidParameterValue') {
|
||||
return callback(err);
|
||||
}
|
||||
return callback(null, true);
|
||||
};
|
||||
|
||||
if (!callback) {
|
||||
promise = new Promise((resolve, reject) => {
|
||||
callback = shared.callbackPromise(resolve, reject);
|
||||
});
|
||||
}
|
||||
const cb = err => {
|
||||
if (err && (err.code || err.Code) !== 'InvalidParameterValue') {
|
||||
return callback(err);
|
||||
}
|
||||
return callback(null, true);
|
||||
};
|
||||
|
||||
if (typeof ses.send === 'function' && aws.SendRawEmailCommand) {
|
||||
// v3 API
|
||||
sesMessage.RawMessage.Data = Buffer.from(sesMessage.RawMessage.Data);
|
||||
ses.send(new aws.SendRawEmailCommand(sesMessage), cb);
|
||||
} else {
|
||||
// v2 API
|
||||
ses.sendRawEmail(sesMessage, cb).promise();
|
||||
ses.sendRawEmail(sesMessage, cb);
|
||||
}
|
||||
|
||||
return promise;
|
||||
|
||||
191
node_modules/nodemailer/lib/shared/index.js
generated
vendored
191
node_modules/nodemailer/lib/shared/index.js
generated
vendored
@ -5,14 +5,51 @@
|
||||
const urllib = require('url');
|
||||
const util = require('util');
|
||||
const fs = require('fs');
|
||||
const fetch = require('../fetch');
|
||||
const nmfetch = require('../fetch');
|
||||
const dns = require('dns');
|
||||
const net = require('net');
|
||||
const os = require('os');
|
||||
|
||||
const DNS_TTL = 5 * 60 * 1000;
|
||||
|
||||
const resolver = (family, hostname, callback) => {
|
||||
dns['resolve' + family](hostname, (err, addresses) => {
|
||||
let networkInterfaces;
|
||||
try {
|
||||
networkInterfaces = os.networkInterfaces();
|
||||
} catch (err) {
|
||||
// fails on some systems
|
||||
}
|
||||
|
||||
module.exports.networkInterfaces = networkInterfaces;
|
||||
|
||||
const isFamilySupported = (family, allowInternal) => {
|
||||
let networkInterfaces = module.exports.networkInterfaces;
|
||||
if (!networkInterfaces) {
|
||||
// hope for the best
|
||||
return true;
|
||||
}
|
||||
|
||||
const familySupported =
|
||||
// crux that replaces Object.values(networkInterfaces) as Object.values is not supported in nodejs v6
|
||||
Object.keys(networkInterfaces)
|
||||
.map(key => networkInterfaces[key])
|
||||
// crux that replaces .flat() as it is not supported in older Node versions (v10 and older)
|
||||
.reduce((acc, val) => acc.concat(val), [])
|
||||
.filter(i => !i.internal || allowInternal)
|
||||
.filter(i => i.family === 'IPv' + family || i.family === family).length > 0;
|
||||
|
||||
return familySupported;
|
||||
};
|
||||
|
||||
const resolver = (family, hostname, options, callback) => {
|
||||
options = options || {};
|
||||
const familySupported = isFamilySupported(family, options.allowInternalNetworkInterfaces);
|
||||
|
||||
if (!familySupported) {
|
||||
return callback(null, []);
|
||||
}
|
||||
|
||||
const resolver = dns.Resolver ? new dns.Resolver(options) : dns;
|
||||
resolver['resolve' + family](hostname, (err, addresses) => {
|
||||
if (err) {
|
||||
switch (err.code) {
|
||||
case dns.NODATA:
|
||||
@ -20,6 +57,7 @@ const resolver = (family, hostname, callback) => {
|
||||
case dns.NOTIMP:
|
||||
case dns.SERVFAIL:
|
||||
case dns.CONNREFUSED:
|
||||
case dns.REFUSED:
|
||||
case 'EAI_AGAIN':
|
||||
return callback(null, []);
|
||||
}
|
||||
@ -30,100 +68,195 @@ const resolver = (family, hostname, callback) => {
|
||||
};
|
||||
|
||||
const dnsCache = (module.exports.dnsCache = new Map());
|
||||
|
||||
const formatDNSValue = (value, extra) => {
|
||||
if (!value) {
|
||||
return Object.assign({}, extra || {});
|
||||
}
|
||||
|
||||
return Object.assign(
|
||||
{
|
||||
servername: value.servername,
|
||||
host:
|
||||
!value.addresses || !value.addresses.length
|
||||
? null
|
||||
: value.addresses.length === 1
|
||||
? value.addresses[0]
|
||||
: value.addresses[Math.floor(Math.random() * value.addresses.length)]
|
||||
},
|
||||
extra || {}
|
||||
);
|
||||
};
|
||||
|
||||
module.exports.resolveHostname = (options, callback) => {
|
||||
options = options || {};
|
||||
|
||||
if (!options.host && options.servername) {
|
||||
options.host = options.servername;
|
||||
}
|
||||
|
||||
if (!options.host || net.isIP(options.host)) {
|
||||
// nothing to do here
|
||||
let value = {
|
||||
host: options.host,
|
||||
addresses: [options.host],
|
||||
servername: options.servername || false
|
||||
};
|
||||
return callback(null, value);
|
||||
return callback(
|
||||
null,
|
||||
formatDNSValue(value, {
|
||||
cached: false
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
let cached;
|
||||
|
||||
if (dnsCache.has(options.host)) {
|
||||
cached = dnsCache.get(options.host);
|
||||
|
||||
if (!cached.expires || cached.expires >= Date.now()) {
|
||||
return callback(null, {
|
||||
host: cached.value.host,
|
||||
servername: cached.value.servername,
|
||||
_cached: true
|
||||
});
|
||||
return callback(
|
||||
null,
|
||||
formatDNSValue(cached.value, {
|
||||
cached: true
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
resolver(4, options.host, (err, addresses) => {
|
||||
resolver(4, options.host, options, (err, addresses) => {
|
||||
if (err) {
|
||||
if (cached) {
|
||||
// ignore error, use expired value
|
||||
return callback(null, cached.value);
|
||||
return callback(
|
||||
null,
|
||||
formatDNSValue(cached.value, {
|
||||
cached: true,
|
||||
error: err
|
||||
})
|
||||
);
|
||||
}
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
if (addresses && addresses.length) {
|
||||
let value = {
|
||||
host: addresses[0] || options.host,
|
||||
addresses,
|
||||
servername: options.servername || options.host
|
||||
};
|
||||
|
||||
dnsCache.set(options.host, {
|
||||
value,
|
||||
expires: Date.now() + DNS_TTL
|
||||
expires: Date.now() + (options.dnsTtl || DNS_TTL)
|
||||
});
|
||||
return callback(null, value);
|
||||
|
||||
return callback(
|
||||
null,
|
||||
formatDNSValue(value, {
|
||||
cached: false
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
resolver(6, options.host, (err, addresses) => {
|
||||
resolver(6, options.host, options, (err, addresses) => {
|
||||
if (err) {
|
||||
if (cached) {
|
||||
// ignore error, use expired value
|
||||
return callback(null, cached.value);
|
||||
return callback(
|
||||
null,
|
||||
formatDNSValue(cached.value, {
|
||||
cached: true,
|
||||
error: err
|
||||
})
|
||||
);
|
||||
}
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
if (addresses && addresses.length) {
|
||||
let value = {
|
||||
host: addresses[0] || options.host,
|
||||
addresses,
|
||||
servername: options.servername || options.host
|
||||
};
|
||||
|
||||
dnsCache.set(options.host, {
|
||||
value,
|
||||
expires: Date.now() + DNS_TTL
|
||||
expires: Date.now() + (options.dnsTtl || DNS_TTL)
|
||||
});
|
||||
return callback(null, value);
|
||||
|
||||
return callback(
|
||||
null,
|
||||
formatDNSValue(value, {
|
||||
cached: false
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
dns.lookup(options.host, {}, (err, address) => {
|
||||
dns.lookup(options.host, { all: true }, (err, addresses) => {
|
||||
if (err) {
|
||||
if (cached) {
|
||||
// ignore error, use expired value
|
||||
return callback(null, cached.value);
|
||||
return callback(
|
||||
null,
|
||||
formatDNSValue(cached.value, {
|
||||
cached: true,
|
||||
error: err
|
||||
})
|
||||
);
|
||||
}
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
let address = addresses
|
||||
? addresses
|
||||
.filter(addr => isFamilySupported(addr.family))
|
||||
.map(addr => addr.address)
|
||||
.shift()
|
||||
: false;
|
||||
|
||||
if (addresses && addresses.length && !address) {
|
||||
// there are addresses but none can be used
|
||||
let err = new Error(`Can not use IPv${addresses[0].family} addresses with current network`);
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
if (!address && cached) {
|
||||
// nothing was found, fallback to cached value
|
||||
return callback(null, cached.value);
|
||||
return callback(
|
||||
null,
|
||||
formatDNSValue(cached.value, {
|
||||
cached: true
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
let value = {
|
||||
host: address || options.host,
|
||||
addresses: address ? [address] : [options.host],
|
||||
servername: options.servername || options.host
|
||||
};
|
||||
|
||||
dnsCache.set(options.host, {
|
||||
value,
|
||||
expires: Date.now() + DNS_TTL
|
||||
expires: Date.now() + (options.dnsTtl || DNS_TTL)
|
||||
});
|
||||
return callback(null, value);
|
||||
|
||||
return callback(
|
||||
null,
|
||||
formatDNSValue(value, {
|
||||
cached: false
|
||||
})
|
||||
);
|
||||
});
|
||||
} catch (err) {
|
||||
if (cached) {
|
||||
// ignore error, use expired value
|
||||
return callback(null, cached.value);
|
||||
return callback(
|
||||
null,
|
||||
formatDNSValue(cached.value, {
|
||||
cached: true,
|
||||
error: err
|
||||
})
|
||||
);
|
||||
}
|
||||
return callback(err);
|
||||
}
|
||||
@ -335,7 +468,7 @@ module.exports.resolveContent = (data, key, callback) => {
|
||||
callback(null, value);
|
||||
});
|
||||
} else if (/^https?:\/\//i.test(content.path || content.href)) {
|
||||
contentStream = fetch(content.path || content.href);
|
||||
contentStream = nmfetch(content.path || content.href);
|
||||
return resolveStream(contentStream, callback);
|
||||
} else if (/^data:/i.test(content.path || content.href)) {
|
||||
let parts = (content.path || content.href).match(/^data:((?:[^;]*;)*(?:[^,]*)),(.*)$/i);
|
||||
|
||||
14
node_modules/nodemailer/lib/smtp-connection/http-proxy-client.js
generated
vendored
14
node_modules/nodemailer/lib/smtp-connection/http-proxy-client.js
generated
vendored
@ -44,7 +44,7 @@ function httpProxyClient(proxyUrl, destinationPort, destinationHost, callback) {
|
||||
// Error harness for initial connection. Once connection is established, the responsibility
|
||||
// to handle errors is passed to whoever uses this socket
|
||||
let finished = false;
|
||||
let tempSocketErr = function (err) {
|
||||
let tempSocketErr = err => {
|
||||
if (finished) {
|
||||
return;
|
||||
}
|
||||
@ -57,6 +57,12 @@ function httpProxyClient(proxyUrl, destinationPort, destinationHost, callback) {
|
||||
callback(err);
|
||||
};
|
||||
|
||||
let timeoutErr = () => {
|
||||
let err = new Error('Proxy socket timed out');
|
||||
err.code = 'ETIMEDOUT';
|
||||
tempSocketErr(err);
|
||||
};
|
||||
|
||||
socket = connect(options, () => {
|
||||
if (finished) {
|
||||
return;
|
||||
@ -119,12 +125,18 @@ function httpProxyClient(proxyUrl, destinationPort, destinationHost, callback) {
|
||||
}
|
||||
|
||||
socket.removeListener('error', tempSocketErr);
|
||||
socket.removeListener('timeout', timeoutErr);
|
||||
socket.setTimeout(0);
|
||||
|
||||
return callback(null, socket);
|
||||
}
|
||||
};
|
||||
socket.on('data', onSocketData);
|
||||
});
|
||||
|
||||
socket.setTimeout(httpProxyClient.timeout || 30 * 1000);
|
||||
socket.on('timeout', timeoutErr);
|
||||
|
||||
socket.once('error', tempSocketErr);
|
||||
}
|
||||
|
||||
|
||||
72
node_modules/nodemailer/lib/smtp-connection/index.js
generated
vendored
72
node_modules/nodemailer/lib/smtp-connection/index.js
generated
vendored
@ -14,6 +14,7 @@ const shared = require('../shared');
|
||||
const CONNECTION_TIMEOUT = 2 * 60 * 1000; // how much to wait for the connection to be established
|
||||
const SOCKET_TIMEOUT = 10 * 60 * 1000; // how much to wait for socket inactivity before disconnecting the client
|
||||
const GREETING_TIMEOUT = 30 * 1000; // how much to wait after connection is established but SMTP greeting is not receieved
|
||||
const DNS_TIMEOUT = 30 * 1000; // how much to wait for resolveHostname
|
||||
|
||||
/**
|
||||
* Generates a SMTP connection object
|
||||
@ -30,6 +31,7 @@ const GREETING_TIMEOUT = 30 * 1000; // how much to wait after connection is esta
|
||||
* * **greetingTimeout** - Time to wait in ms until greeting message is received from the server (defaults to 10000)
|
||||
* * **connectionTimeout** - how many milliseconds to wait for the connection to establish
|
||||
* * **socketTimeout** - Time of inactivity until the connection is closed (defaults to 1 hour)
|
||||
* * **dnsTimeout** - Time to wait in ms for the DNS requests to be resolved (defaults to 30 seconds)
|
||||
* * **lmtp** - if true, uses LMTP instead of SMTP protocol
|
||||
* * **logger** - bunyan compatible logger interface
|
||||
* * **debug** - if true pass SMTP traffic to the logger
|
||||
@ -56,6 +58,8 @@ class SMTPConnection extends EventEmitter {
|
||||
this.port = Number(this.options.port) || (this.secureConnection ? 465 : 587);
|
||||
this.host = this.options.host || 'localhost';
|
||||
|
||||
this.allowInternalNetworkInterfaces = this.options.allowInternalNetworkInterfaces || false;
|
||||
|
||||
if (typeof this.options.secure === 'undefined' && this.port === 465) {
|
||||
// if secure option is not set but port is 465, then default to secure
|
||||
this.secureConnection = true;
|
||||
@ -217,7 +221,9 @@ class SMTPConnection extends EventEmitter {
|
||||
|
||||
let opts = {
|
||||
port: this.port,
|
||||
host: this.host
|
||||
host: this.host,
|
||||
allowInternalNetworkInterfaces: this.allowInternalNetworkInterfaces,
|
||||
timeout: this.options.dnsTimeout || DNS_TIMEOUT
|
||||
};
|
||||
|
||||
if (this.options.localAddress) {
|
||||
@ -261,12 +267,12 @@ class SMTPConnection extends EventEmitter {
|
||||
tnx: 'dns',
|
||||
source: opts.host,
|
||||
resolved: resolved.host,
|
||||
cached: !!resolved._cached
|
||||
cached: !!resolved.cached
|
||||
},
|
||||
'Resolved %s as %s [cache %s]',
|
||||
opts.host,
|
||||
resolved.host,
|
||||
resolved._cached ? 'hit' : 'miss'
|
||||
resolved.cached ? 'hit' : 'miss'
|
||||
);
|
||||
Object.keys(resolved).forEach(key => {
|
||||
if (key.charAt(0) !== '_' && resolved[key]) {
|
||||
@ -299,12 +305,12 @@ class SMTPConnection extends EventEmitter {
|
||||
tnx: 'dns',
|
||||
source: opts.host,
|
||||
resolved: resolved.host,
|
||||
cached: !!resolved._cached
|
||||
cached: !!resolved.cached
|
||||
},
|
||||
'Resolved %s as %s [cache %s]',
|
||||
opts.host,
|
||||
resolved.host,
|
||||
resolved._cached ? 'hit' : 'miss'
|
||||
resolved.cached ? 'hit' : 'miss'
|
||||
);
|
||||
Object.keys(resolved).forEach(key => {
|
||||
if (key.charAt(0) !== '_' && resolved[key]) {
|
||||
@ -332,12 +338,12 @@ class SMTPConnection extends EventEmitter {
|
||||
tnx: 'dns',
|
||||
source: opts.host,
|
||||
resolved: resolved.host,
|
||||
cached: !!resolved._cached
|
||||
cached: !!resolved.cached
|
||||
},
|
||||
'Resolved %s as %s [cache %s]',
|
||||
opts.host,
|
||||
resolved.host,
|
||||
resolved._cached ? 'hit' : 'miss'
|
||||
resolved.cached ? 'hit' : 'miss'
|
||||
);
|
||||
Object.keys(resolved).forEach(key => {
|
||||
if (key.charAt(0) !== '_' && resolved[key]) {
|
||||
@ -548,6 +554,16 @@ class SMTPConnection extends EventEmitter {
|
||||
'\u0000' +
|
||||
this._auth.credentials.pass,
|
||||
'utf-8'
|
||||
).toString('base64'),
|
||||
// log entry without passwords
|
||||
'AUTH PLAIN ' +
|
||||
Buffer.from(
|
||||
//this._auth.user+'\u0000'+
|
||||
'\u0000' + // skip authorization identity as it causes problems with some servers
|
||||
this._auth.credentials.user +
|
||||
'\u0000' +
|
||||
'/* secret */',
|
||||
'utf-8'
|
||||
).toString('base64')
|
||||
);
|
||||
return;
|
||||
@ -945,8 +961,9 @@ class SMTPConnection extends EventEmitter {
|
||||
* Send a command to the server, append \r\n
|
||||
*
|
||||
* @param {String} str String to be sent to the server
|
||||
* @param {String} logStr Optional string to be used for logging instead of the actual string
|
||||
*/
|
||||
_sendCommand(str) {
|
||||
_sendCommand(str, logStr) {
|
||||
if (this._destroyed) {
|
||||
// Connection already closed, can't send any more data
|
||||
return;
|
||||
@ -961,7 +978,7 @@ class SMTPConnection extends EventEmitter {
|
||||
{
|
||||
tnx: 'client'
|
||||
},
|
||||
(str || '').toString().replace(/\r?\n$/, '')
|
||||
(logStr || str || '').toString().replace(/\r?\n$/, '')
|
||||
);
|
||||
}
|
||||
|
||||
@ -1097,7 +1114,7 @@ class SMTPConnection extends EventEmitter {
|
||||
notify = notify.join(',');
|
||||
}
|
||||
|
||||
let orcpt = (params.orcpt || params.recipient || '').toString() || null;
|
||||
let orcpt = (params.recipient || params.orcpt || '').toString() || null;
|
||||
if (orcpt && orcpt.indexOf(';') < 0) {
|
||||
orcpt = 'rfc822;' + orcpt;
|
||||
}
|
||||
@ -1420,18 +1437,21 @@ class SMTPConnection extends EventEmitter {
|
||||
|
||||
// Decode from base64
|
||||
let base64decoded = Buffer.from(challengeString, 'base64').toString('ascii'),
|
||||
hmac_md5 = crypto.createHmac('md5', this._auth.credentials.pass);
|
||||
hmacMD5 = crypto.createHmac('md5', this._auth.credentials.pass);
|
||||
|
||||
hmac_md5.update(base64decoded);
|
||||
hmacMD5.update(base64decoded);
|
||||
|
||||
let hex_hmac = hmac_md5.digest('hex');
|
||||
let prepended = this._auth.credentials.user + ' ' + hex_hmac;
|
||||
let prepended = this._auth.credentials.user + ' ' + hmacMD5.digest('hex');
|
||||
|
||||
this._responseActions.push(str => {
|
||||
this._actionAUTH_CRAM_MD5_PASS(str, callback);
|
||||
});
|
||||
|
||||
this._sendCommand(Buffer.from(prepended).toString('base64'));
|
||||
this._sendCommand(
|
||||
Buffer.from(prepended).toString('base64'),
|
||||
// hidden hash for logs
|
||||
Buffer.from(this._auth.credentials.user + ' /* secret */').toString('base64')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1476,7 +1496,11 @@ class SMTPConnection extends EventEmitter {
|
||||
this._actionAUTHComplete(str, callback);
|
||||
});
|
||||
|
||||
this._sendCommand(Buffer.from(this._auth.credentials.pass + '', 'utf-8').toString('base64'));
|
||||
this._sendCommand(
|
||||
Buffer.from((this._auth.credentials.pass || '').toString(), 'utf-8').toString('base64'),
|
||||
// Hidden pass for logs
|
||||
Buffer.from('/* secret */', 'utf-8').toString('base64')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1706,7 +1730,11 @@ class SMTPConnection extends EventEmitter {
|
||||
this._responseActions.push(str => {
|
||||
this._actionAUTHComplete(str, isRetry, callback);
|
||||
});
|
||||
this._sendCommand('AUTH XOAUTH2 ' + this._auth.oauth2.buildXOAuth2Token(accessToken));
|
||||
this._sendCommand(
|
||||
'AUTH XOAUTH2 ' + this._auth.oauth2.buildXOAuth2Token(accessToken),
|
||||
// Hidden for logs
|
||||
'AUTH XOAUTH2 ' + this._auth.oauth2.buildXOAuth2Token('/* secret */')
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@ -1733,10 +1761,16 @@ class SMTPConnection extends EventEmitter {
|
||||
|
||||
_getHostname() {
|
||||
// defaul hostname is machine hostname or [IP]
|
||||
let defaultHostname = os.hostname() || '';
|
||||
let defaultHostname;
|
||||
try {
|
||||
defaultHostname = os.hostname() || '';
|
||||
} catch (err) {
|
||||
// fails on windows 7
|
||||
defaultHostname = 'localhost';
|
||||
}
|
||||
|
||||
// ignore if not FQDN
|
||||
if (defaultHostname.indexOf('.') < 0) {
|
||||
if (!defaultHostname || defaultHostname.indexOf('.') < 0) {
|
||||
defaultHostname = '[127.0.0.1]';
|
||||
}
|
||||
|
||||
|
||||
7
node_modules/nodemailer/lib/smtp-pool/index.js
generated
vendored
7
node_modules/nodemailer/lib/smtp-pool/index.js
generated
vendored
@ -627,6 +627,13 @@ class SMTPPool extends EventEmitter {
|
||||
|
||||
finalize();
|
||||
});
|
||||
} else if (!auth && connection.allowsAuth && options.forceAuth) {
|
||||
let err = new Error('Authentication info was not provided');
|
||||
err.code = 'NoAuth';
|
||||
|
||||
returned = true;
|
||||
connection.close();
|
||||
return callback(err);
|
||||
} else {
|
||||
finalize();
|
||||
}
|
||||
|
||||
8
node_modules/nodemailer/lib/smtp-transport/index.js
generated
vendored
8
node_modules/nodemailer/lib/smtp-transport/index.js
generated
vendored
@ -18,6 +18,7 @@ class SMTPTransport extends EventEmitter {
|
||||
super();
|
||||
|
||||
options = options || {};
|
||||
|
||||
if (typeof options === 'string') {
|
||||
options = {
|
||||
url: options
|
||||
@ -384,6 +385,13 @@ class SMTPTransport extends EventEmitter {
|
||||
|
||||
finalize();
|
||||
});
|
||||
} else if (!authData && connection.allowsAuth && options.forceAuth) {
|
||||
let err = new Error('Authentication info was not provided');
|
||||
err.code = 'NoAuth';
|
||||
|
||||
returned = true;
|
||||
connection.close();
|
||||
return callback(err);
|
||||
} else {
|
||||
finalize();
|
||||
}
|
||||
|
||||
18
node_modules/nodemailer/lib/well-known/services.json
generated
vendored
18
node_modules/nodemailer/lib/well-known/services.json
generated
vendored
@ -11,6 +11,12 @@
|
||||
"host": "smtp.aol.com",
|
||||
"port": 587
|
||||
},
|
||||
|
||||
"Bluewin": {
|
||||
"host": "smtpauths.bluewin.ch",
|
||||
"domains": ["bluewin.ch"],
|
||||
"port": 465
|
||||
},
|
||||
|
||||
"DebugMail": {
|
||||
"host": "debugmail.io",
|
||||
@ -72,7 +78,7 @@
|
||||
"Hotmail": {
|
||||
"aliases": ["Outlook", "Outlook.com", "Hotmail.com"],
|
||||
"domains": ["hotmail.com", "outlook.com"],
|
||||
"host": "smtp.live.com",
|
||||
"host": "smtp-mail.outlook.com",
|
||||
"port": 587
|
||||
},
|
||||
|
||||
@ -83,6 +89,12 @@
|
||||
"port": 587
|
||||
},
|
||||
|
||||
"Infomaniak": {
|
||||
"host": "mail.infomaniak.com",
|
||||
"domains": ["ik.me", "ikmail.com", "etik.com"],
|
||||
"port": 587
|
||||
},
|
||||
|
||||
"mail.ee": {
|
||||
"host": "smtp.mail.ee"
|
||||
},
|
||||
@ -182,8 +194,8 @@
|
||||
},
|
||||
|
||||
"SendCloud": {
|
||||
"host": "smtpcloud.sohu.com",
|
||||
"port": 25
|
||||
"host": "smtp.sendcloud.net",
|
||||
"port": 2525
|
||||
},
|
||||
|
||||
"SendGrid": {
|
||||
|
||||
4
node_modules/nodemailer/lib/xoauth2/index.js
generated
vendored
4
node_modules/nodemailer/lib/xoauth2/index.js
generated
vendored
@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const Stream = require('stream').Stream;
|
||||
const fetch = require('../fetch');
|
||||
const nmfetch = require('../fetch');
|
||||
const crypto = require('crypto');
|
||||
const shared = require('../shared');
|
||||
|
||||
@ -310,7 +310,7 @@ class XOAuth2 extends Stream {
|
||||
let chunks = [];
|
||||
let chunklen = 0;
|
||||
|
||||
let req = fetch(url, {
|
||||
let req = nmfetch(url, {
|
||||
method: 'post',
|
||||
headers: params.customHeaders,
|
||||
body: payload,
|
||||
|
||||
24
node_modules/nodemailer/package.json
generated
vendored
24
node_modules/nodemailer/package.json
generated
vendored
@ -1,10 +1,10 @@
|
||||
{
|
||||
"name": "nodemailer",
|
||||
"version": "6.6.2",
|
||||
"version": "6.8.0",
|
||||
"description": "Easy as cake e-mail sending from your Node.js applications",
|
||||
"main": "lib/nodemailer.js",
|
||||
"scripts": {
|
||||
"test": "grunt"
|
||||
"test": "grunt --trace-warnings"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -20,23 +20,25 @@
|
||||
},
|
||||
"homepage": "https://nodemailer.com/",
|
||||
"devDependencies": {
|
||||
"@aws-sdk/client-ses": "3.180.0",
|
||||
"aws-sdk": "2.1225.0",
|
||||
"bunyan": "1.8.15",
|
||||
"chai": "4.3.4",
|
||||
"chai": "4.3.6",
|
||||
"eslint-config-nodemailer": "1.2.0",
|
||||
"eslint-config-prettier": "8.3.0",
|
||||
"grunt": "1.4.1",
|
||||
"eslint-config-prettier": "8.5.0",
|
||||
"grunt": "1.5.3",
|
||||
"grunt-cli": "1.4.3",
|
||||
"grunt-eslint": "23.0.0",
|
||||
"grunt-eslint": "24.0.0",
|
||||
"grunt-mocha-test": "0.13.3",
|
||||
"libbase64": "1.2.1",
|
||||
"libmime": "5.0.0",
|
||||
"libmime": "5.1.0",
|
||||
"libqp": "1.1.0",
|
||||
"mocha": "9.0.0",
|
||||
"nodemailer-ntlm-auth": "1.0.1",
|
||||
"mocha": "10.0.0",
|
||||
"nodemailer-ntlm-auth": "1.0.3",
|
||||
"proxy": "1.0.2",
|
||||
"proxy-test-server": "1.0.0",
|
||||
"sinon": "11.1.1",
|
||||
"smtp-server": "3.9.0"
|
||||
"sinon": "14.0.0",
|
||||
"smtp-server": "3.11.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
|
||||
Reference in New Issue
Block a user