doipjs/dist/doip.js

3272 lines
86 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-20 01:15:39 -07:00
(function (process){(function (){
// 'path' module extracted from Node.js v8.11.1 (only the posix part)
// transplited with Babel
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
function assertPath(path) {
if (typeof path !== 'string') {
throw new TypeError('Path must be a string. Received ' + JSON.stringify(path));
}
}
// Resolves . and .. elements in a path with directory names
function normalizeStringPosix(path, allowAboveRoot) {
var res = '';
var lastSegmentLength = 0;
var lastSlash = -1;
var dots = 0;
var code;
for (var i = 0; i <= path.length; ++i) {
if (i < path.length)
code = path.charCodeAt(i);
else if (code === 47 /*/*/)
break;
else
code = 47 /*/*/;
if (code === 47 /*/*/) {
if (lastSlash === i - 1 || dots === 1) {
// NOOP
} else if (lastSlash !== i - 1 && dots === 2) {
if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 /*.*/ || res.charCodeAt(res.length - 2) !== 46 /*.*/) {
if (res.length > 2) {
var lastSlashIndex = res.lastIndexOf('/');
if (lastSlashIndex !== res.length - 1) {
if (lastSlashIndex === -1) {
res = '';
lastSegmentLength = 0;
} else {
res = res.slice(0, lastSlashIndex);
lastSegmentLength = res.length - 1 - res.lastIndexOf('/');
}
lastSlash = i;
dots = 0;
continue;
}
} else if (res.length === 2 || res.length === 1) {
res = '';
lastSegmentLength = 0;
lastSlash = i;
dots = 0;
continue;
}
}
if (allowAboveRoot) {
if (res.length > 0)
res += '/..';
else
res = '..';
lastSegmentLength = 2;
}
} else {
if (res.length > 0)
res += '/' + path.slice(lastSlash + 1, i);
else
res = path.slice(lastSlash + 1, i);
lastSegmentLength = i - lastSlash - 1;
}
lastSlash = i;
dots = 0;
} else if (code === 46 /*.*/ && dots !== -1) {
++dots;
} else {
dots = -1;
}
}
return res;
}
function _format(sep, pathObject) {
var dir = pathObject.dir || pathObject.root;
var base = pathObject.base || (pathObject.name || '') + (pathObject.ext || '');
if (!dir) {
return base;
}
if (dir === pathObject.root) {
return dir + base;
}
return dir + sep + base;
}
var posix = {
// path.resolve([from ...], to)
resolve: function resolve() {
var resolvedPath = '';
var resolvedAbsolute = false;
var cwd;
for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
var path;
if (i >= 0)
path = arguments[i];
else {
if (cwd === undefined)
cwd = process.cwd();
path = cwd;
}
assertPath(path);
// Skip empty entries
if (path.length === 0) {
continue;
}
resolvedPath = path + '/' + resolvedPath;
resolvedAbsolute = path.charCodeAt(0) === 47 /*/*/;
}
// At this point the path should be resolved to a full absolute path, but
// handle relative paths to be safe (might happen when process.cwd() fails)
// Normalize the path
resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute);
if (resolvedAbsolute) {
if (resolvedPath.length > 0)
return '/' + resolvedPath;
else
return '/';
} else if (resolvedPath.length > 0) {
return resolvedPath;
} else {
return '.';
}
},
normalize: function normalize(path) {
assertPath(path);
if (path.length === 0) return '.';
var isAbsolute = path.charCodeAt(0) === 47 /*/*/;
var trailingSeparator = path.charCodeAt(path.length - 1) === 47 /*/*/;
// Normalize the path
path = normalizeStringPosix(path, !isAbsolute);
if (path.length === 0 && !isAbsolute) path = '.';
if (path.length > 0 && trailingSeparator) path += '/';
if (isAbsolute) return '/' + path;
return path;
},
isAbsolute: function isAbsolute(path) {
assertPath(path);
return path.length > 0 && path.charCodeAt(0) === 47 /*/*/;
},
join: function join() {
if (arguments.length === 0)
return '.';
var joined;
for (var i = 0; i < arguments.length; ++i) {
var arg = arguments[i];
assertPath(arg);
if (arg.length > 0) {
if (joined === undefined)
joined = arg;
else
joined += '/' + arg;
}
}
if (joined === undefined)
return '.';
return posix.normalize(joined);
},
relative: function relative(from, to) {
assertPath(from);
assertPath(to);
if (from === to) return '';
from = posix.resolve(from);
to = posix.resolve(to);
if (from === to) return '';
// Trim any leading backslashes
var fromStart = 1;
for (; fromStart < from.length; ++fromStart) {
if (from.charCodeAt(fromStart) !== 47 /*/*/)
break;
}
var fromEnd = from.length;
var fromLen = fromEnd - fromStart;
// Trim any leading backslashes
var toStart = 1;
for (; toStart < to.length; ++toStart) {
if (to.charCodeAt(toStart) !== 47 /*/*/)
break;
}
var toEnd = to.length;
var toLen = toEnd - toStart;
// Compare paths to find the longest common path from root
var length = fromLen < toLen ? fromLen : toLen;
var lastCommonSep = -1;
var i = 0;
for (; i <= length; ++i) {
if (i === length) {
if (toLen > length) {
if (to.charCodeAt(toStart + i) === 47 /*/*/) {
// We get here if `from` is the exact base path for `to`.
// For example: from='/foo/bar'; to='/foo/bar/baz'
return to.slice(toStart + i + 1);
} else if (i === 0) {
// We get here if `from` is the root
// For example: from='/'; to='/foo'
return to.slice(toStart + i);
}
} else if (fromLen > length) {
if (from.charCodeAt(fromStart + i) === 47 /*/*/) {
// We get here if `to` is the exact base path for `from`.
// For example: from='/foo/bar/baz'; to='/foo/bar'
lastCommonSep = i;
} else if (i === 0) {
// We get here if `to` is the root.
// For example: from='/foo'; to='/'
lastCommonSep = 0;
}
}
break;
}
var fromCode = from.charCodeAt(fromStart + i);
var toCode = to.charCodeAt(toStart + i);
if (fromCode !== toCode)
break;
else if (fromCode === 47 /*/*/)
lastCommonSep = i;
}
var out = '';
// Generate the relative path based on the path difference between `to`
// and `from`
for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) {
if (i === fromEnd || from.charCodeAt(i) === 47 /*/*/) {
if (out.length === 0)
out += '..';
else
out += '/..';
}
}
// Lastly, append the rest of the destination (`to`) path that comes after
// the common path parts
if (out.length > 0)
return out + to.slice(toStart + lastCommonSep);
else {
toStart += lastCommonSep;
if (to.charCodeAt(toStart) === 47 /*/*/)
++toStart;
return to.slice(toStart);
}
},
_makeLong: function _makeLong(path) {
return path;
},
dirname: function dirname(path) {
assertPath(path);
if (path.length === 0) return '.';
var code = path.charCodeAt(0);
var hasRoot = code === 47 /*/*/;
var end = -1;
var matchedSlash = true;
for (var i = path.length - 1; i >= 1; --i) {
code = path.charCodeAt(i);
if (code === 47 /*/*/) {
if (!matchedSlash) {
end = i;
break;
}
} else {
// We saw the first non-path separator
matchedSlash = false;
}
}
if (end === -1) return hasRoot ? '/' : '.';
if (hasRoot && end === 1) return '//';
return path.slice(0, end);
},
basename: function basename(path, ext) {
if (ext !== undefined && typeof ext !== 'string') throw new TypeError('"ext" argument must be a string');
assertPath(path);
var start = 0;
var end = -1;
var matchedSlash = true;
var i;
if (ext !== undefined && ext.length > 0 && ext.length <= path.length) {
if (ext.length === path.length && ext === path) return '';
var extIdx = ext.length - 1;
var firstNonSlashEnd = -1;
for (i = path.length - 1; i >= 0; --i) {
var code = path.charCodeAt(i);
if (code === 47 /*/*/) {
// If we reached a path separator that was not part of a set of path
// separators at the end of the string, stop now
if (!matchedSlash) {
start = i + 1;
break;
}
} else {
if (firstNonSlashEnd === -1) {
// We saw the first non-path separator, remember this index in case
// we need it if the extension ends up not matching
matchedSlash = false;
firstNonSlashEnd = i + 1;
}
if (extIdx >= 0) {
// Try to match the explicit extension
if (code === ext.charCodeAt(extIdx)) {
if (--extIdx === -1) {
// We matched the extension, so mark this as the end of our path
// component
end = i;
}
} else {
// Extension does not match, so our result is the entire path
// component
extIdx = -1;
end = firstNonSlashEnd;
}
}
}
}
if (start === end) end = firstNonSlashEnd;else if (end === -1) end = path.length;
return path.slice(start, end);
} else {
for (i = path.length - 1; i >= 0; --i) {
if (path.charCodeAt(i) === 47 /*/*/) {
// If we reached a path separator that was not part of a set of path
// separators at the end of the string, stop now
if (!matchedSlash) {
start = i + 1;
break;
}
} else if (end === -1) {
// We saw the first non-path separator, mark this as the end of our
// path component
matchedSlash = false;
end = i + 1;
}
}
if (end === -1) return '';
return path.slice(start, end);
}
},
extname: function extname(path) {
assertPath(path);
var startDot = -1;
var startPart = 0;
var end = -1;
var matchedSlash = true;
// Track the state of characters (if any) we see before our first dot and
// after any path separator we find
var preDotState = 0;
for (var i = path.length - 1; i >= 0; --i) {
var code = path.charCodeAt(i);
if (code === 47 /*/*/) {
// If we reached a path separator that was not part of a set of path
// separators at the end of the string, stop now
if (!matchedSlash) {
startPart = i + 1;
break;
}
continue;
}
if (end === -1) {
// We saw the first non-path separator, mark this as the end of our
// extension
matchedSlash = false;
end = i + 1;
}
if (code === 46 /*.*/) {
// If this is our first dot, mark it as the start of our extension
if (startDot === -1)
startDot = i;
else if (preDotState !== 1)
preDotState = 1;
} else if (startDot !== -1) {
// We saw a non-dot and non-path separator before our dot, so we should
// have a good chance at having a non-empty extension
preDotState = -1;
}
}
if (startDot === -1 || end === -1 ||
// We saw a non-dot character immediately before the dot
preDotState === 0 ||
// The (right-most) trimmed path component is exactly '..'
preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
return '';
}
return path.slice(startDot, end);
},
format: function format(pathObject) {
if (pathObject === null || typeof pathObject !== 'object') {
throw new TypeError('The "pathObject" argument must be of type Object. Received type ' + typeof pathObject);
}
return _format('/', pathObject);
},
parse: function parse(path) {
assertPath(path);
var ret = { root: '', dir: '', base: '', ext: '', name: '' };
if (path.length === 0) return ret;
var code = path.charCodeAt(0);
var isAbsolute = code === 47 /*/*/;
var start;
if (isAbsolute) {
ret.root = '/';
start = 1;
} else {
start = 0;
}
var startDot = -1;
var startPart = 0;
var end = -1;
var matchedSlash = true;
var i = path.length - 1;
// Track the state of characters (if any) we see before our first dot and
// after any path separator we find
var preDotState = 0;
// Get non-dir info
for (; i >= start; --i) {
code = path.charCodeAt(i);
if (code === 47 /*/*/) {
// If we reached a path separator that was not part of a set of path
// separators at the end of the string, stop now
if (!matchedSlash) {
startPart = i + 1;
break;
}
continue;
}
if (end === -1) {
// We saw the first non-path separator, mark this as the end of our
// extension
matchedSlash = false;
end = i + 1;
}
if (code === 46 /*.*/) {
// If this is our first dot, mark it as the start of our extension
if (startDot === -1) startDot = i;else if (preDotState !== 1) preDotState = 1;
} else if (startDot !== -1) {
// We saw a non-dot and non-path separator before our dot, so we should
// have a good chance at having a non-empty extension
preDotState = -1;
}
}
if (startDot === -1 || end === -1 ||
// We saw a non-dot character immediately before the dot
preDotState === 0 ||
// The (right-most) trimmed path component is exactly '..'
preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
if (end !== -1) {
if (startPart === 0 && isAbsolute) ret.base = ret.name = path.slice(1, end);else ret.base = ret.name = path.slice(startPart, end);
}
} else {
if (startPart === 0 && isAbsolute) {
ret.name = path.slice(1, startDot);
ret.base = path.slice(1, end);
} else {
ret.name = path.slice(startPart, startDot);
ret.base = path.slice(startPart, end);
}
ret.ext = path.slice(startDot, end);
}
if (startPart > 0) ret.dir = path.slice(0, startPart - 1);else if (isAbsolute) ret.dir = '/';
return ret;
},
sep: '/',
delimiter: ':',
win32: null,
posix: null
};
posix.posix = posix;
module.exports = posix;
}).call(this)}).call(this,require('_process'))
},{"_process":7}],7:[function(require,module,exports){
// shim for using process in browser
var process = module.exports = {};
// cached from whatever global is present so that test runners that stub it
// don't break things. But we need to wrap it in a try catch in case it is
// wrapped in strict mode code which doesn't define any globals. It's inside a
// function because try/catches deoptimize in certain engines.
var cachedSetTimeout;
var cachedClearTimeout;
function defaultSetTimout() {
throw new Error('setTimeout has not been defined');
}
function defaultClearTimeout () {
throw new Error('clearTimeout has not been defined');
}
(function () {
try {
if (typeof setTimeout === 'function') {
cachedSetTimeout = setTimeout;
} else {
cachedSetTimeout = defaultSetTimout;
}
} catch (e) {
cachedSetTimeout = defaultSetTimout;
}
try {
if (typeof clearTimeout === 'function') {
cachedClearTimeout = clearTimeout;
} else {
cachedClearTimeout = defaultClearTimeout;
}
} catch (e) {
cachedClearTimeout = defaultClearTimeout;
}
} ())
function runTimeout(fun) {
if (cachedSetTimeout === setTimeout) {
//normal enviroments in sane situations
return setTimeout(fun, 0);
}
// if setTimeout wasn't available but was latter defined
if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
cachedSetTimeout = setTimeout;
return setTimeout(fun, 0);
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedSetTimeout(fun, 0);
} catch(e){
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedSetTimeout.call(null, fun, 0);
} catch(e){
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
return cachedSetTimeout.call(this, fun, 0);
}
}
}
function runClearTimeout(marker) {
if (cachedClearTimeout === clearTimeout) {
//normal enviroments in sane situations
return clearTimeout(marker);
}
// if clearTimeout wasn't available but was latter defined
if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
cachedClearTimeout = clearTimeout;
return clearTimeout(marker);
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedClearTimeout(marker);
} catch (e){
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedClearTimeout.call(null, marker);
} catch (e){
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
return cachedClearTimeout.call(this, marker);
}
}
}
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;
function cleanUpNextTick() {
if (!draining || !currentQueue) {
return;
}
draining = false;
if (currentQueue.length) {
queue = currentQueue.concat(queue);
} else {
queueIndex = -1;
}
if (queue.length) {
drainQueue();
}
}
function drainQueue() {
if (draining) {
return;
}
var timeout = runTimeout(cleanUpNextTick);
draining = true;
var len = queue.length;
while(len) {
currentQueue = queue;
queue = [];
while (++queueIndex < len) {
if (currentQueue) {
currentQueue[queueIndex].run();
}
}
queueIndex = -1;
len = queue.length;
}
currentQueue = null;
draining = false;
runClearTimeout(timeout);
}
process.nextTick = function (fun) {
var args = new Array(arguments.length - 1);
if (arguments.length > 1) {
for (var i = 1; i < arguments.length; i++) {
args[i - 1] = arguments[i];
}
}
queue.push(new Item(fun, args));
if (queue.length === 1 && !draining) {
runTimeout(drainQueue);
}
};
// v8 likes predictible objects
function Item(fun, array) {
this.fun = fun;
this.array = array;
}
Item.prototype.run = function () {
this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};
function noop() {}
process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.prependListener = noop;
process.prependOnceListener = noop;
process.listeners = function (name) { return [] }
process.binding = function (name) {
throw new Error('process.binding is not supported');
};
process.cwd = function () { return '/' };
process.chdir = function (dir) {
throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };
},{}],8:[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-20 01:15:39 -07:00
},{}],9:[function(require,module,exports){
2020-11-18 13:51:53 -07:00
module.exports={
"name": "doipjs",
2021-01-13 05:27:58 -07:00
"version": "0.10.0",
2020-11-18 13:51:53 -07:00
"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",
2020-12-07 18:39:30 -07:00
"openpgp": "^4.10.9",
2020-11-18 13:51:53 -07:00
"prettier": "^2.1.2",
"valid-url": "^1.0.9"
},
"devDependencies": {
2020-12-09 18:05:36 -07:00
"browserify-shim": "^3.8.14",
2020-11-18 13:51:53 -07:00
"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": {
2020-12-09 18:05:36 -07:00
"release:bundle": "./node_modules/browserify/bin/cmd.js ./src/index.js --standalone doip -x openpgp -o ./dist/doip.js",
2020-11-18 13:51:53 -07:00
"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)",
2020-12-09 18:05:36 -07:00
"license": "Apache-2.0",
"browserify": {
2020-12-20 15:20:32 -07:00
"transform": [
"browserify-shim"
]
2020-12-09 18:05:36 -07:00
},
"browserify-shim": {
"openpgp": "global:openpgp"
}
2020-11-18 13:51:53 -07:00
}
2020-11-20 01:15:39 -07:00
},{}],10:[function(require,module,exports){
2020-12-09 18:05:36 -07:00
(function (global){(function (){
2020-11-18 13:51:53 -07:00
/*
2021-01-13 05:20:33 -07:00
Copyright 2021 Yarmo Mackenbach
2020-11-18 13:51:53 -07: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
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-20 01:15:39 -07:00
const path = require('path')
2020-11-18 13:51:53 -07:00
const mergeOptions = require('merge-options')
const validUrl = require('valid-url')
2020-12-09 18:05:36 -07:00
const openpgp = (typeof window !== "undefined" ? window['openpgp'] : typeof global !== "undefined" ? global['openpgp'] : null)
2020-11-18 13:51:53 -07:00
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-12-05 15:17:54 -07:00
re = new RegExp(checkClaim, 'gi')
res.isVerified = re.test(proofData.replace(/\r?\n|\r|\\/g, ''))
2020-10-24 17:22:54 -06:00
break
case 'equals':
2020-11-18 13:51:53 -07:00
res.isVerified =
2020-12-05 15:17:54 -07:00
proofData.replace(/\r?\n|\r|\\/g, '').toLowerCase() ==
2020-11-18 13:51:53 -07:00
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) {
2020-12-05 15:17:54 -07:00
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) {
reject(e)
}
})
})
2020-12-11 03:07:13 -07:00
return Promise.allSettled(promises).then((values) => {
return values.map((obj, i) => {
2020-12-20 15:20:32 -07:00
if (obj.status == 'fulfilled') {
return obj.value
} else {
return obj.reason
}
2020-12-11 03:07:13 -07:00
})
2020-12-05 15:17:54 -07:00
})
2020-11-18 13:51:53 -07:00
}
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) {
reject(e)
}
})
})
2020-10-24 17:22:54 -06:00
2020-12-11 03:07:13 -07:00
return Promise.allSettled(promises).then((values) => {
return values.map((obj, i) => {
2020-12-20 15:20:32 -07:00
if (obj.status == 'fulfilled') {
return obj.value
} else {
return obj.reason
}
2020-12-11 03:07:13 -07:00
})
2020-11-18 13:51:53 -07:00
})
}
2020-10-24 06:38:10 -06:00
2020-12-20 15:20:32 -07:00
const promiseClaim = new Promise(async (resolve, reject) => {
let objResult = {
isVerified: false,
errors: [],
serviceproviderData: undefined,
}
2020-10-24 17:22:54 -06:00
2020-12-20 15:20:32 -07:00
const uri = input.replace(/^\s+|\s+$/g, '')
2020-10-24 06:38:10 -06:00
2020-12-20 15:20:32 -07:00
if (!fingerprint) {
fingerprint = null
}
2020-11-06 10:39:06 -07:00
2020-12-20 15:20:32 -07:00
const defaultOpts = {
returnMatchesOnly: false,
proxyPolicy: 'adaptive',
doipProxyHostname: 'proxy.keyoxide.org',
}
opts = mergeOptions(defaultOpts, opts ? opts : {})
2020-10-24 06:38:10 -06:00
2020-12-20 15:20:32 -07:00
if (!validUrl.isUri(uri)) {
objResult.errors.push('invalid_uri')
reject(objResult)
return
}
2020-10-24 06:38:10 -06:00
2020-12-20 15:20:32 -07:00
const spMatches = serviceproviders.match(uri, opts)
2020-12-11 03:07:13 -07:00
2020-12-20 15:20:32 -07:00
if ('returnMatchesOnly' in opts && opts.returnMatchesOnly) {
resolve(spMatches)
return
}
2020-12-11 03:07:13 -07:00
2020-12-20 15:20:32 -07:00
let claimVerificationDone = false,
claimVerificationResult,
sp,
iSp = 0,
res,
proofData,
spData
2020-10-24 17:22:54 -06:00
2020-12-20 15:20:32 -07:00
while (!claimVerificationDone && iSp < spMatches.length) {
spData = spMatches[iSp]
spData.claim.fingerprint = fingerprint
2020-10-24 17:22:54 -06:00
2020-12-20 15:20:32 -07:00
res = null
if (spData.customRequestHandler instanceof Function) {
try {
proofData = await spData.customRequestHandler(spData, opts)
} catch (e) {
objResult.errors.push('custom_request_handler_failed')
}
} else {
switch (opts.proxyPolicy) {
case 'adaptive':
if (spData.proof.useProxy) {
try {
proofData = await serviceproviders.proxyRequestHandler(
spData,
opts
)
} catch (er) {}
} else {
try {
proofData = await serviceproviders.directRequestHandler(
spData,
opts
)
} catch (er) {}
if (!proofData) {
try {
proofData = await serviceproviders.proxyRequestHandler(
spData,
opts
)
} catch (er) {}
}
}
break
case 'fallback':
2020-12-11 03:07:13 -07:00
try {
2020-12-20 15:20:32 -07:00
proofData = await serviceproviders.directRequestHandler(
spData,
opts
)
} catch (er) {}
2020-12-11 03:07:13 -07:00
if (!proofData) {
try {
2020-12-20 15:20:32 -07:00
proofData = await serviceproviders.proxyRequestHandler(
spData,
opts
)
} catch (er) {}
2020-12-11 03:07:13 -07:00
}
2020-12-20 15:20:32 -07:00
break
case 'always':
2020-12-11 03:07:13 -07:00
try {
2020-12-20 15:20:32 -07:00
proofData = await serviceproviders.proxyRequestHandler(
spData,
opts
)
} catch (er) {}
break
case 'never':
try {
proofData = await serviceproviders.directRequestHandler(
spData,
opts
)
} catch (er) {}
break
default:
objResult.errors.push('invalid_proxy_policy')
}
2020-12-11 03:07:13 -07:00
}
2020-11-05 04:14:26 -07:00
2020-12-20 15:20:32 -07:00
if (proofData) {
claimVerificationResult = runVerification(proofData, spData)
2020-10-24 06:38:10 -06:00
2020-12-20 15:20:32 -07:00
if (claimVerificationResult.errors.length == 0) {
claimVerificationDone = true
}
} else {
objResult.errors.push('unsuccessful_claim_verification')
2020-11-03 14:53:04 -07:00
}
2020-12-20 15:20:32 -07:00
iSp++
2020-11-03 14:53:04 -07:00
}
2020-10-24 06:38:10 -06:00
2020-12-20 15:20:32 -07:00
if (!claimVerificationResult) {
claimVerificationResult = {
isVerified: false,
}
}
2020-10-24 06:38:10 -06:00
2020-12-20 15:20:32 -07:00
objResult.isVerified = claimVerificationResult.isVerified
objResult.serviceproviderData = spData
resolve(objResult)
return
})
const promiseTimeout = new Promise((resolve) => {
const objResult = {
2020-11-18 13:51:53 -07:00
isVerified: false,
2020-12-20 15:20:32 -07:00
errors: ['verification_timed_out'],
serviceproviderData: undefined,
2020-11-03 14:53:04 -07:00
}
2020-12-20 15:20:32 -07:00
setTimeout(() => {
resolve(objResult)
return
}, 3000)
})
2020-11-03 14:53:04 -07:00
2020-12-20 15:20:32 -07:00
return await Promise.race([promiseClaim, promiseTimeout])
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
2020-12-09 18:05:36 -07:00
}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2021-01-13 05:27:58 -07:00
},{"./keys":12,"./serviceproviders":13,"./utils":30,"merge-options":5,"path":6,"valid-url":8}],11:[function(require,module,exports){
2020-11-18 13:51:53 -07:00
/*
2021-01-13 05:20:33 -07:00
Copyright 2021 Yarmo Mackenbach
2020-11-18 13:51:53 -07: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
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')
2021-01-07 08:26:31 -07:00
const signatures = require('./signatures')
2020-11-18 13:51:53 -07:00
const serviceproviders = require('./serviceproviders')
const utils = require('./utils')
exports.claims = claims
exports.keys = keys
2021-01-07 08:26:31 -07:00
exports.signatures = signatures
2020-10-24 17:22:54 -06:00
exports.serviceproviders = serviceproviders
exports.utils = utils
2020-10-24 06:38:10 -06:00
2021-01-13 05:27:58 -07:00
},{"./claims":10,"./keys":12,"./serviceproviders":13,"./signatures":29,"./utils":30}],12:[function(require,module,exports){
2020-12-09 18:05:36 -07:00
(function (global){(function (){
2020-11-18 13:51:53 -07:00
/*
2021-01-13 05:20:33 -07:00
Copyright 2021 Yarmo Mackenbach
2020-11-18 13:51:53 -07: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
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-20 01:15:39 -07:00
const path = require('path')
2020-11-18 13:51:53 -07:00
const bent = require('bent')
const req = bent('GET')
const validUrl = require('valid-url')
2020-12-09 18:05:36 -07:00
const openpgp = (typeof window !== "undefined" ? window['openpgp'] : typeof global !== "undefined" ? global['openpgp'] : null)
2020-11-18 13:51:53 -07:00
const mergeOptions = require('merge-options')
2020-12-05 15:17:54 -07:00
const fetchHKP = (identifier, keyserverBaseUrl) => {
return new Promise(async (resolve, reject) => {
2020-11-18 13:51:53 -07:00
keyserverBaseUrl = keyserverBaseUrl
2021-01-03 11:54:15 -07:00
? `https://${keyserverBaseUrl}`
: 'https://keys.openpgp.org'
2020-11-18 13:51:53 -07:00
const hkp = new openpgp.HKP(keyserverBaseUrl)
const lookupOpts = {
query: identifier,
}
2021-01-09 08:07:01 -07:00
2020-11-18 13:51:53 -07:00
let publicKey = await hkp.lookup(lookupOpts)
2021-01-09 08:07:01 -07:00
.catch((error) => {
reject('Key does not exist or could not be fetched')
})
publicKey = await openpgp.key.readArmored(publicKey)
.then((result) => {
return result.keys[0]
})
.catch((error) => {
return null
})
2020-11-18 13:51:53 -07:00
2021-01-09 08:07:01 -07:00
if (publicKey) {
resolve(publicKey)
} else {
2020-12-05 15:17:54 -07:00
reject('Key does not exist or could not be fetched')
}
})
2020-11-18 13:51:53 -07:00
}
2020-12-05 15:17:54 -07:00
const fetchWKD = (identifier) => {
return new Promise(async (resolve, reject) => {
2020-11-18 13:51:53 -07:00
const wkd = new openpgp.WKD()
const lookupOpts = {
email: identifier,
}
2021-01-09 08:07:01 -07:00
const publicKey = await wkd.lookup(lookupOpts)
.then((result) => {
return result.keys[0]
})
.catch((error) => {
return null
})
if (publicKey) {
resolve(publicKey)
} else {
2020-12-05 15:17:54 -07:00
reject('Key does not exist or could not be fetched')
}
})
2020-11-18 13:51:53 -07:00
}
2020-12-05 15:17:54 -07:00
const fetchKeybase = (username, fingerprint) => {
return new Promise(async (resolve, reject) => {
2020-11-18 13:51:53 -07:00
const keyLink = `https://keybase.io/${username}/pgp_keys.asc?fingerprint=${fingerprint}`
try {
const rawKeyContent = await req(opts.keyLink)
2020-12-05 15:17:54 -07:00
.then((response) => {
2020-11-18 13:51:53 -07:00
if (response.status === 200) {
return response
}
})
.then((response) => response.text())
} catch (e) {
2020-12-05 15:17:54 -07:00
reject(`Error fetching Keybase key: ${e.message}`)
2020-11-18 13:51:53 -07:00
}
2021-01-09 08:07:01 -07:00
const publicKey = await openpgp.key.readArmored(rawKeyContent)
.then((result) => {
return result.keys[0]
})
.catch((error) => {
return null
})
2020-11-18 13:51:53 -07:00
2021-01-09 08:07:01 -07:00
if (publicKey) {
resolve(publicKey)
} else {
2020-12-05 15:17:54 -07:00
reject('Key does not exist or could not be fetched')
}
})
2020-11-18 13:51:53 -07:00
}
2020-12-05 15:17:54 -07:00
const fetchPlaintext = (rawKeyContent) => {
return new Promise(async (resolve, reject) => {
2020-11-18 13:51:53 -07:00
const publicKey = (await openpgp.key.readArmored(rawKeyContent)).keys[0]
2020-12-05 15:17:54 -07:00
resolve(publicKey)
})
2020-11-18 13:51:53 -07:00
}
2020-12-05 15:17:54 -07:00
const fetchSignature = (rawSignatureContent, keyserverBaseUrl) => {
return new Promise(async (resolve, reject) => {
2020-11-18 13:51:53 -07:00
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()
2020-12-05 15:17:54 -07:00
resolve(fetchHKP(sigUserId ? sigUserId : sigKeyId, keyserverBaseUrl))
})
2020-11-18 13:51:53 -07:00
}
2020-12-05 15:17:54 -07:00
const fetchURI = (uri) => {
return new Promise(async (resolve, reject) => {
2020-11-18 13:51:53 -07:00
if (!validUrl.isUri(uri)) {
2020-12-05 15:17:54 -07:00
reject('Invalid URI')
2020-11-18 13:51:53 -07:00
}
2020-12-07 18:59:13 -07:00
const re = /([a-zA-Z0-9]*):([a-zA-Z0-9@._=+\-]*)(?:\:([a-zA-Z0-9@._=+\-]*))?/
2020-11-18 13:51:53 -07:00
const match = uri.match(re)
if (!match[1]) {
2020-12-05 15:17:54 -07:00
reject('Invalid URI')
2020-11-18 13:51:53 -07:00
}
switch (match[1]) {
case 'hkp':
2020-12-20 15:20:32 -07:00
resolve(
fetchHKP(match[3] ? match[3] : match[2], match[3] ? match[2] : null)
)
2020-11-18 13:51:53 -07:00
break
case 'wkd':
2020-12-05 15:17:54 -07:00
resolve(fetchWKD(match[2]))
2020-11-18 13:51:53 -07:00
break
case 'kb':
2020-12-05 15:17:54 -07:00
resolve(fetchKeybase(match[2], match.length >= 4 ? match[3] : null))
2020-11-18 13:51:53 -07:00
break
default:
2020-12-05 15:17:54 -07:00
reject('Invalid URI protocol')
2020-11-18 13:51:53 -07:00
break
}
2020-12-05 15:17:54 -07:00
})
2020-11-18 13:51:53 -07:00
}
2020-12-05 15:17:54 -07:00
const process = (publicKey) => {
return new Promise(async (resolve, reject) => {
if (!publicKey) {
reject('Invalid public key')
}
2020-11-18 13:51:53 -07:00
const fingerprint = await publicKey.primaryKey.getFingerprint()
2020-12-05 15:17:54 -07:00
const primaryUser = await publicKey.getPrimaryUser()
const users = publicKey.users
let primaryUserIndex,
usersOutput = []
users.forEach((user, i) => {
usersOutput[i] = {
userData: {
2020-12-26 14:48:18 -07:00
id: user.userId ? user.userId.userid : null,
name: user.userId ? user.userId.name : null,
email: user.userId ? user.userId.email : null,
comment: user.userId ? user.userId.comment : null,
2020-12-05 15:17:54 -07:00
isPrimary: primaryUser.index === i,
},
}
2020-11-18 13:51:53 -07:00
2020-12-26 14:48:18 -07:00
if ('selfCertifications' in user && user.selfCertifications.length > 0) {
2020-12-26 05:58:33 -07:00
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)
}
2020-12-05 15:17:54 -07:00
}
2020-12-26 05:58:33 -07:00
)
} else {
usersOutput[i].notations = []
}
2020-12-05 15:17:54 -07:00
})
resolve({
2020-11-18 13:51:53 -07:00
fingerprint: fingerprint,
2020-12-05 15:17:54 -07:00
users: usersOutput,
primaryUserIndex: primaryUser.index,
})
})
2020-11-18 13:51:53 -07:00
}
2020-12-05 15:17:54 -07:00
const getUserData = (publicKey) => {
return new Promise(async (resolve, reject) => {
2020-11-18 13:51:53 -07:00
const keyData = await process(publicKey)
2020-12-05 15:17:54 -07:00
resolve(keyData.users)
})
2020-11-18 13:51:53 -07:00
}
2020-12-05 15:17:54 -07:00
const getFingerprint = (publicKey) => {
return new Promise(async (resolve, reject) => {
2020-11-18 13:51:53 -07:00
const keyData = await process(publicKey)
2020-12-05 15:17:54 -07:00
resolve(keyData.fingerprint)
})
2020-11-18 13:51:53 -07:00
}
exports.fetch = {
uri: fetchURI,
hkp: fetchHKP,
wkd: fetchWKD,
keybase: fetchKeybase,
plaintext: fetchPlaintext,
signature: fetchSignature,
}
exports.process = process
2020-12-05 15:17:54 -07:00
exports.getUserData = getUserData
2020-11-18 13:51:53 -07:00
exports.getFingerprint = getFingerprint
2020-12-09 18:05:36 -07:00
}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2020-11-20 01:15:39 -07:00
},{"bent":1,"merge-options":5,"path":6,"valid-url":8}],13:[function(require,module,exports){
2020-10-24 06:38:10 -06:00
/*
2021-01-13 05:20:33 -07:00
Copyright 2021 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',
2021-01-13 05:27:58 -07:00
'owncast',
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'),
2021-01-13 05:27:58 -07:00
owncast: require('./serviceproviders/owncast'),
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-12-05 15:17:54 -07:00
const directRequestHandler = (spData, opts) => {
return new Promise(async (resolve, reject) => {
const url = spData.proof.fetch ? spData.proof.fetch : spData.proof.uri
let res
2020-11-03 14:53:04 -07:00
2020-12-05 15:17:54 -07:00
switch (spData.proof.format) {
case 'json':
2020-12-11 03:07:13 -07:00
req(url, null, {
2020-12-05 15:17:54 -07:00
Accept: 'application/json',
'User-Agent': `doipjs/${require('../package.json').version}`,
})
2020-12-20 15:20:32 -07:00
.then(async (res) => {
return await res.json()
})
.then((res) => {
resolve(res)
})
.catch((e) => {
reject(e)
})
2020-12-05 15:17:54 -07:00
break
case 'text':
2020-12-11 03:07:13 -07:00
req(url)
2020-12-20 15:20:32 -07:00
.then(async (res) => {
return await res.text()
})
.then((res) => {
resolve(res)
})
.catch((e) => {
reject(e)
})
2020-12-05 15:17:54 -07:00
break
default:
reject('No specified proof data format')
break
}
})
2020-10-26 16:02:22 -06:00
}
2020-12-05 15:17:54 -07:00
const proxyRequestHandler = (spData, opts) => {
return new Promise(async (resolve, reject) => {
const url = spData.proof.fetch ? spData.proof.fetch : spData.proof.uri
2020-12-20 15:20:32 -07:00
req(utils.generateProxyURL(spData.proof.format, url, opts), null, {
Accept: 'application/json',
2020-12-11 03:07:13 -07:00
})
2020-12-20 15:20:32 -07:00
.then(async (res) => {
return await res.json()
})
.then((res) => {
resolve(res.content)
})
.catch((e) => {
reject(e)
})
2020-12-05 15:17:54 -07:00
})
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
2021-01-13 05:27:58 -07:00
},{"../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/owncast":25,"./serviceproviders/reddit":26,"./serviceproviders/twitter":27,"./serviceproviders/xmpp":28,"./utils":30,"bent":1}],14:[function(require,module,exports){
2020-10-26 05:24:30 -06:00
/*
2021-01-13 05:20:33 -07:00
Copyright 2021 Yarmo Mackenbach
2020-10-26 05:24:30 -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
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]}`,
2020-12-11 03:07:13 -07:00
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: ['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-20 01:15:39 -07:00
},{}],15:[function(require,module,exports){
2020-10-24 17:55:32 -06:00
/*
2021-01-13 05:20:33 -07:00
Copyright 2021 Yarmo Mackenbach
2020-10-24 17:55:32 -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
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-20 01:15:39 -07:00
},{}],16:[function(require,module,exports){
2020-11-03 14:53:04 -07:00
/*
2021-01-13 05:20:33 -07:00
Copyright 2021 Yarmo Mackenbach
2020-11-03 14:53:04 -07: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
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-12-11 03:07:13 -07:00
uri: utils.generateProxyURL('dns', match[1], 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: '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
2021-01-13 05:27:58 -07:00
},{"../utils":30,"bent":1,"dns":3}],17:[function(require,module,exports){
2020-11-03 14:53:04 -07:00
/*
2021-01-13 05:20:33 -07:00
Copyright 2021 Yarmo Mackenbach
2020-11-03 14:53:04 -07: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
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-20 01:15:39 -07:00
},{}],18:[function(require,module,exports){
2020-10-26 05:24:30 -06:00
/*
2021-01-13 05:20:33 -07:00
Copyright 2021 Yarmo Mackenbach
2020-10-26 05:24:30 -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
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-20 01:15:39 -07:00
},{}],19:[function(require,module,exports){
2020-10-26 05:24:30 -06:00
/*
2021-01-13 05:20:33 -07:00
Copyright 2021 Yarmo Mackenbach
2020-10-26 05:24:30 -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
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-20 01:15:39 -07:00
},{}],20:[function(require,module,exports){
2020-10-24 17:55:32 -06:00
/*
2021-01-13 05:20:33 -07:00
Copyright 2021 Yarmo Mackenbach
2020-10-24 17:55:32 -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
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-12-11 03:07:13 -07:00
let resUser
try {
resUser = await req(urlUser, null, { Accept: 'application/json' })
} catch (e) {
2020-12-20 15:20:32 -07:00
resUser = await req(utils.generateProxyURL('web', urlUser, opts), null, {
Accept: 'application/json',
})
2020-12-11 03:07:13 -07:00
}
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`
2020-12-11 03:07:13 -07:00
let resProject
try {
resProject = await req(urlProject, null, { Accept: 'application/json' })
} catch (e) {
resProject = await req(
utils.generateProxyURL('web', urlProject, opts),
null,
{ Accept: 'application/json' }
)
}
2020-10-26 16:02:22 -06:00
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-20 01:15:39 -07:00
},{"bent":1}],21:[function(require,module,exports){
2020-10-26 16:02:22 -06:00
/*
2021-01-13 05:20:33 -07:00
Copyright 2021 Yarmo Mackenbach
2020-10-26 16:02:22 -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
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-20 01:15:39 -07:00
},{}],22:[function(require,module,exports){
2020-11-05 04:14:26 -07:00
/*
2021-01-13 05:20:33 -07:00
Copyright 2021 Yarmo Mackenbach
2020-11-05 04:14:26 -07: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
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-20 01:15:39 -07:00
},{}],23:[function(require,module,exports){
2020-10-24 17:55:32 -06:00
/*
2021-01-13 05:20:33 -07:00
Copyright 2021 Yarmo Mackenbach
2020-10-24 17:55:32 -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
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-20 01:15:39 -07:00
},{}],24:[function(require,module,exports){
2020-11-03 14:53:04 -07:00
/*
2021-01-13 05:20:33 -07:00
Copyright 2021 Yarmo Mackenbach
2020-11-03 14:53:04 -07: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
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-20 01:15:39 -07:00
},{}],25:[function(require,module,exports){
2020-10-26 05:24:30 -06:00
/*
2021-01-13 05:20:33 -07:00
Copyright 2021 Yarmo Mackenbach
2020-10-26 05:24:30 -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
http://www.apache.org/licenses/LICENSE-2.0
2021-01-13 05:27:58 -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 bent = require('bent')
const req = bent('GET')
const reURI = /^https:\/\/(.*)/
const processURI = (uri, opts) => {
if (!opts) {
opts = {}
}
const match = uri.match(reURI)
return {
serviceprovider: {
type: 'web',
name: 'owncast',
},
profile: {
display: match[1],
uri: uri,
qr: null,
},
proof: {
uri: `${uri}/api/config`,
fetch: null,
useProxy: false,
format: 'json',
},
claim: {
fingerprint: null,
format: 'fingerprint',
path: ['socialHandles', 'url'],
relation: 'contains',
},
customRequestHandler: null,
}
}
const tests = [
{
uri: 'https://live.domain.org',
shouldMatch: true,
},
{
uri: 'https://live.domain.org/',
shouldMatch: true,
},
{
uri: 'https://domain.org/live',
shouldMatch: true,
},
{
uri: 'https://domain.org/live/',
shouldMatch: true,
},
]
exports.reURI = reURI
exports.processURI = processURI
exports.tests = tests
},{"bent":1}],26:[function(require,module,exports){
/*
Copyright 2021 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 05:24:30 -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 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
2021-01-13 05:27:58 -07:00
},{}],27:[function(require,module,exports){
2020-10-24 17:55:32 -06:00
/*
2021-01-13 05:20:33 -07:00
Copyright 2021 Yarmo Mackenbach
2020-10-24 17:55:32 -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
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,
2021-01-02 08:38:13 -07:00
fetch: `https://nitter.net/${match[1]}/status/${match[2]}`,
2020-12-11 03:07:13 -07:00
useProxy: true,
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
2021-01-13 05:27:58 -07:00
},{}],28:[function(require,module,exports){
2020-10-24 17:55:32 -06:00
/*
2021-01-13 05:20:33 -07:00
Copyright 2021 Yarmo Mackenbach
2020-10-24 17:55:32 -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
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
2021-01-13 05:27:58 -07:00
},{"../utils":30}],29:[function(require,module,exports){
2021-01-07 08:26:31 -07:00
(function (global){(function (){
/*
2021-01-13 05:20:33 -07:00
Copyright 2021 Yarmo Mackenbach
2021-01-07 08:26:31 -07: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
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 openpgp = (typeof window !== "undefined" ? window['openpgp'] : typeof global !== "undefined" ? global['openpgp'] : null)
const mergeOptions = require('merge-options')
const claims = require('./claims')
const keys = require('./keys')
const verify = (signature, opts) => {
return new Promise(async (resolve, reject) => {
let errors = [],
sigData
2021-01-09 07:22:59 -07:00
2021-01-07 08:26:31 -07:00
try {
sigData = await openpgp.cleartext.readArmored(signature)
} catch (error) {
errors.push('invalid_signature')
reject({ errors: errors })
2021-01-09 07:22:59 -07:00
return
2021-01-07 08:26:31 -07:00
}
2021-01-09 07:22:59 -07:00
const issuerKeyId = sigData.signature.packets[0].issuerKeyId.toHex()
const signersUserId = sigData.signature.packets[0].signersUserId
const preferredKeyServer =
sigData.signature.packets[0].preferredKeyServer ||
2021-01-10 09:59:24 -07:00
'https://keys.openpgp.org/'
2021-01-07 08:26:31 -07:00
const text = sigData.getText()
let sigKeys = []
let sigClaims = []
2021-01-09 07:22:59 -07:00
2021-01-07 08:26:31 -07:00
text.split('\n').forEach((line, i) => {
2021-01-10 04:34:47 -07:00
const match = line.match(/^([a-zA-Z0-9]*)\=(.*)$/i)
2021-01-07 08:26:31 -07:00
if (!match) {
return
}
switch (match[1].toLowerCase()) {
case 'key':
sigKeys.push(match[2])
break
case 'proof':
sigClaims.push(match[2])
break
default:
break
}
})
2021-01-09 07:22:59 -07:00
let keyData, keyUri
// Try overruling key
if (sigKeys.length > 0) {
try {
keyUri = sigKeys[0]
keyData = await keys.fetch.uri(keyUri)
} catch(e) {}
}
// Try WKD
if (!keyData && signersUserId) {
try {
keyUri = `wkd:${signersUserId}`
keyData = await keys.fetch.uri(keyUri)
} catch(e) {}
}
// Try HKP
if (!keyData) {
try {
const match = preferredKeyServer.match(/^(.*\:\/\/)?([^/]*)(?:\/)?$/i)
keyUri = `hkp:${match[2]}:${issuerKeyId ? issuerKeyId : signersUserId}`
keyData = await keys.fetch.uri(keyUri)
} catch(e) {
errors.push('key_not_found')
reject({ errors: errors })
return
}
2021-01-07 08:26:31 -07:00
}
const fingerprint = keyData.keyPacket.getFingerprint()
try {
const sigVerification = await sigData.verify([keyData])
await sigVerification[0].verified
} catch (e) {
errors.push('invalid_signature_verification')
reject({ errors: errors })
2021-01-09 07:22:59 -07:00
return
2021-01-07 08:26:31 -07:00
}
const claimVerifications = await claims.verify(sigClaims, fingerprint, opts)
resolve({
errors: errors,
2021-01-09 07:22:59 -07:00
signature: {
data: sigData.signature,
issuerKeyId: issuerKeyId,
signersUserId: signersUserId,
preferredKeyServer: preferredKeyServer,
},
publicKey: {
data: keyData,
uri: keyUri,
fingerprint: fingerprint,
},
text: text,
2021-01-07 08:26:31 -07:00
claims: claimVerifications,
})
})
}
exports.verify = verify
}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2021-01-13 05:27:58 -07:00
},{"./claims":10,"./keys":12,"merge-options":5}],30:[function(require,module,exports){
2020-11-18 13:51:53 -07:00
/*
2021-01-13 05:20:33 -07:00
Copyright 2021 Yarmo Mackenbach
2020-11-18 13:51:53 -07: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
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-20 01:15:39 -07:00
},{}]},{},[11])(11)
2020-10-24 06:38:10 -06:00
});