Merge branch 'master' into greenkeeper/sinon-3.2.0
This commit is contained in:
commit
02f0ef0a15
3
.gitignore
vendored
3
.gitignore
vendored
@ -34,3 +34,6 @@ node_modules
|
|||||||
|
|
||||||
# Optional REPL history
|
# Optional REPL history
|
||||||
.node_repl_history
|
.node_repl_history
|
||||||
|
|
||||||
|
# npm v5+ lockfile
|
||||||
|
package-lock.json
|
||||||
|
@ -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,
|
||||||
|
@ -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:
|
||||||
|
41
Gruntfile.js
41
Gruntfile.js
@ -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']);
|
|
||||||
|
|
||||||
};
|
|
27
package.json
27
package.json
@ -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": "^3.2.0",
|
"sinon": "^3.2.0",
|
||||||
"supertest": "^2.0.1"
|
"supertest": "^3.0.0"
|
||||||
|
},
|
||||||
|
"greenkeeper": {
|
||||||
|
"ignore": [
|
||||||
|
"nodemailer"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
@ -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');
|
||||||
|
@ -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);
|
||||||
|
@ -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
2
test/mocha.opts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
--recursive
|
||||||
|
-r ./test/setup.js
|
9
test/setup.js
Normal file
9
test/setup.js
Normal 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;
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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', () => {
|
||||||
|
Loading…
Reference in New Issue
Block a user