From 514ba3c4b47221347a8ee2e6414d430f9e1ce34e Mon Sep 17 00:00:00 2001 From: Yarmo Mackenbach Date: Sat, 5 Dec 2020 23:17:54 +0100 Subject: [PATCH] Release 0.7.0 --- CHANGELOG.md | 4 + dist/doip.js | 278 ++++++++++++++++++++++++------------------- dist/doip.min.js | 2 +- docs/_coverpage.md | 2 +- docs/changelog.md | 7 ++ docs/installation.md | 2 +- package.json | 2 +- 7 files changed, 169 insertions(+), 128 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df8e816..75949c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.7.0] - 2020-12-05 +### Changed +- Properly reject promises + ## [0.6.0] - 2020-11-20 ### Changed - Handle multiple users in key diff --git a/dist/doip.js b/dist/doip.js index faed4cd..6954dee 100644 --- a/dist/doip.js +++ b/dist/doip.js @@ -1193,7 +1193,7 @@ process.umask = function() { return 0; }; },{}],9:[function(require,module,exports){ module.exports={ "name": "doipjs", - "version": "0.5.1", + "version": "0.6.0", "description": "Decentralized OpenPGP Identity Proofs library in Node.js", "main": "src/index.js", "dependencies": { @@ -1259,7 +1259,11 @@ limitations under the License. const path = require('path') const mergeOptions = require('merge-options') 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 serviceproviders = require('./serviceproviders') const keys = require('./keys') const utils = require('./utils') @@ -1288,15 +1292,12 @@ const runVerificationJson = ( switch (checkRelation) { default: case 'contains': - re = new RegExp( - checkClaim.replace('[', '\\[').replace(']', '\\]'), - 'gi' - ) - res.isVerified = re.test(proofData.replace(/\r?\n|\r/, '')) + re = new RegExp(checkClaim, 'gi') + res.isVerified = re.test(proofData.replace(/\r?\n|\r|\\/g, '')) break case 'equals': res.isVerified = - proofData.replace(/\r?\n|\r/, '').toLowerCase() == + proofData.replace(/\r?\n|\r|\\/g, '').toLowerCase() == checkClaim.toLowerCase() break case 'oneOf': @@ -1354,9 +1355,24 @@ const runVerification = (proofData, spData) => { const verify = async (input, fingerprint, opts) => { if (input instanceof openpgp.key.Key) { - const fingerprintLocal = await keys.getFingerprint(input) - const claims = await keys.getClaims(input) - return await verify(claims, fingerprintLocal, opts) + const fingerprintFromKey = await keys.getFingerprint(input) + const userData = await keys.getUserData(input) + + const promises = userData.map(async (user, i) => { + return new Promise(async (resolve, reject) => { + try { + const res = await verify(user.notations, fingerprintFromKey, opts) + resolve(res) + } catch (e) { + console.error(`Claim verification failed: ${user.userData.id}`, e) + reject(e) + } + }) + }) + + return Promise.all(promises).then((values) => { + return values + }) } if (input instanceof Array) { const promises = input.map(async (uri, i) => { @@ -1390,7 +1406,7 @@ const verify = async (input, fingerprint, opts) => { opts = mergeOptions(defaultOpts, opts ? opts : {}) if (!validUrl.isUri(uri)) { - throw new Error('Not a valid URI') + throw new Error('Invalid URI') } const spMatches = serviceproviders.match(uri, opts) @@ -1493,11 +1509,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/' @@ -1509,64 +1529,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] @@ -1577,88 +1597,94 @@ 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 fingerprint = await publicKey.primaryKey.getFingerprint() - const user = await publicKey.getPrimaryUser() - - return { - fingerprint: fingerprint, - user: user, +const process = (publicKey) => { + return new Promise(async (resolve, reject) => { + if (!publicKey) { + reject('Invalid public key') } - } catch (e) { - console.error(e) - return undefined - } -} + const fingerprint = await publicKey.primaryKey.getFingerprint() + const primaryUser = await publicKey.getPrimaryUser() + const users = publicKey.users + let primaryUserIndex, + usersOutput = [] -const getClaims = async (publicKey) => { - try { - const keyData = await process(publicKey) - let notations = keyData.user.selfCertification.rawNotations - - notations = notations.map(({ name, value, humanReadable }) => { - if (humanReadable && name === 'proof@metacode.biz') { - return openpgp.util.decode_utf8(value) + users.forEach((user, i) => { + usersOutput[i] = { + userData: { + id: user.userId.userid, + name: user.userId.name, + email: user.userId.email, + comment: user.userId.comment, + 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) + } + } + ) }) - return notations - } catch (e) { - console.error(e) - return undefined - } + resolve({ + fingerprint: fingerprint, + users: usersOutput, + primaryUserIndex: primaryUser.index, + }) + }) } -const getFingerprint = async (publicKey) => { - try { +const getUserData = (publicKey) => { + return new Promise(async (resolve, reject) => { const keyData = await process(publicKey) - return keyData.fingerprint - } catch (e) { - console.error(e) - return undefined - } + resolve(keyData.users) + }) +} + +const getFingerprint = (publicKey) => { + return new Promise(async (resolve, reject) => { + const keyData = await process(publicKey) + + resolve(keyData.fingerprint) + }) } exports.fetch = { @@ -1670,7 +1696,7 @@ exports.fetch = { signature: fetchSignature, } exports.process = process -exports.getClaims = getClaims +exports.getUserData = getUserData exports.getFingerprint = getFingerprint },{"bent":1,"merge-options":5,"path":6,"valid-url":8}],13:[function(require,module,exports){ @@ -1741,37 +1767,41 @@ const match = (uri, opts) => { return matches } -const directRequestHandler = async (spData, opts) => { - const url = spData.proof.fetch ? spData.proof.fetch : spData.proof.uri - let res +const directRequestHandler = (spData, opts) => { + return new Promise(async (resolve, reject) => { + const url = spData.proof.fetch ? spData.proof.fetch : spData.proof.uri + let res - switch (spData.proof.format) { - case 'json': - res = await req(url, null, { - Accept: 'application/json', - 'User-Agent': `doipjs/${require('../package.json').version}`, - }) - return await res.json() - break - case 'text': - res = await req(url) - return await res.text() - break - default: - throw new Error('No specified proof data format') - break - } + switch (spData.proof.format) { + case 'json': + res = await req(url, null, { + Accept: 'application/json', + 'User-Agent': `doipjs/${require('../package.json').version}`, + }) + resolve(await res.json()) + break + case 'text': + res = await req(url) + resolve(await res.text()) + break + default: + reject('No specified proof data format') + break + } + }) } -const proxyRequestHandler = async (spData, opts) => { - const url = spData.proof.fetch ? spData.proof.fetch : spData.proof.uri - const res = await req( - utils.generateProxyURL(spData.proof.format, url, opts), - null, - { Accept: 'application/json' } - ) - const json = await res.json() - return json.content +const proxyRequestHandler = (spData, opts) => { + return new Promise(async (resolve, reject) => { + const url = spData.proof.fetch ? spData.proof.fetch : spData.proof.uri + const res = await req( + utils.generateProxyURL(spData.proof.format, url, opts), + null, + { Accept: 'application/json' } + ) + const json = await res.json() + resolve(json.content) + }) } exports.list = list diff --git a/dist/doip.min.js b/dist/doip.min.js index ea76d9e..3a26f36 100644 --- a/dist/doip.min.js +++ b/dist/doip.min.js @@ -1 +1 @@ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).doip=e()}}((function(){return function e(t,r,o){function i(s,a){if(!r[s]){if(!t[s]){var c="function"==typeof require&&require;if(!a&&c)return c(s,!0);if(n)return n(s,!0);var l=new Error("Cannot find module '"+s+"'");throw l.code="MODULE_NOT_FOUND",l}var u=r[s]={exports:{}};t[s][0].call(u.exports,(function(e){return i(t[s][1][e]||e)}),u,u.exports,e,t,r,o)}return r[s].exports}for(var n="function"==typeof require&&require,s=0;s(r||(r=this.arrayBuffer()),r)}),this.headers={};for(const[t,r]of e.headers.entries())this.headers[t.toLowerCase()]=r}}t.exports=o(((e,t,r,o,n)=>async(s,a,c={})=>{s=n+(s||"");let l=new URL(s);if(o||(o={}),l.username&&(o.Authorization="Basic "+btoa(l.username+":"+l.password),l=new URL(l.protocol+"//"+l.host+l.pathname+l.search)),"https:"!==l.protocol&&"http:"!==l.protocol)throw new Error("Unknown protocol, "+l.protocol);if(a)if(a instanceof ArrayBuffer||ArrayBuffer.isView(a)||"string"==typeof a);else{if("object"!=typeof a)throw new Error("Unknown body type.");a=JSON.stringify(a),o["Content-Type"]="application/json"}c=new Headers({...o||{},...c});const u=await fetch(l,{method:t,headers:c,body:a});if(u.statusCode=u.status,!e.has(u.status))throw new i(u);return"json"===r?u.json():"buffer"===r?u.arrayBuffer():"string"===r?u.text():u}))},{"./core":2}],2:[function(e,t,r){"use strict";const o=new Set(["json","buffer","string"]);t.exports=e=>(...t)=>{const r=new Set;let i,n,s,a="";return t.forEach((e=>{if("string"==typeof e)if(e.toUpperCase()===e){if(i){throw new Error(`Can't set method to ${e}, already set to ${i}.`)}i=e}else if(e.startsWith("http:")||e.startsWith("https:"))a=e;else{if(!o.has(e))throw new Error("Unknown encoding, "+e);n=e}else if("number"==typeof e)r.add(e);else{if("object"!=typeof e)throw new Error("Unknown type: "+typeof e);if(Array.isArray(e)||e instanceof Set)e.forEach((e=>r.add(e)));else{if(s)throw new Error("Cannot set headers twice.");s=e}}})),i||(i="GET"),0===r.size&&r.add(200),e(r,i,n,s,a)}},{}],3:[function(e,t,r){},{}],4:[function(e,t,r){"use strict";t.exports=e=>{if("[object Object]"!==Object.prototype.toString.call(e))return!1;const t=Object.getPrototypeOf(e);return null===t||t===Object.prototype}},{}],5:[function(e,t,r){"use strict";const o=e("is-plain-obj"),{hasOwnProperty:i}=Object.prototype,{propertyIsEnumerable:n}=Object,s=(e,t,r)=>Object.defineProperty(e,t,{value:r,writable:!0,enumerable:!0,configurable:!0}),a=this,c={concatArrays:!1,ignoreUndefined:!1},l=e=>{const t=[];for(const r in e)i.call(e,r)&&t.push(r);if(Object.getOwnPropertySymbols){const r=Object.getOwnPropertySymbols(e);for(const o of r)n.call(e,o)&&t.push(o)}return t};function u(e){return Array.isArray(e)?function(e){const t=e.slice(0,0);return l(e).forEach((r=>{s(t,r,u(e[r]))})),t}(e):o(e)?function(e){const t=null===Object.getPrototypeOf(e)?Object.create(null):{};return l(e).forEach((r=>{s(t,r,u(e[r]))})),t}(e):e}const p=(e,t,r,o)=>(r.forEach((r=>{void 0===t[r]&&o.ignoreUndefined||(r in e&&e[r]!==Object.getPrototypeOf(e)?s(e,r,d(e[r],t[r],o)):s(e,r,u(t[r])))})),e);function d(e,t,r){return r.concatArrays&&Array.isArray(e)&&Array.isArray(t)?((e,t,r)=>{let o=e.slice(0,0),n=0;return[e,t].forEach((t=>{const a=[];for(let r=0;r!a.includes(e))),r)})),o})(e,t,r):o(t)&&o(e)?p(e,t,l(t),r):u(t)}t.exports=function(...e){const t=d(u(c),this!==a&&this||{},c);let r={_:{}};for(const i of e)if(void 0!==i){if(!o(i))throw new TypeError("`"+i+"` is not an Option Object");r=d(r,{_:i},t)}return r._}},{"is-plain-obj":4}],6:[function(e,t,r){(function(e){(function(){"use strict";function r(e){if("string"!=typeof e)throw new TypeError("Path must be a string. Received "+JSON.stringify(e))}function o(e,t){for(var r,o="",i=0,n=-1,s=0,a=0;a<=e.length;++a){if(a2){var c=o.lastIndexOf("/");if(c!==o.length-1){-1===c?(o="",i=0):i=(o=o.slice(0,c)).length-1-o.lastIndexOf("/"),n=a,s=0;continue}}else if(2===o.length||1===o.length){o="",i=0,n=a,s=0;continue}t&&(o.length>0?o+="/..":o="..",i=2)}else o.length>0?o+="/"+e.slice(n+1,a):o=e.slice(n+1,a),i=a-n-1;n=a,s=0}else 46===r&&-1!==s?++s:s=-1}return o}var i={resolve:function(){for(var t,i="",n=!1,s=arguments.length-1;s>=-1&&!n;s--){var a;s>=0?a=arguments[s]:(void 0===t&&(t=e.cwd()),a=t),r(a),0!==a.length&&(i=a+"/"+i,n=47===a.charCodeAt(0))}return i=o(i,!n),n?i.length>0?"/"+i:"/":i.length>0?i:"."},normalize:function(e){if(r(e),0===e.length)return".";var t=47===e.charCodeAt(0),i=47===e.charCodeAt(e.length-1);return 0!==(e=o(e,!t)).length||t||(e="."),e.length>0&&i&&(e+="/"),t?"/"+e:e},isAbsolute:function(e){return r(e),e.length>0&&47===e.charCodeAt(0)},join:function(){if(0===arguments.length)return".";for(var e,t=0;t0&&(void 0===e?e=o:e+="/"+o)}return void 0===e?".":i.normalize(e)},relative:function(e,t){if(r(e),r(t),e===t)return"";if((e=i.resolve(e))===(t=i.resolve(t)))return"";for(var o=1;ol){if(47===t.charCodeAt(a+p))return t.slice(a+p+1);if(0===p)return t.slice(a+p)}else s>l&&(47===e.charCodeAt(o+p)?u=p:0===p&&(u=0));break}var d=e.charCodeAt(o+p);if(d!==t.charCodeAt(a+p))break;47===d&&(u=p)}var h="";for(p=o+u+1;p<=n;++p)p!==n&&47!==e.charCodeAt(p)||(0===h.length?h+="..":h+="/..");return h.length>0?h+t.slice(a+u):(a+=u,47===t.charCodeAt(a)&&++a,t.slice(a))},_makeLong:function(e){return e},dirname:function(e){if(r(e),0===e.length)return".";for(var t=e.charCodeAt(0),o=47===t,i=-1,n=!0,s=e.length-1;s>=1;--s)if(47===(t=e.charCodeAt(s))){if(!n){i=s;break}}else n=!1;return-1===i?o?"/":".":o&&1===i?"//":e.slice(0,i)},basename:function(e,t){if(void 0!==t&&"string"!=typeof t)throw new TypeError('"ext" argument must be a string');r(e);var o,i=0,n=-1,s=!0;if(void 0!==t&&t.length>0&&t.length<=e.length){if(t.length===e.length&&t===e)return"";var a=t.length-1,c=-1;for(o=e.length-1;o>=0;--o){var l=e.charCodeAt(o);if(47===l){if(!s){i=o+1;break}}else-1===c&&(s=!1,c=o+1),a>=0&&(l===t.charCodeAt(a)?-1==--a&&(n=o):(a=-1,n=c))}return i===n?n=c:-1===n&&(n=e.length),e.slice(i,n)}for(o=e.length-1;o>=0;--o)if(47===e.charCodeAt(o)){if(!s){i=o+1;break}}else-1===n&&(s=!1,n=o+1);return-1===n?"":e.slice(i,n)},extname:function(e){r(e);for(var t=-1,o=0,i=-1,n=!0,s=0,a=e.length-1;a>=0;--a){var c=e.charCodeAt(a);if(47!==c)-1===i&&(n=!1,i=a+1),46===c?-1===t?t=a:1!==s&&(s=1):-1!==t&&(s=-1);else if(!n){o=a+1;break}}return-1===t||-1===i||0===s||1===s&&t===i-1&&t===o+1?"":e.slice(t,i)},format:function(e){if(null===e||"object"!=typeof e)throw new TypeError('The "pathObject" argument must be of type Object. Received type '+typeof e);return function(e,t){var r=t.dir||t.root,o=t.base||(t.name||"")+(t.ext||"");return r?r===t.root?r+o:r+e+o:o}("/",e)},parse:function(e){r(e);var t={root:"",dir:"",base:"",ext:"",name:""};if(0===e.length)return t;var o,i=e.charCodeAt(0),n=47===i;n?(t.root="/",o=1):o=0;for(var s=-1,a=0,c=-1,l=!0,u=e.length-1,p=0;u>=o;--u)if(47!==(i=e.charCodeAt(u)))-1===c&&(l=!1,c=u+1),46===i?-1===s?s=u:1!==p&&(p=1):-1!==s&&(p=-1);else if(!l){a=u+1;break}return-1===s||-1===c||0===p||1===p&&s===c-1&&s===a+1?-1!==c&&(t.base=t.name=0===a&&n?e.slice(1,c):e.slice(a,c)):(0===a&&n?(t.name=e.slice(1,s),t.base=e.slice(1,c)):(t.name=e.slice(a,s),t.base=e.slice(a,c)),t.ext=e.slice(s,c)),a>0?t.dir=e.slice(0,a-1):n&&(t.dir="/"),t},sep:"/",delimiter:":",win32:null,posix:null};i.posix=i,t.exports=i}).call(this)}).call(this,e("_process"))},{_process:7}],7:[function(e,t,r){var o,i,n=t.exports={};function s(){throw new Error("setTimeout has not been defined")}function a(){throw new Error("clearTimeout has not been defined")}function c(e){if(o===setTimeout)return setTimeout(e,0);if((o===s||!o)&&setTimeout)return o=setTimeout,setTimeout(e,0);try{return o(e,0)}catch(t){try{return o.call(null,e,0)}catch(t){return o.call(this,e,0)}}}!function(){try{o="function"==typeof setTimeout?setTimeout:s}catch(e){o=s}try{i="function"==typeof clearTimeout?clearTimeout:a}catch(e){i=a}}();var l,u=[],p=!1,d=-1;function h(){p&&l&&(p=!1,l.length?u=l.concat(u):d=-1,u.length&&f())}function f(){if(!p){var e=c(h);p=!0;for(var t=u.length;t;){for(l=u,u=[];++d1)for(var r=1;r=0){if(o&&o.length){if(0!==i.length&&!/^\//.test(i))return}else if(/^\/\//.test(i))return;if(/^[a-z][a-z0-9\+\-\.]*$/.test(a.toLowerCase()))return c+=a+":",o&&o.length&&(c+="//"+o),c+=i,n&&n.length&&(c+="?"+n),s&&s.length&&(c+="#"+s),c}}}function o(e,o){if(r(e)){var i,n,s,a,c="",l="",u="",p="";if(c=(i=t(e))[1],l=i[2],n=i[3],s=i[4],a=i[5],c){if(o){if("https"!=c.toLowerCase())return}else if("http"!=c.toLowerCase())return;if(l)return/:(\d+)$/.test(l)&&(u=l.match(/:(\d+)$/)[0],l=l.replace(/:\d+$/,"")),p+=c+":",p+="//"+l,u&&(p+=u),p+=n,s&&s.length&&(p+="?"+s),a&&a.length&&(p+="#"+a),p}}}function i(e){return o(e,!0)}function n(e){return o(e)||i(e)}}(t)},{}],9:[function(e,t,r){t.exports={name:"doipjs",version:"0.5.1",description:"Decentralized OpenPGP Identity Proofs library in Node.js",main:"src/index.js",dependencies:{bent:"^7.3.12",browserify:"^17.0.0","merge-options":"^3.0.3",openpgp:"^4.10.8",prettier:"^2.1.2","valid-url":"^1.0.9"},devDependencies:{chai:"^4.2.0","chai-as-promised":"^7.1.1","chai-match-pattern":"^1.2.0","license-check-and-add":"^3.0.4",minify:"^6.0.1",mocha:"^8.2.0"},scripts:{"release:bundle":"./node_modules/browserify/bin/cmd.js ./src/index.js --standalone doip -o ./dist/doip.js","release:minify":"./node_modules/minify/bin/minify.js ./dist/doip.js > ./dist/doip.min.js","prettier:check":"./node_modules/prettier/bin-prettier.js --check .","prettier:write":"./node_modules/prettier/bin-prettier.js --write .","license:check":"./node_modules/license-check-and-add/dist/src/cli.js check","license:add":"./node_modules/license-check-and-add/dist/src/cli.js add","license:remove":"./node_modules/license-check-and-add/dist/src/cli.js remove",docs:"docsify serve ./docs",test:"./node_modules/mocha/bin/mocha"},repository:{type:"git",url:"https://codeberg.org/keyoxide/doipjs"},homepage:"https://js.doip.rocks",keywords:["pgp","gpg","openpgp","encryption","decentralized","identity"],author:"Yarmo Mackenbach (https://yarmo.eu)",license:"Apache-2.0"}},{}],10:[function(e,t,r){const o=e("path"),i=e("merge-options"),n=e("valid-url"),s=e(o.join(e.resolve("openpgp"),"..","openpgp.min.js")),a=e("./serviceproviders"),c=e("./keys"),l=e("./utils"),u=(e,t,r,o,i)=>{let n;if(e.isVerified||!t)return e;if(Array.isArray(t))return t.forEach(((t,n)=>{e=u(e,t,r,o,i)})),e;if(0==r.length){switch(i){default:case"contains":n=new RegExp(o.replace("[","\\[").replace("]","\\]"),"gi"),e.isVerified=n.test(t.replace(/\r?\n|\r/,""));break;case"equals":e.isVerified=t.replace(/\r?\n|\r/,"").toLowerCase()==o.toLowerCase();break;case"oneOf":n=new RegExp(o,"gi"),e.isVerified=n.test(t.join("|"))}return e}try{r[0]}catch(t){return e.errors.push("err_data_structure_incorrect"),e}return e=u(e,t[r[0]],r.slice(1),o,i)},p=(e,t)=>{let r={isVerified:!1,errors:[]};switch(t.proof.format){case"json":r=u(r,e,t.claim.path,l.generateClaim(t.claim.fingerprint,t.claim.format),t.claim.relation);break;case"text":re=new RegExp(l.generateClaim(t.claim.fingerprint,t.claim.format),"gi"),r.isVerified=re.test(e.replace(/\r?\n|\r/,""))}return r},d=async(e,t,r)=>{if(e instanceof s.key.Key){const t=await c.getFingerprint(e),o=await c.getClaims(e);return await d(o,t,r)}if(e instanceof Array){const o=e.map((async(e,o)=>new Promise((async(o,i)=>{try{o(await d(e,t,r))}catch(t){console.error("Claim verification failed: "+e,t),i(t)}}))));return Promise.all(o).then((e=>e))}const o=e;t||(t=null);if(r=i({returnMatchesOnly:!1,proxyPolicy:"adaptive",doipProxyHostname:"proxy.keyoxide.org"},r||{}),!n.isUri(o))throw new Error("Not a valid URI");const l=a.match(o,r);if("returnMatchesOnly"in r&&r.returnMatchesOnly)return l;let u,h,f,m,g=!1,y=0;for(;!g&&y{try{t=t||"https://keys.openpgp.org/";const r=new s.HKP(t),o={query:e};let i=await r.lookup(o);return i=(await s.key.readArmored(i)).keys[0],i}catch(e){return void console.error(e)}}),c=async e=>{try{const t=new s.WKD,r={email:e};return(await t.lookup(r)).keys[0]}catch(e){return void console.error(e)}},l=async(e,t)=>{try{try{await i(opts.keyLink).then((function(e){if(200===e.status)return e})).then((e=>e.text()))}catch(e){return}return(await s.key.readArmored(rawKeyContent)).keys[0]}catch(e){return void console.error(e)}},u=async e=>{try{const t=await e.primaryKey.getFingerprint();return{fingerprint:t,user:await e.getPrimaryUser()}}catch(e){return void console.error(e)}};r.fetch={uri:async e=>{try{if(!n.isUri(e))throw new Error("Invalid URI");const t=/([a-zA-Z0-9]*):([a-zA-Z0-9@._=+\-]*)(\:[a-zA-Z0-9@._=+\-]*)?/,r=e.match(t);if(!r[1])throw new Error("Invalid URI");switch(r[1]){case"hkp":return a(r[2],r.length>=4?r[3]:null);case"wkd":return c(r[2]);case"kb":return l(r[2],r.length>=4&&r[3]);default:throw new Error("Invalid URI protocol")}}catch(e){return void console.error(e)}},hkp:a,wkd:c,keybase:l,plaintext:async e=>{try{return(await s.key.readArmored(e)).keys[0]}catch(e){return void console.error(e)}},signature:async(e,t)=>{try{let r=await s.signature.readArmored(e);if("compressed"in r.packets[0]){r=r.packets[0];await s.stream.readToEnd(await r.packets[1].getText())}const o=r.packets[0].signersUserId,i=await r.packets[0].issuerKeyId.toHex();return a(o||i,t)}catch(e){return void console.error(e)}}},r.process=u,r.getClaims=async e=>{try{let t=(await u(e)).user.selfCertification.rawNotations;return t=t.map((({name:e,value:t,humanReadable:r})=>{if(r&&"proof@metacode.biz"===e)return s.util.decode_utf8(t)})),t}catch(e){return void console.error(e)}},r.getFingerprint=async e=>{try{return(await u(e)).fingerprint}catch(e){return void console.error(e)}}},{bent:1,"merge-options":5,path:6,"valid-url":8}],13:[function(e,t,r){const o=e("bent")("GET"),i=e("./utils"),n=["dns","xmpp","twitter","reddit","liberapay","hackernews","lobsters","devto","gitea","gitlab","github","mastodon","fediverse","discourse"],s={dns:e("./serviceproviders/dns"),xmpp:e("./serviceproviders/xmpp"),twitter:e("./serviceproviders/twitter"),reddit:e("./serviceproviders/reddit"),liberapay:e("./serviceproviders/liberapay"),hackernews:e("./serviceproviders/hackernews"),lobsters:e("./serviceproviders/lobsters"),devto:e("./serviceproviders/devto"),gitea:e("./serviceproviders/gitea"),gitlab:e("./serviceproviders/gitlab"),github:e("./serviceproviders/github"),mastodon:e("./serviceproviders/mastodon"),fediverse:e("./serviceproviders/fediverse"),discourse:e("./serviceproviders/discourse")};r.list=n,r.data=s,r.match=(e,t)=>{let r,o=[];return n.forEach(((i,n)=>{r=s[i],r.reURI.test(e)&&o.push(r.processURI(e,t))})),o},r.directRequestHandler=async(t,r)=>{const i=t.proof.fetch?t.proof.fetch:t.proof.uri;let n;switch(t.proof.format){case"json":return n=await o(i,null,{Accept:"application/json","User-Agent":"doipjs/"+e("../package.json").version}),await n.json();case"text":return n=await o(i),await n.text();default:throw new Error("No specified proof data format")}},r.proxyRequestHandler=async(e,t)=>{const r=e.proof.fetch?e.proof.fetch:e.proof.uri,n=await o(i.generateProxyURL(e.proof.format,r,t),null,{Accept:"application/json"});return(await n.json()).content}},{"../package.json":9,"./serviceproviders/devto":14,"./serviceproviders/discourse":15,"./serviceproviders/dns":16,"./serviceproviders/fediverse":17,"./serviceproviders/gitea":18,"./serviceproviders/github":19,"./serviceproviders/gitlab":20,"./serviceproviders/hackernews":21,"./serviceproviders/liberapay":22,"./serviceproviders/lobsters":23,"./serviceproviders/mastodon":24,"./serviceproviders/reddit":25,"./serviceproviders/twitter":26,"./serviceproviders/xmpp":27,"./utils":28,bent:1}],14:[function(e,t,r){const o=/^https:\/\/dev\.to\/(.*)\/(.*)\/?/;r.reURI=o,r.processURI=(e,t)=>{t||(t={});const r=e.match(o);return{serviceprovider:{type:"web",name:"devto"},profile:{display:r[1],uri:"https://dev.to/"+r[1],qr:null},proof:{uri:e,fetch:`https://dev.to/api/articles/${r[1]}/${r[2]}`,useProxy:!1,format:"json"},claim:{fingerprint:null,format:"message",path:["body_markdown"],relation:"contains"},customRequestHandler:null}},r.tests=[{uri:"https://dev.to/alice/post",shouldMatch:!0},{uri:"https://dev.to/alice/post/",shouldMatch:!0},{uri:"https://domain.org/alice/post",shouldMatch:!1}]},{}],15:[function(e,t,r){const o=/^https:\/\/(.*)\/u\/(.*)\/?/;r.reURI=o,r.processURI=(e,t)=>{t||(t={});const r=e.match(o);return{serviceprovider:{type:"web",name:"discourse"},profile:{display:`${r[2]}@${r[1]}`,uri:e,qr:null},proof:{uri:e,fetch:`https://${r[1]}/u/${r[2]}.json`,useProxy:!0,format:"json"},claim:{fingerprint:null,format:"message",path:["user","bio_raw"],relation:"contains"},customRequestHandler:null}},r.tests=[{uri:"https://domain.org/u/alice",shouldMatch:!0},{uri:"https://domain.org/u/alice/",shouldMatch:!0},{uri:"https://domain.org/alice",shouldMatch:!1}]},{}],16:[function(e,t,r){const o=e("dns"),i=e("bent")("GET"),n=e("../utils"),s=/^dns:([a-zA-Z0-9\.\-\_]*)(?:\?(.*))?/,a=async(e,t)=>{if("resolveTxt"in o){const t=async()=>new Promise(((t,r)=>{o.resolveTxt(e.profile.display,((e,o)=>{e&&r(e),t(o)}))}));return{hostname:e.profile.display,records:{txt:await t()}}}{const t=await i(e.proof.uri,null,{Accept:"application/json"});return await t.json()}};r.reURI=s,r.processURI=(e,t)=>{t||(t={});const r=e.match(s);return{serviceprovider:{type:"web",name:"dns"},profile:{display:r[1],uri:"https://"+r[1],qr:null},proof:{uri:n.generateProxyURL("dns",r[1]),fetch:null,useProxy:!1,format:"json"},claim:{fingerprint:null,format:"uri",path:["records","txt"],relation:"contains"},customRequestHandler:a}},r.tests=[{uri:"dns:domain.org",shouldMatch:!0},{uri:"dns:domain.org?type=TXT",shouldMatch:!0},{uri:"https://domain.org",shouldMatch:!1}]},{"../utils":28,bent:1,dns:3}],17:[function(e,t,r){const o=/^https:\/\/(.*)\/users\/(.*)\/?/;r.reURI=o,r.processURI=(e,t)=>{t||(t={});const r=e.match(o);return{serviceprovider:{type:"web",name:"fediverse"},profile:{display:`@${r[2]}@${r[1]}`,uri:e,qr:null},proof:{uri:e,fetch:null,useProxy:!1,format:"json"},claim:{fingerprint:null,format:"fingerprint",path:["summary"],relation:"contains"},customRequestHandler:null}},r.tests=[{uri:"https://domain.org/users/alice",shouldMatch:!0},{uri:"https://domain.org/users/alice/",shouldMatch:!0},{uri:"https://domain.org/alice",shouldMatch:!1}]},{}],18:[function(e,t,r){const o=/^https:\/\/(.*)\/(.*)\/gitea_proof\/?/;r.reURI=o,r.processURI=(e,t)=>{t||(t={});const r=e.match(o);return{serviceprovider:{type:"web",name:"gitea"},profile:{display:`${r[2]}@${r[1]}`,uri:`https://${r[1]}/${r[2]}`,qr:null},proof:{uri:e,fetch:`https://${r[1]}/api/v1/repos/${r[2]}/gitea_proof`,useProxy:!0,format:"json"},claim:{fingerprint:null,format:"message",path:["description"],relation:"equals"},customRequestHandler:null}},r.tests=[{uri:"https://domain.org/alice/gitea_proof",shouldMatch:!0},{uri:"https://domain.org/alice/gitea_proof/",shouldMatch:!0},{uri:"https://domain.org/alice/other_proof",shouldMatch:!1}]},{}],19:[function(e,t,r){const o=/^https:\/\/gist\.github\.com\/(.*)\/(.*)\/?/;r.reURI=o,r.processURI=(e,t)=>{t||(t={});const r=e.match(o);return{serviceprovider:{type:"web",name:"github"},profile:{display:r[1],uri:"https://github.com/"+r[1],qr:null},proof:{uri:e,fetch:"https://api.github.com/gists/"+r[2],useProxy:!1,format:"json"},claim:{fingerprint:null,format:"message",path:["files","openpgp.md","content"],relation:"contains"},customRequestHandler:null}},r.tests=[{uri:"https://gist.github.com/Alice/123456789",shouldMatch:!0},{uri:"https://gist.github.com/Alice/123456789/",shouldMatch:!0},{uri:"https://domain.org/Alice/123456789",shouldMatch:!1}]},{}],20:[function(e,t,r){const o=e("bent")("GET"),i=/^https:\/\/(.*)\/(.*)\/gitlab_proof\/?/,n=async(e,t)=>{const r=e.proof.uri.match(i),n=`https://${r[1]}/api/v4/users?username=${r[2]}`,s=await o(n,"json",{Accept:"application/json"}),a=(await s.json()).find((e=>e.username===r[2]));if(!a)throw new Error("No user with username "+r[2]);const c=`https://${r[1]}/api/v4/users/${a.id}/projects`,l=await o(c,{},{Accept:"application/json"}),u=(await l.json()).find((e=>"gitlab_proof"===e.path));if(!u)throw new Error("No project at "+e.proof.uri);return u};r.reURI=i,r.processURI=(e,t)=>{t||(t={});const r=e.match(i);return{serviceprovider:{type:"web",name:"gitlab"},profile:{display:`${r[2]}@${r[1]}`,uri:`https://${r[1]}/${r[2]}`,qr:null},proof:{uri:e,fetch:null,useProxy:!1,format:"json"},claim:{fingerprint:null,format:"message",path:["description"],relation:"equals"},customRequestHandler:n}},r.tests=[{uri:"https://gitlab.domain.org/alice/gitlab_proof",shouldMatch:!0},{uri:"https://gitlab.domain.org/alice/gitlab_proof/",shouldMatch:!0},{uri:"https://domain.org/alice/other_proof",shouldMatch:!1}]},{bent:1}],21:[function(e,t,r){const o=/^https:\/\/news\.ycombinator\.com\/user\?id=(.*)\/?/;r.reURI=o,r.processURI=(e,t)=>{t||(t={});const r=e.match(o);return{serviceprovider:{type:"web",name:"hackernews"},profile:{display:r[1],uri:e,qr:null},proof:{uri:`https://hacker-news.firebaseio.com/v0/user/${r[1]}.json`,fetch:null,useProxy:!0,format:"json"},claim:{fingerprint:null,format:"uri",path:["about"],relation:"contains"},customRequestHandler:null}},r.tests=[{uri:"https://news.ycombinator.com/user?id=Alice",shouldMatch:!0},{uri:"https://news.ycombinator.com/user?id=Alice/",shouldMatch:!0},{uri:"https://domain.org/user?id=Alice",shouldMatch:!1}]},{}],22:[function(e,t,r){const o=/^https:\/\/liberapay\.com\/(.*)\/?/;r.reURI=o,r.processURI=(e,t)=>{t||(t={});const r=e.match(o);return{serviceprovider:{type:"web",name:"liberapay"},profile:{display:r[1],uri:e,qr:null},proof:{uri:e,fetch:`https://liberapay.com/${r[1]}/public.json`,useProxy:!1,format:"json"},claim:{fingerprint:null,format:"message",path:["statements","content"],relation:"contains"},customRequestHandler:null}},r.tests=[{uri:"https://liberapay.com/alice",shouldMatch:!0},{uri:"https://liberapay.com/alice/",shouldMatch:!0},{uri:"https://domain.org/alice",shouldMatch:!1}]},{}],23:[function(e,t,r){const o=/^https:\/\/lobste\.rs\/u\/(.*)\/?/;r.reURI=o,r.processURI=(e,t)=>{t||(t={});const r=e.match(o);return{serviceprovider:{type:"web",name:"lobsters"},profile:{display:r[1],uri:e,qr:null},proof:{uri:`https://lobste.rs/u/${r[1]}.json`,fetch:null,useProxy:!0,format:"json"},claim:{fingerprint:null,format:"message",path:["about"],relation:"contains"},customRequestHandler:null}},r.tests=[{uri:"https://lobste.rs/u/Alice",shouldMatch:!0},{uri:"https://lobste.rs/u/Alice/",shouldMatch:!0},{uri:"https://domain.org/u/Alice",shouldMatch:!1}]},{}],24:[function(e,t,r){const o=/^https:\/\/(.*)\/@(.*)\/?/;r.reURI=o,r.processURI=(e,t)=>{t||(t={});const r=e.match(o);return{serviceprovider:{type:"web",name:"mastodon"},profile:{display:`@${r[2]}@${r[1]}`,uri:e,qr:null},proof:{uri:e,fetch:null,useProxy:!1,format:"json"},claim:{fingerprint:null,format:"fingerprint",path:["attachment","value"],relation:"contains"},customRequestHandler:null}},r.tests=[{uri:"https://domain.org/@alice",shouldMatch:!0},{uri:"https://domain.org/@alice/",shouldMatch:!0},{uri:"https://domain.org/alice",shouldMatch:!1}]},{}],25:[function(e,t,r){const o=/^https:\/\/(?:www\.)?reddit\.com\/user\/(.*)\/comments\/(.*)\/(.*)\/?/;r.reURI=o,r.processURI=(e,t)=>{t||(t={});const r=e.match(o);return{serviceprovider:{type:"web",name:"reddit"},profile:{display:r[1],uri:"https://www.reddit.com/user/"+r[1],qr:null},proof:{uri:e,fetch:`https://www.reddit.com/user/${r[1]}/comments/${r[2]}.json`,useProxy:!0,format:"json"},claim:{fingerprint:null,format:"message",path:["data","children","data","selftext"],relation:"contains"},customRequestHandler:null}},r.tests=[{uri:"https://www.reddit.com/user/Alice/comments/123456/post",shouldMatch:!0},{uri:"https://www.reddit.com/user/Alice/comments/123456/post/",shouldMatch:!0},{uri:"https://reddit.com/user/Alice/comments/123456/post",shouldMatch:!0},{uri:"https://reddit.com/user/Alice/comments/123456/post/",shouldMatch:!0},{uri:"https://domain.org/user/Alice/comments/123456/post",shouldMatch:!1}]},{}],26:[function(e,t,r){const o=/^https:\/\/twitter\.com\/(.*)\/status\/([0-9]*)(?:\?.*)?/;r.reURI=o,r.processURI=(e,t)=>{t||(t={});const r=e.match(o);return{serviceprovider:{type:"web",name:"twitter"},profile:{display:"@"+r[1],uri:"https://twitter.com/"+r[1],qr:null},proof:{uri:e,fetch:`https://mobile.twitter.com/${r[1]}/status/${r[2]}`,useProxy:!1,format:"text"},claim:{fingerprint:null,format:"message",path:[],relation:"contains"},customRequestHandler:null}},r.tests=[{uri:"https://twitter.com/alice/status/1234567890123456789",shouldMatch:!0},{uri:"https://twitter.com/alice/status/1234567890123456789/",shouldMatch:!0},{uri:"https://domain.org/alice/status/1234567890123456789",shouldMatch:!1}]},{}],27:[function(e,t,r){const o=e("../utils"),i=/^xmpp:([a-zA-Z0-9\.\-\_]*)@([a-zA-Z0-9\.\-\_]*)(?:\?(.*))?/;r.reURI=i,r.processURI=(e,t)=>{t||(t={});const r=e.match(i);return{serviceprovider:{type:"communication",name:"xmpp"},profile:{display:`${r[1]}@${r[2]}`,uri:e,qr:e},proof:{uri:o.generateProxyURL("xmpp",`${r[1]}@${r[2]}`,t),fetch:null,useProxy:!1,format:"json"},claim:{fingerprint:null,format:"message",path:[],relation:"contains"},customRequestHandler:null}},r.tests=[{uri:"xmpp:alice@domain.org",shouldMatch:!0},{uri:"xmpp:alice@domain.org?omemo-sid-123456789=A1B2C3D4E5F6G7H8I9",shouldMatch:!0},{uri:"https://domain.org",shouldMatch:!1}]},{"../utils":28}],28:[function(e,t,r){r.generateProxyURL=(e,t,r)=>{if(!r||!r.doipProxyHostname)return null;let o="";return"xmpp"==e&&(o+="/DESC"),`https://${r.doipProxyHostname}/api/1/get/${e}/${encodeURIComponent(t)}${o}`},r.generateClaim=(e,t)=>{switch(t){case"uri":return"openpgp4fpr:"+e;case"message":return`[Verifying my OpenPGP key: openpgp4fpr:${e}]`;case"fingerprint":return e;default:throw new Error("No valid claim format")}}},{}]},{},[11])(11)})); +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).doip=e()}}((function(){return function e(t,r,o){function i(n,a){if(!r[n]){if(!t[n]){var c="function"==typeof require&&require;if(!a&&c)return c(n,!0);if(s)return s(n,!0);var l=new Error("Cannot find module '"+n+"'");throw l.code="MODULE_NOT_FOUND",l}var u=r[n]={exports:{}};t[n][0].call(u.exports,(function(e){return i(t[n][1][e]||e)}),u,u.exports,e,t,r,o)}return r[n].exports}for(var s="function"==typeof require&&require,n=0;n(r||(r=this.arrayBuffer()),r)}),this.headers={};for(const[t,r]of e.headers.entries())this.headers[t.toLowerCase()]=r}}t.exports=o(((e,t,r,o,s)=>async(n,a,c={})=>{n=s+(n||"");let l=new URL(n);if(o||(o={}),l.username&&(o.Authorization="Basic "+btoa(l.username+":"+l.password),l=new URL(l.protocol+"//"+l.host+l.pathname+l.search)),"https:"!==l.protocol&&"http:"!==l.protocol)throw new Error(`Unknown protocol, ${l.protocol}`);if(a)if(a instanceof ArrayBuffer||ArrayBuffer.isView(a)||"string"==typeof a);else{if("object"!=typeof a)throw new Error("Unknown body type.");a=JSON.stringify(a),o["Content-Type"]="application/json"}c=new Headers({...o||{},...c});const u=await fetch(l,{method:t,headers:c,body:a});if(u.statusCode=u.status,!e.has(u.status))throw new i(u);return"json"===r?u.json():"buffer"===r?u.arrayBuffer():"string"===r?u.text():u}))},{"./core":2}],2:[function(e,t,r){"use strict";const o=new Set(["json","buffer","string"]);t.exports=e=>(...t)=>{const r=new Set;let i,s,n,a="";return t.forEach((e=>{if("string"==typeof e)if(e.toUpperCase()===e){if(i){throw new Error(`Can't set method to ${e}, already set to ${i}.`)}i=e}else if(e.startsWith("http:")||e.startsWith("https:"))a=e;else{if(!o.has(e))throw new Error(`Unknown encoding, ${e}`);s=e}else if("number"==typeof e)r.add(e);else{if("object"!=typeof e)throw new Error("Unknown type: "+typeof e);if(Array.isArray(e)||e instanceof Set)e.forEach((e=>r.add(e)));else{if(n)throw new Error("Cannot set headers twice.");n=e}}})),i||(i="GET"),0===r.size&&r.add(200),e(r,i,s,n,a)}},{}],3:[function(e,t,r){},{}],4:[function(e,t,r){"use strict";t.exports=e=>{if("[object Object]"!==Object.prototype.toString.call(e))return!1;const t=Object.getPrototypeOf(e);return null===t||t===Object.prototype}},{}],5:[function(e,t,r){"use strict";const o=e("is-plain-obj"),{hasOwnProperty:i}=Object.prototype,{propertyIsEnumerable:s}=Object,n=(e,t,r)=>Object.defineProperty(e,t,{value:r,writable:!0,enumerable:!0,configurable:!0}),a=this,c={concatArrays:!1,ignoreUndefined:!1},l=e=>{const t=[];for(const r in e)i.call(e,r)&&t.push(r);if(Object.getOwnPropertySymbols){const r=Object.getOwnPropertySymbols(e);for(const o of r)s.call(e,o)&&t.push(o)}return t};function u(e){return Array.isArray(e)?function(e){const t=e.slice(0,0);return l(e).forEach((r=>{n(t,r,u(e[r]))})),t}(e):o(e)?function(e){const t=null===Object.getPrototypeOf(e)?Object.create(null):{};return l(e).forEach((r=>{n(t,r,u(e[r]))})),t}(e):e}const p=(e,t,r,o)=>(r.forEach((r=>{void 0===t[r]&&o.ignoreUndefined||(r in e&&e[r]!==Object.getPrototypeOf(e)?n(e,r,d(e[r],t[r],o)):n(e,r,u(t[r])))})),e);function d(e,t,r){return r.concatArrays&&Array.isArray(e)&&Array.isArray(t)?((e,t,r)=>{let o=e.slice(0,0),s=0;return[e,t].forEach((t=>{const a=[];for(let r=0;r!a.includes(e))),r)})),o})(e,t,r):o(t)&&o(e)?p(e,t,l(t),r):u(t)}t.exports=function(...e){const t=d(u(c),this!==a&&this||{},c);let r={_:{}};for(const i of e)if(void 0!==i){if(!o(i))throw new TypeError("`"+i+"` is not an Option Object");r=d(r,{_:i},t)}return r._}},{"is-plain-obj":4}],6:[function(e,t,r){(function(e){(function(){"use strict";function r(e){if("string"!=typeof e)throw new TypeError("Path must be a string. Received "+JSON.stringify(e))}function o(e,t){for(var r,o="",i=0,s=-1,n=0,a=0;a<=e.length;++a){if(a2){var c=o.lastIndexOf("/");if(c!==o.length-1){-1===c?(o="",i=0):i=(o=o.slice(0,c)).length-1-o.lastIndexOf("/"),s=a,n=0;continue}}else if(2===o.length||1===o.length){o="",i=0,s=a,n=0;continue}t&&(o.length>0?o+="/..":o="..",i=2)}else o.length>0?o+="/"+e.slice(s+1,a):o=e.slice(s+1,a),i=a-s-1;s=a,n=0}else 46===r&&-1!==n?++n:n=-1}return o}var i={resolve:function(){for(var t,i="",s=!1,n=arguments.length-1;n>=-1&&!s;n--){var a;n>=0?a=arguments[n]:(void 0===t&&(t=e.cwd()),a=t),r(a),0!==a.length&&(i=a+"/"+i,s=47===a.charCodeAt(0))}return i=o(i,!s),s?i.length>0?"/"+i:"/":i.length>0?i:"."},normalize:function(e){if(r(e),0===e.length)return".";var t=47===e.charCodeAt(0),i=47===e.charCodeAt(e.length-1);return 0!==(e=o(e,!t)).length||t||(e="."),e.length>0&&i&&(e+="/"),t?"/"+e:e},isAbsolute:function(e){return r(e),e.length>0&&47===e.charCodeAt(0)},join:function(){if(0===arguments.length)return".";for(var e,t=0;t0&&(void 0===e?e=o:e+="/"+o)}return void 0===e?".":i.normalize(e)},relative:function(e,t){if(r(e),r(t),e===t)return"";if((e=i.resolve(e))===(t=i.resolve(t)))return"";for(var o=1;ol){if(47===t.charCodeAt(a+p))return t.slice(a+p+1);if(0===p)return t.slice(a+p)}else n>l&&(47===e.charCodeAt(o+p)?u=p:0===p&&(u=0));break}var d=e.charCodeAt(o+p);if(d!==t.charCodeAt(a+p))break;47===d&&(u=p)}var h="";for(p=o+u+1;p<=s;++p)p!==s&&47!==e.charCodeAt(p)||(0===h.length?h+="..":h+="/..");return h.length>0?h+t.slice(a+u):(a+=u,47===t.charCodeAt(a)&&++a,t.slice(a))},_makeLong:function(e){return e},dirname:function(e){if(r(e),0===e.length)return".";for(var t=e.charCodeAt(0),o=47===t,i=-1,s=!0,n=e.length-1;n>=1;--n)if(47===(t=e.charCodeAt(n))){if(!s){i=n;break}}else s=!1;return-1===i?o?"/":".":o&&1===i?"//":e.slice(0,i)},basename:function(e,t){if(void 0!==t&&"string"!=typeof t)throw new TypeError('"ext" argument must be a string');r(e);var o,i=0,s=-1,n=!0;if(void 0!==t&&t.length>0&&t.length<=e.length){if(t.length===e.length&&t===e)return"";var a=t.length-1,c=-1;for(o=e.length-1;o>=0;--o){var l=e.charCodeAt(o);if(47===l){if(!n){i=o+1;break}}else-1===c&&(n=!1,c=o+1),a>=0&&(l===t.charCodeAt(a)?-1==--a&&(s=o):(a=-1,s=c))}return i===s?s=c:-1===s&&(s=e.length),e.slice(i,s)}for(o=e.length-1;o>=0;--o)if(47===e.charCodeAt(o)){if(!n){i=o+1;break}}else-1===s&&(n=!1,s=o+1);return-1===s?"":e.slice(i,s)},extname:function(e){r(e);for(var t=-1,o=0,i=-1,s=!0,n=0,a=e.length-1;a>=0;--a){var c=e.charCodeAt(a);if(47!==c)-1===i&&(s=!1,i=a+1),46===c?-1===t?t=a:1!==n&&(n=1):-1!==t&&(n=-1);else if(!s){o=a+1;break}}return-1===t||-1===i||0===n||1===n&&t===i-1&&t===o+1?"":e.slice(t,i)},format:function(e){if(null===e||"object"!=typeof e)throw new TypeError('The "pathObject" argument must be of type Object. Received type '+typeof e);return function(e,t){var r=t.dir||t.root,o=t.base||(t.name||"")+(t.ext||"");return r?r===t.root?r+o:r+e+o:o}("/",e)},parse:function(e){r(e);var t={root:"",dir:"",base:"",ext:"",name:""};if(0===e.length)return t;var o,i=e.charCodeAt(0),s=47===i;s?(t.root="/",o=1):o=0;for(var n=-1,a=0,c=-1,l=!0,u=e.length-1,p=0;u>=o;--u)if(47!==(i=e.charCodeAt(u)))-1===c&&(l=!1,c=u+1),46===i?-1===n?n=u:1!==p&&(p=1):-1!==n&&(p=-1);else if(!l){a=u+1;break}return-1===n||-1===c||0===p||1===p&&n===c-1&&n===a+1?-1!==c&&(t.base=t.name=0===a&&s?e.slice(1,c):e.slice(a,c)):(0===a&&s?(t.name=e.slice(1,n),t.base=e.slice(1,c)):(t.name=e.slice(a,n),t.base=e.slice(a,c)),t.ext=e.slice(n,c)),a>0?t.dir=e.slice(0,a-1):s&&(t.dir="/"),t},sep:"/",delimiter:":",win32:null,posix:null};i.posix=i,t.exports=i}).call(this)}).call(this,e("_process"))},{_process:7}],7:[function(e,t,r){var o,i,s=t.exports={};function n(){throw new Error("setTimeout has not been defined")}function a(){throw new Error("clearTimeout has not been defined")}function c(e){if(o===setTimeout)return setTimeout(e,0);if((o===n||!o)&&setTimeout)return o=setTimeout,setTimeout(e,0);try{return o(e,0)}catch(t){try{return o.call(null,e,0)}catch(t){return o.call(this,e,0)}}}!function(){try{o="function"==typeof setTimeout?setTimeout:n}catch(e){o=n}try{i="function"==typeof clearTimeout?clearTimeout:a}catch(e){i=a}}();var l,u=[],p=!1,d=-1;function h(){p&&l&&(p=!1,l.length?u=l.concat(u):d=-1,u.length&&f())}function f(){if(!p){var e=c(h);p=!0;for(var t=u.length;t;){for(l=u,u=[];++d1)for(var r=1;r=0){if(o&&o.length){if(0!==i.length&&!/^\//.test(i))return}else if(/^\/\//.test(i))return;if(/^[a-z][a-z0-9\+\-\.]*$/.test(a.toLowerCase()))return c+=a+":",o&&o.length&&(c+="//"+o),c+=i,s&&s.length&&(c+="?"+s),n&&n.length&&(c+="#"+n),c}}}function o(e,o){if(r(e)){var i,s,n,a,c="",l="",u="",p="";if(c=(i=t(e))[1],l=i[2],s=i[3],n=i[4],a=i[5],c){if(o){if("https"!=c.toLowerCase())return}else if("http"!=c.toLowerCase())return;if(l)return/:(\d+)$/.test(l)&&(u=l.match(/:(\d+)$/)[0],l=l.replace(/:\d+$/,"")),p+=c+":",p+="//"+l,u&&(p+=u),p+=s,n&&n.length&&(p+="?"+n),a&&a.length&&(p+="#"+a),p}}}function i(e){return o(e,!0)}function s(e){return o(e)||i(e)}}(t)},{}],9:[function(e,t,r){t.exports={name:"doipjs",version:"0.6.0",description:"Decentralized OpenPGP Identity Proofs library in Node.js",main:"src/index.js",dependencies:{bent:"^7.3.12",browserify:"^17.0.0","merge-options":"^3.0.3",openpgp:"^4.10.8",prettier:"^2.1.2","valid-url":"^1.0.9"},devDependencies:{chai:"^4.2.0","chai-as-promised":"^7.1.1","chai-match-pattern":"^1.2.0","license-check-and-add":"^3.0.4",minify:"^6.0.1",mocha:"^8.2.0"},scripts:{"release:bundle":"./node_modules/browserify/bin/cmd.js ./src/index.js --standalone doip -o ./dist/doip.js","release:minify":"./node_modules/minify/bin/minify.js ./dist/doip.js > ./dist/doip.min.js","prettier:check":"./node_modules/prettier/bin-prettier.js --check .","prettier:write":"./node_modules/prettier/bin-prettier.js --write .","license:check":"./node_modules/license-check-and-add/dist/src/cli.js check","license:add":"./node_modules/license-check-and-add/dist/src/cli.js add","license:remove":"./node_modules/license-check-and-add/dist/src/cli.js remove",docs:"docsify serve ./docs",test:"./node_modules/mocha/bin/mocha"},repository:{type:"git",url:"https://codeberg.org/keyoxide/doipjs"},homepage:"https://js.doip.rocks",keywords:["pgp","gpg","openpgp","encryption","decentralized","identity"],author:"Yarmo Mackenbach (https://yarmo.eu)",license:"Apache-2.0"}},{}],10:[function(e,t,r){const o=e("path"),i=e("merge-options"),s=e("valid-url"),n=e(o.join(e.resolve("openpgp"),"..","openpgp.min.js")),a=e("./serviceproviders"),c=e("./keys"),l=e("./utils"),u=(e,t,r,o,i)=>{let s;if(e.isVerified||!t)return e;if(Array.isArray(t))return t.forEach(((t,s)=>{e=u(e,t,r,o,i)})),e;if(0==r.length){switch(i){default:case"contains":s=new RegExp(o,"gi"),e.isVerified=s.test(t.replace(/\r?\n|\r|\\/g,""));break;case"equals":e.isVerified=t.replace(/\r?\n|\r|\\/g,"").toLowerCase()==o.toLowerCase();break;case"oneOf":s=new RegExp(o,"gi"),e.isVerified=s.test(t.join("|"))}return e}try{r[0]}catch(t){return e.errors.push("err_data_structure_incorrect"),e}return e=u(e,t[r[0]],r.slice(1),o,i)},p=(e,t)=>{let r={isVerified:!1,errors:[]};switch(t.proof.format){case"json":r=u(r,e,t.claim.path,l.generateClaim(t.claim.fingerprint,t.claim.format),t.claim.relation);break;case"text":re=new RegExp(l.generateClaim(t.claim.fingerprint,t.claim.format),"gi"),r.isVerified=re.test(e.replace(/\r?\n|\r/,""))}return r},d=async(e,t,r)=>{if(e instanceof n.key.Key){const t=await c.getFingerprint(e),o=(await c.getUserData(e)).map((async(e,o)=>new Promise((async(o,i)=>{try{o(await d(e.notations,t,r))}catch(t){console.error(`Claim verification failed: ${e.userData.id}`,t),i(t)}}))));return Promise.all(o).then((e=>e))}if(e instanceof Array){const o=e.map((async(e,o)=>new Promise((async(o,i)=>{try{o(await d(e,t,r))}catch(t){console.error(`Claim verification failed: ${e}`,t),i(t)}}))));return Promise.all(o).then((e=>e))}const o=e;t||(t=null);if(r=i({returnMatchesOnly:!1,proxyPolicy:"adaptive",doipProxyHostname:"proxy.keyoxide.org"},r||{}),!s.isUri(o))throw new Error("Invalid URI");const l=a.match(o,r);if("returnMatchesOnly"in r&&r.returnMatchesOnly)return l;let u,h,f,m,g=!1,y=0;for(;!g&&ynew Promise((async(r,o)=>{t=t||"https://keys.openpgp.org/";const i=new n.HKP(t),s={query:e};let a=await i.lookup(s);a=(await n.key.readArmored(a)).keys[0],null==a&&o("Key does not exist or could not be fetched"),r(a)}))),c=e=>new Promise((async(t,r)=>{const o=new n.WKD,i={email:e},s=(await o.lookup(i)).keys[0];null==s&&r("Key does not exist or could not be fetched"),t(s)})),l=(e,t)=>new Promise((async(e,t)=>{try{await i(opts.keyLink).then((e=>{if(200===e.status)return e})).then((e=>e.text()))}catch(e){t(`Error fetching Keybase key: ${e.message}`)}const r=(await n.key.readArmored(rawKeyContent)).keys[0];null==r&&t("Key does not exist or could not be fetched"),e(r)})),u=e=>new Promise((async(t,r)=>{e||r("Invalid public key");const o=await e.primaryKey.getFingerprint(),i=await e.getPrimaryUser(),s=e.users;let a=[];s.forEach(((e,t)=>{a[t]={userData:{id:e.userId.userid,name:e.userId.name,email:e.userId.email,comment:e.userId.comment,isPrimary:i.index===t}};const r=e.selfCertifications[0].rawNotations;a[t].notations=r.map((({name:e,value:t,humanReadable:r})=>{if(r&&"proof@metacode.biz"===e)return n.util.decode_utf8(t)}))})),t({fingerprint:o,users:a,primaryUserIndex:i.index})}));r.fetch={uri:e=>new Promise((async(t,r)=>{s.isUri(e)||r("Invalid URI");const o=e.match(/([a-zA-Z0-9]*):([a-zA-Z0-9@._=+\-]*)(\:[a-zA-Z0-9@._=+\-]*)?/);switch(o[1]||r("Invalid URI"),o[1]){case"hkp":t(a(o[2],o.length>=4?o[3]:null));break;case"wkd":t(c(o[2]));break;case"kb":t(l(o[2],o.length>=4&&o[3]));break;default:r("Invalid URI protocol")}})),hkp:a,wkd:c,keybase:l,plaintext:e=>new Promise((async(t,r)=>{t((await n.key.readArmored(e)).keys[0])})),signature:(e,t)=>new Promise((async(r,o)=>{let i=await n.signature.readArmored(e);if("compressed"in i.packets[0]){i=i.packets[0];await n.stream.readToEnd(await i.packets[1].getText())}const s=i.packets[0].signersUserId,c=await i.packets[0].issuerKeyId.toHex();r(a(s||c,t))}))},r.process=u,r.getUserData=e=>new Promise((async(t,r)=>{t((await u(e)).users)})),r.getFingerprint=e=>new Promise((async(t,r)=>{t((await u(e)).fingerprint)}))},{bent:1,"merge-options":5,path:6,"valid-url":8}],13:[function(e,t,r){const o=e("bent")("GET"),i=e("./utils"),s=["dns","xmpp","twitter","reddit","liberapay","hackernews","lobsters","devto","gitea","gitlab","github","mastodon","fediverse","discourse"],n={dns:e("./serviceproviders/dns"),xmpp:e("./serviceproviders/xmpp"),twitter:e("./serviceproviders/twitter"),reddit:e("./serviceproviders/reddit"),liberapay:e("./serviceproviders/liberapay"),hackernews:e("./serviceproviders/hackernews"),lobsters:e("./serviceproviders/lobsters"),devto:e("./serviceproviders/devto"),gitea:e("./serviceproviders/gitea"),gitlab:e("./serviceproviders/gitlab"),github:e("./serviceproviders/github"),mastodon:e("./serviceproviders/mastodon"),fediverse:e("./serviceproviders/fediverse"),discourse:e("./serviceproviders/discourse")};r.list=s,r.data=n,r.match=(e,t)=>{let r,o=[];return s.forEach(((i,s)=>{r=n[i],r.reURI.test(e)&&o.push(r.processURI(e,t))})),o},r.directRequestHandler=(t,r)=>new Promise((async(r,i)=>{const s=t.proof.fetch?t.proof.fetch:t.proof.uri;let n;switch(t.proof.format){case"json":n=await o(s,null,{Accept:"application/json","User-Agent":`doipjs/${e("../package.json").version}`}),r(await n.json());break;case"text":n=await o(s),r(await n.text());break;default:i("No specified proof data format")}})),r.proxyRequestHandler=(e,t)=>new Promise((async(r,s)=>{const n=e.proof.fetch?e.proof.fetch:e.proof.uri,a=await o(i.generateProxyURL(e.proof.format,n,t),null,{Accept:"application/json"});r((await a.json()).content)}))},{"../package.json":9,"./serviceproviders/devto":14,"./serviceproviders/discourse":15,"./serviceproviders/dns":16,"./serviceproviders/fediverse":17,"./serviceproviders/gitea":18,"./serviceproviders/github":19,"./serviceproviders/gitlab":20,"./serviceproviders/hackernews":21,"./serviceproviders/liberapay":22,"./serviceproviders/lobsters":23,"./serviceproviders/mastodon":24,"./serviceproviders/reddit":25,"./serviceproviders/twitter":26,"./serviceproviders/xmpp":27,"./utils":28,bent:1}],14:[function(e,t,r){const o=/^https:\/\/dev\.to\/(.*)\/(.*)\/?/;r.reURI=o,r.processURI=(e,t)=>{t||(t={});const r=e.match(o);return{serviceprovider:{type:"web",name:"devto"},profile:{display:r[1],uri:`https://dev.to/${r[1]}`,qr:null},proof:{uri:e,fetch:`https://dev.to/api/articles/${r[1]}/${r[2]}`,useProxy:!1,format:"json"},claim:{fingerprint:null,format:"message",path:["body_markdown"],relation:"contains"},customRequestHandler:null}},r.tests=[{uri:"https://dev.to/alice/post",shouldMatch:!0},{uri:"https://dev.to/alice/post/",shouldMatch:!0},{uri:"https://domain.org/alice/post",shouldMatch:!1}]},{}],15:[function(e,t,r){const o=/^https:\/\/(.*)\/u\/(.*)\/?/;r.reURI=o,r.processURI=(e,t)=>{t||(t={});const r=e.match(o);return{serviceprovider:{type:"web",name:"discourse"},profile:{display:`${r[2]}@${r[1]}`,uri:e,qr:null},proof:{uri:e,fetch:`https://${r[1]}/u/${r[2]}.json`,useProxy:!0,format:"json"},claim:{fingerprint:null,format:"message",path:["user","bio_raw"],relation:"contains"},customRequestHandler:null}},r.tests=[{uri:"https://domain.org/u/alice",shouldMatch:!0},{uri:"https://domain.org/u/alice/",shouldMatch:!0},{uri:"https://domain.org/alice",shouldMatch:!1}]},{}],16:[function(e,t,r){const o=e("dns"),i=e("bent")("GET"),s=e("../utils"),n=/^dns:([a-zA-Z0-9\.\-\_]*)(?:\?(.*))?/,a=async(e,t)=>{if("resolveTxt"in o){const t=async()=>new Promise(((t,r)=>{o.resolveTxt(e.profile.display,((e,o)=>{e&&r(e),t(o)}))}));return{hostname:e.profile.display,records:{txt:await t()}}}{const t=await i(e.proof.uri,null,{Accept:"application/json"});return await t.json()}};r.reURI=n,r.processURI=(e,t)=>{t||(t={});const r=e.match(n);return{serviceprovider:{type:"web",name:"dns"},profile:{display:r[1],uri:`https://${r[1]}`,qr:null},proof:{uri:s.generateProxyURL("dns",r[1]),fetch:null,useProxy:!1,format:"json"},claim:{fingerprint:null,format:"uri",path:["records","txt"],relation:"contains"},customRequestHandler:a}},r.tests=[{uri:"dns:domain.org",shouldMatch:!0},{uri:"dns:domain.org?type=TXT",shouldMatch:!0},{uri:"https://domain.org",shouldMatch:!1}]},{"../utils":28,bent:1,dns:3}],17:[function(e,t,r){const o=/^https:\/\/(.*)\/users\/(.*)\/?/;r.reURI=o,r.processURI=(e,t)=>{t||(t={});const r=e.match(o);return{serviceprovider:{type:"web",name:"fediverse"},profile:{display:`@${r[2]}@${r[1]}`,uri:e,qr:null},proof:{uri:e,fetch:null,useProxy:!1,format:"json"},claim:{fingerprint:null,format:"fingerprint",path:["summary"],relation:"contains"},customRequestHandler:null}},r.tests=[{uri:"https://domain.org/users/alice",shouldMatch:!0},{uri:"https://domain.org/users/alice/",shouldMatch:!0},{uri:"https://domain.org/alice",shouldMatch:!1}]},{}],18:[function(e,t,r){const o=/^https:\/\/(.*)\/(.*)\/gitea_proof\/?/;r.reURI=o,r.processURI=(e,t)=>{t||(t={});const r=e.match(o);return{serviceprovider:{type:"web",name:"gitea"},profile:{display:`${r[2]}@${r[1]}`,uri:`https://${r[1]}/${r[2]}`,qr:null},proof:{uri:e,fetch:`https://${r[1]}/api/v1/repos/${r[2]}/gitea_proof`,useProxy:!0,format:"json"},claim:{fingerprint:null,format:"message",path:["description"],relation:"equals"},customRequestHandler:null}},r.tests=[{uri:"https://domain.org/alice/gitea_proof",shouldMatch:!0},{uri:"https://domain.org/alice/gitea_proof/",shouldMatch:!0},{uri:"https://domain.org/alice/other_proof",shouldMatch:!1}]},{}],19:[function(e,t,r){const o=/^https:\/\/gist\.github\.com\/(.*)\/(.*)\/?/;r.reURI=o,r.processURI=(e,t)=>{t||(t={});const r=e.match(o);return{serviceprovider:{type:"web",name:"github"},profile:{display:r[1],uri:`https://github.com/${r[1]}`,qr:null},proof:{uri:e,fetch:`https://api.github.com/gists/${r[2]}`,useProxy:!1,format:"json"},claim:{fingerprint:null,format:"message",path:["files","openpgp.md","content"],relation:"contains"},customRequestHandler:null}},r.tests=[{uri:"https://gist.github.com/Alice/123456789",shouldMatch:!0},{uri:"https://gist.github.com/Alice/123456789/",shouldMatch:!0},{uri:"https://domain.org/Alice/123456789",shouldMatch:!1}]},{}],20:[function(e,t,r){const o=e("bent")("GET"),i=/^https:\/\/(.*)\/(.*)\/gitlab_proof\/?/,s=async(e,t)=>{const r=e.proof.uri.match(i),s=`https://${r[1]}/api/v4/users?username=${r[2]}`,n=await o(s,"json",{Accept:"application/json"}),a=(await n.json()).find((e=>e.username===r[2]));if(!a)throw new Error(`No user with username ${r[2]}`);const c=`https://${r[1]}/api/v4/users/${a.id}/projects`,l=await o(c,{},{Accept:"application/json"}),u=(await l.json()).find((e=>"gitlab_proof"===e.path));if(!u)throw new Error(`No project at ${e.proof.uri}`);return u};r.reURI=i,r.processURI=(e,t)=>{t||(t={});const r=e.match(i);return{serviceprovider:{type:"web",name:"gitlab"},profile:{display:`${r[2]}@${r[1]}`,uri:`https://${r[1]}/${r[2]}`,qr:null},proof:{uri:e,fetch:null,useProxy:!1,format:"json"},claim:{fingerprint:null,format:"message",path:["description"],relation:"equals"},customRequestHandler:s}},r.tests=[{uri:"https://gitlab.domain.org/alice/gitlab_proof",shouldMatch:!0},{uri:"https://gitlab.domain.org/alice/gitlab_proof/",shouldMatch:!0},{uri:"https://domain.org/alice/other_proof",shouldMatch:!1}]},{bent:1}],21:[function(e,t,r){const o=/^https:\/\/news\.ycombinator\.com\/user\?id=(.*)\/?/;r.reURI=o,r.processURI=(e,t)=>{t||(t={});const r=e.match(o);return{serviceprovider:{type:"web",name:"hackernews"},profile:{display:r[1],uri:e,qr:null},proof:{uri:`https://hacker-news.firebaseio.com/v0/user/${r[1]}.json`,fetch:null,useProxy:!0,format:"json"},claim:{fingerprint:null,format:"uri",path:["about"],relation:"contains"},customRequestHandler:null}},r.tests=[{uri:"https://news.ycombinator.com/user?id=Alice",shouldMatch:!0},{uri:"https://news.ycombinator.com/user?id=Alice/",shouldMatch:!0},{uri:"https://domain.org/user?id=Alice",shouldMatch:!1}]},{}],22:[function(e,t,r){const o=/^https:\/\/liberapay\.com\/(.*)\/?/;r.reURI=o,r.processURI=(e,t)=>{t||(t={});const r=e.match(o);return{serviceprovider:{type:"web",name:"liberapay"},profile:{display:r[1],uri:e,qr:null},proof:{uri:e,fetch:`https://liberapay.com/${r[1]}/public.json`,useProxy:!1,format:"json"},claim:{fingerprint:null,format:"message",path:["statements","content"],relation:"contains"},customRequestHandler:null}},r.tests=[{uri:"https://liberapay.com/alice",shouldMatch:!0},{uri:"https://liberapay.com/alice/",shouldMatch:!0},{uri:"https://domain.org/alice",shouldMatch:!1}]},{}],23:[function(e,t,r){const o=/^https:\/\/lobste\.rs\/u\/(.*)\/?/;r.reURI=o,r.processURI=(e,t)=>{t||(t={});const r=e.match(o);return{serviceprovider:{type:"web",name:"lobsters"},profile:{display:r[1],uri:e,qr:null},proof:{uri:`https://lobste.rs/u/${r[1]}.json`,fetch:null,useProxy:!0,format:"json"},claim:{fingerprint:null,format:"message",path:["about"],relation:"contains"},customRequestHandler:null}},r.tests=[{uri:"https://lobste.rs/u/Alice",shouldMatch:!0},{uri:"https://lobste.rs/u/Alice/",shouldMatch:!0},{uri:"https://domain.org/u/Alice",shouldMatch:!1}]},{}],24:[function(e,t,r){const o=/^https:\/\/(.*)\/@(.*)\/?/;r.reURI=o,r.processURI=(e,t)=>{t||(t={});const r=e.match(o);return{serviceprovider:{type:"web",name:"mastodon"},profile:{display:`@${r[2]}@${r[1]}`,uri:e,qr:null},proof:{uri:e,fetch:null,useProxy:!1,format:"json"},claim:{fingerprint:null,format:"fingerprint",path:["attachment","value"],relation:"contains"},customRequestHandler:null}},r.tests=[{uri:"https://domain.org/@alice",shouldMatch:!0},{uri:"https://domain.org/@alice/",shouldMatch:!0},{uri:"https://domain.org/alice",shouldMatch:!1}]},{}],25:[function(e,t,r){const o=/^https:\/\/(?:www\.)?reddit\.com\/user\/(.*)\/comments\/(.*)\/(.*)\/?/;r.reURI=o,r.processURI=(e,t)=>{t||(t={});const r=e.match(o);return{serviceprovider:{type:"web",name:"reddit"},profile:{display:r[1],uri:`https://www.reddit.com/user/${r[1]}`,qr:null},proof:{uri:e,fetch:`https://www.reddit.com/user/${r[1]}/comments/${r[2]}.json`,useProxy:!0,format:"json"},claim:{fingerprint:null,format:"message",path:["data","children","data","selftext"],relation:"contains"},customRequestHandler:null}},r.tests=[{uri:"https://www.reddit.com/user/Alice/comments/123456/post",shouldMatch:!0},{uri:"https://www.reddit.com/user/Alice/comments/123456/post/",shouldMatch:!0},{uri:"https://reddit.com/user/Alice/comments/123456/post",shouldMatch:!0},{uri:"https://reddit.com/user/Alice/comments/123456/post/",shouldMatch:!0},{uri:"https://domain.org/user/Alice/comments/123456/post",shouldMatch:!1}]},{}],26:[function(e,t,r){const o=/^https:\/\/twitter\.com\/(.*)\/status\/([0-9]*)(?:\?.*)?/;r.reURI=o,r.processURI=(e,t)=>{t||(t={});const r=e.match(o);return{serviceprovider:{type:"web",name:"twitter"},profile:{display:`@${r[1]}`,uri:`https://twitter.com/${r[1]}`,qr:null},proof:{uri:e,fetch:`https://mobile.twitter.com/${r[1]}/status/${r[2]}`,useProxy:!1,format:"text"},claim:{fingerprint:null,format:"message",path:[],relation:"contains"},customRequestHandler:null}},r.tests=[{uri:"https://twitter.com/alice/status/1234567890123456789",shouldMatch:!0},{uri:"https://twitter.com/alice/status/1234567890123456789/",shouldMatch:!0},{uri:"https://domain.org/alice/status/1234567890123456789",shouldMatch:!1}]},{}],27:[function(e,t,r){const o=e("../utils"),i=/^xmpp:([a-zA-Z0-9\.\-\_]*)@([a-zA-Z0-9\.\-\_]*)(?:\?(.*))?/;r.reURI=i,r.processURI=(e,t)=>{t||(t={});const r=e.match(i);return{serviceprovider:{type:"communication",name:"xmpp"},profile:{display:`${r[1]}@${r[2]}`,uri:e,qr:e},proof:{uri:o.generateProxyURL("xmpp",`${r[1]}@${r[2]}`,t),fetch:null,useProxy:!1,format:"json"},claim:{fingerprint:null,format:"message",path:[],relation:"contains"},customRequestHandler:null}},r.tests=[{uri:"xmpp:alice@domain.org",shouldMatch:!0},{uri:"xmpp:alice@domain.org?omemo-sid-123456789=A1B2C3D4E5F6G7H8I9",shouldMatch:!0},{uri:"https://domain.org",shouldMatch:!1}]},{"../utils":28}],28:[function(e,t,r){r.generateProxyURL=(e,t,r)=>{if(!r||!r.doipProxyHostname)return null;let o="";return"xmpp"==e&&(o+="/DESC"),`https://${r.doipProxyHostname}/api/1/get/${e}/${encodeURIComponent(t)}${o}`},r.generateClaim=(e,t)=>{switch(t){case"uri":return`openpgp4fpr:${e}`;case"message":return`[Verifying my OpenPGP key: openpgp4fpr:${e}]`;case"fingerprint":return e;default:throw new Error("No valid claim format")}}},{}]},{},[11])(11)})); diff --git a/docs/_coverpage.md b/docs/_coverpage.md index 00a02bc..8096788 100644 --- a/docs/_coverpage.md +++ b/docs/_coverpage.md @@ -1,4 +1,4 @@ -# doip.js 0.6.0 +# doip.js 0.7.0 diff --git a/docs/changelog.md b/docs/changelog.md index 3e0da94..79a9c92 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,5 +1,12 @@ # Changelog +## [0.7.0] + +[2020-12-05](https://codeberg.org/keyoxide/doipjs/releases/tag/0.7.0) + +### Changed +- Properly reject promises + ## [0.6.0] [2020-11-20](https://codeberg.org/keyoxide/doipjs/releases/tag/0.6.0) diff --git a/docs/installation.md b/docs/installation.md index ebb9fbf..b4122e4 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -15,7 +15,7 @@ npm install --save doipjs Install on website by including the following HTML snippet: ```html - + ``` Next step: [quick start (Node.js)](quickstart-nodejs.md) and [quick start (browser)](quickstart-browser.md) diff --git a/package.json b/package.json index 0ac8718..77db83f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "doipjs", - "version": "0.6.0", + "version": "0.7.0", "description": "Decentralized OpenPGP Identity Proofs library in Node.js", "main": "src/index.js", "dependencies": {