Merge branch 'master' into greenkeeper/sinon-2.3.8

This commit is contained in:
Tankred Hase 2017-08-14 13:10:58 +08:00 committed by GitHub
commit 1fc0d608d9
17 changed files with 61 additions and 112 deletions

3
.gitignore vendored
View File

@ -34,3 +34,6 @@ node_modules
# Optional REPL history # Optional REPL history
.node_repl_history .node_repl_history
# npm v5+ lockfile
package-lock.json

View File

@ -15,6 +15,8 @@
"esnext": true, "esnext": true,
"globals": { "globals": {
"expect": true,
"sinon": true,
"describe" : true, "describe" : true,
"it" : true, "it" : true,
"before" : true, "before" : true,

View File

@ -1,11 +1,8 @@
sudo: false sudo: false
language: node_js language: node_js
node_js: node_js:
- "4"
- "6" - "6"
- "7"
before_script: before_script:
- npm install -g grunt-cli
- mongo test_db --eval 'db.addUser("travis", "test");' - mongo test_db --eval 'db.addUser("travis", "test");'
notifications: notifications:
email: email:

View File

@ -1,41 +0,0 @@
'use strict';
module.exports = function(grunt) {
grunt.initConfig({
jshint: {
all: ['*.js', 'src/**/*.js', 'test/**/*.js'],
options: {
jshintrc: '.jshintrc'
}
},
jscs: {
src: ['*.js', 'src/**/*.js', 'test/**/*.js'],
options: {
config: ".jscsrc"
}
},
mochaTest: {
test: {
options: {
reporter: 'spec'
},
src: [
'test/unit/*.js',
'test/integration/*.js',
]
}
}
});
// Load the plugin(s)
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-jscs');
grunt.loadNpmTasks('grunt-mocha-test');
// Default task(s).
grunt.registerTask('test', ['jshint', 'jscs', 'mochaTest']);
};

View File

@ -7,35 +7,42 @@
"url": "https://github.com/mailvelope/keyserver.git" "url": "https://github.com/mailvelope/keyserver.git"
}, },
"engines": { "engines": {
"node": ">=4" "node": ">=6"
}, },
"scripts": { "scripts": {
"start": ": ${NODE_ENV=development} && node index.js", "start": ": ${NODE_ENV=development} && node index.js",
"test": ": ${NODE_ENV=development} && grunt test" "test": ": ${NODE_ENV=development} && npm run test:jshint && npm run test:jscs && npm run test:unit && npm run test:integration",
"test:jshint": "jshint *.js src/**/*.js test/**/*.js",
"test:jscs": "jscs *.js src/**/*.js test/**/*.js",
"test:unit": "mocha --opts test/mocha.opts ./test/unit/",
"test:integration": "mocha --opts test/mocha.opts ./test/integration"
}, },
"dependencies": { "dependencies": {
"addressparser": "^1.0.1", "addressparser": "^1.0.1",
"co": "^4.6.0", "co": "^4.6.0",
"co-body": "^4.2.0", "co-body": "^5.1.1",
"config": "^1.20.4", "config": "^1.20.4",
"koa": "^1.2.0", "koa": "^1.2.0",
"koa-router": "^5.4.0", "koa-router": "^5.4.0",
"koa-static": "^2.0.0", "koa-static": "^2.0.0",
"mongodb": "^2.1.20", "mongodb": "^2.2.31",
"nodemailer": "^2.4.2", "nodemailer": "^2.4.2",
"nodemailer-openpgp": "^1.0.2", "nodemailer-openpgp": "^1.0.2",
"npmlog": "^4.0.2", "npmlog": "^4.0.2",
"openpgp": "^2.3.0" "openpgp": "^2.3.0"
}, },
"devDependencies": { "devDependencies": {
"chai": "^3.5.0", "chai": "^4.1.1",
"co-mocha": "^1.1.2", "co-mocha": "^1.1.2",
"grunt": "^1.0.1", "jscs": "^3.0.7",
"grunt-contrib-jshint": "^1.0.0", "jshint": "^2.9.4",
"grunt-jscs": "^3.0.1",
"grunt-mocha-test": "^0.13.2",
"mocha": "^3.2.0", "mocha": "^3.2.0",
"sinon": "^2.3.8", "sinon": "^2.3.8",
"supertest": "^2.0.1" "supertest": "^3.0.0"
},
"greenkeeper": {
"ignore": [
"nodemailer"
]
} }
} }

