Properly reject promises

This commit is contained in:
Yarmo Mackenbach 2020-12-05 23:13:44 +01:00
parent f49e9029e9
commit b9c76b7c0e
2 changed files with 99 additions and 89 deletions

View file

@ -17,11 +17,15 @@ const path = require('path')
const bent = require('bent') const bent = require('bent')
const req = bent('GET') const req = bent('GET')
const validUrl = require('valid-url') 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 mergeOptions = require('merge-options')
const fetchHKP = async (identifier, keyserverBaseUrl) => { const fetchHKP = (identifier, keyserverBaseUrl) => {
try { return new Promise(async (resolve, reject) => {
keyserverBaseUrl = keyserverBaseUrl keyserverBaseUrl = keyserverBaseUrl
? keyserverBaseUrl ? keyserverBaseUrl
: 'https://keys.openpgp.org/' : 'https://keys.openpgp.org/'
@ -33,64 +37,64 @@ const fetchHKP = async (identifier, keyserverBaseUrl) => {
let publicKey = await hkp.lookup(lookupOpts) let publicKey = await hkp.lookup(lookupOpts)
publicKey = (await openpgp.key.readArmored(publicKey)).keys[0] publicKey = (await openpgp.key.readArmored(publicKey)).keys[0]
return publicKey if (publicKey == undefined) {
} catch (e) { reject('Key does not exist or could not be fetched')
console.error(e) }
return undefined
} resolve(publicKey)
})
} }
const fetchWKD = async (identifier) => { const fetchWKD = (identifier) => {
try { return new Promise(async (resolve, reject) => {
const wkd = new openpgp.WKD() const wkd = new openpgp.WKD()
const lookupOpts = { const lookupOpts = {
email: identifier, email: identifier,
} }
const publicKey = (await wkd.lookup(lookupOpts)).keys[0] const publicKey = (await wkd.lookup(lookupOpts)).keys[0]
return publicKey if (publicKey == undefined) {
} catch (e) { reject('Key does not exist or could not be fetched')
console.error(e) }
return undefined
} resolve(publicKey)
})
} }
const fetchKeybase = async (username, fingerprint) => { const fetchKeybase = (username, fingerprint) => {
try { return new Promise(async (resolve, reject) => {
const keyLink = `https://keybase.io/${username}/pgp_keys.asc?fingerprint=${fingerprint}` const keyLink = `https://keybase.io/${username}/pgp_keys.asc?fingerprint=${fingerprint}`
try { try {
const rawKeyContent = await req(opts.keyLink) const rawKeyContent = await req(opts.keyLink)
.then(function (response) { .then((response) => {
if (response.status === 200) { if (response.status === 200) {
return response return response
} }
}) })
.then((response) => response.text()) .then((response) => response.text())
} catch (e) { } catch (e) {
return undefined reject(`Error fetching Keybase key: ${e.message}`)
} }
const publicKey = (await openpgp.key.readArmored(rawKeyContent)).keys[0] const publicKey = (await openpgp.key.readArmored(rawKeyContent)).keys[0]
return publicKey if (publicKey == undefined) {
} catch (e) { reject('Key does not exist or could not be fetched')
console.error(e) }
return undefined
} resolve(publicKey)
})
} }
const fetchPlaintext = async (rawKeyContent) => { const fetchPlaintext = (rawKeyContent) => {
try { return new Promise(async (resolve, reject) => {
const publicKey = (await openpgp.key.readArmored(rawKeyContent)).keys[0] const publicKey = (await openpgp.key.readArmored(rawKeyContent)).keys[0]
return publicKey resolve(publicKey)
} catch (e) { })
console.error(e)
return undefined
}
} }
const fetchSignature = async (rawSignatureContent, keyserverBaseUrl) => { const fetchSignature = (rawSignatureContent, keyserverBaseUrl) => {
try { return new Promise(async (resolve, reject) => {
let sig = await openpgp.signature.readArmored(rawSignatureContent) let sig = await openpgp.signature.readArmored(rawSignatureContent)
if ('compressed' in sig.packets[0]) { if ('compressed' in sig.packets[0]) {
sig = sig.packets[0] sig = sig.packets[0]
@ -101,52 +105,50 @@ const fetchSignature = async (rawSignatureContent, keyserverBaseUrl) => {
const sigUserId = sig.packets[0].signersUserId const sigUserId = sig.packets[0].signersUserId
const sigKeyId = await sig.packets[0].issuerKeyId.toHex() const sigKeyId = await sig.packets[0].issuerKeyId.toHex()
return fetchHKP(sigUserId ? sigUserId : sigKeyId, keyserverBaseUrl) resolve(fetchHKP(sigUserId ? sigUserId : sigKeyId, keyserverBaseUrl))
} catch (e) { })
console.error(e)
return undefined
}
} }
const fetchURI = async (uri) => { const fetchURI = (uri) => {
try { return new Promise(async (resolve, reject) => {
if (!validUrl.isUri(uri)) { 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 re = /([a-zA-Z0-9]*):([a-zA-Z0-9@._=+\-]*)(\:[a-zA-Z0-9@._=+\-]*)?/
const match = uri.match(re) const match = uri.match(re)
if (!match[1]) { if (!match[1]) {
throw new Error('Invalid URI') reject('Invalid URI')
} }
switch (match[1]) { switch (match[1]) {
case 'hkp': case 'hkp':
return fetchHKP(match[2], match.length >= 4 ? match[3] : null) resolve(fetchHKP(match[2], match.length >= 4 ? match[3] : null))
break break
case 'wkd': case 'wkd':
return fetchWKD(match[2]) resolve(fetchWKD(match[2]))
break break
case 'kb': case 'kb':
return fetchKeybase(match[2], match.length >= 4 ? match[3] : null) resolve(fetchKeybase(match[2], match.length >= 4 ? match[3] : null))
break break
default: default:
throw new Error('Invalid URI protocol') reject('Invalid URI protocol')
break break
} }
} catch (e) { })
console.error(e)
return undefined
}
} }
const process = async (publicKey) => { const process = (publicKey) => {
try { return new Promise(async (resolve, reject) => {
if (!publicKey) {
reject('Invalid public key')
}
const fingerprint = await publicKey.primaryKey.getFingerprint() const fingerprint = await publicKey.primaryKey.getFingerprint()
const primaryUser = await publicKey.getPrimaryUser() const primaryUser = await publicKey.getPrimaryUser()
const users = publicKey.users const users = publicKey.users
let primaryUserIndex, usersOutput = [] let primaryUserIndex,
usersOutput = []
users.forEach((user, i) => { users.forEach((user, i) => {
usersOutput[i] = { usersOutput[i] = {
@ -155,49 +157,42 @@ const process = async (publicKey) => {
name: user.userId.name, name: user.userId.name,
email: user.userId.email, email: user.userId.email,
comment: user.userId.comment, comment: user.userId.comment,
isPrimary: primaryUser.index === i isPrimary: primaryUser.index === i,
} },
} }
const notations = user.selfCertifications[0].rawNotations const notations = user.selfCertifications[0].rawNotations
usersOutput[i].notations = notations.map(({ name, value, humanReadable }) => { usersOutput[i].notations = notations.map(
if (humanReadable && name === 'proof@metacode.biz') { ({ name, value, humanReadable }) => {
return openpgp.util.decode_utf8(value) if (humanReadable && name === 'proof@metacode.biz') {
return openpgp.util.decode_utf8(value)
}
} }
}) )
}) })
return { resolve({
fingerprint: fingerprint, fingerprint: fingerprint,
users: usersOutput, users: usersOutput,
primaryUserIndex: primaryUser.index, primaryUserIndex: primaryUser.index,
} })
} catch (e) { })
console.error(e)
return undefined
}
} }
const getUserData = async (publicKey) => { const getUserData = (publicKey) => {
try { return new Promise(async (resolve, reject) => {
const keyData = await process(publicKey) const keyData = await process(publicKey)
return keyData.users resolve(keyData.users)
} catch (e) { })
console.error(e)
return undefined
}
} }
const getFingerprint = async (publicKey) => { const getFingerprint = (publicKey) => {
try { return new Promise(async (resolve, reject) => {
const keyData = await process(publicKey) const keyData = await process(publicKey)
return keyData.fingerprint resolve(keyData.fingerprint)
} catch (e) { })
console.error(e)
return undefined
}
} }
exports.fetch = { exports.fetch = {

View file

@ -15,14 +15,19 @@ limitations under the License.
*/ */
const chai = require('chai') const chai = require('chai')
const expect = chai.expect const expect = chai.expect
chai.use(require('chai-as-promised'))
const path = require('path') 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 doipjs = require('../src')
const pubKeyFingerprint = `3637202523e7c1309ab79e99ef2dc5827b445f4b` const pubKeyFingerprint = `3637202523e7c1309ab79e99ef2dc5827b445f4b`
const pubKeyEmail = `test@doip.rocks` const pubKeyEmail = `test@doip.rocks`
const pubKeyPlaintext = `-----BEGIN PGP PUBLIC KEY BLOCK----- const pubKeyPlaintext = `-----BEGIN PGP PUBLIC KEY BLOCK-----
mQGNBF+036UBDACoxWRdp7rBAFB2l/+dxX0XA50NJC92EEacB5L0TnC0lP/MsNHv mQGNBF+036UBDACoxWRdp7rBAFB2l/+dxX0XA50NJC92EEacB5L0TnC0lP/MsNHv
fAv/A9vgTwrPudvcHdE/urAjQswfIU3LpFxbBOWNYWOv6ssrzBH4vVGMyxfu2GGu fAv/A9vgTwrPudvcHdE/urAjQswfIU3LpFxbBOWNYWOv6ssrzBH4vVGMyxfu2GGu
@ -54,12 +59,14 @@ describe('keys.fetch.uri', () => {
expect(doipjs.keys.fetch.uri).to.have.length(1) expect(doipjs.keys.fetch.uri).to.have.length(1)
}) })
it('should return a Key object when provided a hkp: uri', async () => { it('should return a Key object when provided a hkp: uri', async () => {
expect(await doipjs.keys.fetch.uri(`hkp:${pubKeyFingerprint}`)).to.be.instanceOf( expect(
openpgp.key.Key await doipjs.keys.fetch.uri(`hkp:${pubKeyFingerprint}`)
) ).to.be.instanceOf(openpgp.key.Key)
}) })
it('should return undefined when provided an invalid uri', async () => { it('should reject when provided an invalid uri', () => {
expect(await doipjs.keys.fetch.uri(`inv:${pubKeyFingerprint}`)).to.be.undefined 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 () => { 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 () => { 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'
)
}) })
}) })