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" ,
2020-12-07 18:59:13 -07:00
"version" : "0.7.4" ,
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" : {
"chai" : "^4.2.0" ,
"chai-as-promised" : "^7.1.1" ,
"chai-match-pattern" : "^1.2.0" ,
"license-check-and-add" : "^3.0.4" ,
"minify" : "^6.0.1" ,
"mocha" : "^8.2.0"
} ,
"scripts" : {
"release:bundle" : "./node_modules/browserify/bin/cmd.js ./src/index.js --standalone doip -o ./dist/doip.js" ,
"release:minify" : "./node_modules/minify/bin/minify.js ./dist/doip.js > ./dist/doip.min.js" ,
"prettier:check" : "./node_modules/prettier/bin-prettier.js --check ." ,
"prettier:write" : "./node_modules/prettier/bin-prettier.js --write ." ,
"license:check" : "./node_modules/license-check-and-add/dist/src/cli.js check" ,
"license:add" : "./node_modules/license-check-and-add/dist/src/cli.js add" ,
"license:remove" : "./node_modules/license-check-and-add/dist/src/cli.js remove" ,
"docs" : "docsify serve ./docs" ,
"test" : "./node_modules/mocha/bin/mocha"
} ,
"repository" : {
"type" : "git" ,
"url" : "https://codeberg.org/keyoxide/doipjs"
} ,
"homepage" : "https://js.doip.rocks" ,
"keywords" : [
"pgp" ,
"gpg" ,
"openpgp" ,
"encryption" ,
"decentralized" ,
"identity"
] ,
"author" : "Yarmo Mackenbach <yarmo@yarmo.eu> (https://yarmo.eu)" ,
"license" : "Apache-2.0"
}
2020-11-20 01:15:39 -07:00
} , { } ] , 10 : [ function ( require , module , exports ) {
2020-11-18 13:51:53 -07:00
/ *
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
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-05 15:17:54 -07:00
const openpgp = require ( path . join (
require . resolve ( 'openpgp' ) ,
'..' ,
'openpgp.min.js'
) )
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 ) {
console . error ( ` Claim verification failed: ${ user . userData . id } ` , e )
reject ( e )
}
} )
} )
return Promise . all ( promises ) . then ( ( values ) => {
return values
} )
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 ) {
console . error ( ` Claim verification failed: ${ uri } ` , e )
reject ( e )
}
} )
} )
2020-10-24 17:22:54 -06:00
2020-11-18 13:51:53 -07:00
return Promise . all ( promises ) . then ( ( values ) => {
return values
} )
}
2020-10-24 06:38:10 -06:00
2020-11-18 13:51:53 -07:00
const uri = input
2020-10-24 17:22:54 -06:00
2020-11-18 13:51:53 -07:00
if ( ! fingerprint ) {
fingerprint = null
}
2020-10-24 06:38:10 -06:00
2020-11-06 10:39:06 -07:00
const defaultOpts = {
returnMatchesOnly : false ,
proxyPolicy : 'adaptive' ,
2020-11-18 13:51:53 -07:00
doipProxyHostname : 'proxy.keyoxide.org' ,
2020-11-06 10:39:06 -07:00
}
2020-11-18 13:51:53 -07:00
opts = mergeOptions ( defaultOpts , opts ? opts : { } )
2020-11-06 10:39:06 -07:00
2020-10-24 06:38:10 -06:00
if ( ! validUrl . isUri ( uri ) ) {
2020-12-05 15:17:54 -07:00
throw new Error ( 'Invalid URI' )
2020-10-24 06:38:10 -06:00
}
2020-10-24 17:22:54 -06:00
const spMatches = serviceproviders . match ( uri , opts )
2020-10-24 06:38:10 -06:00
if ( 'returnMatchesOnly' in opts && opts . returnMatchesOnly ) {
return spMatches
}
2020-11-18 13:51:53 -07:00
let claimVerificationDone = false ,
claimVerificationResult ,
sp ,
iSp = 0 ,
res ,
proofData ,
spData
2020-11-03 14:53:04 -07:00
while ( ! claimVerificationDone && iSp < spMatches . length ) {
2020-10-24 17:22:54 -06:00
spData = spMatches [ iSp ]
spData . claim . fingerprint = fingerprint
res = null
2020-10-26 16:02:22 -06:00
if ( spData . customRequestHandler instanceof Function ) {
proofData = await spData . customRequestHandler ( spData , opts )
2020-11-18 13:51:53 -07:00
} else if (
! spData . proof . useProxy ||
( 'proxyPolicy' in opts && ! opts . useProxyWhenNeeded )
) {
2020-11-06 10:39:06 -07:00
proofData = await serviceproviders . directRequestHandler ( spData , opts )
2020-10-26 16:02:22 -06:00
} else {
2020-11-06 10:39:06 -07:00
proofData = await serviceproviders . proxyRequestHandler ( spData , opts )
2020-10-24 17:22:54 -06:00
}
2020-11-05 04:14:26 -07:00
2020-11-03 14:53:04 -07:00
if ( proofData ) {
2020-11-18 13:51:53 -07:00
claimVerificationResult = runVerification ( proofData , spData )
2020-10-24 06:38:10 -06:00
2020-11-03 14:53:04 -07:00
if ( claimVerificationResult . errors . length == 0 ) {
claimVerificationDone = true
}
}
2020-10-24 06:38:10 -06:00
2020-10-24 17:22:54 -06:00
iSp ++
}
2020-10-24 06:38:10 -06:00
2020-11-03 14:53:04 -07:00
if ( ! claimVerificationResult ) {
claimVerificationResult = {
2020-11-18 13:51:53 -07:00
isVerified : false ,
2020-11-03 14:53:04 -07:00
}
}
2020-10-24 06:38:10 -06:00
return {
2020-11-03 14:53:04 -07:00
isVerified : claimVerificationResult . isVerified ,
2020-11-18 13:51:53 -07:00
serviceproviderData : spData ,
2020-10-24 06:38:10 -06:00
}
}
2020-10-24 17:22:54 -06:00
exports . verify = verify
2020-11-18 13:51:53 -07:00
2020-11-20 01:15:39 -07:00
} , { "./keys" : 12 , "./serviceproviders" : 13 , "./utils" : 28 , "merge-options" : 5 , "path" : 6 , "valid-url" : 8 } ] , 11 : [ function ( require , module , exports ) {
2020-11-18 13:51:53 -07:00
/ *
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
const claims = require ( './claims' )
const keys = require ( './keys' )
const serviceproviders = require ( './serviceproviders' )
const utils = require ( './utils' )
exports . claims = claims
exports . keys = keys
2020-10-24 17:22:54 -06:00
exports . serviceproviders = serviceproviders
exports . utils = utils
2020-10-24 06:38:10 -06:00
2020-11-20 01:15:39 -07:00
} , { "./claims" : 10 , "./keys" : 12 , "./serviceproviders" : 13 , "./utils" : 28 } ] , 12 : [ function ( require , module , exports ) {
2020-11-18 13:51:53 -07:00
/ *
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
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-05 15:17:54 -07:00
const openpgp = require ( path . join (
require . resolve ( 'openpgp' ) ,
'..' ,
'openpgp.min.js'
) )
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
2020-12-07 18:39:30 -07:00
? ` https:// ${ keyserverBaseUrl } / `
2020-11-18 13:51:53 -07:00
: 'https://keys.openpgp.org/'
const hkp = new openpgp . HKP ( keyserverBaseUrl )
const lookupOpts = {
query : identifier ,
}
let publicKey = await hkp . lookup ( lookupOpts )
publicKey = ( await openpgp . key . readArmored ( publicKey ) ) . keys [ 0 ]
2020-12-05 15:17:54 -07:00
if ( publicKey == undefined ) {
reject ( 'Key does not exist or could not be fetched' )
}
resolve ( publicKey )
} )
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 ,
}
const publicKey = ( await wkd . lookup ( lookupOpts ) ) . keys [ 0 ]
2020-12-05 15:17:54 -07:00
if ( publicKey == undefined ) {
reject ( 'Key does not exist or could not be fetched' )
}
resolve ( publicKey )
} )
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
}
const publicKey = ( await openpgp . key . readArmored ( rawKeyContent ) ) . keys [ 0 ]
2020-12-05 15:17:54 -07:00
if ( publicKey == undefined ) {
reject ( 'Key does not exist or could not be fetched' )
}
resolve ( publicKey )
} )
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-07 18:59:13 -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 : {
id : user . userId . userid ,
name : user . userId . name ,
email : user . userId . email ,
comment : user . userId . comment ,
isPrimary : primaryUser . index === i ,
} ,
}
2020-11-18 13:51:53 -07:00
2020-12-05 15:17:54 -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 )
}
}
)
} )
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-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
/ *
2020-10-24 17:22:54 -06:00
Copyright 2020 Yarmo Mackenbach
2020-10-24 06:38:10 -06:00
2020-10-24 17:22:54 -06:00
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
2020-10-24 06:38:10 -06:00
2020-10-24 17:22:54 -06:00
http : //www.apache.org/licenses/LICENSE-2.0
2020-10-24 06:38:10 -06:00
2020-10-24 17:22:54 -06:00
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
2020-10-26 16:02:22 -06:00
const bent = require ( 'bent' )
const req = bent ( 'GET' )
2020-11-05 04:14:26 -07:00
const utils = require ( './utils' )
2020-10-26 16:02:22 -06:00
2020-10-24 17:22:54 -06:00
const list = [
'dns' ,
'xmpp' ,
'twitter' ,
2020-10-26 05:24:30 -06:00
'reddit' ,
2020-11-05 04:14:26 -07:00
'liberapay' ,
2020-10-24 17:22:54 -06:00
'hackernews' ,
'lobsters' ,
2020-10-26 05:24:30 -06:00
'devto' ,
'gitea' ,
2020-10-26 16:02:22 -06:00
'gitlab' ,
2020-10-26 05:24:30 -06:00
'github' ,
2020-11-03 14:53:04 -07:00
'mastodon' ,
'fediverse' ,
'discourse' ,
2020-10-24 17:22:54 -06:00
]
2020-10-24 06:38:10 -06:00
2020-10-24 17:55:32 -06:00
const data = {
dns : require ( './serviceproviders/dns' ) ,
xmpp : require ( './serviceproviders/xmpp' ) ,
twitter : require ( './serviceproviders/twitter' ) ,
2020-10-26 05:24:30 -06:00
reddit : require ( './serviceproviders/reddit' ) ,
2020-11-05 04:14:26 -07:00
liberapay : require ( './serviceproviders/liberapay' ) ,
2020-10-24 17:55:32 -06:00
hackernews : require ( './serviceproviders/hackernews' ) ,
lobsters : require ( './serviceproviders/lobsters' ) ,
2020-10-26 05:24:30 -06:00
devto : require ( './serviceproviders/devto' ) ,
gitea : require ( './serviceproviders/gitea' ) ,
2020-10-26 16:02:22 -06:00
gitlab : require ( './serviceproviders/gitlab' ) ,
2020-10-26 05:24:30 -06:00
github : require ( './serviceproviders/github' ) ,
2020-11-03 14:53:04 -07:00
mastodon : require ( './serviceproviders/mastodon' ) ,
fediverse : require ( './serviceproviders/fediverse' ) ,
discourse : require ( './serviceproviders/discourse' ) ,
2020-10-24 17:55:32 -06:00
}
2020-10-24 06:38:10 -06:00
2020-10-24 17:22:54 -06:00
const match = ( uri , opts ) => {
2020-11-18 13:51:53 -07:00
let matches = [ ] ,
sp
2020-10-24 06:38:10 -06:00
2020-10-24 17:22:54 -06:00
list . forEach ( ( spName , i ) => {
sp = data [ spName ]
if ( sp . reURI . test ( uri ) ) {
matches . push ( sp . processURI ( uri , opts ) )
}
} )
2020-10-24 06:38:10 -06:00
2020-10-24 17:22:54 -06:00
return matches
2020-10-24 06:38:10 -06:00
}
2020-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' :
res = await req ( url , null , {
Accept : 'application/json' ,
'User-Agent' : ` doipjs/ ${ require ( '../package.json' ) . version } ` ,
} )
resolve ( await res . json ( ) )
break
case 'text' :
res = await req ( url )
resolve ( await res . text ( ) )
break
default :
reject ( 'No specified proof data format' )
break
}
} )
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
const res = await req (
utils . generateProxyURL ( spData . proof . format , url , opts ) ,
null ,
{ Accept : 'application/json' }
)
const json = await res . json ( )
resolve ( json . content )
} )
2020-10-26 16:02:22 -06:00
}
2020-10-24 17:22:54 -06:00
exports . list = list
exports . data = data
exports . match = match
2020-10-26 16:02:22 -06:00
exports . directRequestHandler = directRequestHandler
exports . proxyRequestHandler = proxyRequestHandler
2020-10-24 17:22:54 -06:00
2020-11-20 01:15:39 -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/reddit" : 25 , "./serviceproviders/twitter" : 26 , "./serviceproviders/xmpp" : 27 , "./utils" : 28 , "bent" : 1 } ] , 14 : [ function ( require , module , exports ) {
2020-10-26 05:24:30 -06:00
/ *
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
const reURI = /^https:\/\/dev\.to\/(.*)\/(.*)\/?/
const processURI = ( uri , opts ) => {
2020-11-18 13:51:53 -07:00
if ( ! opts ) {
opts = { }
}
2020-10-26 05:24:30 -06:00
const match = uri . match ( reURI )
return {
serviceprovider : {
type : 'web' ,
2020-11-18 13:51:53 -07:00
name : 'devto' ,
2020-10-26 05:24:30 -06:00
} ,
profile : {
display : match [ 1 ] ,
2020-11-06 10:39:06 -07:00
uri : ` https://dev.to/ ${ match [ 1 ] } ` ,
2020-11-18 13:51:53 -07:00
qr : null ,
2020-10-26 05:24:30 -06:00
} ,
proof : {
uri : uri ,
fetch : ` https://dev.to/api/articles/ ${ match [ 1 ] } / ${ match [ 2 ] } ` ,
useProxy : false ,
2020-11-18 13:51:53 -07:00
format : 'json' ,
2020-10-26 05:24:30 -06:00
} ,
claim : {
fingerprint : null ,
format : 'message' ,
path : [ 'body_markdown' ] ,
2020-11-18 13:51:53 -07:00
relation : 'contains' ,
2020-10-26 05:24:30 -06:00
} ,
2020-11-18 13:51:53 -07:00
customRequestHandler : null ,
2020-10-26 05:24:30 -06:00
}
}
const tests = [
{
uri : 'https://dev.to/alice/post' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-10-26 05:24:30 -06:00
} ,
{
uri : 'https://dev.to/alice/post/' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-10-26 05:24:30 -06:00
} ,
{
uri : 'https://domain.org/alice/post' ,
2020-11-18 13:51:53 -07:00
shouldMatch : false ,
} ,
2020-10-26 05:24:30 -06:00
]
exports . reURI = reURI
exports . processURI = processURI
exports . tests = tests
2020-11-20 01:15:39 -07:00
} , { } ] , 15 : [ function ( require , module , exports ) {
2020-10-24 17:55:32 -06:00
/ *
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
2020-11-03 14:53:04 -07:00
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
const reURI = /^https:\/\/(.*)\/u\/(.*)\/?/
const processURI = ( uri , opts ) => {
2020-11-18 13:51:53 -07:00
if ( ! opts ) {
opts = { }
}
2020-11-03 14:53:04 -07:00
const match = uri . match ( reURI )
return {
serviceprovider : {
type : 'web' ,
2020-11-18 13:51:53 -07:00
name : 'discourse' ,
2020-11-03 14:53:04 -07:00
} ,
profile : {
display : ` ${ match [ 2 ] } @ ${ match [ 1 ] } ` ,
2020-11-06 10:39:06 -07:00
uri : uri ,
2020-11-18 13:51:53 -07:00
qr : null ,
2020-11-03 14:53:04 -07:00
} ,
proof : {
uri : uri ,
fetch : ` https:// ${ match [ 1 ] } /u/ ${ match [ 2 ] } .json ` ,
useProxy : true ,
2020-11-18 13:51:53 -07:00
format : 'json' ,
2020-11-03 14:53:04 -07:00
} ,
claim : {
fingerprint : null ,
format : 'message' ,
path : [ 'user' , 'bio_raw' ] ,
2020-11-18 13:51:53 -07:00
relation : 'contains' ,
2020-11-03 14:53:04 -07:00
} ,
2020-11-18 13:51:53 -07:00
customRequestHandler : null ,
2020-11-03 14:53:04 -07:00
}
}
const tests = [
{
uri : 'https://domain.org/u/alice' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-11-03 14:53:04 -07:00
} ,
{
uri : 'https://domain.org/u/alice/' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-11-03 14:53:04 -07:00
} ,
{
uri : 'https://domain.org/alice' ,
2020-11-18 13:51:53 -07:00
shouldMatch : false ,
} ,
2020-11-03 14:53:04 -07:00
]
exports . reURI = reURI
exports . processURI = processURI
exports . tests = tests
2020-11-20 01:15:39 -07:00
} , { } ] , 16 : [ function ( require , module , exports ) {
2020-11-03 14:53:04 -07:00
/ *
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
2020-10-24 17:55:32 -06:00
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
2020-11-06 10:39:06 -07:00
const dns = require ( 'dns' )
const bent = require ( 'bent' )
const req = bent ( 'GET' )
2020-11-05 04:14:26 -07:00
const utils = require ( '../utils' )
2020-10-24 17:55:32 -06:00
const reURI = /^dns:([a-zA-Z0-9\.\-\_]*)(?:\?(.*))?/
2020-11-06 10:39:06 -07:00
const customRequestHandler = async ( spData , opts ) => {
2020-11-18 13:51:53 -07:00
if ( 'resolveTxt' in dns ) {
2020-11-06 10:39:06 -07:00
const prom = async ( ) => {
return new Promise ( ( resolve , reject ) => {
dns . resolveTxt ( spData . profile . display , ( err , records ) => {
if ( err ) reject ( err )
resolve ( records )
} )
} )
}
return {
hostname : spData . profile . display ,
records : {
2020-11-18 13:51:53 -07:00
txt : await prom ( ) ,
} ,
2020-11-06 10:39:06 -07:00
}
} else {
2020-11-18 13:51:53 -07:00
const res = await req ( spData . proof . uri , null , {
Accept : 'application/json' ,
} )
2020-11-06 10:39:06 -07:00
const json = await res . json ( )
return json
}
}
2020-10-24 17:55:32 -06:00
const processURI = ( uri , opts ) => {
2020-11-18 13:51:53 -07:00
if ( ! opts ) {
opts = { }
}
2020-10-24 17:55:32 -06:00
const match = uri . match ( reURI )
return {
serviceprovider : {
type : 'web' ,
2020-11-18 13:51:53 -07:00
name : 'dns' ,
2020-10-24 17:55:32 -06:00
} ,
profile : {
display : match [ 1 ] ,
2020-11-06 10:39:06 -07:00
uri : ` https:// ${ match [ 1 ] } ` ,
2020-11-18 13:51:53 -07:00
qr : null ,
2020-10-24 17:55:32 -06:00
} ,
proof : {
2020-11-05 04:14:26 -07:00
uri : utils . generateProxyURL ( 'dns' , match [ 1 ] ) ,
2020-10-24 17:55:32 -06:00
fetch : null ,
useProxy : false ,
2020-11-18 13:51:53 -07:00
format : 'json' ,
2020-10-24 17:55:32 -06:00
} ,
claim : {
fingerprint : null ,
format : 'uri' ,
2020-11-05 04:14:26 -07:00
path : [ 'records' , 'txt' ] ,
2020-11-18 13:51:53 -07:00
relation : 'contains' ,
2020-10-24 17:55:32 -06:00
} ,
2020-11-18 13:51:53 -07:00
customRequestHandler : customRequestHandler ,
2020-10-24 17:55:32 -06:00
}
}
const tests = [
{
uri : 'dns:domain.org' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-10-24 17:55:32 -06:00
} ,
{
uri : 'dns:domain.org?type=TXT' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-10-24 17:55:32 -06:00
} ,
{
uri : 'https://domain.org' ,
2020-11-18 13:51:53 -07:00
shouldMatch : false ,
} ,
2020-10-24 17:55:32 -06:00
]
exports . reURI = reURI
exports . processURI = processURI
exports . tests = tests
2020-11-20 01:15:39 -07:00
} , { "../utils" : 28 , "bent" : 1 , "dns" : 3 } ] , 17 : [ function ( require , module , exports ) {
2020-11-03 14:53:04 -07:00
/ *
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
const reURI = /^https:\/\/(.*)\/users\/(.*)\/?/
const processURI = ( uri , opts ) => {
2020-11-18 13:51:53 -07:00
if ( ! opts ) {
opts = { }
}
2020-11-03 14:53:04 -07:00
const match = uri . match ( reURI )
return {
serviceprovider : {
type : 'web' ,
2020-11-18 13:51:53 -07:00
name : 'fediverse' ,
2020-11-03 14:53:04 -07:00
} ,
profile : {
display : ` @ ${ match [ 2 ] } @ ${ match [ 1 ] } ` ,
2020-11-06 10:39:06 -07:00
uri : uri ,
2020-11-18 13:51:53 -07:00
qr : null ,
2020-11-03 14:53:04 -07:00
} ,
proof : {
uri : uri ,
fetch : null ,
useProxy : false ,
2020-11-18 13:51:53 -07:00
format : 'json' ,
2020-11-03 14:53:04 -07:00
} ,
claim : {
fingerprint : null ,
format : 'fingerprint' ,
path : [ 'summary' ] ,
2020-11-18 13:51:53 -07:00
relation : 'contains' ,
2020-11-03 14:53:04 -07:00
} ,
2020-11-18 13:51:53 -07:00
customRequestHandler : null ,
2020-11-03 14:53:04 -07:00
}
}
const tests = [
{
uri : 'https://domain.org/users/alice' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-11-03 14:53:04 -07:00
} ,
{
uri : 'https://domain.org/users/alice/' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-11-03 14:53:04 -07:00
} ,
{
uri : 'https://domain.org/alice' ,
2020-11-18 13:51:53 -07:00
shouldMatch : false ,
} ,
2020-11-03 14:53:04 -07:00
]
exports . reURI = reURI
exports . processURI = processURI
exports . tests = tests
2020-11-20 01:15:39 -07:00
} , { } ] , 18 : [ function ( require , module , exports ) {
2020-10-26 05:24:30 -06:00
/ *
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
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
/ *
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
2020-11-05 04:14:26 -07:00
const reURI = /^https:\/\/gist\.github\.com\/(.*)\/(.*)\/?/
2020-10-26 05:24:30 -06:00
const processURI = ( uri , opts ) => {
2020-11-18 13:51:53 -07:00
if ( ! opts ) {
opts = { }
}
2020-10-26 05:24:30 -06:00
const match = uri . match ( reURI )
return {
serviceprovider : {
type : 'web' ,
2020-11-18 13:51:53 -07:00
name : 'github' ,
2020-10-26 05:24:30 -06:00
} ,
profile : {
display : match [ 1 ] ,
2020-11-06 10:39:06 -07:00
uri : ` https://github.com/ ${ match [ 1 ] } ` ,
2020-11-18 13:51:53 -07:00
qr : null ,
2020-10-26 05:24:30 -06:00
} ,
proof : {
uri : uri ,
fetch : ` https://api.github.com/gists/ ${ match [ 2 ] } ` ,
useProxy : false ,
2020-11-18 13:51:53 -07:00
format : 'json' ,
2020-10-26 05:24:30 -06:00
} ,
claim : {
fingerprint : null ,
format : 'message' ,
path : [ 'files' , 'openpgp.md' , 'content' ] ,
2020-11-18 13:51:53 -07:00
relation : 'contains' ,
2020-10-26 05:24:30 -06:00
} ,
2020-11-18 13:51:53 -07:00
customRequestHandler : null ,
2020-10-26 05:24:30 -06:00
}
}
const tests = [
{
uri : 'https://gist.github.com/Alice/123456789' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-10-26 05:24:30 -06:00
} ,
{
uri : 'https://gist.github.com/Alice/123456789/' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-10-26 05:24:30 -06:00
} ,
{
uri : 'https://domain.org/Alice/123456789' ,
2020-11-18 13:51:53 -07:00
shouldMatch : false ,
} ,
2020-10-26 05:24:30 -06:00
]
exports . reURI = reURI
exports . processURI = processURI
exports . tests = tests
2020-11-20 01:15:39 -07:00
} , { } ] , 20 : [ function ( require , module , exports ) {
2020-10-24 17:55:32 -06:00
/ *
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
2020-10-26 16:02:22 -06:00
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
const bent = require ( 'bent' )
const req = bent ( 'GET' )
const reURI = /^https:\/\/(.*)\/(.*)\/gitlab_proof\/?/
const customRequestHandler = async ( spData , opts ) => {
const match = spData . proof . uri . match ( reURI )
const urlUser = ` https:// ${ match [ 1 ] } /api/v4/users?username= ${ match [ 2 ] } `
2020-11-03 14:53:04 -07:00
const resUser = await req ( urlUser , 'json' , { Accept : 'application/json' } )
2020-10-26 16:02:22 -06:00
const jsonUser = await resUser . json ( )
2020-11-18 13:51:53 -07:00
const user = jsonUser . find ( ( user ) => user . username === match [ 2 ] )
2020-10-26 16:02:22 -06:00
if ( ! user ) {
2020-11-18 13:51:53 -07:00
throw new Error ( ` No user with username ${ match [ 2 ] } ` )
2020-10-26 16:02:22 -06:00
}
const urlProject = ` https:// ${ match [ 1 ] } /api/v4/users/ ${ user . id } /projects `
const resProject = await req ( urlProject , { } , { Accept : 'application/json' } )
const jsonProject = await resProject . json ( )
2020-11-18 13:51:53 -07:00
const project = jsonProject . find ( ( proj ) => proj . path === 'gitlab_proof' )
2020-10-26 16:02:22 -06:00
if ( ! project ) {
2020-11-18 13:51:53 -07:00
throw new Error ( ` No project at ${ spData . proof . uri } ` )
2020-10-26 16:02:22 -06:00
}
return project
}
const processURI = ( uri , opts ) => {
2020-11-18 13:51:53 -07:00
if ( ! opts ) {
opts = { }
}
2020-10-26 16:02:22 -06:00
const match = uri . match ( reURI )
return {
serviceprovider : {
type : 'web' ,
2020-11-18 13:51:53 -07:00
name : 'gitlab' ,
2020-10-26 16:02:22 -06:00
} ,
profile : {
display : ` ${ match [ 2 ] } @ ${ match [ 1 ] } ` ,
2020-11-06 10:39:06 -07:00
uri : ` https:// ${ match [ 1 ] } / ${ match [ 2 ] } ` ,
2020-11-18 13:51:53 -07:00
qr : null ,
2020-10-26 16:02:22 -06:00
} ,
proof : {
uri : uri ,
fetch : null ,
useProxy : false ,
2020-11-18 13:51:53 -07:00
format : 'json' ,
2020-10-26 16:02:22 -06:00
} ,
claim : {
fingerprint : null ,
format : 'message' ,
path : [ 'description' ] ,
2020-11-18 13:51:53 -07:00
relation : 'equals' ,
2020-10-26 16:02:22 -06:00
} ,
2020-11-18 13:51:53 -07:00
customRequestHandler : customRequestHandler ,
2020-10-26 16:02:22 -06:00
}
}
const tests = [
{
uri : 'https://gitlab.domain.org/alice/gitlab_proof' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-10-26 16:02:22 -06:00
} ,
{
uri : 'https://gitlab.domain.org/alice/gitlab_proof/' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-10-26 16:02:22 -06:00
} ,
{
uri : 'https://domain.org/alice/other_proof' ,
2020-11-18 13:51:53 -07:00
shouldMatch : false ,
} ,
2020-10-26 16:02:22 -06:00
]
exports . reURI = reURI
exports . processURI = processURI
exports . tests = tests
2020-11-20 01:15:39 -07:00
} , { "bent" : 1 } ] , 21 : [ function ( require , module , exports ) {
2020-10-26 16:02:22 -06:00
/ *
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
2020-10-24 17:55:32 -06:00
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
2020-11-05 04:14:26 -07:00
const reURI = /^https:\/\/news\.ycombinator\.com\/user\?id=(.*)\/?/
2020-10-24 17:55:32 -06:00
const processURI = ( uri , opts ) => {
2020-11-18 13:51:53 -07:00
if ( ! opts ) {
opts = { }
}
2020-10-24 17:55:32 -06:00
const match = uri . match ( reURI )
return {
serviceprovider : {
type : 'web' ,
2020-11-18 13:51:53 -07:00
name : 'hackernews' ,
2020-10-24 17:55:32 -06:00
} ,
profile : {
display : match [ 1 ] ,
2020-11-06 10:39:06 -07:00
uri : uri ,
2020-11-18 13:51:53 -07:00
qr : null ,
2020-10-24 17:55:32 -06:00
} ,
proof : {
uri : ` https://hacker-news.firebaseio.com/v0/user/ ${ match [ 1 ] } .json ` ,
fetch : null ,
useProxy : true ,
2020-11-18 13:51:53 -07:00
format : 'json' ,
2020-10-24 17:55:32 -06:00
} ,
claim : {
fingerprint : null ,
format : 'uri' ,
path : [ 'about' ] ,
2020-11-18 13:51:53 -07:00
relation : 'contains' ,
2020-10-24 17:55:32 -06:00
} ,
2020-11-18 13:51:53 -07:00
customRequestHandler : null ,
2020-10-24 17:55:32 -06:00
}
}
const tests = [
{
uri : 'https://news.ycombinator.com/user?id=Alice' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-10-24 17:55:32 -06:00
} ,
{
uri : 'https://news.ycombinator.com/user?id=Alice/' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-10-24 17:55:32 -06:00
} ,
{
uri : 'https://domain.org/user?id=Alice' ,
2020-11-18 13:51:53 -07:00
shouldMatch : false ,
} ,
2020-10-24 17:55:32 -06:00
]
exports . reURI = reURI
exports . processURI = processURI
exports . tests = tests
2020-11-20 01:15:39 -07:00
} , { } ] , 22 : [ function ( require , module , exports ) {
2020-11-05 04:14:26 -07:00
/ *
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
const reURI = /^https:\/\/liberapay\.com\/(.*)\/?/
const processURI = ( uri , opts ) => {
2020-11-18 13:51:53 -07:00
if ( ! opts ) {
opts = { }
}
2020-11-05 04:14:26 -07:00
const match = uri . match ( reURI )
return {
serviceprovider : {
type : 'web' ,
2020-11-18 13:51:53 -07:00
name : 'liberapay' ,
2020-11-05 04:14:26 -07:00
} ,
profile : {
display : match [ 1 ] ,
2020-11-06 10:39:06 -07:00
uri : uri ,
2020-11-18 13:51:53 -07:00
qr : null ,
2020-11-05 04:14:26 -07:00
} ,
proof : {
uri : uri ,
fetch : ` https://liberapay.com/ ${ match [ 1 ] } /public.json ` ,
useProxy : false ,
2020-11-18 13:51:53 -07:00
format : 'json' ,
2020-11-05 04:14:26 -07:00
} ,
claim : {
fingerprint : null ,
format : 'message' ,
path : [ 'statements' , 'content' ] ,
2020-11-18 13:51:53 -07:00
relation : 'contains' ,
2020-11-05 04:14:26 -07:00
} ,
2020-11-18 13:51:53 -07:00
customRequestHandler : null ,
2020-11-05 04:14:26 -07:00
}
}
const tests = [
{
uri : 'https://liberapay.com/alice' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-11-05 04:14:26 -07:00
} ,
{
uri : 'https://liberapay.com/alice/' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-11-05 04:14:26 -07:00
} ,
{
uri : 'https://domain.org/alice' ,
2020-11-18 13:51:53 -07:00
shouldMatch : false ,
} ,
2020-11-05 04:14:26 -07:00
]
exports . reURI = reURI
exports . processURI = processURI
exports . tests = tests
2020-11-20 01:15:39 -07:00
} , { } ] , 23 : [ function ( require , module , exports ) {
2020-10-24 17:55:32 -06:00
/ *
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
2020-11-05 04:14:26 -07:00
const reURI = /^https:\/\/lobste\.rs\/u\/(.*)\/?/
2020-10-24 17:55:32 -06:00
const processURI = ( uri , opts ) => {
2020-11-18 13:51:53 -07:00
if ( ! opts ) {
opts = { }
}
2020-10-24 17:55:32 -06:00
const match = uri . match ( reURI )
return {
serviceprovider : {
type : 'web' ,
2020-11-18 13:51:53 -07:00
name : 'lobsters' ,
2020-10-24 17:55:32 -06:00
} ,
profile : {
display : match [ 1 ] ,
2020-11-06 10:39:06 -07:00
uri : uri ,
2020-11-18 13:51:53 -07:00
qr : null ,
2020-10-24 17:55:32 -06:00
} ,
proof : {
uri : ` https://lobste.rs/u/ ${ match [ 1 ] } .json ` ,
fetch : null ,
useProxy : true ,
2020-11-18 13:51:53 -07:00
format : 'json' ,
2020-10-24 17:55:32 -06:00
} ,
claim : {
fingerprint : null ,
format : 'message' ,
path : [ 'about' ] ,
2020-11-18 13:51:53 -07:00
relation : 'contains' ,
2020-10-24 17:55:32 -06:00
} ,
2020-11-18 13:51:53 -07:00
customRequestHandler : null ,
2020-10-24 17:55:32 -06:00
}
}
const tests = [
{
uri : 'https://lobste.rs/u/Alice' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-10-24 17:55:32 -06:00
} ,
{
uri : 'https://lobste.rs/u/Alice/' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-10-24 17:55:32 -06:00
} ,
{
uri : 'https://domain.org/u/Alice' ,
2020-11-18 13:51:53 -07:00
shouldMatch : false ,
} ,
2020-10-24 17:55:32 -06:00
]
exports . reURI = reURI
exports . processURI = processURI
exports . tests = tests
2020-11-20 01:15:39 -07:00
} , { } ] , 24 : [ function ( require , module , exports ) {
2020-11-03 14:53:04 -07:00
/ *
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
const reURI = /^https:\/\/(.*)\/@(.*)\/?/
const processURI = ( uri , opts ) => {
2020-11-18 13:51:53 -07:00
if ( ! opts ) {
opts = { }
}
2020-11-03 14:53:04 -07:00
const match = uri . match ( reURI )
return {
serviceprovider : {
type : 'web' ,
2020-11-18 13:51:53 -07:00
name : 'mastodon' ,
2020-11-03 14:53:04 -07:00
} ,
profile : {
display : ` @ ${ match [ 2 ] } @ ${ match [ 1 ] } ` ,
2020-11-06 10:39:06 -07:00
uri : uri ,
2020-11-18 13:51:53 -07:00
qr : null ,
2020-11-03 14:53:04 -07:00
} ,
proof : {
uri : uri ,
fetch : null ,
useProxy : false ,
2020-11-18 13:51:53 -07:00
format : 'json' ,
2020-11-03 14:53:04 -07:00
} ,
claim : {
fingerprint : null ,
format : 'fingerprint' ,
path : [ 'attachment' , 'value' ] ,
2020-11-18 13:51:53 -07:00
relation : 'contains' ,
2020-11-03 14:53:04 -07:00
} ,
2020-11-18 13:51:53 -07:00
customRequestHandler : null ,
2020-11-03 14:53:04 -07:00
}
}
const tests = [
{
uri : 'https://domain.org/@alice' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-11-03 14:53:04 -07:00
} ,
{
uri : 'https://domain.org/@alice/' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-11-03 14:53:04 -07:00
} ,
{
uri : 'https://domain.org/alice' ,
2020-11-18 13:51:53 -07:00
shouldMatch : false ,
} ,
2020-11-03 14:53:04 -07:00
]
exports . reURI = reURI
exports . processURI = processURI
exports . tests = tests
2020-11-20 01:15:39 -07:00
} , { } ] , 25 : [ function ( require , module , exports ) {
2020-10-26 05:24:30 -06:00
/ *
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
const reURI = /^https:\/\/(?:www\.)?reddit\.com\/user\/(.*)\/comments\/(.*)\/(.*)\/?/
const processURI = ( uri , opts ) => {
2020-11-18 13:51:53 -07:00
if ( ! opts ) {
opts = { }
}
2020-10-26 05:24:30 -06:00
const match = uri . match ( reURI )
return {
serviceprovider : {
type : 'web' ,
2020-11-18 13:51:53 -07:00
name : 'reddit' ,
2020-10-26 05:24:30 -06:00
} ,
profile : {
display : match [ 1 ] ,
2020-11-06 10:39:06 -07:00
uri : ` https://www.reddit.com/user/ ${ match [ 1 ] } ` ,
2020-11-18 13:51:53 -07:00
qr : null ,
2020-10-26 05:24:30 -06:00
} ,
proof : {
uri : uri ,
fetch : ` https://www.reddit.com/user/ ${ match [ 1 ] } /comments/ ${ match [ 2 ] } .json ` ,
useProxy : true ,
2020-11-18 13:51:53 -07:00
format : 'json' ,
2020-10-26 05:24:30 -06:00
} ,
claim : {
fingerprint : null ,
format : 'message' ,
path : [ 'data' , 'children' , 'data' , 'selftext' ] ,
2020-11-18 13:51:53 -07:00
relation : 'contains' ,
2020-10-26 05:24:30 -06:00
} ,
2020-11-18 13:51:53 -07:00
customRequestHandler : null ,
2020-10-26 05:24:30 -06:00
}
}
const tests = [
{
uri : 'https://www.reddit.com/user/Alice/comments/123456/post' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-10-26 05:24:30 -06:00
} ,
{
uri : 'https://www.reddit.com/user/Alice/comments/123456/post/' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-10-26 05:24:30 -06:00
} ,
{
uri : 'https://reddit.com/user/Alice/comments/123456/post' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-10-26 05:24:30 -06:00
} ,
{
uri : 'https://reddit.com/user/Alice/comments/123456/post/' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-10-26 05:24:30 -06:00
} ,
{
uri : 'https://domain.org/user/Alice/comments/123456/post' ,
2020-11-18 13:51:53 -07:00
shouldMatch : false ,
} ,
2020-10-26 05:24:30 -06:00
]
exports . reURI = reURI
exports . processURI = processURI
exports . tests = tests
2020-11-20 01:15:39 -07:00
} , { } ] , 26 : [ function ( require , module , exports ) {
2020-10-24 17:55:32 -06:00
/ *
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
const reURI = /^https:\/\/twitter\.com\/(.*)\/status\/([0-9]*)(?:\?.*)?/
const processURI = ( uri , opts ) => {
2020-11-18 13:51:53 -07:00
if ( ! opts ) {
opts = { }
}
2020-10-24 17:55:32 -06:00
const match = uri . match ( reURI )
return {
serviceprovider : {
type : 'web' ,
2020-11-18 13:51:53 -07:00
name : 'twitter' ,
2020-10-24 17:55:32 -06:00
} ,
profile : {
display : ` @ ${ match [ 1 ] } ` ,
2020-11-06 10:39:06 -07:00
uri : ` https://twitter.com/ ${ match [ 1 ] } ` ,
2020-11-18 13:51:53 -07:00
qr : null ,
2020-10-24 17:55:32 -06:00
} ,
proof : {
uri : uri ,
fetch : ` https://mobile.twitter.com/ ${ match [ 1 ] } /status/ ${ match [ 2 ] } ` ,
useProxy : false ,
2020-11-18 13:51:53 -07:00
format : 'text' ,
2020-10-24 17:55:32 -06:00
} ,
claim : {
fingerprint : null ,
format : 'message' ,
path : [ ] ,
2020-11-18 13:51:53 -07:00
relation : 'contains' ,
2020-10-24 17:55:32 -06:00
} ,
2020-11-18 13:51:53 -07:00
customRequestHandler : null ,
2020-10-24 17:55:32 -06:00
}
}
const tests = [
{
uri : 'https://twitter.com/alice/status/1234567890123456789' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-10-24 17:55:32 -06:00
} ,
{
uri : 'https://twitter.com/alice/status/1234567890123456789/' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-10-24 17:55:32 -06:00
} ,
{
uri : 'https://domain.org/alice/status/1234567890123456789' ,
2020-11-18 13:51:53 -07:00
shouldMatch : false ,
} ,
2020-10-24 17:55:32 -06:00
]
exports . reURI = reURI
exports . processURI = processURI
exports . tests = tests
2020-11-20 01:15:39 -07:00
} , { } ] , 27 : [ function ( require , module , exports ) {
2020-10-24 17:55:32 -06:00
/ *
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
2020-11-18 13:51:53 -07:00
const utils = require ( '../utils' )
2020-10-24 17:55:32 -06:00
const reURI = /^xmpp:([a-zA-Z0-9\.\-\_]*)@([a-zA-Z0-9\.\-\_]*)(?:\?(.*))?/
const processURI = ( uri , opts ) => {
2020-11-18 13:51:53 -07:00
if ( ! opts ) {
opts = { }
}
2020-10-24 17:55:32 -06:00
const match = uri . match ( reURI )
return {
serviceprovider : {
type : 'communication' ,
2020-11-18 13:51:53 -07:00
name : 'xmpp' ,
2020-10-24 17:55:32 -06:00
} ,
profile : {
display : ` ${ match [ 1 ] } @ ${ match [ 2 ] } ` ,
2020-11-06 10:39:06 -07:00
uri : uri ,
2020-11-18 13:51:53 -07:00
qr : uri ,
2020-10-24 17:55:32 -06:00
} ,
proof : {
2020-11-18 13:51:53 -07:00
uri : utils . generateProxyURL ( 'xmpp' , ` ${ match [ 1 ] } @ ${ match [ 2 ] } ` , opts ) ,
2020-10-24 17:55:32 -06:00
fetch : null ,
useProxy : false ,
2020-11-18 13:51:53 -07:00
format : 'json' ,
2020-10-24 17:55:32 -06:00
} ,
claim : {
fingerprint : null ,
format : 'message' ,
path : [ ] ,
2020-11-18 13:51:53 -07:00
relation : 'contains' ,
2020-10-24 17:55:32 -06:00
} ,
2020-11-18 13:51:53 -07:00
customRequestHandler : null ,
2020-10-24 17:55:32 -06:00
}
}
const tests = [
{
uri : 'xmpp:alice@domain.org' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-10-24 17:55:32 -06:00
} ,
{
uri : 'xmpp:alice@domain.org?omemo-sid-123456789=A1B2C3D4E5F6G7H8I9' ,
2020-11-18 13:51:53 -07:00
shouldMatch : true ,
2020-10-24 17:55:32 -06:00
} ,
{
uri : 'https://domain.org' ,
2020-11-18 13:51:53 -07:00
shouldMatch : false ,
} ,
2020-10-24 17:55:32 -06:00
]
exports . reURI = reURI
exports . processURI = processURI
exports . tests = tests
2020-11-20 01:15:39 -07:00
} , { "../utils" : 28 } ] , 28 : [ function ( require , module , exports ) {
2020-11-18 13:51:53 -07:00
/ *
Copyright 2020 Yarmo Mackenbach
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
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
} ) ;