mirror of https://github.com/eleith/emailjs.git
Compare commits
6 Commits
8b3c0b16f8
...
3a4ba01e01
Author | SHA1 | Date |
---|---|---|
eleith | 3a4ba01e01 | |
eleith | 426d270068 | |
eleith | 03694001e5 | |
eleith | ed54a25008 | |
eleith | 70b89d9361 | |
eleith | a6063e44a6 |
|
@ -12,10 +12,10 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: node
|
||||
uses: actions/setup-node@v2
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
|
||||
|
|
|
@ -8,14 +8,14 @@ jobs:
|
|||
fail-fast: false
|
||||
matrix:
|
||||
node: [^12, ^14, ^16, ^18]
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: node
|
||||
uses: actions/setup-node@v2
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
|
||||
|
|
|
@ -4,7 +4,11 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [3.9.0] - [TBD]
|
||||
## [4.0.2] - 2023-05-12
|
||||
### Fixed
|
||||
- redact passwords in error messages [#339](https://github.com/eleith/emailjs/issues/339)
|
||||
|
||||
## [4.0.0] - 2022-04-20
|
||||
### Added
|
||||
- support `isolatedModules` and `preserveValueImports` compilation scenarios [#305](https://github.com/eleith/emailjs/pull/305)
|
||||
|
||||
|
|
3
email.js
3
email.js
|
@ -1249,7 +1249,7 @@ class SMTPConnection extends EventEmitter {
|
|||
this.user = () => user;
|
||||
this.password = () => password;
|
||||
if (typeof logger === 'function') {
|
||||
this.log = log;
|
||||
this.log = logger;
|
||||
}
|
||||
}
|
||||
/**
|
||||
|
@ -1726,6 +1726,7 @@ class SMTPConnection extends EventEmitter {
|
|||
const failed = (err, data) => {
|
||||
this.loggedin = false;
|
||||
this.close(); // if auth is bad, close the connection, it won't get better by itself
|
||||
err.message = err.message.replace(this.password(), 'REDACTED');
|
||||
caller(callback, SMTPError.create('authorization.failed', SMTPErrorStates.AUTHFAILED, err, data));
|
||||
};
|
||||
/**
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "emailjs",
|
||||
"description": "send text/html emails and attachments (files, streams and strings) from node.js to any smtp server",
|
||||
"version": "4.0.1",
|
||||
"version": "4.0.2",
|
||||
"author": "eleith",
|
||||
"contributors": [
|
||||
"izuzak",
|
||||
|
@ -31,7 +31,7 @@
|
|||
"prettier": "2.6.2",
|
||||
"rollup": "2.70.2",
|
||||
"smtp-server": "3.11.0",
|
||||
"ts-node": "10.7.0",
|
||||
"ts-node": "10.9.1",
|
||||
"tslib": "2.4.0",
|
||||
"typescript": "4.3.5"
|
||||
},
|
||||
|
|
|
@ -779,6 +779,9 @@ export class SMTPConnection extends EventEmitter {
|
|||
const failed = (err: Error, data: unknown) => {
|
||||
this.loggedin = false;
|
||||
this.close(); // if auth is bad, close the connection, it won't get better by itself
|
||||
|
||||
err.message = err.message.replace(this.password(), 'REDACTED');
|
||||
|
||||
caller(
|
||||
callback,
|
||||
SMTPError.create(
|
||||
|
|
28
test/auth.ts
28
test/auth.ts
|
@ -14,15 +14,15 @@ function send(
|
|||
authMethods = [],
|
||||
authOptional = false,
|
||||
secure = false,
|
||||
password = 'honey',
|
||||
}: {
|
||||
authMethods?: (keyof typeof AUTH_METHODS)[];
|
||||
authOptional?: boolean;
|
||||
secure?: boolean;
|
||||
password?: string;
|
||||
} = {}
|
||||
) {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
t.plan(5);
|
||||
|
||||
const msg = {
|
||||
subject: 'this is a test TEXT message from emailjs',
|
||||
from: 'piglet@gmail.com',
|
||||
|
@ -44,9 +44,14 @@ function send(
|
|||
? accessToken === 'honey'
|
||||
: password === 'honey')
|
||||
) {
|
||||
t.plan(5);
|
||||
callback(null, { user: 'pooh' });
|
||||
} else {
|
||||
return callback(new Error('invalid user / pass'));
|
||||
return callback(
|
||||
new Error(
|
||||
`invalid user or pass: ${username || accessToken} ${password}`
|
||||
)
|
||||
);
|
||||
}
|
||||
},
|
||||
async onData(stream, _session, callback: () => void) {
|
||||
|
@ -68,12 +73,12 @@ function send(
|
|||
server.listen(p, () => {
|
||||
const options = Object.assign(
|
||||
{ port: p, ssl: secure, authentication: authMethods },
|
||||
authOptional ? {} : { user: 'pooh', password: 'honey' }
|
||||
authOptional ? {} : { user: 'pooh', password }
|
||||
);
|
||||
new SMTPClient(options).send(new Message(msg), (err) => {
|
||||
server.close(() => {
|
||||
if (err) {
|
||||
reject(err.message);
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
|
@ -120,3 +125,16 @@ test('XOAUTH2 authentication (encrypted) should succeed', async (t) => {
|
|||
send(t, { authMethods: [AUTH_METHODS.XOAUTH2], secure: true })
|
||||
);
|
||||
});
|
||||
|
||||
test('on authentication.failed error message should not contain password', async (t) => {
|
||||
t.plan(1);
|
||||
|
||||
const password = 'passpot';
|
||||
await send(t, {
|
||||
authMethods: [AUTH_METHODS.LOGIN],
|
||||
secure: true,
|
||||
password,
|
||||
}).catch((err) => {
|
||||
t.false(err.message.includes(password));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -73,7 +73,7 @@ test('client invokes callback exactly once for invalid connection', async (t) =>
|
|||
await t.notThrowsAsync(
|
||||
new Promise<void>((resolve, reject) => {
|
||||
let counter = 0;
|
||||
const invalidClient = new SMTPClient({ host: 'bar.baz' });
|
||||
const invalidClient = new SMTPClient({ host: 'localhost' });
|
||||
const incrementCounter = () => {
|
||||
if (counter > 0) {
|
||||
reject();
|
||||
|
@ -423,7 +423,7 @@ test('client sendAsync can have error caught when awaited', async (t) => {
|
|||
};
|
||||
|
||||
try {
|
||||
const invalidClient = new SMTPClient({ host: 'bar.baz' });
|
||||
const invalidClient = new SMTPClient({ host: '127.0.0.1' });
|
||||
const message = await invalidClient.sendAsync(new Message(msg));
|
||||
t.true(message instanceof Message);
|
||||
t.fail();
|
||||
|
|
Loading…
Reference in New Issue