Merge pull request #44 from mailvelope/dev/purge-old-unverified-keys

Dev/purge old unverified keys
This commit is contained in:
Tankred Hase 2017-08-22 15:31:09 +08:00 committed by GitHub
commit 258117d36d
5 changed files with 68 additions and 0 deletions

View File

@ -38,6 +38,10 @@ module.exports = {
name: process.env.SENDER_NAME, name: process.env.SENDER_NAME,
email: process.env.SENDER_EMAIL email: process.env.SENDER_EMAIL
} }
},
publicKey: {
purgeTimeInDays: process.env.PUBLIC_KEY_PURGE_TIME || 30
} }
}; };

View File

@ -72,6 +72,7 @@ class PGP {
fingerprint, fingerprint,
userIds, userIds,
created: primaryKey.created, created: primaryKey.created,
uploaded: new Date(),
algorithm: primaryKey.algorithm, algorithm: primaryKey.algorithm,
keySize: primaryKey.getBitSize(), keySize: primaryKey.getBitSize(),
publicKeyArmored publicKeyArmored

View File

@ -17,6 +17,7 @@
'use strict'; 'use strict';
const config = require('config');
const util = require('./util'); const util = require('./util');
const tpl = require('../email/templates.json'); const tpl = require('../email/templates.json');
@ -66,6 +67,8 @@ class PublicKey {
* @yield {undefined} * @yield {undefined}
*/ */
async put({publicKeyArmored, primaryEmail, origin}) { async put({publicKeyArmored, primaryEmail, origin}) {
// lazily purge old/unverified keys on every key upload
await this._purgeOldUnverified();
// parse key block // parse key block
const key = this._pgp.parseKey(publicKeyArmored); const 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
@ -79,6 +82,22 @@ class PublicKey {
await this._sendVerifyEmail(key, primaryEmail, origin); await this._sendVerifyEmail(key, primaryEmail, origin);
} }
/**
* Delete all keys where no user id has been verified after x days.
* @yield {undefined}
*/
async _purgeOldUnverified() {
// create date in the past to compare with
const xDaysAgo = new Date();
xDaysAgo.setDate(xDaysAgo.getDate() - config.publicKey.purgeTimeInDays);
// remove unverified keys older than x days (or no 'uploaded' attribute)
const query = {
'userIds.verified': {$ne: true},
uploaded: {$lt: xDaysAgo}
};
return this._mongo.remove(query, DB_TYPE);
}
/** /**
* Persist the public key and its user ids in the database. * Persist the public key and its user ids in the database.
* @param {Object} key public key parameters * @param {Object} key public key parameters

View File

@ -104,6 +104,47 @@ describe('Public Key Integration Tests', function() {
}); });
}); });
describe('_purgeOldUnverified', () => {
let key;
beforeEach(async () => {
key = pgp.parseKey(publicKeyArmored);
});
it('should work for no keys', async () => {
const r = await publicKey._purgeOldUnverified();
expect(r.deletedCount).to.equal(0);
});
it('should not remove a current unverified key', async () => {
await publicKey._persisKey(key);
const r = await publicKey._purgeOldUnverified();
expect(r.deletedCount).to.equal(0);
});
it('should not remove a current verified key', async () => {
key.userIds[0].verified = true;
await publicKey._persisKey(key);
const r = await publicKey._purgeOldUnverified();
expect(r.deletedCount).to.equal(0);
});
it('should not remove an old verified key', async () => {
key.uploaded.setDate(key.uploaded.getDate() - 31);
key.userIds[0].verified = true;
await publicKey._persisKey(key);
const r = await publicKey._purgeOldUnverified();
expect(r.deletedCount).to.equal(0);
});
it('should remove an old unverified key', async () => {
key.uploaded.setDate(key.uploaded.getDate() - 31);
await publicKey._persisKey(key);
const r = await publicKey._purgeOldUnverified();
expect(r.deletedCount).to.equal(1);
});
});
describe('verify', () => { describe('verify', () => {
it('should update the document', async () => { it('should update the document', async () => {
await publicKey.put({publicKeyArmored, primaryEmail, origin}); await publicKey.put({publicKeyArmored, primaryEmail, origin});

View File

@ -94,6 +94,7 @@ describe('PGP Unit Tests', () => {
expect(params.userIds[0].name).to.equal('safewithme testuser'); expect(params.userIds[0].name).to.equal('safewithme testuser');
expect(params.userIds[0].email).to.equal('safewithme.testuser@gmail.com'); expect(params.userIds[0].email).to.equal('safewithme.testuser@gmail.com');
expect(params.created.getTime()).to.exist; expect(params.created.getTime()).to.exist;
expect(params.uploaded.getTime()).to.exist;
expect(params.algorithm).to.equal('rsa_encrypt_sign'); expect(params.algorithm).to.equal('rsa_encrypt_sign');
expect(params.keySize).to.equal(2048); expect(params.keySize).to.equal(2048);
expect(params.publicKeyArmored).to.equal(key1Armored); expect(params.publicKeyArmored).to.equal(key1Armored);
@ -105,6 +106,7 @@ describe('PGP Unit Tests', () => {
expect(params.fingerprint).to.equal('e3317db04d3958fd5f662c37b8e4105cc9dedc77'); expect(params.fingerprint).to.equal('e3317db04d3958fd5f662c37b8e4105cc9dedc77');
expect(params.userIds.length).to.equal(1); expect(params.userIds.length).to.equal(1);
expect(params.created.getTime()).to.exist; expect(params.created.getTime()).to.exist;
expect(params.uploaded.getTime()).to.exist;
expect(params.algorithm).to.equal('rsa_encrypt_sign'); expect(params.algorithm).to.equal('rsa_encrypt_sign');
expect(params.keySize).to.equal(4096); expect(params.keySize).to.equal(4096);
expect(params.publicKeyArmored).to.equal(pgp.trimKey(key2Armored)); expect(params.publicKeyArmored).to.equal(pgp.trimKey(key2Armored));
@ -116,6 +118,7 @@ describe('PGP Unit Tests', () => {
expect(params.fingerprint).to.equal('04062c70b446e33016e219a74001a127a90de8e1'); expect(params.fingerprint).to.equal('04062c70b446e33016e219a74001a127a90de8e1');
expect(params.userIds.length).to.equal(4); expect(params.userIds.length).to.equal(4);
expect(params.created.getTime()).to.exist; expect(params.created.getTime()).to.exist;
expect(params.uploaded.getTime()).to.exist;
expect(params.algorithm).to.equal('rsa_encrypt_sign'); expect(params.algorithm).to.equal('rsa_encrypt_sign');
expect(params.keySize).to.equal(4096); expect(params.keySize).to.equal(4096);
expect(params.publicKeyArmored).to.equal(pgp.trimKey(key3Armored)); expect(params.publicKeyArmored).to.equal(pgp.trimKey(key3Armored));