Update dependencies, fix package conflicts, add packages (ejs, email-templates)
This commit is contained in:
parent
0baf3fc857
commit
a2b941b0ae
22
package.json
22
package.json
@ -21,22 +21,24 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"addressparser": "^1.0.1",
|
||||
"co-body": "^5.1.1",
|
||||
"config": "^1.20.4",
|
||||
"co-body": "^6.0.0",
|
||||
"config": "^3.0.1",
|
||||
"ejs": "^2.6.1",
|
||||
"email-templates": "^5.0.3",
|
||||
"koa": "^2.3.0",
|
||||
"koa-router": "^7.2.1",
|
||||
"koa-static": "^4.0.1",
|
||||
"mongodb": "^2.2.31",
|
||||
"nodemailer": "^4.0.1",
|
||||
"openpgp": "^2.3.0",
|
||||
"winston": "^2.3.1",
|
||||
"koa-static": "^5.0.0",
|
||||
"mongodb": "^3.1.13",
|
||||
"nodemailer": "^5.1.1",
|
||||
"openpgp": "^4.4.6",
|
||||
"winston": "^3.2.1",
|
||||
"winston-papertrail": "^1.0.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chai": "^4.1.1",
|
||||
"eslint": "^4.4.1",
|
||||
"mocha": "^3.2.0",
|
||||
"sinon": "^1.17.4",
|
||||
"eslint": "^5.13.0",
|
||||
"mocha": "^5.2.0",
|
||||
"sinon": "^7.2.3",
|
||||
"supertest": "^3.0.0"
|
||||
},
|
||||
"greenkeeper": {
|
||||
|
@ -34,7 +34,8 @@ class Mongo {
|
||||
async init({uri, user, pass}) {
|
||||
log.info('mongo', 'Connecting to MongoDB ...');
|
||||
const url = `mongodb://${user}:${pass}@${uri}`;
|
||||
this._db = await MongoClient.connect(url);
|
||||
const client = await MongoClient.connect(url, {useNewUrlParser: true});
|
||||
this._db = client.db();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,19 +18,36 @@
|
||||
'use strict';
|
||||
|
||||
const log = require('winston');
|
||||
const {SPLAT} = require('triple-beam');
|
||||
const config = require('config');
|
||||
require('winston-papertrail');
|
||||
|
||||
log.exitOnError = false;
|
||||
log.level = config.log.level;
|
||||
|
||||
|
||||
// Reformat logging text, due to deprecated logger usage
|
||||
const formatLogs = log.format(info => {
|
||||
info.message = `${info.message} -> ${info[SPLAT].join(', ')}`;
|
||||
return info;
|
||||
});
|
||||
|
||||
exports.init = function({host, port}) {
|
||||
if (!host || !port) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
log.add(new log.transports.Console({
|
||||
format: log.format.combine(
|
||||
formatLogs(),
|
||||
log.format.simple()
|
||||
)
|
||||
}));
|
||||
}
|
||||
return;
|
||||
}
|
||||
log.add(log.transports.Papertrail, {
|
||||
log.add(new log.transports.Papertrail({
|
||||
format: formatLogs(),
|
||||
level: config.log.level,
|
||||
host,
|
||||
port
|
||||
});
|
||||
}));
|
||||
};
|
||||
|
@ -37,7 +37,7 @@ class Email {
|
||||
* @param {boolean} pgp (optional) if outgoing emails are encrypted to the user's public key.
|
||||
*/
|
||||
init({host, port = 465, auth, tls, starttls, pgp, sender}) {
|
||||
this._transport = nodemailer.createTransport({
|
||||
const transporter = nodemailer.createTransport({
|
||||
host,
|
||||
port,
|
||||
auth,
|
||||
|
2
src/email/templates/verifyKey/html.ejs
Normal file
2
src/email/templates/verifyKey/html.ejs
Normal file
@ -0,0 +1,2 @@
|
||||
<p>Hello <%= name %>,</p>
|
||||
<p>please <a href="<%= `${baseUrl}/api/v1/key?op=verify&keyId=${keyId}&nonce=${nonce}` %>">click here to verify</a> your key.</p>
|
1
src/email/templates/verifyKey/subject.ejs
Normal file
1
src/email/templates/verifyKey/subject.ejs
Normal file
@ -0,0 +1 @@
|
||||
Verify Your Key
|
2
src/email/templates/verifyRemove/html.ejs
Normal file
2
src/email/templates/verifyRemove/html.ejs
Normal file
@ -0,0 +1,2 @@
|
||||
<p>Hello <%= name %>,</p>
|
||||
<p>please <a href="<%= `${baseUrl}/api/v1/key?op=verifyRemove&keyId=${keyId}&nonce=${nonce}` %>">click here to verify</a> the removal of your key.</p>
|
1
src/email/templates/verifyRemove/subject.ejs
Normal file
1
src/email/templates/verifyRemove/subject.ejs
Normal file
@ -0,0 +1 @@
|
||||
Verify Key Removal
|
@ -34,10 +34,10 @@ class PGP {
|
||||
* @param {String} publicKeyArmored ascii armored pgp key block
|
||||
* @return {Object} public key document to persist
|
||||
*/
|
||||
parseKey(publicKeyArmored) {
|
||||
async parseKey(publicKeyArmored) {
|
||||
publicKeyArmored = this.trimKey(publicKeyArmored);
|
||||
|
||||
const r = openpgp.key.readArmored(publicKeyArmored);
|
||||
const r = await openpgp.key.readArmored(publicKeyArmored);
|
||||
if (r.err) {
|
||||
const error = r.err[0];
|
||||
log.error('pgp', 'Failed to parse PGP key:\n%s', publicKeyArmored, error);
|
||||
@ -49,23 +49,26 @@ class PGP {
|
||||
// verify primary key
|
||||
const key = r.keys[0];
|
||||
const primaryKey = key.primaryKey;
|
||||
if (key.verifyPrimaryKey() !== openpgp.enums.keyStatus.valid) {
|
||||
if (await key.verifyPrimaryKey() !== openpgp.enums.keyStatus.valid) {
|
||||
util.throw(400, 'Invalid PGP key: primary key verification failed');
|
||||
}
|
||||
|
||||
// accept version 4 keys only
|
||||
const keyId = primaryKey.getKeyId().toHex();
|
||||
const fingerprint = primaryKey.fingerprint;
|
||||
const fingerprint = primaryKey.getFingerprint();
|
||||
if (!util.isKeyId(keyId) || !util.isFingerPrint(fingerprint)) {
|
||||
util.throw(400, 'Invalid PGP key: only v4 keys are accepted');
|
||||
}
|
||||
|
||||
// check for at least one valid user id
|
||||
const userIds = this.parseUserIds(key.users, primaryKey);
|
||||
const userIds = await this.parseUserIds(key.users, primaryKey);
|
||||
if (!userIds.length) {
|
||||
util.throw(400, 'Invalid PGP key: invalid user ids');
|
||||
}
|
||||
|
||||
// get algorithm details from primary key
|
||||
const keyInfo = key.primaryKey.getAlgorithmInfo();
|
||||
|
||||
// public key document that is stored in the database
|
||||
return {
|
||||
keyId,
|
||||
@ -73,8 +76,8 @@ class PGP {
|
||||
userIds,
|
||||
created: primaryKey.created,
|
||||
uploaded: new Date(),
|
||||
algorithm: primaryKey.algorithm,
|
||||
keySize: primaryKey.getBitSize(),
|
||||
algorithm: keyInfo.algorithm,
|
||||
keySize: keyInfo.bits,
|
||||
publicKeyArmored
|
||||
};
|
||||
}
|
||||
@ -110,20 +113,15 @@ class PGP {
|
||||
* @param {Array} users A list of openpgp.js user objects
|
||||
* @return {Array} An array of user id objects
|
||||
*/
|
||||
parseUserIds(users, primaryKey) {
|
||||
async parseUserIds(users, primaryKey) {
|
||||
if (!users || !users.length) {
|
||||
util.throw(400, 'Invalid PGP key: no user id found');
|
||||
}
|
||||
// at least one user id signature must be valid
|
||||
// at least one user id must be valid, revoked or expired
|
||||
const result = [];
|
||||
for (const user of users) {
|
||||
let oneValid = false;
|
||||
for (const cert of user.selfCertifications) {
|
||||
if (user.isValidSelfCertificate(primaryKey, cert)) {
|
||||
oneValid = true;
|
||||
}
|
||||
}
|
||||
if (oneValid && user.userId && user.userId.userid) {
|
||||
const userStatus = await user.verify(primaryKey);
|
||||
if (userStatus !== openpgp.enums.keyStatus.invalid && user.userId && user.userId.userid) {
|
||||
const uid = addressparser(user.userId.userid)[0];
|
||||
if (util.isEmail(uid.address)) {
|
||||
result.push(uid);
|
||||
|
@ -70,7 +70,7 @@ class PublicKey {
|
||||
// lazily purge old/unverified keys on every key upload
|
||||
await this._purgeOldUnverified();
|
||||
// parse key block
|
||||
const key = this._pgp.parseKey(publicKeyArmored);
|
||||
const key = await this._pgp.parseKey(publicKeyArmored);
|
||||
// check for existing verified key with same id
|
||||
const verified = await this.getVerified({keyId: key.keyId});
|
||||
if (verified) {
|
||||
|
Loading…
Reference in New Issue
Block a user