View File

@ -31,9 +31,9 @@ class Mongo {
* @param {String} pass The database user's password * @param {String} pass The database user's password
* @yield {undefined} * @yield {undefined}
*/ */
*init(options) { *init({ uri, user, pass }) {
let uri = 'mongodb://' + options.user + ':' + options.pass + '@' + options.uri; let url = 'mongodb://' + user + ':' + pass + '@' + uri;
this._db = yield MongoClient.connect(uri); this._db = yield MongoClient.connect(url);
} }
/** /**

View File

@ -37,18 +37,18 @@ class Email {
* @param {boolean} starttls (optional) force STARTTLS to prevent downgrade attack. Defaults to true. * @param {boolean} starttls (optional) force STARTTLS to prevent downgrade attack. Defaults to true.
* @param {boolean} pgp (optional) if outgoing emails are encrypted to the user's public key. * @param {boolean} pgp (optional) if outgoing emails are encrypted to the user's public key.
*/ */
init(options) { init({ host, port=465, auth, tls, starttls, pgp, sender }) {
this._transport = nodemailer.createTransport({ this._transport = nodemailer.createTransport({
host: options.host, host,
port: options.port || 465, port,
auth: options.auth, auth,
secure: (options.tls !== undefined) ? util.isTrue(options.tls) : true, secure: (tls !== undefined) ? util.isTrue(tls) : true,
requireTLS: (options.starttls !== undefined) ? util.isTrue(options.starttls) : true, requireTLS: (starttls !== undefined) ? util.isTrue(starttls) : true,
}); });
if (util.isTrue(options.pgp)) { if (util.isTrue(pgp)) {
this._transport.use('stream', openpgpEncrypt()); this._transport.use('stream', openpgpEncrypt());
} }
this._sender = options.sender; this._sender = sender;
} }
/** /**
@ -59,8 +59,7 @@ class Email {
* @param {Object} origin origin of the server * @param {Object} origin origin of the server
* @yield {Object} send response from the SMTP server * @yield {Object} send response from the SMTP server
*/ */
*send(options) { *send({ template, userId, keyId, origin }) {
let template = options.template, userId = options.userId, keyId = options.keyId, origin = options.origin;
let message = { let message = {
from: this._sender, from: this._sender,
to: userId, to: userId,
@ -87,26 +86,25 @@ class Email {
* @param {Object} params (optional) nodermailer template parameters * @param {Object} params (optional) nodermailer template parameters
* @yield {Object} reponse object containing SMTP info * @yield {Object} reponse object containing SMTP info
*/ */
*_sendHelper(options) { *_sendHelper({ from, to, subject, text, html, params={} }) {
let template = { let template = {
subject: options.subject, subject,
text: options.text, text,
html: options.html, html,
encryptionKeys: [options.to.publicKeyArmored] encryptionKeys: [to.publicKeyArmored]
}; };
let sender = { let sender = {
from: { from: {
name: options.from.name, name: from.name,
address: options.from.email address: from.email
} }
}; };
let recipient = { let recipient = {
to: { to: {
name: options.to.name, name: to.name,
address: options.to.email address: to.email
} }
}; };
let params = options.params || {};
try { try {
let sendFn = this._transport.templateSender(template, sender); let sendFn = this._transport.templateSender(template, sender);
@ -116,7 +114,7 @@ class Email {
} }
return info; return info;
} catch(error) { } catch(error) {
log.error('email', 'Sending message failed.', error, options); log.error('email', 'Sending message failed.', error);
util.throw(500, 'Sending email to user failed'); util.throw(500, 'Sending email to user failed');
} }
} }

View File

@ -66,9 +66,8 @@ class PublicKey {
* @param {Object} origin Required for links to the keyserver e.g. { protocol:'https', host:'openpgpkeys@example.com' } * @param {Object} origin Required for links to the keyserver e.g. { protocol:'https', host:'openpgpkeys@example.com' }
* @yield {undefined} * @yield {undefined}
*/ */
*put(options) { *put({ publicKeyArmored, primaryEmail, origin }) {
// parse key block // parse key block
let publicKeyArmored = options.publicKeyArmored, primaryEmail = options.primaryEmail, origin = options.origin;
let key = this._pgp.parseKey(publicKeyArmored); let key = this._pgp.parseKey(publicKeyArmored);
// check for existing verfied key by id or email addresses // check for existing verfied key by id or email addresses
let verified = yield this.getVerified(key); let verified = yield this.getVerified(key);
@ -128,8 +127,7 @@ class PublicKey {
* @param {string} nonce The verification nonce proving email address ownership * @param {string} nonce The verification nonce proving email address ownership
* @yield {undefined} * @yield {undefined}
*/ */
*verify(options) { *verify({ keyId, nonce }) {
let keyId = options.keyId, nonce = options.nonce;
// look for verification nonce in database // look for verification nonce in database
let query = { keyId, 'userIds.nonce':nonce }; let query = { keyId, 'userIds.nonce':nonce };
let key = yield this._mongo.get(query, DB_TYPE); let key = yield this._mongo.get(query, DB_TYPE);
@ -157,8 +155,7 @@ class PublicKey {
* @param {string} keyId (optional) The public key id * @param {string} keyId (optional) The public key id
* @yield {Object} The verified key document * @yield {Object} The verified key document
*/ */
*getVerified(options) { *getVerified({ userIds, fingerprint, keyId }) {
let fingerprint = options.fingerprint, userIds = options.userIds, keyId = options.keyId;
let queries = []; let queries = [];
// query by fingerprint // query by fingerprint
if (fingerprint) { if (fingerprint) {
@ -196,8 +193,7 @@ class PublicKey {
* @param {String} email (optional) The user's email address * @param {String} email (optional) The user's email address
* @yield {Object} The public key document * @yield {Object} The public key document
*/ */
*get(options) { *get({ fingerprint, keyId, email }) {
let fingerprint = options.fingerprint, keyId = options.keyId, email = options.email;
// look for verified key // look for verified key
let userIds = email ? [{ email:email }] : undefined; let userIds = email ? [{ email:email }] : undefined;
let key = yield this.getVerified({ keyId, fingerprint, userIds }); let key = yield this.getVerified({ keyId, fingerprint, userIds });
@ -224,8 +220,7 @@ class PublicKey {
* @param {Object} origin Required for links to the keyserver e.g. { protocol:'https', host:'openpgpkeys@example.com' } * @param {Object} origin Required for links to the keyserver e.g. { protocol:'https', host:'openpgpkeys@example.com' }
* @yield {undefined} * @yield {undefined}
*/ */
*requestRemove(options) { *requestRemove({ keyId, email, origin }) {
let keyId = options.keyId, email = options.email, origin = options.origin;
// flag user ids for removal // flag user ids for removal
let key = yield this._flagForRemove(keyId, email); let key = yield this._flagForRemove(keyId, email);
if (!key) { if (!key) {
@ -277,8 +272,7 @@ class PublicKey {
* @param {string} nonce The verification nonce proving email address ownership * @param {string} nonce The verification nonce proving email address ownership
* @yield {undefined} * @yield {undefined}
*/ */
*verifyRemove(options) { *verifyRemove({ keyId, nonce }) {
let keyId = options.keyId, nonce = options.nonce;
// check if key exists in database // check if key exists in database
let flagged = yield this._mongo.get({ keyId, 'userIds.nonce':nonce }, DB_TYPE); let flagged = yield this._mongo.get({ keyId, 'userIds.nonce':nonce }, DB_TYPE);
if (!flagged) { if (!flagged) {

View File

@ -1,14 +1,10 @@
'use strict'; 'use strict';
require('co-mocha')(require('mocha')); // monkey patch mocha for generators
const request = require('supertest'); const request = require('supertest');
const Mongo = require('../../src/dao/mongo'); const Mongo = require('../../src/dao/mongo');
const nodemailer = require('nodemailer'); const nodemailer = require('nodemailer');
const config = require('config'); const config = require('config');
const fs = require('fs'); const fs = require('fs');
const expect = require('chai').expect;
const sinon = require('sinon');
describe('Koa App (HTTP Server) Integration Tests', function() { describe('Koa App (HTTP Server) Integration Tests', function() {
this.timeout(20000); this.timeout(20000);

View File

@ -1,8 +1,5 @@
'use strict'; 'use strict';
require('co-mocha')(require('mocha')); // monkey patch mocha for generators
const expect = require('chai').expect;
const config = require('config'); const config = require('config');
const Email = require('../../src/email/email'); const Email = require('../../src/email/email');
const tpl = require('../../src/email/templates.json'); const tpl = require('../../src/email/templates.json');

View File

@ -1,10 +1,7 @@
'use strict'; 'use strict';
require('co-mocha')(require('mocha')); // monkey patch mocha for generators
const config = require('config'); const config = require('config');
const Mongo = require('../../src/dao/mongo'); const Mongo = require('../../src/dao/mongo');
const expect = require('chai').expect;
describe('Mongo Integration Tests', function() { describe('Mongo Integration Tests', function() {
this.timeout(20000); this.timeout(20000);

View File

@ -1,15 +1,11 @@
'use strict'; 'use strict';
require('co-mocha')(require('mocha')); // monkey patch mocha for generators
const config = require('config'); const config = require('config');
const nodemailer = require('nodemailer'); const nodemailer = require('nodemailer');
const Email = require('../../src/email/email'); const Email = require('../../src/email/email');
const Mongo = require('../../src/dao/mongo'); const Mongo = require('../../src/dao/mongo');
const PGP = require('../../src/service/pgp'); const PGP = require('../../src/service/pgp');
const PublicKey = require('../../src/service/public-key'); const PublicKey = require('../../src/service/public-key');
const expect = require('chai').expect;
const sinon = require('sinon');
describe('Public Key Integration Tests', function() { describe('Public Key Integration Tests', function() {
this.timeout(20000); this.timeout(20000);

2
test/mocha.opts Normal file
View File

@ -0,0 +1,2 @@
--recursive
-r ./test/setup.js

9
test/setup.js Normal file
View File

@ -0,0 +1,9 @@
'use strict';
require('co-mocha')(require('mocha')); // monkey patch mocha for generators
const expect = require('chai').expect;
const sinon = require('sinon');
global.expect = expect;
global.sinon = sinon;

View File

@ -1,13 +1,8 @@
'use strict'; 'use strict';
require('co-mocha')(require('mocha')); // monkey patch mocha for generators
const expect = require('chai').expect;
const log = require('npmlog'); const log = require('npmlog');
const Email = require('../../src/email/email'); const Email = require('../../src/email/email');
const nodemailer = require('nodemailer'); const nodemailer = require('nodemailer');
const sinon = require('sinon');
describe('Email Unit Tests', () => { describe('Email Unit Tests', () => {
let email, sendFnStub; let email, sendFnStub;

View File

@ -1,11 +1,9 @@
'use strict'; 'use strict';
const fs = require('fs'); const fs = require('fs');
const expect = require('chai').expect;
const log = require('npmlog'); const log = require('npmlog');
const openpgp = require('openpgp'); const openpgp = require('openpgp');
const PGP = require('../../src/service/pgp'); const PGP = require('../../src/service/pgp');
const sinon = require('sinon');
describe('PGP Unit Tests', () => { describe('PGP Unit Tests', () => {
let pgp, key1Armored, key2Armored, key3Armored; let pgp, key1Armored, key2Armored, key3Armored;

View File

@ -1,6 +1,5 @@
'use strict'; 'use strict';
const expect = require('chai').expect;
const util = require('../../src/service/util'); const util = require('../../src/service/util');
describe('Util Unit Tests', () => { describe('Util Unit Tests', () => {