doipjs/dist/doip.js

2148 lines
644 KiB
JavaScript
Raw Normal View History

2020-10-24 17:22:54 -06:00
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.doip = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
'use strict'
/* global fetch, btoa, Headers */
const core = require('./core')
2020-10-24 07:11:14 -06:00
2020-10-24 17:22:54 -06:00
class StatusError extends Error {
constructor (res, ...params) {
super(...params)
2020-10-24 07:11:14 -06:00
2020-10-24 17:22:54 -06:00
if (Error.captureStackTrace) {
Error.captureStackTrace(this, StatusError)
}
2020-10-24 07:11:14 -06:00
2020-10-24 17:22:54 -06:00
this.name = 'StatusError'
this.message = res.statusMessage
this.statusCode = res.status
this.res = res
this.json = res.json.bind(res)
this.text = res.text.bind(res)
this.arrayBuffer = res.arrayBuffer.bind(res)
let buffer
const get = () => {
if (!buffer) buffer = this.arrayBuffer()
return buffer
}
Object.defineProperty(this, 'responseBody', { get })
// match Node.js headers object
this.headers = {}
for (const [key, value] of res.headers.entries()) {
this.headers[key.toLowerCase()] = value
}
}
}
const mkrequest = (statusCodes, method, encoding, headers, baseurl) => async (_url, body, _headers = {}) => {
_url = baseurl + (_url || '')
let parsed = new URL(_url)
if (!headers) headers = {}
if (parsed.username) {
headers.Authorization = 'Basic ' + btoa(parsed.username + ':' + parsed.password)
parsed = new URL(parsed.protocol + '//' + parsed.host + parsed.pathname + parsed.search)
}
if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') {
throw new Error(`Unknown protocol, ${parsed.protocol}`)
}
if (body) {
if (body instanceof ArrayBuffer ||
ArrayBuffer.isView(body) ||
typeof body === 'string'
) {
// noop
} else if (typeof body === 'object') {
body = JSON.stringify(body)
headers['Content-Type'] = 'application/json'
} else {
throw new Error('Unknown body type.')
}
}
_headers = new Headers({ ...(headers || {}), ..._headers })
const resp = await fetch(parsed, { method, headers: _headers, body })
resp.statusCode = resp.status
if (!statusCodes.has(resp.status)) {
throw new StatusError(resp)
}
if (encoding === 'json') return resp.json()
else if (encoding === 'buffer') return resp.arrayBuffer()
else if (encoding === 'string') return resp.text()
else return resp
}
module.exports = core(mkrequest)
},{"./core":2}],2:[function(require,module,exports){
'use strict'
const encodings = new Set(['json', 'buffer', 'string'])
module.exports = mkrequest => (...args) => {
const statusCodes = new Set()
let method
let encoding
let headers
let baseurl = ''
args.forEach(arg => {
if (typeof arg === 'string') {
if (arg.toUpperCase() === arg) {
if (method) {
const msg = `Can't set method to ${arg}, already set to ${method}.`
throw new Error(msg)
} else {
method = arg
}
} else if (arg.startsWith('http:') || arg.startsWith('https:')) {
baseurl = arg
} else {
if (encodings.has(arg)) {
encoding = arg
} else {
throw new Error(`Unknown encoding, ${arg}`)
}
}
} else if (typeof arg === 'number') {
statusCodes.add(arg)
} else if (typeof arg === 'object') {
if (Array.isArray(arg) || arg instanceof Set) {
arg.forEach(code => statusCodes.add(code))
} else {
if (headers) {
throw new Error('Cannot set headers twice.')
}
headers = arg
}
} else {
throw new Error(`Unknown type: ${typeof arg}`)
}
})
if (!method) method = 'GET'
if (statusCodes.size === 0) {
statusCodes.add(200)
}
return mkrequest(statusCodes, method, encoding, headers, baseurl)
}
},{}],3:[function(require,module,exports){
2020-11-05 04:14:26 -07:00
},{}],4:[function(require,module,exports){
2020-11-06 10:39:06 -07:00
'use strict';
2020-11-05 04:14:26 -07:00
2020-11-06 10:39:06 -07:00
module.exports = value => {
if (Object.prototype.toString.call(value) !== '[object Object]') {
return false;
}
2020-11-05 04:14:26 -07:00
2020-11-06 10:39:06 -07:00
const prototype = Object.getPrototypeOf(value);
return prototype === null || prototype === Object.prototype;
};
2020-11-05 04:14:26 -07:00
2020-11-06 10:39:06 -07:00
},{}],5:[function(require,module,exports){
'use strict';
const isOptionObject = require('is-plain-obj');
const {hasOwnProperty} = Object.prototype;
const {propertyIsEnumerable} = Object;
const defineProperty = (object, name, value) => Object.defineProperty(object, name, {
value,
writable: true,
enumerable: true,
configurable: true
});
2020-11-05 04:14:26 -07:00
2020-11-06 10:39:06 -07:00
const globalThis = this;
const defaultMergeOptions = {
concatArrays: false,
ignoreUndefined: false
};
2020-11-05 04:14:26 -07:00
2020-11-06 10:39:06 -07:00
const getEnumerableOwnPropertyKeys = value => {
const keys = [];
2020-11-05 04:14:26 -07:00
2020-11-06 10:39:06 -07:00
for (const key in value) {
if (hasOwnProperty.call(value, key)) {
keys.push(key);
}
}
2020-11-05 04:14:26 -07:00
2020-11-06 10:39:06 -07:00
/* istanbul ignore else */
if (Object.getOwnPropertySymbols) {
const symbols = Object.getOwnPropertySymbols(value);
2020-11-05 04:14:26 -07:00
2020-11-06 10:39:06 -07:00
for (const symbol of symbols) {
if (propertyIsEnumerable.call(value, symbol)) {
keys.push(symbol);
}
}
}
2020-11-05 04:14:26 -07:00
2020-11-06 10:39:06 -07:00
return keys;
};
2020-11-05 04:14:26 -07:00
2020-11-06 10:39:06 -07:00
function clone(value) {
if (Array.isArray(value)) {
return cloneArray(value);
}
2020-11-05 04:14:26 -07:00
2020-11-06 10:39:06 -07:00
if (isOptionObject(value)) {
return cloneOptionObject(value);
}
2020-11-05 04:14:26 -07:00
2020-11-06 10:39:06 -07:00
return value;
2020-11-05 04:14:26 -07:00
}
2020-11-06 10:39:06 -07:00
function cloneArray(array) {
const result = array.slice(0, 0);
2020-11-05 04:14:26 -07:00
2020-11-06 10:39:06 -07:00
getEnumerableOwnPropertyKeys(array).forEach(key => {
defineProperty(result, key, clone(array[key]));
});
2020-11-05 04:14:26 -07:00
2020-11-06 10:39:06 -07:00
return result;
2020-11-05 04:14:26 -07:00
}
2020-11-06 10:39:06 -07:00
function cloneOptionObject(object) {
const result = Object.getPrototypeOf(object) === null ? Object.create(null) : {};
2020-11-05 04:14:26 -07:00
2020-11-06 10:39:06 -07:00
getEnumerableOwnPropertyKeys(object).forEach(key => {
defineProperty(result, key, clone(object[key]));
});
2020-11-05 04:14:26 -07:00
2020-11-06 10:39:06 -07:00
return result;
}
2020-11-05 04:14:26 -07:00
2020-11-06 10:39:06 -07:00
/**
* @param {*} merged already cloned
* @param {*} source something to merge
* @param {string[]} keys keys to merge
* @param {Object} config Config Object
* @returns {*} cloned Object
*/
const mergeKeys = (merged, source, keys, config) => {
keys.forEach(key => {
if (typeof source[key] === 'undefined' && config.ignoreUndefined) {
return;
}
// Do not recurse into prototype chain of merged
if (key in merged && merged[key] !== Object.getPrototypeOf(merged)) {
defineProperty(merged, key, merge(merged[key], source[key], config));
} else {
defineProperty(merged, key, clone(source[key]));
}
});
return merged;
2020-11-05 04:14:26 -07:00
};
2020-11-06 10:39:06 -07:00
/**
* @param {*} merged already cloned
* @param {*} source something to merge
* @param {Object} config Config Object
* @returns {*} cloned Object
*
* see [Array.prototype.concat ( ...arguments )](http://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.concat)
*/
const concatArrays = (merged, source, config) => {
let result = merged.slice(0, 0);
let resultIndex = 0;
[merged, source].forEach(array => {
const indices = [];
// `result.concat(array)` with cloning
for (let k = 0; k < array.length; k++) {
if (!hasOwnProperty.call(array, k)) {
continue;
}
indices.push(String(k));
if (array === merged) {
// Already cloned
defineProperty(result, resultIndex++, array[k]);
} else {
defineProperty(result, resultIndex++, clone(array[k]));
}
}
// Merge non-index keys
result = mergeKeys(result, array, getEnumerableOwnPropertyKeys(array).filter(key => !indices.includes(key)), config);
});
return result;
};
2020-11-05 04:14:26 -07:00
2020-11-06 10:39:06 -07:00
/**
* @param {*} merged already cloned
* @param {*} source something to merge
* @param {Object} config Config Object
* @returns {*} cloned Object
*/
function merge(merged, source, config) {
if (config.concatArrays && Array.isArray(merged) && Array.isArray(source)) {
return concatArrays(merged, source, config);
}
if (!isOptionObject(source) || !isOptionObject(merged)) {
return clone(source);
}
return mergeKeys(merged, source, getEnumerableOwnPropertyKeys(source), config);
2020-11-05 04:14:26 -07:00
}
2020-11-06 10:39:06 -07:00
module.exports = function (...options) {
const config = merge(clone(defaultMergeOptions), (this !== globalThis && this) || {}, defaultMergeOptions);
let merged = {_: {}};
2020-11-05 04:14:26 -07:00
2020-11-06 10:39:06 -07:00
for (const option of options) {
if (option === undefined) {
continue;
}
2020-11-05 04:14:26 -07:00
2020-11-06 10:39:06 -07:00
if (!isOptionObject(option)) {
throw new TypeError('`' + option + '` is not an Option Object');
}
2020-11-05 04:14:26 -07:00
2020-11-06 10:39:06 -07:00
merged = merge(merged, {_: option}, config);
}
2020-11-05 04:14:26 -07:00
2020-11-06 10:39:06 -07:00
return merged._;
2020-11-05 04:14:26 -07:00
};
2020-11-06 10:39:06 -07:00
},{"is-plain-obj":4}],6:[function(require,module,exports){
2020-11-18 13:51:53 -07:00
(function (global){(function (){
/*! OpenPGP.js v4.10.8 - 2020-08-28 - this is LGPL licensed code, see LICENSE/our website https://openpgpjs.org/ for more information. */
!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).openpgp=e()}}(function(){return function(){return function e(t,r,n){function i(s,o){if(!r[s]){if(!t[s]){var u="function"==typeof require&&require;if(!o&&u)return u(s,!0);if(a)return a(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var f=r[s]={exports:{}};t[s][0].call(f.exports,function(e){return i(t[s][1][e]||e)},f,f.exports,e,t,r,n)}return r[s].exports}for(var a="function"==typeof require&&require,s=0;s<n.length;s++)i(n[s]);return i}}()({1:[function(e,t,r){(function(e){"use strict";var n;n=void 0,function(t){const r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?Symbol:e=>`Symbol(${e})`,n="undefined"!=typeof self?self:"undefined"!=typeof window?window:void 0!==e?e:void 0,i=Number.isNaN||function(e){return e!=e};function a(e){return"object"==typeof e&&null!==e||"function"==typeof e}function s(e,t,r){Object.defineProperty(e,t,{value:r,writable:!0,enumerable:!0,configurable:!0})}function o(e){return e.slice()}function u(e,t,r,n,i){new Uint8Array(e).set(new Uint8Array(r,n,i),t)}function c(e){return!1!==function(e){return"number"==typeof e&&(!i(e)&&!(e<0))}(e)&&e!==1/0}function f(e,t,r){if("function"!=typeof e)throw new TypeError("Argument is not a function");return Function.prototype.apply.call(e,t,r)}function d(e,t,r,n){const i=e[t];if(void 0!==i){if("function"!=typeof i)throw new TypeError(`${i} is not a method`);switch(r){case 0:return()=>h(i,e,n);case 1:return t=>{const r=[t].concat(n);return h(i,e,r)}}}return()=>Promise.resolve()}function l(e,t,r){const n=e[t];if(void 0!==n)return f(n,e,r)}function h(e,t,r){try{return Promise.resolve(f(e,t,r))}catch(e){return Promise.reject(e)}}function p(e){return e}function y(e){if(e=Number(e),i(e)||e<0)throw new RangeError("highWaterMark property of a queuing strategy must be non-negative and non-NaN");return e}function b(e){if(void 0===e)return()=>1;if("function"!=typeof e)throw new TypeError("size property of a queuing strategy must be a function");return t=>e(t)}function m(e,t,r){return Promise.prototype.then.call(e,t,r)}function g(e,t,r){let n,i;const a=new Promise((e,t)=>{n=e,i=t});return void 0===r&&(r=(e=>{throw e})),function(e,t,r){let n=!1;const i=e=>{!1===n&&(n=!0,r(e))};let a=0,s=0;const o=e.length,u=new Array(o);for(const c of e){const e=a;m(c,r=>{u[e]=r,++s===o&&t(u)},i),++a}}(e,e=>{try{const r=t(e);n(r)}catch(e){i(e)}},e=>{try{const t=r(e);n(t)}catch(e){i(e)}}),a}function w(e){}function _(e){e&&e instanceof w.AssertionError&&setTimeout(()=>{throw e},0)}function v(e){const t=e._queue.shift();return e._queueTotalSize-=t.size,e._queueTotalSize<0&&(e._queueTotalSize=0),t.value}function k(e,t,r){if(!c(r=Number(r)))throw new RangeError("Size must be a finite, non-NaN, non-negative number.");e._queue.push({value:t,size:r}),e._queueTotalSize+=r}function A(e){e._queue=[],e._queueTotalSize=0}w.AssertionError=function(){};const S=r("[[AbortSteps]]"),E=r("[[ErrorSteps]]");class P{constructor(e={},t={}){M(this);const r=t.size;let n=t.highWaterMark;if(void 0!==e.type)throw new RangeError("Invalid type is specified");const i=b(r);void 0===n&&(n=1),function(e,t,r,n){const i=Object.create(H.prototype),a=d(t,"write",1,[i]),s=d(t,"close",0,[]),o=d(t,"abort",1,[]);W(e,i,function(){return l(t,"start",[i])},a,s,o,r,n)}(this,e,n=y(n),i)}get locked(){if(!1===C(this))throw X("locked");return K(this)}abort(e){return!1===C(this)?Promise.reject(X("abort")):!0===K(this)?Promise.reject(new TypeError("Cannot abort a stream that already has a writer")):U(this,e)}getWriter(){if(!1===C(this))throw X("getWriter");return x(this)}}function x(e){return new z(e)}function M(e){e._state="writable",e._storedError=void 0,e._writer=void 0,e._writableStreamController=void 0,e._writeRequests=[],e._inFlightWriteRequest=void 0,e._closeRequest=void 0,e._inFlightCloseRequest=void 0,e._pendingAbortRequest=void 0,e.
}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],7:[function(require,module,exports){
2020-10-24 06:38:10 -06:00
(function(module) {
'use strict';
module.exports.is_uri = is_iri;
module.exports.is_http_uri = is_http_iri;
module.exports.is_https_uri = is_https_iri;
module.exports.is_web_uri = is_web_iri;
// Create aliases
module.exports.isUri = is_iri;
module.exports.isHttpUri = is_http_iri;
module.exports.isHttpsUri = is_https_iri;
module.exports.isWebUri = is_web_iri;
// private function
// internal URI spitter method - direct from RFC 3986
var splitUri = function(uri) {
var splitted = uri.match(/(?:([^:\/?#]+):)?(?:\/\/([^\/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?/);
return splitted;
};
function is_iri(value) {
if (!value) {
return;
}
// check for illegal characters
if (/[^a-z0-9\:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,\;\=\.\-\_\~\%]/i.test(value)) return;
// check for hex escapes that aren't complete
if (/%[^0-9a-f]/i.test(value)) return;
if (/%[0-9a-f](:?[^0-9a-f]|$)/i.test(value)) return;
var splitted = [];
var scheme = '';
var authority = '';
var path = '';
var query = '';
var fragment = '';
var out = '';
// from RFC 3986
splitted = splitUri(value);
scheme = splitted[1];
authority = splitted[2];
path = splitted[3];
query = splitted[4];
fragment = splitted[5];
// scheme and path are required, though the path can be empty
if (!(scheme && scheme.length && path.length >= 0)) return;
// if authority is present, the path must be empty or begin with a /
if (authority && authority.length) {
if (!(path.length === 0 || /^\//.test(path))) return;
} else {
// if authority is not present, the path must not start with //
if (/^\/\//.test(path)) return;
}
// scheme must begin with a letter, then consist of letters, digits, +, ., or -
if (!/^[a-z][a-z0-9\+\-\.]*$/.test(scheme.toLowerCase())) return;
// re-assemble the URL per section 5.3 in RFC 3986
out += scheme + ':';
if (authority && authority.length) {
out += '//' + authority;
}
out += path;
if (query && query.length) {
out += '?' + query;
}
if (fragment && fragment.length) {
out += '#' + fragment;
}
return out;
}
function is_http_iri(value, allowHttps) {
if (!is_iri(value)) {
return;
}
var splitted = [];
var scheme = '';
var authority = '';
var path = '';
var port = '';
var query = '';
var fragment = '';
var out = '';
// from RFC 3986
splitted = splitUri(value);
scheme = splitted[1];
authority = splitted[2];
path = splitted[3];
query = splitted[4];
fragment = splitted[5];
if (!scheme) return;
if(allowHttps) {
if (scheme.toLowerCase() != 'https') return;
} else {
if (scheme.toLowerCase() != 'http') return;
}
// fully-qualified URIs must have an authority section that is
// a valid host
if (!authority) {
return;
}
// enable port component
if (/:(\d+)$/.test(authority)) {
port = authority.match(/:(\d+)$/)[0];
authority = authority.replace(/:\d+$/, '');
}
out += scheme + ':';
out += '//' + authority;
if (port) {
out += port;
}
out += path;
if(query && query.length){
out += '?' + query;
}
if(fragment && fragment.length){
out += '#' + fragment;
}
return out;
}
function is_https_iri(value) {
return is_http_iri(value, true);
}
function is_web_iri(value) {
return (is_http_iri(value) || is_https_iri(value));
}
})(module);
2020-11-18 13:51:53 -07:00
},{}],8:[function(require,module,exports){
module.exports={
"name": "doipjs",
"version": "0.5.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 <yarmo@yarmo.eu> (https://yarmo.eu)",
"license": "Apache-2.0"
}
},{}],9:[function(require,module,exports){
/*
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
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.
*/
const mergeOptions = require('merge-options')
const validUrl = require('valid-url')
const openpgp = require('../node_modules/openpgp/dist/openpgp.min.js')
const serviceproviders = require('./serviceproviders')
const keys = require('./keys')
2020-10-24 17:22:54 -06:00
const utils = require('./utils')
2020-10-24 06:38:10 -06:00
2020-11-18 13:51:53 -07:00
const runVerificationJson = (
res,
proofData,
checkPath,
checkClaim,
checkRelation
) => {
2020-11-03 14:53:04 -07:00
let re
2020-10-24 06:38:10 -06:00
2020-11-03 14:53:04 -07:00
if (res.isVerified || !proofData) {
return res
2020-10-24 17:22:54 -06:00
}
2020-10-24 06:38:10 -06:00
2020-11-05 04:14:26 -07:00
if (Array.isArray(proofData)) {
proofData.forEach((item, i) => {
2020-11-18 13:51:53 -07:00
res = runVerificationJson(res, item, checkPath, checkClaim, checkRelation)
2020-11-05 04:14:26 -07:00
})
return res
}
2020-10-24 17:22:54 -06:00
if (checkPath.length == 0) {
switch (checkRelation) {
default:
case 'contains':
2020-11-18 13:51:53 -07:00
re = new RegExp(
checkClaim.replace('[', '\\[').replace(']', '\\]'),
'gi'
)
2020-11-03 14:53:04 -07:00
res.isVerified = re.test(proofData.replace(/\r?\n|\r/, ''))
2020-10-24 17:22:54 -06:00
break
case 'equals':
2020-11-18 13:51:53 -07:00
res.isVerified =
proofData.replace(/\r?\n|\r/, '').toLowerCase() ==
checkClaim.toLowerCase()
2020-10-24 17:22:54 -06:00
break
case 'oneOf':
2020-11-18 13:51:53 -07:00
re = new RegExp(checkClaim, 'gi')
res.isVerified = re.test(proofData.join('|'))
2020-10-24 17:22:54 -06:00
break
}
2020-11-03 14:53:04 -07:00
return res
}
2020-11-06 10:39:06 -07:00
try {
checkPath[0] in proofData
2020-11-18 13:51:53 -07:00
} catch (e) {
2020-11-03 14:53:04 -07:00
res.errors.push('err_data_structure_incorrect')
return res
2020-10-24 17:22:54 -06:00
}
2020-10-24 06:38:10 -06:00
2020-11-18 13:51:53 -07:00
res = runVerificationJson(
res,
proofData[checkPath[0]],
checkPath.slice(1),
checkClaim,
checkRelation
)
2020-11-03 14:53:04 -07:00
return res
2020-10-24 17:22:54 -06:00
}
2020-10-24 06:38:10 -06:00
2020-11-18 13:51:53 -07:00
const runVerification = (proofData, spData) => {
2020-11-03 14:53:04 -07:00
let res = {
isVerified: false,
2020-11-18 13:51:53 -07:00
errors: [],
2020-11-03 14:53:04 -07:00
}
2020-10-24 17:22:54 -06:00
switch (spData.proof.format) {
case 'json':
2020-11-18 13:51:53 -07:00
res = runVerificationJson(
res,
proofData,
spData.claim.path,
utils.generateClaim(spData.claim.fingerprint, spData.claim.format),
spData.claim.relation
)
2020-10-24 17:22:54 -06:00
break
case 'text':
2020-11-18 13:51:53 -07:00
re = new RegExp(
utils.generateClaim(spData.claim.fingerprint, spData.claim.format),
'gi'
)
res.isVerified = re.test(proofData.replace(/\r?\n|\r/, ''))
2020-10-24 17:22:54 -06:00
break
}
2020-11-03 14:53:04 -07:00
return res
2020-10-24 17:22:54 -06:00
}
2020-10-24 06:38:10 -06:00
2020-11-18 13:51:53 -07:00
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)
}
if (input instanceof Array) {
const promises = input.map(async (uri, i) => {
return new Promise(async (resolve, reject) => {
try {
const res = await verify(uri, fingerprint, opts)
resolve(res)
} catch (e) {
console.error(`Claim verification failed: ${uri}`, e)
reject(e)
}
})
})
2020-10-24 17:22:54 -06:00
2020-11-18 13:51:53 -07:00
return Promise.all(promises).then((values) => {
return values
})
}
2020-10-24 06:38:10 -06:00
2020-11-18 13:51:53 -07:00
const uri = input
2020-10-24 17:22:54 -06:00
2020-11-18 13:51:53 -07:00
if (!fingerprint) {
fingerprint = null
}
2020-10-24 06:38:10 -06:00
2020-11-06 10:39:06 -07:00
const defaultOpts = {
returnMatchesOnly: false,
proxyPolicy: 'adaptive',
2020-11-18 13:51:53 -07:00
doipProxyHostname: 'proxy.keyoxide.org',
2020-11-06 10:39:06 -07:00
}
2020-11-18 13:51:53 -07:00
opts = mergeOptions(defaultOpts, opts ? opts : {})
2020-11-06 10:39:06 -07:00
2020-10-24 06:38:10 -06:00
if (!validUrl.isUri(uri)) {
throw new Error('Not a valid URI')
}
2020-10-24 17:22:54 -06:00
const spMatches = serviceproviders.match(uri, opts)
2020-10-24 06:38:10 -06:00
if ('returnMatchesOnly' in opts && opts.returnMatchesOnly) {
return spMatches
}
2020-11-18 13:51:53 -07:00
let claimVerificationDone = false,
claimVerificationResult,
sp,
iSp = 0,
res,
proofData,
spData
2020-11-03 14:53:04 -07:00
while (!claimVerificationDone && iSp < spMatches.length) {
2020-10-24 17:22:54 -06:00
spData = spMatches[iSp]
spData.claim.fingerprint = fingerprint
res = null
2020-10-26 16:02:22 -06:00
if (spData.customRequestHandler instanceof Function) {
proofData = await spData.customRequestHandler(spData, opts)
2020-11-18 13:51:53 -07:00
} else if (
!spData.proof.useProxy ||
('proxyPolicy' in opts && !opts.useProxyWhenNeeded)
) {
2020-11-06 10:39:06 -07:00
proofData = await serviceproviders.directRequestHandler(spData, opts)
2020-10-26 16:02:22 -06:00
} else {
2020-11-06 10:39:06 -07:00
proofData = await serviceproviders.proxyRequestHandler(spData, opts)
2020-10-24 17:22:54 -06:00
}
2020-11-05 04:14:26 -07:00
2020-11-03 14:53:04 -07:00
if (proofData) {
2020-11-18 13:51:53 -07:00
claimVerificationResult = runVerification(proofData, spData)
2020-10-24 06:38:10 -06:00
2020-11-03 14:53:04 -07:00
if (claimVerificationResult.errors.length == 0) {
claimVerificationDone = true
}
}
2020-10-24 06:38:10 -06:00
2020-10-24 17:22:54 -06:00
iSp++
}
2020-10-24 06:38:10 -06:00
2020-11-03 14:53:04 -07:00
if (!claimVerificationResult) {
claimVerificationResult = {
2020-11-18 13:51:53 -07:00
isVerified: false,
2020-11-03 14:53:04 -07:00
}
}
2020-10-24 06:38:10 -06:00
return {
2020-11-03 14:53:04 -07:00
isVerified: claimVerificationResult.isVerified,
2020-11-18 13:51:53 -07:00
serviceproviderData: spData,
2020-10-24 06:38:10 -06:00
}
}
2020-10-24 17:22:54 -06:00
exports.verify = verify
2020-11-18 13:51:53 -07:00
},{"../node_modules/openpgp/dist/openpgp.min.js":6,"./keys":11,"./serviceproviders":12,"./utils":27,"merge-options":5,"valid-url":7}],10:[function(require,module,exports){
/*
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
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.
*/
const claims = require('./claims')
const keys = require('./keys')
const serviceproviders = require('./serviceproviders')
const utils = require('./utils')
exports.claims = claims
exports.keys = keys
2020-10-24 17:22:54 -06:00
exports.serviceproviders = serviceproviders
exports.utils = utils
2020-10-24 06:38:10 -06:00
2020-11-18 13:51:53 -07:00
},{"./claims":9,"./keys":11,"./serviceproviders":12,"./utils":27}],11:[function(require,module,exports){
/*
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
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.
*/
const bent = require('bent')
const req = bent('GET')
const validUrl = require('valid-url')
const openpgp = require('../node_modules/openpgp/dist/openpgp.min.js')
const mergeOptions = require('merge-options')
const fetchHKP = async (identifier, keyserverBaseUrl) => {
try {
keyserverBaseUrl = keyserverBaseUrl
? keyserverBaseUrl
: 'https://keys.openpgp.org/'
const hkp = new openpgp.HKP(keyserverBaseUrl)
const lookupOpts = {
query: identifier,
}
let publicKey = await hkp.lookup(lookupOpts)
publicKey = (await openpgp.key.readArmored(publicKey)).keys[0]
return publicKey
} catch (e) {
console.error(e)
return undefined
}
}
const fetchWKD = async (identifier) => {
try {
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
}
}
const fetchKeybase = async (username, fingerprint) => {
try {
const keyLink = `https://keybase.io/${username}/pgp_keys.asc?fingerprint=${fingerprint}`
try {
const rawKeyContent = await req(opts.keyLink)
.then(function (response) {
if (response.status === 200) {
return response
}
})
.then((response) => response.text())
} catch (e) {
return undefined
}
const publicKey = (await openpgp.key.readArmored(rawKeyContent)).keys[0]
return publicKey
} catch (e) {
console.error(e)
return undefined
}
}
const fetchPlaintext = async (rawKeyContent) => {
try {
const publicKey = (await openpgp.key.readArmored(rawKeyContent)).keys[0]
return publicKey
} catch (e) {
console.error(e)
return undefined
}
}
const fetchSignature = async (rawSignatureContent, keyserverBaseUrl) => {
try {
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()
return fetchHKP(sigUserId ? sigUserId : sigKeyId, keyserverBaseUrl)
} catch (e) {
console.error(e)
return undefined
}
}
const fetchURI = async (uri) => {
try {
if (!validUrl.isUri(uri)) {
throw new Error('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')
}
switch (match[1]) {
case 'hkp':
return fetchHKP(match[2], match.length >= 4 ? match[3] : null)
break
case 'wkd':
return fetchWKD(match[2])
break
case 'kb':
return fetchKeybase(match[2], match.length >= 4 ? match[3] : null)
break
default:
throw new Error('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,
}
} catch (e) {
console.error(e)
return undefined
}
}
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)
}
})
return notations
} catch (e) {
console.error(e)
return undefined
}
}
const getFingerprint = async (publicKey) => {
try {
const keyData = await process(publicKey)
return keyData.fingerprint
} catch (e) {
console.error(e)
return undefined
}
}
exports.fetch = {
uri: fetchURI,
hkp: fetchHKP,
wkd: fetchWKD,
keybase: fetchKeybase,
plaintext: fetchPlaintext,
signature: fetchSignature,
}
exports.process = process
exports.getClaims = getClaims
exports.getFingerprint = getFingerprint
},{"../node_modules/openpgp/dist/openpgp.min.js":6,"bent":1,"merge-options":5,"valid-url":7}],12:[function(require,module,exports){
2020-10-24 06:38:10 -06:00
/*
2020-10-24 17:22:54 -06:00
Copyright 2020 Yarmo Mackenbach
2020-10-24 06:38:10 -06:00
2020-10-24 17:22:54 -06:00
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
2020-10-24 06:38:10 -06:00
2020-10-24 17:22:54 -06:00
http://www.apache.org/licenses/LICENSE-2.0
2020-10-24 06:38:10 -06:00
2020-10-24 17:22:54 -06:00
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
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.
*/
2020-10-26 16:02:22 -06:00
const bent = require('bent')
const req = bent('GET')
2020-11-05 04:14:26 -07:00
const utils = require('./utils')
2020-10-26 16:02:22 -06:00
2020-10-24 17:22:54 -06:00
const list = [
'dns',
'xmpp',
'twitter',
2020-10-26 05:24:30 -06:00
'reddit',
2020-11-05 04:14:26 -07:00
'liberapay',
2020-10-24 17:22:54 -06:00
'hackernews',
'lobsters',
2020-10-26 05:24:30 -06:00
'devto',
'gitea',
2020-10-26 16:02:22 -06:00
'gitlab',
2020-10-26 05:24:30 -06:00
'github',
2020-11-03 14:53:04 -07:00
'mastodon',
'fediverse',
'discourse',
2020-10-24 17:22:54 -06:00
]
2020-10-24 06:38:10 -06:00
2020-10-24 17:55:32 -06:00
const data = {
dns: require('./serviceproviders/dns'),
xmpp: require('./serviceproviders/xmpp'),
twitter: require('./serviceproviders/twitter'),
2020-10-26 05:24:30 -06:00
reddit: require('./serviceproviders/reddit'),
2020-11-05 04:14:26 -07:00
liberapay: require('./serviceproviders/liberapay'),
2020-10-24 17:55:32 -06:00
hackernews: require('./serviceproviders/hackernews'),
lobsters: require('./serviceproviders/lobsters'),
2020-10-26 05:24:30 -06:00
devto: require('./serviceproviders/devto'),
gitea: require('./serviceproviders/gitea'),
2020-10-26 16:02:22 -06:00
gitlab: require('./serviceproviders/gitlab'),
2020-10-26 05:24:30 -06:00
github: require('./serviceproviders/github'),
2020-11-03 14:53:04 -07:00
mastodon: require('./serviceproviders/mastodon'),
fediverse: require('./serviceproviders/fediverse'),
discourse: require('./serviceproviders/discourse'),
2020-10-24 17:55:32 -06:00
}
2020-10-24 06:38:10 -06:00
2020-10-24 17:22:54 -06:00
const match = (uri, opts) => {
2020-11-18 13:51:53 -07:00
let matches = [],
sp
2020-10-24 06:38:10 -06:00
2020-10-24 17:22:54 -06:00
list.forEach((spName, i) => {
sp = data[spName]
if (sp.reURI.test(uri)) {
matches.push(sp.processURI(uri, opts))
}
})
2020-10-24 06:38:10 -06:00
2020-10-24 17:22:54 -06:00
return matches
2020-10-24 06:38:10 -06:00
}
2020-11-06 10:39:06 -07:00
const directRequestHandler = async (spData, opts) => {
2020-11-18 13:51:53 -07:00
const url = spData.proof.fetch ? spData.proof.fetch : spData.proof.uri
let res
2020-11-03 14:53:04 -07:00
2020-10-26 16:02:22 -06:00
switch (spData.proof.format) {
case 'json':
2020-11-18 13:51:53 -07:00
res = await req(url, null, {
Accept: 'application/json',
'User-Agent': `doipjs/${require('../package.json').version}`,
})
2020-10-26 16:02:22 -06:00
return await res.json()
break
case 'text':
2020-11-18 13:51:53 -07:00
res = await req(url)
2020-10-26 16:02:22 -06:00
return await res.text()
break
default:
throw new Error('No specified proof data format')
break
}
}
2020-11-06 10:39:06 -07:00
const proxyRequestHandler = async (spData, opts) => {
2020-11-05 04:14:26 -07:00
const url = spData.proof.fetch ? spData.proof.fetch : spData.proof.uri
2020-11-18 13:51:53 -07:00
const res = await req(
utils.generateProxyURL(spData.proof.format, url, opts),
null,
{ Accept: 'application/json' }
)
2020-11-05 04:14:26 -07:00
const json = await res.json()
return json.content
2020-10-26 16:02:22 -06:00
}
2020-10-24 17:22:54 -06:00
exports.list = list
exports.data = data
exports.match = match
2020-10-26 16:02:22 -06:00
exports.directRequestHandler = directRequestHandler
exports.proxyRequestHandler = proxyRequestHandler
2020-10-24 17:22:54 -06:00
2020-11-18 13:51:53 -07:00
},{"../package.json":8,"./serviceproviders/devto":13,"./serviceproviders/discourse":14,"./serviceproviders/dns":15,"./serviceproviders/fediverse":16,"./serviceproviders/gitea":17,"./serviceproviders/github":18,"./serviceproviders/gitlab":19,"./serviceproviders/hackernews":20,"./serviceproviders/liberapay":21,"./serviceproviders/lobsters":22,"./serviceproviders/mastodon":23,"./serviceproviders/reddit":24,"./serviceproviders/twitter":25,"./serviceproviders/xmpp":26,"./utils":27,"bent":1}],13:[function(require,module,exports){
2020-10-26 05:24:30 -06:00
/*
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
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.
*/
const reURI = /^https:\/\/dev\.to\/(.*)\/(.*)\/?/
const processURI = (uri, opts) => {
2020-11-18 13:51:53 -07:00
if (!opts) {
opts = {}
}
2020-10-26 05:24:30 -06:00
const match = uri.match(reURI)
return {
serviceprovider: {
type: 'web',
2020-11-18 13:51:53 -07:00
name: 'devto',
2020-10-26 05:24:30 -06:00
},
profile: {
display: match[1],
2020-11-06 10:39:06 -07:00
uri: `https://dev.to/${match[1]}`,
2020-11-18 13:51:53 -07:00
qr: null,
2020-10-26 05:24:30 -06:00
},
proof: {
uri: uri,
fetch: `https://dev.to/api/articles/${match[1]}/${match[2]}`,
useProxy: false,
2020-11-18 13:51:53 -07:00
format: 'json',
2020-10-26 05:24:30 -06:00
},
claim: {
fingerprint: null,
format: 'message',
path: ['body_markdown'],
2020-11-18 13:51:53 -07:00
relation: 'contains',
2020-10-26 05:24:30 -06:00
},
2020-11-18 13:51:53 -07:00
customRequestHandler: null,
2020-10-26 05:24:30 -06:00
}
}
const tests = [
{
uri: 'https://dev.to/alice/post',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-10-26 05:24:30 -06:00
},
{
uri: 'https://dev.to/alice/post/',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-10-26 05:24:30 -06:00
},
{
uri: 'https://domain.org/alice/post',
2020-11-18 13:51:53 -07:00
shouldMatch: false,
},
2020-10-26 05:24:30 -06:00
]
exports.reURI = reURI
exports.processURI = processURI
exports.tests = tests
2020-11-18 13:51:53 -07:00
},{}],14:[function(require,module,exports){
2020-10-24 17:55:32 -06:00
/*
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
2020-11-03 14:53:04 -07:00
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
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.
*/
const reURI = /^https:\/\/(.*)\/u\/(.*)\/?/
const processURI = (uri, opts) => {
2020-11-18 13:51:53 -07:00
if (!opts) {
opts = {}
}
2020-11-03 14:53:04 -07:00
const match = uri.match(reURI)
return {
serviceprovider: {
type: 'web',
2020-11-18 13:51:53 -07:00
name: 'discourse',
2020-11-03 14:53:04 -07:00
},
profile: {
display: `${match[2]}@${match[1]}`,
2020-11-06 10:39:06 -07:00
uri: uri,
2020-11-18 13:51:53 -07:00
qr: null,
2020-11-03 14:53:04 -07:00
},
proof: {
uri: uri,
fetch: `https://${match[1]}/u/${match[2]}.json`,
useProxy: true,
2020-11-18 13:51:53 -07:00
format: 'json',
2020-11-03 14:53:04 -07:00
},
claim: {
fingerprint: null,
format: 'message',
path: ['user', 'bio_raw'],
2020-11-18 13:51:53 -07:00
relation: 'contains',
2020-11-03 14:53:04 -07:00
},
2020-11-18 13:51:53 -07:00
customRequestHandler: null,
2020-11-03 14:53:04 -07:00
}
}
const tests = [
{
uri: 'https://domain.org/u/alice',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-11-03 14:53:04 -07:00
},
{
uri: 'https://domain.org/u/alice/',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-11-03 14:53:04 -07:00
},
{
uri: 'https://domain.org/alice',
2020-11-18 13:51:53 -07:00
shouldMatch: false,
},
2020-11-03 14:53:04 -07:00
]
exports.reURI = reURI
exports.processURI = processURI
exports.tests = tests
2020-11-18 13:51:53 -07:00
},{}],15:[function(require,module,exports){
2020-11-03 14:53:04 -07:00
/*
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
2020-10-24 17:55:32 -06:00
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
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.
*/
2020-11-06 10:39:06 -07:00
const dns = require('dns')
const bent = require('bent')
const req = bent('GET')
2020-11-05 04:14:26 -07:00
const utils = require('../utils')
2020-10-24 17:55:32 -06:00
const reURI = /^dns:([a-zA-Z0-9\.\-\_]*)(?:\?(.*))?/
2020-11-06 10:39:06 -07:00
const customRequestHandler = async (spData, opts) => {
2020-11-18 13:51:53 -07:00
if ('resolveTxt' in dns) {
2020-11-06 10:39:06 -07:00
const prom = async () => {
return new Promise((resolve, reject) => {
dns.resolveTxt(spData.profile.display, (err, records) => {
if (err) reject(err)
resolve(records)
})
})
}
return {
hostname: spData.profile.display,
records: {
2020-11-18 13:51:53 -07:00
txt: await prom(),
},
2020-11-06 10:39:06 -07:00
}
} else {
2020-11-18 13:51:53 -07:00
const res = await req(spData.proof.uri, null, {
Accept: 'application/json',
})
2020-11-06 10:39:06 -07:00
const json = await res.json()
return json
}
}
2020-10-24 17:55:32 -06:00
const processURI = (uri, opts) => {
2020-11-18 13:51:53 -07:00
if (!opts) {
opts = {}
}
2020-10-24 17:55:32 -06:00
const match = uri.match(reURI)
return {
serviceprovider: {
type: 'web',
2020-11-18 13:51:53 -07:00
name: 'dns',
2020-10-24 17:55:32 -06:00
},
profile: {
display: match[1],
2020-11-06 10:39:06 -07:00
uri: `https://${match[1]}`,
2020-11-18 13:51:53 -07:00
qr: null,
2020-10-24 17:55:32 -06:00
},
proof: {
2020-11-05 04:14:26 -07:00
uri: utils.generateProxyURL('dns', match[1]),
2020-10-24 17:55:32 -06:00
fetch: null,
useProxy: false,
2020-11-18 13:51:53 -07:00
format: 'json',
2020-10-24 17:55:32 -06:00
},
claim: {
fingerprint: null,
format: 'uri',
2020-11-05 04:14:26 -07:00
path: ['records', 'txt'],
2020-11-18 13:51:53 -07:00
relation: 'contains',
2020-10-24 17:55:32 -06:00
},
2020-11-18 13:51:53 -07:00
customRequestHandler: customRequestHandler,
2020-10-24 17:55:32 -06:00
}
}
const tests = [
{
uri: 'dns:domain.org',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-10-24 17:55:32 -06:00
},
{
uri: 'dns:domain.org?type=TXT',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-10-24 17:55:32 -06:00
},
{
uri: 'https://domain.org',
2020-11-18 13:51:53 -07:00
shouldMatch: false,
},
2020-10-24 17:55:32 -06:00
]
exports.reURI = reURI
exports.processURI = processURI
exports.tests = tests
2020-11-18 13:51:53 -07:00
},{"../utils":27,"bent":1,"dns":3}],16:[function(require,module,exports){
2020-11-03 14:53:04 -07:00
/*
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
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.
*/
const reURI = /^https:\/\/(.*)\/users\/(.*)\/?/
const processURI = (uri, opts) => {
2020-11-18 13:51:53 -07:00
if (!opts) {
opts = {}
}
2020-11-03 14:53:04 -07:00
const match = uri.match(reURI)
return {
serviceprovider: {
type: 'web',
2020-11-18 13:51:53 -07:00
name: 'fediverse',
2020-11-03 14:53:04 -07:00
},
profile: {
display: `@${match[2]}@${match[1]}`,
2020-11-06 10:39:06 -07:00
uri: uri,
2020-11-18 13:51:53 -07:00
qr: null,
2020-11-03 14:53:04 -07:00
},
proof: {
uri: uri,
fetch: null,
useProxy: false,
2020-11-18 13:51:53 -07:00
format: 'json',
2020-11-03 14:53:04 -07:00
},
claim: {
fingerprint: null,
format: 'fingerprint',
path: ['summary'],
2020-11-18 13:51:53 -07:00
relation: 'contains',
2020-11-03 14:53:04 -07:00
},
2020-11-18 13:51:53 -07:00
customRequestHandler: null,
2020-11-03 14:53:04 -07:00
}
}
const tests = [
{
uri: 'https://domain.org/users/alice',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-11-03 14:53:04 -07:00
},
{
uri: 'https://domain.org/users/alice/',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-11-03 14:53:04 -07:00
},
{
uri: 'https://domain.org/alice',
2020-11-18 13:51:53 -07:00
shouldMatch: false,
},
2020-11-03 14:53:04 -07:00
]
exports.reURI = reURI
exports.processURI = processURI
exports.tests = tests
2020-11-18 13:51:53 -07:00
},{}],17:[function(require,module,exports){
2020-10-26 05:24:30 -06:00
/*
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
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.
*/
const reURI = /^https:\/\/(.*)\/(.*)\/gitea_proof\/?/
const processURI = (uri, opts) => {
2020-11-18 13:51:53 -07:00
if (!opts) {
opts = {}
}
2020-10-26 05:24:30 -06:00
const match = uri.match(reURI)
return {
serviceprovider: {
type: 'web',
2020-11-18 13:51:53 -07:00
name: 'gitea',
2020-10-26 05:24:30 -06:00
},
profile: {
display: `${match[2]}@${match[1]}`,
2020-11-06 10:39:06 -07:00
uri: `https://${match[1]}/${match[2]}`,
2020-11-18 13:51:53 -07:00
qr: null,
2020-10-26 05:24:30 -06:00
},
proof: {
uri: uri,
fetch: `https://${match[1]}/api/v1/repos/${match[2]}/gitea_proof`,
useProxy: true,
2020-11-18 13:51:53 -07:00
format: 'json',
2020-10-26 05:24:30 -06:00
},
claim: {
fingerprint: null,
format: 'message',
path: ['description'],
2020-11-18 13:51:53 -07:00
relation: 'equals',
2020-10-26 05:24:30 -06:00
},
2020-11-18 13:51:53 -07:00
customRequestHandler: null,
2020-10-26 05:24:30 -06:00
}
}
const tests = [
{
uri: 'https://domain.org/alice/gitea_proof',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-10-26 05:24:30 -06:00
},
{
uri: 'https://domain.org/alice/gitea_proof/',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-10-26 05:24:30 -06:00
},
{
uri: 'https://domain.org/alice/other_proof',
2020-11-18 13:51:53 -07:00
shouldMatch: false,
},
2020-10-26 05:24:30 -06:00
]
exports.reURI = reURI
exports.processURI = processURI
exports.tests = tests
2020-11-18 13:51:53 -07:00
},{}],18:[function(require,module,exports){
2020-10-26 05:24:30 -06:00
/*
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
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.
*/
2020-11-05 04:14:26 -07:00
const reURI = /^https:\/\/gist\.github\.com\/(.*)\/(.*)\/?/
2020-10-26 05:24:30 -06:00
const processURI = (uri, opts) => {
2020-11-18 13:51:53 -07:00
if (!opts) {
opts = {}
}
2020-10-26 05:24:30 -06:00
const match = uri.match(reURI)
return {
serviceprovider: {
type: 'web',
2020-11-18 13:51:53 -07:00
name: 'github',
2020-10-26 05:24:30 -06:00
},
profile: {
display: match[1],
2020-11-06 10:39:06 -07:00
uri: `https://github.com/${match[1]}`,
2020-11-18 13:51:53 -07:00
qr: null,
2020-10-26 05:24:30 -06:00
},
proof: {
uri: uri,
fetch: `https://api.github.com/gists/${match[2]}`,
useProxy: false,
2020-11-18 13:51:53 -07:00
format: 'json',
2020-10-26 05:24:30 -06:00
},
claim: {
fingerprint: null,
format: 'message',
path: ['files', 'openpgp.md', 'content'],
2020-11-18 13:51:53 -07:00
relation: 'contains',
2020-10-26 05:24:30 -06:00
},
2020-11-18 13:51:53 -07:00
customRequestHandler: null,
2020-10-26 05:24:30 -06:00
}
}
const tests = [
{
uri: 'https://gist.github.com/Alice/123456789',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-10-26 05:24:30 -06:00
},
{
uri: 'https://gist.github.com/Alice/123456789/',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-10-26 05:24:30 -06:00
},
{
uri: 'https://domain.org/Alice/123456789',
2020-11-18 13:51:53 -07:00
shouldMatch: false,
},
2020-10-26 05:24:30 -06:00
]
exports.reURI = reURI
exports.processURI = processURI
exports.tests = tests
2020-11-18 13:51:53 -07:00
},{}],19:[function(require,module,exports){
2020-10-24 17:55:32 -06:00
/*
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
2020-10-26 16:02:22 -06:00
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
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.
*/
const bent = require('bent')
const req = bent('GET')
const reURI = /^https:\/\/(.*)\/(.*)\/gitlab_proof\/?/
const customRequestHandler = async (spData, opts) => {
const match = spData.proof.uri.match(reURI)
const urlUser = `https://${match[1]}/api/v4/users?username=${match[2]}`
2020-11-03 14:53:04 -07:00
const resUser = await req(urlUser, 'json', { Accept: 'application/json' })
2020-10-26 16:02:22 -06:00
const jsonUser = await resUser.json()
2020-11-18 13:51:53 -07:00
const user = jsonUser.find((user) => user.username === match[2])
2020-10-26 16:02:22 -06:00
if (!user) {
2020-11-18 13:51:53 -07:00
throw new Error(`No user with username ${match[2]}`)
2020-10-26 16:02:22 -06:00
}
const urlProject = `https://${match[1]}/api/v4/users/${user.id}/projects`
const resProject = await req(urlProject, {}, { Accept: 'application/json' })
const jsonProject = await resProject.json()
2020-11-18 13:51:53 -07:00
const project = jsonProject.find((proj) => proj.path === 'gitlab_proof')
2020-10-26 16:02:22 -06:00
if (!project) {
2020-11-18 13:51:53 -07:00
throw new Error(`No project at ${spData.proof.uri}`)
2020-10-26 16:02:22 -06:00
}
return project
}
const processURI = (uri, opts) => {
2020-11-18 13:51:53 -07:00
if (!opts) {
opts = {}
}
2020-10-26 16:02:22 -06:00
const match = uri.match(reURI)
return {
serviceprovider: {
type: 'web',
2020-11-18 13:51:53 -07:00
name: 'gitlab',
2020-10-26 16:02:22 -06:00
},
profile: {
display: `${match[2]}@${match[1]}`,
2020-11-06 10:39:06 -07:00
uri: `https://${match[1]}/${match[2]}`,
2020-11-18 13:51:53 -07:00
qr: null,
2020-10-26 16:02:22 -06:00
},
proof: {
uri: uri,
fetch: null,
useProxy: false,
2020-11-18 13:51:53 -07:00
format: 'json',
2020-10-26 16:02:22 -06:00
},
claim: {
fingerprint: null,
format: 'message',
path: ['description'],
2020-11-18 13:51:53 -07:00
relation: 'equals',
2020-10-26 16:02:22 -06:00
},
2020-11-18 13:51:53 -07:00
customRequestHandler: customRequestHandler,
2020-10-26 16:02:22 -06:00
}
}
const tests = [
{
uri: 'https://gitlab.domain.org/alice/gitlab_proof',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-10-26 16:02:22 -06:00
},
{
uri: 'https://gitlab.domain.org/alice/gitlab_proof/',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-10-26 16:02:22 -06:00
},
{
uri: 'https://domain.org/alice/other_proof',
2020-11-18 13:51:53 -07:00
shouldMatch: false,
},
2020-10-26 16:02:22 -06:00
]
exports.reURI = reURI
exports.processURI = processURI
exports.tests = tests
2020-11-18 13:51:53 -07:00
},{"bent":1}],20:[function(require,module,exports){
2020-10-26 16:02:22 -06:00
/*
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
2020-10-24 17:55:32 -06:00
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
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.
*/
2020-11-05 04:14:26 -07:00
const reURI = /^https:\/\/news\.ycombinator\.com\/user\?id=(.*)\/?/
2020-10-24 17:55:32 -06:00
const processURI = (uri, opts) => {
2020-11-18 13:51:53 -07:00
if (!opts) {
opts = {}
}
2020-10-24 17:55:32 -06:00
const match = uri.match(reURI)
return {
serviceprovider: {
type: 'web',
2020-11-18 13:51:53 -07:00
name: 'hackernews',
2020-10-24 17:55:32 -06:00
},
profile: {
display: match[1],
2020-11-06 10:39:06 -07:00
uri: uri,
2020-11-18 13:51:53 -07:00
qr: null,
2020-10-24 17:55:32 -06:00
},
proof: {
uri: `https://hacker-news.firebaseio.com/v0/user/${match[1]}.json`,
fetch: null,
useProxy: true,
2020-11-18 13:51:53 -07:00
format: 'json',
2020-10-24 17:55:32 -06:00
},
claim: {
fingerprint: null,
format: 'uri',
path: ['about'],
2020-11-18 13:51:53 -07:00
relation: 'contains',
2020-10-24 17:55:32 -06:00
},
2020-11-18 13:51:53 -07:00
customRequestHandler: null,
2020-10-24 17:55:32 -06:00
}
}
const tests = [
{
uri: 'https://news.ycombinator.com/user?id=Alice',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-10-24 17:55:32 -06:00
},
{
uri: 'https://news.ycombinator.com/user?id=Alice/',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-10-24 17:55:32 -06:00
},
{
uri: 'https://domain.org/user?id=Alice',
2020-11-18 13:51:53 -07:00
shouldMatch: false,
},
2020-10-24 17:55:32 -06:00
]
exports.reURI = reURI
exports.processURI = processURI
exports.tests = tests
2020-11-18 13:51:53 -07:00
},{}],21:[function(require,module,exports){
2020-11-05 04:14:26 -07:00
/*
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
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.
*/
const reURI = /^https:\/\/liberapay\.com\/(.*)\/?/
const processURI = (uri, opts) => {
2020-11-18 13:51:53 -07:00
if (!opts) {
opts = {}
}
2020-11-05 04:14:26 -07:00
const match = uri.match(reURI)
return {
serviceprovider: {
type: 'web',
2020-11-18 13:51:53 -07:00
name: 'liberapay',
2020-11-05 04:14:26 -07:00
},
profile: {
display: match[1],
2020-11-06 10:39:06 -07:00
uri: uri,
2020-11-18 13:51:53 -07:00
qr: null,
2020-11-05 04:14:26 -07:00
},
proof: {
uri: uri,
fetch: `https://liberapay.com/${match[1]}/public.json`,
useProxy: false,
2020-11-18 13:51:53 -07:00
format: 'json',
2020-11-05 04:14:26 -07:00
},
claim: {
fingerprint: null,
format: 'message',
path: ['statements', 'content'],
2020-11-18 13:51:53 -07:00
relation: 'contains',
2020-11-05 04:14:26 -07:00
},
2020-11-18 13:51:53 -07:00
customRequestHandler: null,
2020-11-05 04:14:26 -07:00
}
}
const tests = [
{
uri: 'https://liberapay.com/alice',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-11-05 04:14:26 -07:00
},
{
uri: 'https://liberapay.com/alice/',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-11-05 04:14:26 -07:00
},
{
uri: 'https://domain.org/alice',
2020-11-18 13:51:53 -07:00
shouldMatch: false,
},
2020-11-05 04:14:26 -07:00
]
exports.reURI = reURI
exports.processURI = processURI
exports.tests = tests
2020-11-18 13:51:53 -07:00
},{}],22:[function(require,module,exports){
2020-10-24 17:55:32 -06:00
/*
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
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.
*/
2020-11-05 04:14:26 -07:00
const reURI = /^https:\/\/lobste\.rs\/u\/(.*)\/?/
2020-10-24 17:55:32 -06:00
const processURI = (uri, opts) => {
2020-11-18 13:51:53 -07:00
if (!opts) {
opts = {}
}
2020-10-24 17:55:32 -06:00
const match = uri.match(reURI)
return {
serviceprovider: {
type: 'web',
2020-11-18 13:51:53 -07:00
name: 'lobsters',
2020-10-24 17:55:32 -06:00
},
profile: {
display: match[1],
2020-11-06 10:39:06 -07:00
uri: uri,
2020-11-18 13:51:53 -07:00
qr: null,
2020-10-24 17:55:32 -06:00
},
proof: {
uri: `https://lobste.rs/u/${match[1]}.json`,
fetch: null,
useProxy: true,
2020-11-18 13:51:53 -07:00
format: 'json',
2020-10-24 17:55:32 -06:00
},
claim: {
fingerprint: null,
format: 'message',
path: ['about'],
2020-11-18 13:51:53 -07:00
relation: 'contains',
2020-10-24 17:55:32 -06:00
},
2020-11-18 13:51:53 -07:00
customRequestHandler: null,
2020-10-24 17:55:32 -06:00
}
}
const tests = [
{
uri: 'https://lobste.rs/u/Alice',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-10-24 17:55:32 -06:00
},
{
uri: 'https://lobste.rs/u/Alice/',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-10-24 17:55:32 -06:00
},
{
uri: 'https://domain.org/u/Alice',
2020-11-18 13:51:53 -07:00
shouldMatch: false,
},
2020-10-24 17:55:32 -06:00
]
exports.reURI = reURI
exports.processURI = processURI
exports.tests = tests
2020-11-18 13:51:53 -07:00
},{}],23:[function(require,module,exports){
2020-11-03 14:53:04 -07:00
/*
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
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.
*/
const reURI = /^https:\/\/(.*)\/@(.*)\/?/
const processURI = (uri, opts) => {
2020-11-18 13:51:53 -07:00
if (!opts) {
opts = {}
}
2020-11-03 14:53:04 -07:00
const match = uri.match(reURI)
return {
serviceprovider: {
type: 'web',
2020-11-18 13:51:53 -07:00
name: 'mastodon',
2020-11-03 14:53:04 -07:00
},
profile: {
display: `@${match[2]}@${match[1]}`,
2020-11-06 10:39:06 -07:00
uri: uri,
2020-11-18 13:51:53 -07:00
qr: null,
2020-11-03 14:53:04 -07:00
},
proof: {
uri: uri,
fetch: null,
useProxy: false,
2020-11-18 13:51:53 -07:00
format: 'json',
2020-11-03 14:53:04 -07:00
},
claim: {
fingerprint: null,
format: 'fingerprint',
path: ['attachment', 'value'],
2020-11-18 13:51:53 -07:00
relation: 'contains',
2020-11-03 14:53:04 -07:00
},
2020-11-18 13:51:53 -07:00
customRequestHandler: null,
2020-11-03 14:53:04 -07:00
}
}
const tests = [
{
uri: 'https://domain.org/@alice',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-11-03 14:53:04 -07:00
},
{
uri: 'https://domain.org/@alice/',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-11-03 14:53:04 -07:00
},
{
uri: 'https://domain.org/alice',
2020-11-18 13:51:53 -07:00
shouldMatch: false,
},
2020-11-03 14:53:04 -07:00
]
exports.reURI = reURI
exports.processURI = processURI
exports.tests = tests
2020-11-18 13:51:53 -07:00
},{}],24:[function(require,module,exports){
2020-10-26 05:24:30 -06:00
/*
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
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.
*/
const reURI = /^https:\/\/(?:www\.)?reddit\.com\/user\/(.*)\/comments\/(.*)\/(.*)\/?/
const processURI = (uri, opts) => {
2020-11-18 13:51:53 -07:00
if (!opts) {
opts = {}
}
2020-10-26 05:24:30 -06:00
const match = uri.match(reURI)
return {
serviceprovider: {
type: 'web',
2020-11-18 13:51:53 -07:00
name: 'reddit',
2020-10-26 05:24:30 -06:00
},
profile: {
display: match[1],
2020-11-06 10:39:06 -07:00
uri: `https://www.reddit.com/user/${match[1]}`,
2020-11-18 13:51:53 -07:00
qr: null,
2020-10-26 05:24:30 -06:00
},
proof: {
uri: uri,
fetch: `https://www.reddit.com/user/${match[1]}/comments/${match[2]}.json`,
useProxy: true,
2020-11-18 13:51:53 -07:00
format: 'json',
2020-10-26 05:24:30 -06:00
},
claim: {
fingerprint: null,
format: 'message',
path: ['data', 'children', 'data', 'selftext'],
2020-11-18 13:51:53 -07:00
relation: 'contains',
2020-10-26 05:24:30 -06:00
},
2020-11-18 13:51:53 -07:00
customRequestHandler: null,
2020-10-26 05:24:30 -06:00
}
}
const tests = [
{
uri: 'https://www.reddit.com/user/Alice/comments/123456/post',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-10-26 05:24:30 -06:00
},
{
uri: 'https://www.reddit.com/user/Alice/comments/123456/post/',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-10-26 05:24:30 -06:00
},
{
uri: 'https://reddit.com/user/Alice/comments/123456/post',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-10-26 05:24:30 -06:00
},
{
uri: 'https://reddit.com/user/Alice/comments/123456/post/',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-10-26 05:24:30 -06:00
},
{
uri: 'https://domain.org/user/Alice/comments/123456/post',
2020-11-18 13:51:53 -07:00
shouldMatch: false,
},
2020-10-26 05:24:30 -06:00
]
exports.reURI = reURI
exports.processURI = processURI
exports.tests = tests
2020-11-18 13:51:53 -07:00
},{}],25:[function(require,module,exports){
2020-10-24 17:55:32 -06:00
/*
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
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.
*/
const reURI = /^https:\/\/twitter\.com\/(.*)\/status\/([0-9]*)(?:\?.*)?/
const processURI = (uri, opts) => {
2020-11-18 13:51:53 -07:00
if (!opts) {
opts = {}
}
2020-10-24 17:55:32 -06:00
const match = uri.match(reURI)
return {
serviceprovider: {
type: 'web',
2020-11-18 13:51:53 -07:00
name: 'twitter',
2020-10-24 17:55:32 -06:00
},
profile: {
display: `@${match[1]}`,
2020-11-06 10:39:06 -07:00
uri: `https://twitter.com/${match[1]}`,
2020-11-18 13:51:53 -07:00
qr: null,
2020-10-24 17:55:32 -06:00
},
proof: {
uri: uri,
fetch: `https://mobile.twitter.com/${match[1]}/status/${match[2]}`,
useProxy: false,
2020-11-18 13:51:53 -07:00
format: 'text',
2020-10-24 17:55:32 -06:00
},
claim: {
fingerprint: null,
format: 'message',
path: [],
2020-11-18 13:51:53 -07:00
relation: 'contains',
2020-10-24 17:55:32 -06:00
},
2020-11-18 13:51:53 -07:00
customRequestHandler: null,
2020-10-24 17:55:32 -06:00
}
}
const tests = [
{
uri: 'https://twitter.com/alice/status/1234567890123456789',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-10-24 17:55:32 -06:00
},
{
uri: 'https://twitter.com/alice/status/1234567890123456789/',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-10-24 17:55:32 -06:00
},
{
uri: 'https://domain.org/alice/status/1234567890123456789',
2020-11-18 13:51:53 -07:00
shouldMatch: false,
},
2020-10-24 17:55:32 -06:00
]
exports.reURI = reURI
exports.processURI = processURI
exports.tests = tests
2020-11-18 13:51:53 -07:00
},{}],26:[function(require,module,exports){
2020-10-24 17:55:32 -06:00
/*
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
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.
*/
2020-11-18 13:51:53 -07:00
const utils = require('../utils')
2020-10-24 17:55:32 -06:00
const reURI = /^xmpp:([a-zA-Z0-9\.\-\_]*)@([a-zA-Z0-9\.\-\_]*)(?:\?(.*))?/
const processURI = (uri, opts) => {
2020-11-18 13:51:53 -07:00
if (!opts) {
opts = {}
}
2020-10-24 17:55:32 -06:00
const match = uri.match(reURI)
return {
serviceprovider: {
type: 'communication',
2020-11-18 13:51:53 -07:00
name: 'xmpp',
2020-10-24 17:55:32 -06:00
},
profile: {
display: `${match[1]}@${match[2]}`,
2020-11-06 10:39:06 -07:00
uri: uri,
2020-11-18 13:51:53 -07:00
qr: uri,
2020-10-24 17:55:32 -06:00
},
proof: {
2020-11-18 13:51:53 -07:00
uri: utils.generateProxyURL('xmpp', `${match[1]}@${match[2]}`, opts),
2020-10-24 17:55:32 -06:00
fetch: null,
useProxy: false,
2020-11-18 13:51:53 -07:00
format: 'json',
2020-10-24 17:55:32 -06:00
},
claim: {
fingerprint: null,
format: 'message',
path: [],
2020-11-18 13:51:53 -07:00
relation: 'contains',
2020-10-24 17:55:32 -06:00
},
2020-11-18 13:51:53 -07:00
customRequestHandler: null,
2020-10-24 17:55:32 -06:00
}
}
const tests = [
{
uri: 'xmpp:alice@domain.org',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-10-24 17:55:32 -06:00
},
{
uri: 'xmpp:alice@domain.org?omemo-sid-123456789=A1B2C3D4E5F6G7H8I9',
2020-11-18 13:51:53 -07:00
shouldMatch: true,
2020-10-24 17:55:32 -06:00
},
{
uri: 'https://domain.org',
2020-11-18 13:51:53 -07:00
shouldMatch: false,
},
2020-10-24 17:55:32 -06:00
]
exports.reURI = reURI
exports.processURI = processURI
exports.tests = tests
2020-11-18 13:51:53 -07:00
},{"../utils":27}],27:[function(require,module,exports){
/*
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
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.
*/
2020-11-06 10:39:06 -07:00
const generateProxyURL = (type, url, opts) => {
2020-11-18 13:51:53 -07:00
if (!opts || !opts.doipProxyHostname) {
return null
}
let addParam = ''
if (type == 'xmpp') {
addParam += '/DESC'
}
return `https://${
opts.doipProxyHostname
}/api/1/get/${type}/${encodeURIComponent(url)}${addParam}`
2020-11-05 04:14:26 -07:00
}
2020-10-24 17:22:54 -06:00
const generateClaim = (fingerprint, format) => {
switch (format) {
case 'uri':
return `openpgp4fpr:${fingerprint}`
2020-11-18 13:51:53 -07:00
break
2020-10-24 17:22:54 -06:00
case 'message':
return `[Verifying my OpenPGP key: openpgp4fpr:${fingerprint}]`
2020-11-18 13:51:53 -07:00
break
2020-10-24 17:22:54 -06:00
case 'fingerprint':
return fingerprint
2020-11-18 13:51:53 -07:00
break
2020-10-24 17:22:54 -06:00
default:
throw new Error('No valid claim format')
2020-10-24 06:38:10 -06:00
}
2020-10-24 17:22:54 -06:00
}
2020-10-24 06:38:10 -06:00
2020-11-05 04:14:26 -07:00
exports.generateProxyURL = generateProxyURL
2020-10-24 17:22:54 -06:00
exports.generateClaim = generateClaim
2020-10-24 06:38:10 -06:00
2020-11-18 13:51:53 -07:00
},{}]},{},[10])(10)
2020-10-24 06:38:10 -06:00
});