Skip to content

Commit

Permalink
fix: Allow smtp to take in username password (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
tkyi authored May 10, 2018
1 parent 661d969 commit f45428a
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 68 deletions.
52 changes: 2 additions & 50 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,51 +1,3 @@
# Contributing
# Contributing to Screwdriver

Thank you for considering contributing! There are many ways you can help.

## Issues

File an issue if you think you've found a bug. Be sure to describe

1. How can it be reproduced?
2. What did you expect?
3. What actually occurred?
4. Version, platform, etc. if possibly relevant.

## Docs

Documentation, READMEs, and examples are extremely important. Please help improve them and if you find a typo or notice a problem, please send a fix or say something.

## Submitting Patches

Patches for fixes, features, and improvements are accepted through pull requests.

* Write good commit messages, in the present tense! (Add X, not Added X). Short title, blank line, bullet points if needed. Capitalize the first letter of the title or bullet item. No punctuation in the title.
* Code must pass lint and style checks.
* All external methods must be documented.
* Include tests to improve coverage and prevent regressions.
* Squash changes into a single commit per feature/fix. Ask if you're unsure how to discretize your work.

Please ask before embarking on a large improvement so you're not disappointed if it does not align with the goals of the project or owner(s).

## Commit message format

To be consistent, we require commit messages to be in this specific format: `<type>(<scope>): <subject>`

* Types:
* feat (feature)
* fix (bug fix)
* docs (documentation)
* style (formatting, missing semi colons, …)
* refactor
* test (when adding missing tests)
* chore (maintain)
* Scope: anything that specifies the scope of the commit. Can be blank or `*`
* Subject: description of the commit. For **breaking changes** that require major version bump, add `BREAKING CHANGE` to the commit message.

**Examples commit messages:**
* Bug fix: `fix: Remove extra space`
* Breaking change: `feat(scm): Support new scm plugin. BREAKING CHANGE: github no longer works`

## Feature Requests

Make the case for a feature via an issue with a good title. The feature should be discussed and given a target inclusion milestone or closed.
Have a look at our guidelines, as well as pointers on where to start making changes, in our official [documentation](http://docs.screwdriver.cd/about/contributing).
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ The class has a variety of knobs to tweak when interacting with Email Notificati
| config.host | String | SMTP Host URL |
| config.port | Number | Port to use when connecting to SMTP |
| config.from | String | Sender email address |
| config.username | String | Optional username for SMTP |
| config.password | String | Optional password for SMTP |

The interface looks for email-specific build data:

Expand Down
20 changes: 11 additions & 9 deletions email.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@ const nodemailer = require('nodemailer');

/**
* Sends email message
* @param {object} mailOpts keys described below
* @param {string} mailOpts.from sender email address (must be compatible with smtp)
* @param {(string|string[])} mailOpts.to recipient(s) of email
* @param {string} mailOpts.subject subject of email
* @param {string} mailOpts.text plain text body of email
* @param {string} mailOpts.html html body of email
* @param {object} smtpConfig keys described below
* @param {string} smtpConfig.host smtp server host url
* @param {number} smtpConfig.port smtp host port (e.g. 25)
* @param {Object} mailOpts
* @param {String} mailOpts.from sender email address (must be compatible with smtp)
* @param {(String|String[])} mailOpts.to recipient(s) of email
* @param {String} mailOpts.subject subject of email
* @param {String} mailOpts.text plain text body of email
* @param {String} mailOpts.html html body of email
* @param {Object} smtpConfig
* @param {String} smtpConfig.host smtp server host url
* @param {Number} smtpConfig.port smtp host port (e.g. 25)
* @param {String} [smtpConfig.auth.user] smtp username
* @param {String} [smtpConfig.auth.pass] smtp password
*/
module.exports = (mailOpts, smtpConfig) => {
const transporter = nodemailer.createTransport(smtpConfig);
Expand Down
11 changes: 10 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ const SCHEMA_SMTP_CONFIG = Joi.object()
.keys({
host: Joi.string().required(),
port: Joi.number().integer().required(),
from: SCHEMA_ADDRESS.required()
from: SCHEMA_ADDRESS.required(),
username: Joi.string(),
password: Joi.string()
});

class EmailNotifier extends NotificationBase {
Expand Down Expand Up @@ -108,6 +110,13 @@ class EmailNotifier extends NotificationBase {
port: this.config.port
};

if (this.config.username && this.config.password) {
smtpConfig.auth = {
user: this.config.username,
pass: this.config.password
};
}

emailer(mailOpts, smtpConfig);
}
}
Expand Down
11 changes: 4 additions & 7 deletions screwdriver.yaml
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
workflow:
- publish

shared:
image: node:6
image: node:8

jobs:
main:
requires: [~pr, ~commit]
steps:
- install: npm install
- test: npm test

publish:
steps:
- install: npm install semantic-release
- publish: npm run semantic-release
requires: main
template: screwdriver-cd/semantic-release
secrets:
# Publishing to NPM
- NPM_TOKEN
Expand Down
48 changes: 47 additions & 1 deletion test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,30 @@ describe('index', () => {
});
});

it('creates a nodemailer with auth when password and username are provided', (done) => {
configMock.username = 'batman';
configMock.password = 'robin';

notifier = new EmailNotifier(configMock, serverMock, 'build_status_test');

serverMock.event(eventMock);
serverMock.on(eventMock, data => notifier.notify(data));
serverMock.emit(eventMock, buildDataMock);

process.nextTick(() => {
assert.calledWith(nodemailerMock.createTransport,
{
host: configMock.host,
port: configMock.port,
auth: {
user: configMock.username,
pass: configMock.password
}
});
done();
});
});

it('verifies that non-included status returns null', (done) => {
const buildDataMockUnincluded = {
settings: {
Expand All @@ -106,7 +130,7 @@ describe('index', () => {
});
});

it('verifies that non-subscribed status does not send a notifcation', (done) => {
it('verifies that non-subscribed status does not send a notification', (done) => {
const buildDataMockUnincluded = {
settings: {
email: {
Expand Down Expand Up @@ -249,6 +273,28 @@ describe('index', () => {
}
});

it('validates the username', () => {
configMock.username = 22;
try {
notifier = new EmailNotifier(configMock, serverMock, 'build_status_test');
assert.fail('should not get here');
} catch (err) {
assert.instanceOf(err, Error);
assert.equal(err.name, 'ValidationError');
}
});

it('validates the password', () => {
configMock.password = 22;
try {
notifier = new EmailNotifier(configMock, serverMock, 'build_status_test');
assert.fail('should not get here');
} catch (err) {
assert.instanceOf(err, Error);
assert.equal(err.name, 'ValidationError');
}
});

it('validates config format', () => {
configMock = ['this', 'is', 'wrong'];

Expand Down

0 comments on commit f45428a

Please sign in to comment.