forked from Mirrors/doipjs
Add jsdoc documentation
This commit is contained in:
parent
7ae9d2f9b1
commit
1a463594dc
20 changed files with 412 additions and 126 deletions
25
jsdoc-lib.json
Normal file
25
jsdoc-lib.json
Normal file
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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/"
|
||||
|
|
105
src/claim.js
105
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<object>} 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,
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
80
src/enums.js
80
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
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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')
|
|
@ -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) => {
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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
|
||||
|
|
112
src/keys.js
112
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
|
||||
}
|
|
@ -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<object|string>}
|
||||
*/
|
||||
const fetch = (data, opts) => {
|
||||
switch (data.proof.request.fetcher) {
|
||||
case E.Fetcher.HTTP:
|
||||
|
|
|
@ -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<object>}
|
||||
*/
|
||||
const process = (signature) => {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
let sigData,
|
||||
|
|
18
src/utils.js
18
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:
|
||||
|
|
|
@ -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,
|
||||
|
|
BIN
static/doip.png
Normal file
BIN
static/doip.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
Loading…
Reference in a new issue