diff --git a/src/keys.js b/src/keys.js index 887cd0e..f4ad20d 100644 --- a/src/keys.js +++ b/src/keys.js @@ -17,11 +17,15 @@ const path = require('path') const bent = require('bent') const req = bent('GET') const validUrl = require('valid-url') -const openpgp = require(path.join(require.resolve('openpgp'), '..', 'openpgp.min.js')) +const openpgp = require(path.join( + require.resolve('openpgp'), + '..', + 'openpgp.min.js' +)) const mergeOptions = require('merge-options') -const fetchHKP = async (identifier, keyserverBaseUrl) => { - try { +const fetchHKP = (identifier, keyserverBaseUrl) => { + return new Promise(async (resolve, reject) => { keyserverBaseUrl = keyserverBaseUrl ? keyserverBaseUrl : 'https://keys.openpgp.org/' @@ -33,64 +37,64 @@ const fetchHKP = async (identifier, keyserverBaseUrl) => { let publicKey = await hkp.lookup(lookupOpts) publicKey = (await openpgp.key.readArmored(publicKey)).keys[0] - return publicKey - } catch (e) { - console.error(e) - return undefined - } + if (publicKey == undefined) { + reject('Key does not exist or could not be fetched') + } + + resolve(publicKey) + }) } -const fetchWKD = async (identifier) => { - try { +const fetchWKD = (identifier) => { + return new Promise(async (resolve, reject) => { const wkd = new openpgp.WKD() const lookupOpts = { email: identifier, } const publicKey = (await wkd.lookup(lookupOpts)).keys[0] - return publicKey - } catch (e) { - console.error(e) - return undefined - } + if (publicKey == undefined) { + reject('Key does not exist or could not be fetched') + } + + resolve(publicKey) + }) } -const fetchKeybase = async (username, fingerprint) => { - try { +const fetchKeybase = (username, fingerprint) => { + return new Promise(async (resolve, reject) => { const keyLink = `https://keybase.io/${username}/pgp_keys.asc?fingerprint=${fingerprint}` try { const rawKeyContent = await req(opts.keyLink) - .then(function (response) { + .then((response) => { if (response.status === 200) { return response } }) .then((response) => response.text()) } catch (e) { - return undefined + reject(`Error fetching Keybase key: ${e.message}`) } const publicKey = (await openpgp.key.readArmored(rawKeyContent)).keys[0] - return publicKey - } catch (e) { - console.error(e) - return undefined - } + if (publicKey == undefined) { + reject('Key does not exist or could not be fetched') + } + + resolve(publicKey) + }) } -const fetchPlaintext = async (rawKeyContent) => { - try { +const fetchPlaintext = (rawKeyContent) => { + return new Promise(async (resolve, reject) => { const publicKey = (await openpgp.key.readArmored(rawKeyContent)).keys[0] - return publicKey - } catch (e) { - console.error(e) - return undefined - } + resolve(publicKey) + }) } -const fetchSignature = async (rawSignatureContent, keyserverBaseUrl) => { - try { +const fetchSignature = (rawSignatureContent, keyserverBaseUrl) => { + return new Promise(async (resolve, reject) => { let sig = await openpgp.signature.readArmored(rawSignatureContent) if ('compressed' in sig.packets[0]) { sig = sig.packets[0] @@ -101,52 +105,50 @@ const fetchSignature = async (rawSignatureContent, keyserverBaseUrl) => { const sigUserId = sig.packets[0].signersUserId const sigKeyId = await sig.packets[0].issuerKeyId.toHex() - return fetchHKP(sigUserId ? sigUserId : sigKeyId, keyserverBaseUrl) - } catch (e) { - console.error(e) - return undefined - } + resolve(fetchHKP(sigUserId ? sigUserId : sigKeyId, keyserverBaseUrl)) + }) } -const fetchURI = async (uri) => { - try { +const fetchURI = (uri) => { + return new Promise(async (resolve, reject) => { if (!validUrl.isUri(uri)) { - throw new Error('Invalid URI') + reject('Invalid URI') } const re = /([a-zA-Z0-9]*):([a-zA-Z0-9@._=+\-]*)(\:[a-zA-Z0-9@._=+\-]*)?/ const match = uri.match(re) if (!match[1]) { - throw new Error('Invalid URI') + reject('Invalid URI') } switch (match[1]) { case 'hkp': - return fetchHKP(match[2], match.length >= 4 ? match[3] : null) + resolve(fetchHKP(match[2], match.length >= 4 ? match[3] : null)) break case 'wkd': - return fetchWKD(match[2]) + resolve(fetchWKD(match[2])) break case 'kb': - return fetchKeybase(match[2], match.length >= 4 ? match[3] : null) + resolve(fetchKeybase(match[2], match.length >= 4 ? match[3] : null)) break default: - throw new Error('Invalid URI protocol') + reject('Invalid URI protocol') break } - } catch (e) { - console.error(e) - return undefined - } + }) } -const process = async (publicKey) => { - try { +const process = (publicKey) => { + return new Promise(async (resolve, reject) => { + if (!publicKey) { + reject('Invalid public key') + } const fingerprint = await publicKey.primaryKey.getFingerprint() const primaryUser = await publicKey.getPrimaryUser() const users = publicKey.users - let primaryUserIndex, usersOutput = [] + let primaryUserIndex, + usersOutput = [] users.forEach((user, i) => { usersOutput[i] = { @@ -155,49 +157,42 @@ const process = async (publicKey) => { name: user.userId.name, email: user.userId.email, comment: user.userId.comment, - isPrimary: primaryUser.index === i - } + isPrimary: primaryUser.index === i, + }, } const notations = user.selfCertifications[0].rawNotations - usersOutput[i].notations = notations.map(({ name, value, humanReadable }) => { - if (humanReadable && name === 'proof@metacode.biz') { - return openpgp.util.decode_utf8(value) + usersOutput[i].notations = notations.map( + ({ name, value, humanReadable }) => { + if (humanReadable && name === 'proof@metacode.biz') { + return openpgp.util.decode_utf8(value) + } } - }) + ) }) - return { + resolve({ fingerprint: fingerprint, users: usersOutput, primaryUserIndex: primaryUser.index, - } - } catch (e) { - console.error(e) - return undefined - } + }) + }) } -const getUserData = async (publicKey) => { - try { +const getUserData = (publicKey) => { + return new Promise(async (resolve, reject) => { const keyData = await process(publicKey) - return keyData.users - } catch (e) { - console.error(e) - return undefined - } + resolve(keyData.users) + }) } -const getFingerprint = async (publicKey) => { - try { +const getFingerprint = (publicKey) => { + return new Promise(async (resolve, reject) => { const keyData = await process(publicKey) - return keyData.fingerprint - } catch (e) { - console.error(e) - return undefined - } + resolve(keyData.fingerprint) + }) } exports.fetch = { diff --git a/test/keys.test.js b/test/keys.test.js index 60a73e0..370855b 100644 --- a/test/keys.test.js +++ b/test/keys.test.js @@ -15,14 +15,19 @@ limitations under the License. */ const chai = require('chai') const expect = chai.expect +chai.use(require('chai-as-promised')) const path = require('path') -const openpgp = require(path.join(require.resolve('openpgp'), '..', 'openpgp.min.js')) +const openpgp = require(path.join( + require.resolve('openpgp'), + '..', + 'openpgp.min.js' +)) const doipjs = require('../src') const pubKeyFingerprint = `3637202523e7c1309ab79e99ef2dc5827b445f4b` -const pubKeyEmail = `test@doip.rocks` -const pubKeyPlaintext = `-----BEGIN PGP PUBLIC KEY BLOCK----- +const pubKeyEmail = `test@doip.rocks` +const pubKeyPlaintext = `-----BEGIN PGP PUBLIC KEY BLOCK----- mQGNBF+036UBDACoxWRdp7rBAFB2l/+dxX0XA50NJC92EEacB5L0TnC0lP/MsNHv fAv/A9vgTwrPudvcHdE/urAjQswfIU3LpFxbBOWNYWOv6ssrzBH4vVGMyxfu2GGu @@ -54,12 +59,14 @@ describe('keys.fetch.uri', () => { expect(doipjs.keys.fetch.uri).to.have.length(1) }) it('should return a Key object when provided a hkp: uri', async () => { - expect(await doipjs.keys.fetch.uri(`hkp:${pubKeyFingerprint}`)).to.be.instanceOf( - openpgp.key.Key - ) + expect( + await doipjs.keys.fetch.uri(`hkp:${pubKeyFingerprint}`) + ).to.be.instanceOf(openpgp.key.Key) }) - it('should return undefined when provided an invalid uri', async () => { - expect(await doipjs.keys.fetch.uri(`inv:${pubKeyFingerprint}`)).to.be.undefined + it('should reject when provided an invalid uri', () => { + return expect( + doipjs.keys.fetch.uri(`inv:${pubKeyFingerprint}`) + ).to.eventually.be.rejectedWith('Invalid URI protocol') }) }) @@ -79,10 +86,18 @@ describe('keys.fetch.hkp', () => { ) }) it('should return undefined when provided an invalid fingerprint', async () => { - expect(await doipjs.keys.fetch.hkp('4637202523e7c1309ab79e99ef2dc5827b445f4b')).to.be.undefined + return expect( + doipjs.keys.fetch.hkp('4637202523e7c1309ab79e99ef2dc5827b445f4b') + ).to.eventually.be.rejectedWith( + 'Key does not exist or could not be fetched' + ) }) it('should return undefined when provided an invalid email address', async () => { - expect(await doipjs.keys.fetch.hkp('invalid@doip.rocks')).to.be.undefined + return expect( + doipjs.keys.fetch.hkp('invalid@doip.rocks') + ).to.eventually.be.rejectedWith( + 'Key does not exist or could not be fetched' + ) }) })