diff --git a/jsdoc-lib.json b/jsdoc-lib.json new file mode 100644 index 0000000..5ea6458 --- /dev/null +++ b/jsdoc-lib.json @@ -0,0 +1,25 @@ +{ + "plugins": ["plugins/markdown"], + "source": { + "include": [ + "./src", + "./README.md" + ] + }, + "recurseDepth": 2, + "templates": { + "default": { + "staticFiles": { + "include": [ + "./static" + ] + } + } + }, + "opts": { + "template": "node_modules/docdash" + }, + "docdash": { + "search": true + } +} \ No newline at end of file diff --git a/package.json b/package.json index 556fbaf..6a9be73 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "license:check": "./node_modules/.bin/license-check-and-add check", "license:add": "./node_modules/.bin/license-check-and-add add", "license:remove": "./node_modules/.bin/license-check-and-add remove", - "docs:lib": "./node_modules/.bin/jsdoc -c jsdoc-lib.json -d ./docs", + "docs:lib": "./node_modules/.bin/jsdoc -c jsdoc-lib.json -r -d ./docs", "test": "./node_modules/.bin/mocha", "proxy": "NODE_ENV=production node ./src/proxy/", "proxy:dev": "NODE_ENV=development ./node_modules/.bin/nodemon ./src/proxy/" diff --git a/src/claim.js b/src/claim.js index d730372..cb26755 100644 --- a/src/claim.js +++ b/src/claim.js @@ -23,20 +23,24 @@ const defaults = require('./defaults') const E = require('./enums') /** - * OpenPGP-based identity claim * @class - * @property {String} uri - The claim's URI - * @property {String} uri - The claim's URI - * @property {String} uri - The claim's URI - * @property {String} uri - The claim's URI - * @property {String} uri - The claim's URI + * @classdesc OpenPGP-based identity claim + * @property {string} uri - The claim's URI + * @property {string} fingerprint - The fingerprint to verify the claim against + * @property {string} status - The current status of the claim + * @property {Array} matches - The claim definitions matched against the URI + * @property {object} result - The result of the verification process */ class Claim { /** * Initialize a Claim object * @constructor - * @param {string} [uri] - The URI of the identity claim - * @param {string} [fingerprint] - The fingerprint of the OpenPGP key + * @param {string} [uri] - The URI of the identity claim + * @param {string} [fingerprint] - The fingerprint of the OpenPGP key + * @example + * const claim = doip.Claim(); + * const claim = doip.Claim('dns:domain.tld?type=TXT'); + * const claim = doip.Claim('dns:domain.tld?type=TXT', '123abc123abc'); */ constructor(uri, fingerprint) { // Import JSON @@ -45,7 +49,7 @@ class Claim { case 1: this._uri = data.uri this._fingerprint = data.fingerprint - this._state = data.state + this._status = data.status this._dataMatches = data.dataMatches this._verification = data.verification break @@ -61,6 +65,7 @@ class Claim { if (uri && !validUrl.isUri(uri)) { throw new Error('Invalid URI') } + // Verify validity of fingerprint if (fingerprint) { try { @@ -72,67 +77,39 @@ class Claim { this._uri = uri ? uri : null this._fingerprint = fingerprint ? fingerprint : null - this._state = E.ClaimState.INIT + this._status = E.ClaimStatus.INIT this._dataMatches = null this._verification = null } - /** - * Get the claim's URI - */ get uri() { return this._uri } - /** - * Get the fingerprint the claim is supposed to acknowledge - * @function - * @returns {string} - */ get fingerprint() { return this._fingerprint } - /** - * Get the current state of the claim's verification process - * @function - * @returns {string} - */ - get state() { - return this._state + get status() { + return this._status } - /** - * Get the candidate claim definitions the URI matched against - * @function - * @returns {object} - */ get matches() { - if (this._state === E.ClaimState.INIT) { + if (this._status === E.ClaimStatus.INIT) { throw new Error('This claim has not yet been matched') } return this._dataMatches } - /** - * Get the result of the verification process - * @function - * @returns {object} - */ get result() { - if (this._state !== E.ClaimState.VERIFIED) { + if (this._status !== E.ClaimStatus.VERIFIED) { throw new Error('This claim has not yet been verified') } return this._verification } - /** - * Set the claim's URI - * @function - * @param {string} uri - The new claim URI - */ set uri(uri) { - if (this._state !== E.ClaimState.INIT) { + if (this._status !== E.ClaimStatus.INIT) { throw new Error( 'Cannot change the URI, this claim has already been matched' ) @@ -147,13 +124,8 @@ class Claim { this._uri = uri } - /** - * Set the claim's fingerprint to verify against - * @function - * @param {string} fingerprint - The new fingerprint - */ set fingerprint(fingerprint) { - if (this._state === E.ClaimState.VERIFIED) { + if (this._status === E.ClaimStatus.VERIFIED) { throw new Error( 'Cannot change the fingerprint, this claim has already been verified' ) @@ -161,29 +133,14 @@ class Claim { this._fingerprint = fingerprint } - /** - * Throw error when attempting to alter the state - * @function - * @param {any} anything - Anything will throw an error - */ - set state(anything) { - throw new Error("Cannot change a claim's state") + set status(anything) { + throw new Error("Cannot change a claim's status") } - /** - * Throw error when attempting to alter the dataMatches - * @function - * @param {any} anything - Anything will throw an error - */ set dataMatches(anything) { throw new Error("Cannot change a claim's dataMatches") } - /** - * Throw error when attempting to alter the verification data - * @function - * @param {any} anything - Anything will throw an error - */ set verification(anything) { throw new Error("Cannot change a claim's verification data") } @@ -193,7 +150,7 @@ class Claim { * @function */ match() { - if (this._state !== E.ClaimState.INIT) { + if (this._status !== E.ClaimStatus.INIT) { throw new Error('This claim was already matched') } if (this._uri === null) { @@ -224,7 +181,7 @@ class Claim { return true }) - this._state = E.ClaimState.MATCHED + this._status = E.ClaimStatus.MATCHED } /** @@ -237,10 +194,10 @@ class Claim { * @param {object} [opts] - Options for proxy, fetchers */ async verify(opts) { - if (this._state === E.ClaimState.INIT) { + if (this._status === E.ClaimStatus.INIT) { throw new Error('This claim has not yet been matched') } - if (this._state === E.ClaimState.VERIFIED) { + if (this._status === E.ClaimStatus.VERIFIED) { throw new Error('This claim has already been verified') } if (this._fingerprint === null) { @@ -298,18 +255,18 @@ class Claim { } } - this._state = E.ClaimState.VERIFIED + this._status = E.ClaimStatus.VERIFIED } /** - * Get the ambiguity of the claim. A claim is only unambiguous if any + * Determine the ambiguity of the claim. A claim is only unambiguous if any * of the candidates is unambiguous. An ambiguous claim should never be * displayed in an user interface when its result is negative. * @function * @returns {boolean} */ isAmbiguous() { - if (this._state === E.ClaimState.INIT) { + if (this._status === E.ClaimStatus.INIT) { throw new Error('The claim has not been matched yet') } if (this._dataMatches.length === 0) { @@ -331,7 +288,7 @@ class Claim { claimVersion: 1, uri: this._uri, fingerprint: this._fingerprint, - state: this._state, + status: this._status, dataMatches: this._dataMatches, verification: this._verification, } diff --git a/src/defaults.js b/src/defaults.js index 8bb4e07..014741a 100644 --- a/src/defaults.js +++ b/src/defaults.js @@ -15,6 +15,30 @@ limitations under the License. */ const E = require('./enums') +/** + * Contains default values + * @module defaults + */ + +/** + * The default options used throughout the library + * @constant {object} + * @property {object} proxy - Options related to the proxy + * @property {string|null} proxy.hostname - The hostname of the proxy + * @property {string} proxy.policy - The policy that defines when to use a proxy ({@link module:enums~ProxyPolicy|here}) + * @property {object} claims - Options related to claim verification + * @property {object} claims.irc - Options related to the verification of IRC claims + * @property {string|null} claims.irc.nick - The nick that the library uses to connect to the IRC server + * @property {object} claims.matrix - Options related to the verification of Matrix claims + * @property {string|null} claims.matrix.instance - The server hostname on which the library can log in + * @property {string|null} claims.matrix.accessToken - The access token required to identify the library ({@link https://www.matrix.org/docs/guides/client-server-api|Matrix docs}) + * @property {object} claims.xmpp - Options related to the verification of XMPP claims + * @property {string|null} claims.xmpp.service - The server hostname on which the library can log in + * @property {string|null} claims.xmpp.username - The username used to log in + * @property {string|null} claims.xmpp.password - The password used to log in + * @property {object} claims.twitter - Options related to the verification of Twitter claims + * @property {string|null} claims.twitter.bearerToken - The Twitter API's bearer token ({@link https://developer.twitter.com/en/docs/authentication/oauth-2-0/bearer-tokens|Twitter docs}) + */ const opts = { proxy: { hostname: null, diff --git a/src/enums.js b/src/enums.js index 86fd609..95da108 100644 --- a/src/enums.js +++ b/src/enums.js @@ -13,66 +13,123 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ +/** + * Contains enums + * @module enums + */ + +/** + * The proxy policy that decides how to fetch a proof + * @readonly + * @enum {string} + */ const ProxyPolicy = { + /** Proxy usage decision depends on environment and service provider */ ADAPTIVE: 'adaptive', + /** Always use a proxy */ ALWAYS: 'always', + /** Never use a proxy, skip a verification if a proxy is inevitable */ NEVER: 'never', } Object.freeze(ProxyPolicy) +/** + * Methods for fetching proofs + * @readonly + * @enum {string} + */ const Fetcher = { + /** Basic HTTP requests */ HTTP: 'http', + /** DNS module from Node.js */ DNS: 'dns', + /** IRC module from Node.js */ IRC: 'irc', + /** XMPP module from Node.js */ XMPP: 'xmpp', + /** HTTP request to Matrix API */ MATRIX: 'matrix', + /** HTTP request to Gitlab API */ GITLAB: 'gitlab', + /** HTTP request to Twitter API */ TWITTER: 'twitter', } Object.freeze(Fetcher) +/** + * Levels of access restriction for proof fetching + * @readonly + * @enum {number} + */ const ProofAccess = { + /** Any HTTP request will work */ GENERIC: 0, + /** CORS requests are denied */ NOCORS: 1, + /** HTTP requests must contain API or access tokens */ GRANTED: 2, + /** Not accessible by HTTP request, needs server software */ SERVER: 3, } Object.freeze(ProofAccess) +/** + * Format of proof + * @readonly + * @enum {string} + */ const ProofFormat = { + /** JSON format */ JSON: 'json', + /** Plaintext format */ TEXT: 'text', } Object.freeze(ProofFormat) +/** + * Format of claim + * @readonly + * @enum {number} + */ const ClaimFormat = { + /** `openpgp4fpr:123123123` */ URI: 0, + /** `123123123` */ FINGERPRINT: 1, + /** `[Verifying my OpenPGP key: openpgp4fpr:123123123]` */ MESSAGE: 2, } Object.freeze(ClaimFormat) +/** + * How to find the claim inside the proof's JSON data + * @readonly + * @enum {number} + */ const ClaimRelation = { + /** Claim is somewhere in the JSON field's textual content */ CONTAINS: 0, + /** Claim is equal to the JSON field's textual content */ EQUALS: 1, + /** Claim is equal to an element of the JSON field's array of strings */ ONEOF: 2, } Object.freeze(ClaimRelation) -const VerificationStatus = { - INIT: 0, - INPROGRESS: 1, - FAILED: 2, - COMPLETED: 3, -} -Object.freeze(VerificationStatus) - -const ClaimState = { +/** + * Status of the Claim instance + * @readonly + * @enum {string} + */ +const ClaimStatus = { + /** Claim has been initialized */ INIT: 'init', + /** Claim has matched its URI to candidate claim definitions */ MATCHED: 'matched', + /** Claim has verified one or multiple candidate claim definitions */ VERIFIED: 'verified', } -Object.freeze(ClaimState) +Object.freeze(ClaimStatus) exports.ProxyPolicy = ProxyPolicy exports.Fetcher = Fetcher @@ -80,5 +137,4 @@ exports.ProofAccess = ProofAccess exports.ProofFormat = ProofFormat exports.ClaimFormat = ClaimFormat exports.ClaimRelation = ClaimRelation -exports.VerificationStatus = VerificationStatus -exports.ClaimState = ClaimState +exports.ClaimStatus = ClaimStatus diff --git a/src/fetcher/dns.js b/src/fetcher/dns.js index 8e4cd35..967f7b8 100644 --- a/src/fetcher/dns.js +++ b/src/fetcher/dns.js @@ -15,8 +15,24 @@ limitations under the License. */ const dns = require('dns') +/** + * @module fetcher/dns + */ + +/** + * The request's timeout value in milliseconds + * @constant {number} timeout + */ module.exports.timeout = 5000 +/** + * Execute a fetch request + * @function + * @async + * @param {object} data - Data used in the request + * @param {string} data.domain - The targeted domain + * @returns {object} + */ module.exports.fn = async (data, opts) => { let timeoutHandle const timeoutPromise = new Promise((resolve, reject) => { diff --git a/src/fetcher/gitlab.js b/src/fetcher/gitlab.js index 948a2c3..d4bbcfb 100644 --- a/src/fetcher/gitlab.js +++ b/src/fetcher/gitlab.js @@ -16,8 +16,25 @@ limitations under the License. const bent = require('bent') const req = bent('GET') +/** + * @module fetcher/gitlab + */ + +/** + * The request's timeout value in milliseconds + * @constant {number} timeout + */ module.exports.timeout = 5000 +/** + * Execute a fetch request + * @function + * @async + * @param {object} data - Data used in the request + * @param {string} data.username - The username of the targeted account + * @param {string} data.domain - The domain on which the targeted account is registered + * @returns {object} + */ module.exports.fn = async (data, opts) => { let timeoutHandle const timeoutPromise = new Promise((resolve, reject) => { @@ -45,7 +62,7 @@ module.exports.fn = async (data, opts) => { const project = jsonProject.find((proj) => proj.path === 'gitlab_proof') if (!project) { - reject(`No project at ${spData.proof.uri}`) + reject(`No project found`) } resolve(project) diff --git a/src/fetcher/http.js b/src/fetcher/http.js index 985765f..ca3d125 100644 --- a/src/fetcher/http.js +++ b/src/fetcher/http.js @@ -17,8 +17,25 @@ const bent = require('bent') const req = bent('GET') const E = require('../enums') +/** + * @module fetcher/http + */ + +/** + * The request's timeout value in milliseconds + * @constant {number} timeout + */ module.exports.timeout = 5000 +/** + * Execute a fetch request + * @function + * @async + * @param {object} data - Data used in the request + * @param {string} data.url - The URL pointing at targeted content + * @param {string} data.format - The format of the targeted content + * @returns {object|string} + */ module.exports.fn = async (data, opts) => { let timeoutHandle const timeoutPromise = new Promise((resolve, reject) => { diff --git a/src/fetcher/index.js b/src/fetcher/index.js index ae41e0d..be3604a 100644 --- a/src/fetcher/index.js +++ b/src/fetcher/index.js @@ -13,10 +13,11 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ + exports.dns = require('./dns') exports.gitlab = require('./gitlab') exports.http = require('./http') exports.irc = require('./irc') exports.matrix = require('./matrix') exports.twitter = require('./twitter') -exports.xmpp = require('./xmpp') +exports.xmpp = require('./xmpp') \ No newline at end of file diff --git a/src/fetcher/irc.js b/src/fetcher/irc.js index 7a05834..19bb39c 100644 --- a/src/fetcher/irc.js +++ b/src/fetcher/irc.js @@ -16,8 +16,27 @@ limitations under the License. const irc = require('irc-upd') const validator = require('validator') +/** + * @module fetcher/irc + */ + +/** + * The request's timeout value in milliseconds + * @constant {number} timeout + */ module.exports.timeout = 20000 +/** + * Execute a fetch request + * @function + * @async + * @param {object} data - Data used in the request + * @param {string} data.nick - The nick of the targeted account + * @param {string} data.domain - The domain on which the targeted account is registered + * @param {object} opts - Options used to enable the request + * @param {string} opts.claims.irc.nick - The nick to be used by the library to log in + * @returns {object} + */ module.exports.fn = async (data, opts) => { let timeoutHandle const timeoutPromise = new Promise((resolve, reject) => { diff --git a/src/fetcher/matrix.js b/src/fetcher/matrix.js index c20e681..0295ee8 100644 --- a/src/fetcher/matrix.js +++ b/src/fetcher/matrix.js @@ -17,8 +17,28 @@ const bent = require('bent') const bentReq = bent('GET') const validator = require('validator') +/** + * @module fetcher/matrix + */ + +/** + * The request's timeout value in milliseconds + * @constant {number} timeout + */ module.exports.timeout = 5000 +/** + * Execute a fetch request + * @function + * @async + * @param {object} data - Data used in the request + * @param {string} data.eventId - The identifier of the targeted post + * @param {string} data.roomId - The identifier of the room containing the targeted post + * @param {object} opts - Options used to enable the request + * @param {string} opts.claims.matrix.instance - The server hostname on which the library can log in + * @param {string} opts.claims.matrix.accessToken - The access token required to identify the library ({@link https://www.matrix.org/docs/guides/client-server-api|Matrix docs}) + * @returns {object} + */ module.exports.fn = async (data, opts) => { let timeoutHandle const timeoutPromise = new Promise((resolve, reject) => { diff --git a/src/fetcher/twitter.js b/src/fetcher/twitter.js index 4f16ffa..dc19172 100644 --- a/src/fetcher/twitter.js +++ b/src/fetcher/twitter.js @@ -17,8 +17,26 @@ const bent = require('bent') const bentReq = bent('GET') const validator = require('validator') +/** + * @module fetcher/twitter + */ + +/** + * The request's timeout value in milliseconds + * @constant {number} timeout + */ module.exports.timeout = 5000 +/** + * Execute a fetch request + * @function + * @async + * @param {object} data - Data used in the request + * @param {number|string} data.tweetId - Identifier of the tweet + * @param {object} opts - Options used to enable the request + * @param {string} opts.claims.twitter.bearerToken - The Twitter API's bearer token + * @returns {object} + */ module.exports.fn = async (data, opts) => { let timeoutHandle const timeoutPromise = new Promise((resolve, reject) => { diff --git a/src/fetcher/xmpp.js b/src/fetcher/xmpp.js index 1895044..b0655dc 100644 --- a/src/fetcher/xmpp.js +++ b/src/fetcher/xmpp.js @@ -18,6 +18,14 @@ const { client, xml } = require('@xmpp/client') const debug = require('@xmpp/debug') const validator = require('validator') +/** + * @module fetcher/xmpp + */ + +/** + * The request's timeout value in milliseconds + * @constant {number} timeout + */ module.exports.timeout = 5000 let xmpp = null, @@ -44,6 +52,19 @@ const xmppStart = async (service, username, password) => { }) } +/** + * Execute a fetch request + * @function + * @async + * @param {object} data - Data used in the request + * @param {string} data.id - The identifier of the targeted account + * @param {string} data.field - The vCard field to return (should be "note") + * @param {object} opts - Options used to enable the request + * @param {string} opts.claims.xmpp.service - The server hostname on which the library can log in + * @param {string} opts.claims.xmpp.username - The username used to log in + * @param {string} opts.claims.xmpp.password - The password used to log in + * @returns {object} + */ module.exports.fn = async (data, opts) => { let timeoutHandle const timeoutPromise = new Promise((resolve, reject) => { diff --git a/src/index.js b/src/index.js index a46a564..e2e71ca 100644 --- a/src/index.js +++ b/src/index.js @@ -16,7 +16,6 @@ limitations under the License. const Claim = require('./claim') const claimDefinitions = require('./claimDefinitions') const proofs = require('./proofs') -const verifications = require('./verifications') const keys = require('./keys') const signatures = require('./signatures') const enums = require('./enums') @@ -26,7 +25,6 @@ const utils = require('./utils') exports.Claim = Claim exports.claimDefinitions = claimDefinitions exports.proofs = proofs -exports.verifications = verifications exports.keys = keys exports.signatures = signatures exports.enums = enums diff --git a/src/keys.js b/src/keys.js index aa941a6..b3fb0b4 100644 --- a/src/keys.js +++ b/src/keys.js @@ -19,10 +19,25 @@ const validUrl = require('valid-url') const openpgp = require('openpgp') const Claim = require('./claim') -const fetchHKP = (identifier, keyserverBaseUrl) => { +/** + * Functions related to the fetching and handling of keys + * @module keys + */ + +/** + * Fetch a public key using keyservers + * @function + * @param {string} identifier - Fingerprint or email address + * @param {string} [keyserverDomain=keys.openpgp.org] - Domain of the keyserver + * @returns {openpgp.key.Key} + * @example + * const key1 = doip.keys.fetchHKP('alice@domain.tld'); + * const key2 = doip.keys.fetchHKP('123abc123abc'); + */ + exports.fetchHKP = (identifier, keyserverDomain) => { return new Promise(async (resolve, reject) => { - keyserverBaseUrl = keyserverBaseUrl - ? `https://${keyserverBaseUrl}` + const keyserverBaseUrl = keyserverDomain + ? `https://${keyserverDomain}` : 'https://keys.openpgp.org' const hkp = new openpgp.HKP(keyserverBaseUrl) @@ -51,7 +66,15 @@ const fetchHKP = (identifier, keyserverBaseUrl) => { }) } -const fetchWKD = (identifier) => { +/** + * Fetch a public key using Web Key Directory + * @function + * @param {string} identifier - Identifier of format 'username@domain.tld` + * @returns {openpgp.key.Key} + * @example + * const key = doip.keys.fetchWKD('alice@domain.tld'); + */ +exports.fetchWKD = (identifier) => { return new Promise(async (resolve, reject) => { const wkd = new openpgp.WKD() const lookupOpts = { @@ -75,7 +98,16 @@ const fetchWKD = (identifier) => { }) } -const fetchKeybase = (username, fingerprint) => { +/** + * Fetch a public key from Keybase + * @function + * @param {string} username - Keybase username + * @param {string} fingerprint - Fingerprint of key + * @returns {openpgp.key.Key} + * @example + * const key = doip.keys.fetchKeybase('alice', '123abc123abc'); + */ +exports.fetchKeybase = (username, fingerprint) => { return new Promise(async (resolve, reject) => { const keyLink = `https://keybase.io/${username}/pgp_keys.asc?fingerprint=${fingerprint}` try { @@ -107,7 +139,21 @@ const fetchKeybase = (username, fingerprint) => { }) } -const fetchPlaintext = (rawKeyContent) => { +/** + * Get a public key from plaintext data + * @function + * @param {string} rawKeyContent - Plaintext ASCII-formatted public key data + * @returns {openpgp.key.Key} + * @example + * const plainkey = `-----BEGIN PGP PUBLIC KEY BLOCK----- + * + * mQINBF0mIsIBEADacleiyiV+z6FIunvLWrO6ZETxGNVpqM+WbBQKdW1BVrJBBolg + * [...] + * =6lib + * -----END PGP PUBLIC KEY BLOCK-----` + * const key = doip.keys.fetchPlaintext(plainkey); + */ +exports.fetchPlaintext = (rawKeyContent) => { return new Promise(async (resolve, reject) => { const publicKey = (await openpgp.key.readArmored(rawKeyContent)).keys[0] @@ -115,23 +161,17 @@ const fetchPlaintext = (rawKeyContent) => { }) } -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] - let sigContent = await openpgp.stream.readToEnd( - await sig.packets[1].getText() - ) - } - const sigUserId = sig.packets[0].signersUserId - const sigKeyId = await sig.packets[0].issuerKeyId.toHex() - - resolve(fetchHKP(sigUserId ? sigUserId : sigKeyId, keyserverBaseUrl)) - }) -} - -const fetchURI = (uri) => { +/** + * Fetch a public key using an URI + * @function + * @param {string} uri - URI that defines the location of the key + * @returns {openpgp.key.Key} + * @example + * const key1 = doip.keys.fetchURI('hkp:alice@domain.tld'); + * const key2 = doip.keys.fetchURI('hkp:123abc123abc'); + * const key3 = doip.keys.fetchURI('wkd:alice@domain.tld'); + */ +exports.fetchURI = (uri) => { return new Promise(async (resolve, reject) => { if (!validUrl.isUri(uri)) { reject('Invalid URI') @@ -163,7 +203,19 @@ const fetchURI = (uri) => { }) } -const process = (publicKey) => { +/** + * Process a public key to get user data and claims + * @function + * @param {openpgp.key.Key} publicKey - The public key to process + * @returns {object} + * @example + * const key = doip.keys.fetchURI('hkp:alice@domain.tld'); + * const data = doip.keys.process(key); + * data.users[0].claims.forEach(claim => { + * console.log(claim.uri); + * }); + */ +exports.process = (publicKey) => { return new Promise(async (resolve, reject) => { if (!publicKey || !(publicKey instanceof openpgp.key.Key)) { reject('Invalid public key') @@ -210,14 +262,4 @@ const process = (publicKey) => { }, }) }) -} - -exports.fetch = { - uri: fetchURI, - hkp: fetchHKP, - wkd: fetchWKD, - keybase: fetchKeybase, - plaintext: fetchPlaintext, - signature: fetchSignature, -} -exports.process = process +} \ No newline at end of file diff --git a/src/proofs.js b/src/proofs.js index 524db5e..04c5b05 100644 --- a/src/proofs.js +++ b/src/proofs.js @@ -18,6 +18,21 @@ const fetcher = require('./fetcher') const utils = require('./utils') const E = require('./enums') +/** + * @module proofs + */ + +/** + * Delegate the proof request to the correct fetcher. + * This method uses the current environment (browser/node), certain values from + * the `data` parameter and the proxy policy set in the `opts` parameter to + * choose the right approach to fetch the proof. An error will be thrown if no + * approach is possible. + * @async + * @param {object} data - Data from a claim definition + * @param {object} opts - Options to enable the request + * @returns {Promise} + */ const fetch = (data, opts) => { switch (data.proof.request.fetcher) { case E.Fetcher.HTTP: diff --git a/src/signatures.js b/src/signatures.js index a2ccba1..987c432 100644 --- a/src/signatures.js +++ b/src/signatures.js @@ -17,6 +17,16 @@ const openpgp = require('openpgp') const Claim = require('./claim') const keys = require('./keys') +/** + * @module signatures + */ + +/** + * Extract data from a signature and fetch the associated key + * @async + * @param {string} signature - The plaintext signature to process + * @returns {Promise} + */ const process = (signature) => { return new Promise(async (resolve, reject) => { let sigData, diff --git a/src/utils.js b/src/utils.js index 6374bcf..276a79a 100644 --- a/src/utils.js +++ b/src/utils.js @@ -16,6 +16,18 @@ limitations under the License. const validator = require('validator') const E = require('./enums') +/** + * @module utils + */ + +/** + * Generate an URL to request data from a proxy server + * @param {string} type - The name of the fetcher the proxy must use + * @param {object} data - The data the proxy must provide to the fetcher + * @param {object} opts - Options to enable the request + * @param {object} opts.proxy.hostname - The hostname of the proxy server + * @returns {string} + */ const generateProxyURL = (type, data, opts) => { try { validator.isFQDN(opts.proxy.hostname) @@ -34,6 +46,12 @@ const generateProxyURL = (type, data, opts) => { )}` } +/** + * Generate the string that must be found in the proof to verify a claim + * @param {string} fingerprint - The fingerprint of the claim + * @param {number} format - The claim's format (see {@link module:enums~ClaimFormat|enums.ClaimFormat}) + * @returns {string} + */ const generateClaim = (fingerprint, format) => { switch (format) { case E.ClaimFormat.URI: diff --git a/src/verifications.js b/src/verifications.js index eec4625..812db1a 100644 --- a/src/verifications.js +++ b/src/verifications.js @@ -16,6 +16,11 @@ limitations under the License. const utils = require('./utils') const E = require('./enums') +/** + * @module verifications + * @ignore + */ + const runJSON = (proofData, checkPath, checkClaim, checkRelation) => { let re @@ -70,6 +75,13 @@ const runJSON = (proofData, checkPath, checkClaim, checkRelation) => { ) } +/** + * Run the verification by finding the formatted fingerprint in the proof + * @param {object} proofData - The proof data + * @param {object} claimData - The claim data + * @param {string} fingerprint - The fingerprint + * @returns {object} + */ const run = (proofData, claimData, fingerprint) => { let res = { result: false, diff --git a/static/doip.png b/static/doip.png new file mode 100644 index 0000000..18be005 Binary files /dev/null and b/static/doip.png differ